diff --git a/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.hxx b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.hxx
index 1ce76429cc78e6defee2257f2c8cf70261509032..af0da7566604d0ebf2103c2a9d9cc90f6cf771f2 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.hxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.hxx
@@ -68,29 +68,28 @@ automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, ext::pair < ext::s
 	automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, DeterministicPushdownStoreSymbolType, DeterministicStateType > dpda ( initialLabel, bottom );
 	dpda.setInputAlphabet ( npda.getInputAlphabet ( ) );
 
-	ext::set < ext::pair < DeterministicStateType, DeterministicPushdownStoreSymbolType > > rubbishReturnTransitions;
+	ext::map < DeterministicStateType, ext::set < DeterministicStateType > > localClosure;
+	ext::map < DeterministicStateType, ext::set < DeterministicPushdownStoreSymbolType > > topSymbols;
 
-	for(;;) {
-		ext::set<ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType>> stateSymbols = existsDirtyStateSymbol(dpda, npda);
+	std::queue < DeterministicStateType > dirtyStates;
+	dirtyStates.push ( initialLabel );
 
-		for ( const ext::pair < DeterministicStateType, DeterministicPushdownStoreSymbolType > & rubbishStateSymbols : rubbishReturnTransitions ) {
-			stateSymbols.erase ( rubbishStateSymbols );
-		}
+	std::queue < ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType> > dirtyStateSymbols;
+	dirtyStateSymbols.push ( ext::make_pair ( initialLabel, bottom ) );
 
-		ext::set<DeterministicStateType> states = existsDirtyState(dpda, npda);
+	while ( ! dirtyStateSymbols.empty ( ) || ! dirtyStates.empty ( ) ) {
+		if ( ! dirtyStateSymbols.empty ( ) ) {
+			DeterministicStateType state = std::move ( dirtyStateSymbols.front ( ).first );
+			DeterministicPushdownStoreSymbolType pdaSymbol = std::move ( dirtyStateSymbols.front ( ).second );
 
-		if(stateSymbols.empty() && states.empty()) break;
+			dirtyStateSymbols.pop ( );
 
-		for ( const ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType> & stateSymbol : stateSymbols ) {
 			if ( common::GlobalData::verbose )
-				common::Streams::log << "Dirty state symbol: " << stateSymbol << std::endl;
-
-			ext::set<common::symbol_or_epsilon < InputSymbolType >> retPart = getRetPartitioning(npda, stateSymbol.first);
+				common::Streams::log << "Dirty state: " << state << " symbol: " << pdaSymbol << std::endl;
 
-			const DeterministicStateType & state = stateSymbol.first;
-			const DeterministicPushdownStoreSymbolType & pdaSymbol = stateSymbol.second;
+			ext::set<common::symbol_or_epsilon < InputSymbolType >> retPart = getRetPartitioning(npda, state);
 
-			for(const common::symbol_or_epsilon < InputSymbolType > & input : retPart ) {
+			for( common::symbol_or_epsilon < InputSymbolType > && input : ext::make_mover ( retPart ) ) {
 				DeterministicStateType to;
 
 				if ( pdaSymbol == dpda.getBottomOfTheStackSymbol ( ) )
@@ -98,37 +97,58 @@ automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, ext::pair < ext::s
 				else
 					to = ret ( state, pdaSymbol, input, npda );
 
-				if ( ! to.empty ( ) ) {
-					dpda.addState ( to );
-					dpda.addReturnTransition ( state, input, pdaSymbol, std::move ( to ) );
-				} else
-					rubbishReturnTransitions.insert ( ext::make_pair ( state, pdaSymbol ) );
+				if ( to.empty ( ) )
+					continue;
+
+				if ( dpda.addState ( to ) )
+					dirtyStates.push ( to );
+
+				localClosure [ pdaSymbol.first ].insert ( to );
+
+				updateTopSymbols ( localClosure, topSymbols, dirtyStateSymbols, to, topSymbols [ pdaSymbol.first ] );
+
+				dpda.addReturnTransition ( state, std::move ( input ), pdaSymbol, std::move ( to ) );
 			}
-		}
+		} else { // ! dirtyStates.empty ( )
+			DeterministicStateType state = std::move ( dirtyStates.front ( ) );
+			dirtyStates.pop ( );
 
-		for(const auto& state : states) {
 			if ( common::GlobalData::verbose )
 				common::Streams::log << "Dirty state: " << state << std::endl;
 
 			ext::set<common::symbol_or_epsilon < InputSymbolType >> localPart = getLocalPartitioning(npda, state);
 			ext::set<common::symbol_or_epsilon < InputSymbolType >> callPart = getCallPartitioning(npda, state);
 
-			for ( const common::symbol_or_epsilon < InputSymbolType > & input : localPart ) {
+			for ( common::symbol_or_epsilon < InputSymbolType > && input : ext::make_mover ( localPart ) ) {
 				DeterministicStateType to = local ( state, input, npda );
-				if ( ! to.empty ( ) ) {
-					dpda.addState ( to );
-					dpda.addLocalTransition ( state, input, std::move ( to ) );
-				}
+
+				if ( to.empty ( ) )
+					continue;
+
+				if ( dpda.addState ( to ) )
+					dirtyStates.push ( to );
+
+				localClosure [ state ].insert ( to );
+
+				updateTopSymbols ( localClosure, topSymbols, dirtyStateSymbols, to, topSymbols [ state ] );
+
+				dpda.addLocalTransition ( state, std::move ( input ), std::move ( to ) );
 			}
-			for ( const common::symbol_or_epsilon < InputSymbolType > & input : callPart ) {
+			for ( common::symbol_or_epsilon < InputSymbolType > && input : ext::make_mover ( callPart ) ) {
 				DeterministicStateType to = call ( state, input, npda );
-				if ( ! to.empty ( ) ) {
-					ext::pair < DeterministicStateType, common::symbol_or_epsilon < InputSymbolType > > pdaSymbol = ext::make_pair ( state, input );
 
-					dpda.addState ( to );
-					dpda.addPushdownStoreSymbol ( pdaSymbol );
-					dpda.addCallTransition ( state, input, std::move ( to ), std::move ( pdaSymbol ) );
-				}
+				if ( to.empty ( ) )
+					continue;
+
+				ext::pair < DeterministicStateType, common::symbol_or_epsilon < InputSymbolType > > pdaSymbol = ext::make_pair ( state, input );
+
+				if ( dpda.addState ( to ) )
+					dirtyStates.push ( to );
+
+				updateTopSymbols ( localClosure, topSymbols, dirtyStateSymbols, to, { pdaSymbol } );
+
+				dpda.addPushdownStoreSymbol ( pdaSymbol );
+				dpda.addCallTransition ( state, std::move ( input ), std::move ( to ), std::move ( pdaSymbol ) );
 			}
 		}
 	}
@@ -137,13 +157,8 @@ automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, ext::pair < ext::s
 	for(const DeterministicStateType & state : dpda.getStates()) {
 		const ext::set<StateType> labels = retrieveDSubSet(state);
 
-		if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end())) {
+		if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end()))
 			dpda.addFinalState(state);
-		}
-	}
-
-	if ( common::GlobalData::verbose ) {
-		common::Streams::log << "Rubbish return transitions: " << rubbishReturnTransitions << std::endl;
 	}
 
 	return dpda;
diff --git a/alib2algo/src/automaton/determinize/DeterminizeVPAPart.hxx b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.hxx
index 568fc725a25eae0c900928c278454589a48be5dd..cfad2055cdca6f34a8e233a1d7106ecb35925128 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeVPAPart.hxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.hxx
@@ -29,43 +29,72 @@ automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pa
 	dpda.setLocalInputAlphabet(npda.getLocalInputAlphabet());
 	dpda.setReturnInputAlphabet(npda.getReturnInputAlphabet());
 
-	for(;;) {
-		ext::set<ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType>> stateSymbols = existsDirtyStateSymbol(dpda, npda);
-		ext::set<DeterministicStateType> states = existsDirtyState(dpda, npda);
+	ext::map < DeterministicStateType, ext::set < DeterministicStateType > > localClosure;
+	ext::map < DeterministicStateType, ext::set < DeterministicPushdownStoreSymbolType > > topSymbols;
 
-		if(stateSymbols.empty() && states.empty()) break;
+	std::queue < DeterministicStateType > dirtyStates;
+	dirtyStates.push ( initialLabel );
 
-		for ( const ext::pair < DeterministicStateType, DeterministicPushdownStoreSymbolType > & stateSymbol : stateSymbols ) {
-			const DeterministicStateType & state = stateSymbol.first;
-			const DeterministicPushdownStoreSymbolType & pdaSymbol = stateSymbol.second;
+	std::queue < ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType> > dirtyStateSymbols;
+	dirtyStateSymbols.push ( ext::make_pair ( initialLabel, bottom ) );
+
+	while ( ! dirtyStateSymbols.empty ( ) || ! dirtyStates.empty ( ) ) {
+		if ( ! dirtyStateSymbols.empty ( ) ) {
+			DeterministicStateType state = std::move ( dirtyStateSymbols.front ( ).first );
+			DeterministicPushdownStoreSymbolType pdaSymbol = std::move ( dirtyStateSymbols.front ( ).second );
+			dirtyStateSymbols.pop ( );
 
 			for ( const InputSymbolType & input : npda.getReturnInputAlphabet ( ) ) {
-				if ( pdaSymbol == dpda.getBottomOfTheStackSymbol ( ) ) {
-					DeterministicStateType to = retInitial ( state, input, npda );
+				DeterministicStateType to;
+
+				if ( pdaSymbol == dpda.getBottomOfTheStackSymbol ( ) )
+					to = retInitial ( state, input, npda );
+				else
+					to = ret ( state, pdaSymbol, input, npda );
+
+				if ( to.empty ( ) )
+					continue;
+
+				if ( dpda.addState ( to ) )
+					dirtyStates.push ( to );
 
-					dpda.addState ( to );
-					dpda.addReturnTransition ( state, input, pdaSymbol, std::move ( to ) );
-				} else {
-					DeterministicStateType to = ret ( state, pdaSymbol, input, npda );
+				localClosure [ pdaSymbol.first ].insert ( to );
 
-					dpda.addState ( to );
-					dpda.addReturnTransition ( state, input, pdaSymbol, std::move ( to ) );
-				}
+				updateTopSymbols ( localClosure, topSymbols, dirtyStateSymbols, to, topSymbols [ pdaSymbol.first ] );
+
+				dpda.addReturnTransition ( state, input, pdaSymbol, std::move ( to ) );
 			}
-		}
+		} else { // ! dirtyStates.empty ( )
+			DeterministicStateType state = std::move ( dirtyStates.front ( ) );
+			dirtyStates.pop ( );
 
-		for ( const DeterministicStateType & state : states ) {
 			for ( const InputSymbolType & input : npda.getLocalInputAlphabet ( ) ) {
 				DeterministicStateType to = local ( state, input, npda );
 
-				dpda.addState ( to );
+				if ( to.empty ( ) )
+					continue;
+
+				if ( dpda.addState ( to ) )
+					dirtyStates.push ( to );
+
+				localClosure [ state ].insert ( to );
+
+				updateTopSymbols ( localClosure, topSymbols, dirtyStateSymbols, to, topSymbols [ state ] );
+
 				dpda.addLocalTransition ( state, input, std::move ( to ) );
 			}
 			for ( const InputSymbolType & input : npda.getCallInputAlphabet ( ) ) {
 				DeterministicStateType to = call ( state, input, npda );
 				ext::pair < DeterministicStateType, InputSymbolType > pdaSymbol = ext::make_pair ( state, input );
 
-				dpda.addState ( to );
+				if ( to.empty ( ) )
+					continue;
+
+				if ( dpda.addState ( to ) )
+					dirtyStates.push ( to );
+
+				updateTopSymbols ( localClosure, topSymbols, dirtyStateSymbols, to, { pdaSymbol } );
+
 				dpda.addPushdownStoreSymbol ( pdaSymbol );
 				dpda.addCallTransition ( state, input, std::move ( to ), std::move ( pdaSymbol ) );
 			}
@@ -76,9 +105,8 @@ automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pa
 	for(const DeterministicStateType & state : dpda.getStates()) {
 		const ext::set<StateType> labels = retrieveDSubSet(state);
 
-		if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end())) {
+		if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end()))
 			dpda.addFinalState(state);
-		}
 	}
 
 	return dpda;
diff --git a/alib2algo/src/automaton/determinize/common/RHDPDACommon.h b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
index 7f2aedf58d2f19bb975a8fbedf15d06b15650580..366cdde28e7f2c09a70cd9ab4341137ed2a6495f 100644
--- a/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
+++ b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
@@ -7,6 +7,7 @@
 #include <alib/map>
 #include "automaton/PDA/VisiblyPushdownDPDA.h"
 #include "automaton/PDA/RealTimeHeightDeterministicDPDA.h"
+#include <queue>
 
 namespace automaton {
 
@@ -129,129 +130,23 @@ ext::set < ext::pair < StateType, StateType > > local ( const ext::set < ext::pa
 	return S1;
 }
 
-template<class T, class R>
-ext::set < typename T::StateType_t > existsDirtyState(const T& d, const R& n) {
-	ext::set < typename T::StateType_t > dirtyStates;
+template < class DeterministicStateType, class DeterministicPushdownStoreSymbolType >
+void updateTopSymbols ( ext::map < DeterministicStateType, ext::set < DeterministicStateType > > & localClosure, ext::map < DeterministicStateType, ext::set < DeterministicPushdownStoreSymbolType > > & topSymbols, std::queue < ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType> > & dirtyStateSymbols, const DeterministicStateType & state, const ext::set < DeterministicPushdownStoreSymbolType > & newSymbols ) {
+	ext::set < DeterministicPushdownStoreSymbolType > missingSymbols;
+	std::set_difference ( newSymbols.begin ( ), newSymbols.end ( ), topSymbols [ state ].begin ( ), topSymbols [ state ].end ( ), std::inserter ( missingSymbols, missingSymbols.end ( ) ) );
 
-	for(const typename T::StateType_t & state : d.getStates ( ) ) {
-		auto dSubSet = retrieveDSubSet(state);
+	if ( missingSymbols.empty ( ) )
+		return;
 
-		bool originalCallsLocals = false;
-		for(const auto& transition : n.getCallTransitions()) {
-			if(dSubSet.count(transition.first.first)) {
-				originalCallsLocals = true;
-				break;
-			}
-		}
-		if(!originalCallsLocals) for(const auto& transition : n.getLocalTransitions()) {
-			if(dSubSet.count(transition.first.first)) {
-				originalCallsLocals = true;
-				break;
-			}
-		}
+	topSymbols [ state ].insert ( missingSymbols.begin ( ), missingSymbols.end ( ) );
 
-		if(!originalCallsLocals) continue;
-		bool deterministicCallLocals = false;
+	for ( const DeterministicStateType & adv : localClosure [ state ] )
+		updateTopSymbols ( localClosure, topSymbols, dirtyStateSymbols, adv, missingSymbols );
 
-		for(const auto& transition : d.getCallTransitions ( ) ) {
-			if(state == transition.first.first) {
-				deterministicCallLocals = true;
-				break;
-			}
-		}
-		if(deterministicCallLocals) for(const auto& transition : d.getLocalTransitions ( ) ) {
-			if(state == transition.first.first) {
-				deterministicCallLocals = true;
-				break;
-			}
-		}
-
-		if(originalCallsLocals && !deterministicCallLocals) dirtyStates.insert(state);
-
-	}
-	return dirtyStates;
+	for ( DeterministicPushdownStoreSymbolType && symbol : ext::make_mover ( missingSymbols ) )
+		dirtyStateSymbols.push ( ext::make_pair ( state, std::move ( symbol ) ) );
 }
 
-template < class T, class DeterministicStateType >
-ext::set < DeterministicStateType > localClosure ( const DeterministicStateType & initState, const T & d ) {
-	ext::set < DeterministicStateType > closed { initState };
-	ext::deque < DeterministicStateType > queue { initState };
-
-	while ( ! queue.empty ( ) ) {
-		DeterministicStateType state = std::move ( queue.back ( ) );
-		queue.pop_back ( );
-
-		for ( const auto & transition : d.getLocalTransitions ( ) ) {
-			if ( transition.second != state )
-				continue;
-
-			if ( closed.insert ( transition.first.first ).second )
-				queue.push_back ( transition.first.first );
-		}
-
-		for ( const auto & transition : d.getReturnTransitions ( ) ) {
-			if ( transition.second != state )
-				continue;
-
-			const auto & popSymbol = std::get < 2 > ( transition.first );
-			if ( popSymbol == d.getBottomOfTheStackSymbol ( ) )
-				continue;
-
-			const DeterministicStateType & statePart = popSymbol.first;
-			if ( closed.insert ( statePart ).second )
-				queue.push_back ( statePart );
-		}
-	}
-
-	return closed;
-}
-
-template < class T, class R >
-ext::set < ext::pair < typename T::StateType_t, typename T::PushdownStoreSymbolType_t > > existsDirtyStateSymbol ( const T & d, const R & n ) {
-	ext::set < ext::pair < typename T::StateType_t, typename T::PushdownStoreSymbolType_t > > dirtyStateSymbols;
-
-	for ( const typename T::StateType_t & state : d.getStates ( ) ) {
-		bool originalPops = false;
-		auto dSubSet = retrieveDSubSet ( state );
-
-		for ( const auto & transition : n.getReturnTransitions ( ) ) {
-			if ( dSubSet.count ( std::get < 0 > ( transition.first ) ) ) {
-				originalPops = true;
-				break;
-			}
-		}
-		if ( ! originalPops )
-			continue;
-
-		ext::set < typename T::PushdownStoreSymbolType_t > topSymbols;
-		for ( const typename T::StateType_t & localState : localClosure ( state, d ) ) {
-			for ( const auto & transition : d.getCallTransitions ( ) ) {
-				const auto & to = transition.second;
-				if ( localState != to.first )
-					continue;
-
-				topSymbols.insert ( to.second );
-			}
-
-			if ( d.getInitialState ( ) == localState )
-				topSymbols.insert ( d.getBottomOfTheStackSymbol ( ) );
-		}
-
-		for ( const auto & transition : d.getReturnTransitions ( ) ) {
-			if ( state != std::get < 0 > ( transition.first ) )
-				continue;
-
-			topSymbols.erase(std::get<2>(transition.first));
-		}
-
-		for ( const typename T::PushdownStoreSymbolType_t & topSymbol : topSymbols )
-			dirtyStateSymbols.insert ( ext::make_pair ( state, topSymbol ) );
-	}
-
-	return dirtyStateSymbols;
-}
-
-
 } /* namespace determinize */
 
 } /* namespace automaton */
diff --git a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
index d9e1c8b263b48a5b95efc2c43581b591270e320f..9561b405fde90a5893ed0e882469202fd3893bd7 100644
--- a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
+++ b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
@@ -98,10 +98,10 @@ TEST_CASE ( "Determinize", "[unit][algo][automaton][determinize]" ) {
 		automaton.addFinalState(DefaultStateType(4));
 
 		auto determinized = automaton::determinize::Determinize::determinize ( automaton );
-		CHECK ( determinized.getStates().size() == 29 );
+		CHECK ( determinized.getStates().size() == 28 );
 		CHECK ( determinized.getFinalStates().size() == 14 );
 		CHECK ( determinized.getCallTransitions().size() == 28 );
-		CHECK ( determinized.getReturnTransitions().size() == 198 );
+		CHECK ( determinized.getReturnTransitions().size() == 196 );
 		CHECK ( determinized.getLocalTransitions().size() == 0 );
 		CHECK ( determinized.getCallTransitions().size() == 28 );