diff --git a/alib2algo/src/automaton/AutomatonPropertiesFSM.cpp b/alib2algo/src/automaton/AutomatonPropertiesFSM.cpp
deleted file mode 100644
index c33a10275d0983e61ca5e021618d7e60033d8a31..0000000000000000000000000000000000000000
--- a/alib2algo/src/automaton/AutomatonPropertiesFSM.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * AutomatonPropertiesFSM.cpp
- *
- *  Created on: 23. 3. 2014
- *	  Author: Tomas Pecka
- */
-
-#include "AutomatonPropertiesFSM.h"
-
-#include <exception/AlibException.h>
-#include <automaton/FSM/ExtendedNFA.h>
-#include <automaton/FSM/CompactNFA.h>
-#include <automaton/FSM/EpsilonNFA.h>
-#include <automaton/FSM/NFA.h>
-#include <automaton/FSM/DFA.h>
-
-#include <set>
-#include <map>
-#include <queue>
-
-namespace automaton {
-
-template<class T>
-std::set<automaton::State> AutomatonPropertiesFSM::getUsefullStates( const T & fsm ) {
-	// 1a
-	std::deque<std::set<automaton::State>> Qi;
-	Qi.push_back( std::set<automaton::State>( ) );
-	Qi.at( 0 ) = fsm.getFinalStates( );
-
-	int i = 1;
-
-	// 1bc
-	while( true ) {
-		Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi
-		for( const auto & p : Qi.at( i - 1 ) )
-			for( const auto & t : fsm.getTransitionsToState( p ) )
-				Qi.at( i ).insert( t.first.first );
-
-		if( Qi.at( i ) == Qi.at( i - 1 ) )
-			break;
-
-		i = i + 1;
-	}
-	return Qi.at( i );
-}
-
-template std::set<automaton::State> AutomatonPropertiesFSM::getUsefullStates( const automaton::EpsilonNFA & fsm );
-template std::set<automaton::State> AutomatonPropertiesFSM::getUsefullStates( const automaton::NFA & fsm );
-template std::set<automaton::State> AutomatonPropertiesFSM::getUsefullStates( const automaton::CompactNFA & fsm );
-template std::set<automaton::State> AutomatonPropertiesFSM::getUsefullStates( const automaton::ExtendedNFA & fsm );
-
-template<>
-std::set<automaton::State> AutomatonPropertiesFSM::getUsefullStates( const automaton::DFA & fsm ) {
-	// 1a
-	std::deque<std::set<automaton::State>> Qi;
-	Qi.push_back( std::set<automaton::State>( ) );
-	Qi.at( 0 ) = fsm.getFinalStates( );
-
-	int i = 1;
-
-	// 1bc
-	while( true ) {
-		Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi
-		for( const auto & p : Qi.at( i - 1 ) )
-			for( const auto & t : fsm.getTransitionsToState( p ) )
-				Qi.at( i ).insert( t.first.first );
-
-		if( Qi.at( i ) == Qi.at( i - 1 ) )
-			break;
-
-		i = i + 1;
-	}
-	return Qi.at( i );
-}
-
-template<class T>
-std::set<automaton::State> AutomatonPropertiesFSM::getUnreachableStates( const T & fsm ) {
-	// 1a
-	std::deque<std::set<automaton::State>> Qi;
-	Qi.push_back( std::set<automaton::State>( ) );
-	Qi.at( 0 ) = {fsm.getInitialState( )};
-
-	int i = 1;
-
-	// 1bc
-	while( true ) {
-		Qi.push_back( Qi.at( i - 1 ) );
-
-		for( const auto & p : Qi.at( i - 1 ) )
-			for( const auto & transition : fsm.getTransitionsFromState( p ) )
-				Qi.at( i ).insert( transition.second.begin(), transition.second.end() );
-
-		if( Qi.at( i ) == Qi.at( i - 1 ) )
-			break;
-
-		i = i + 1;
-	}
-
-	return Qi.at( i );
-}
-
-template std::set<automaton::State> AutomatonPropertiesFSM::getUnreachableStates( const automaton::EpsilonNFA & fsm );
-template std::set<automaton::State> AutomatonPropertiesFSM::getUnreachableStates( const automaton::NFA & fsm );
-template std::set<automaton::State> AutomatonPropertiesFSM::getUnreachableStates( const automaton::CompactNFA & fsm );
-template std::set<automaton::State> AutomatonPropertiesFSM::getUnreachableStates( const automaton::ExtendedNFA & fsm );
-
-template<>
-std::set<automaton::State> AutomatonPropertiesFSM::getUnreachableStates( const automaton::DFA & fsm ) {
-	// 1a
-	std::deque<std::set<automaton::State>> Qi;
-	Qi.push_back( std::set<automaton::State>( ) );
-	Qi.at( 0 ). insert( fsm.getInitialState( ) );
-
-	int i = 1;
-
-	// 1bc
-	while( true ) {
-		Qi.push_back( Qi.at( i - 1 ) );
-
-		for( const auto & p : Qi.at( i - 1 ) )
-			for( const auto & transition : fsm.getTransitionsFromState( p ) )
-				Qi.at( i ).insert( transition.second );
-
-		if( Qi.at( i ) == Qi.at( i - 1 ) )
-			break;
-
-		i = i + 1;
-	}
-
-	return Qi.at( i );
-}
-
-}
-
diff --git a/alib2algo/src/automaton/AutomatonPropertiesFSM.h b/alib2algo/src/automaton/AutomatonPropertiesFSM.h
deleted file mode 100644
index 64f94e888ffc97f69cc583181c7eba1f09e6ef03..0000000000000000000000000000000000000000
--- a/alib2algo/src/automaton/AutomatonPropertiesFSM.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * AutomatonPropertiesFSM.h
- *
- *  Created on: 23. 3. 2014
- *	  Author: Tomas Pecka
- */
-
-#ifndef AUTOMATON_PROPERTIED_FSM_H_
-#define AUTOMATON_PROPERTIED_FSM_H_
-
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <automaton/common/State.h>
-
-namespace automaton {
-
-class AutomatonPropertiesFSM {
-public:
-	/**
-	 * Removes dead states from FSM. Melichar 2.32
-	 */
-	template<class T>
-	static std::set<automaton::State> getUsefullStates( const T & fsm );
-
-	/**
-	 * Removes dead states from FSM. Melichar 2.29
-	 */
-	template<class T>
-	static std::set<automaton::State> getUnreachableStates( const T & fsm );
-};
-
-}
-
-#endif /* AUTOMATON_PROPERTIED_FSM_H_ */
diff --git a/alib2algo/src/automaton/UnreachableStates.cpp b/alib2algo/src/automaton/UnreachableStates.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9e868c8fcd624b0e5ee543779fa56738ddd922c2
--- /dev/null
+++ b/alib2algo/src/automaton/UnreachableStates.cpp
@@ -0,0 +1,185 @@
+/*
+ * UnreachableStates.cpp
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "UnreachableStates.h"
+
+#include <exception/AlibException.h>
+#include <automaton/FSM/ExtendedNFA.h>
+#include <automaton/FSM/CompactNFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <set>
+#include <map>
+#include <queue>
+
+namespace automaton {
+
+std::set<automaton::State> UnreachableStates::unreachableStates(const Automaton& automaton) {
+	std::set<automaton::State> out;
+	automaton.getData().Accept((void*) &out, UnreachableStates::UNREACHABLE_STATES);
+	return out;
+}
+
+template<class T>
+std::set<automaton::State> UnreachableStates::unreachableStates( const T & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ) = {fsm.getInitialState( )};
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) );
+
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & transition : fsm.getTransitionsFromState( p ) )
+				Qi.at( i ).insert( transition.second.begin(), transition.second.end() );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	return Qi.at( i );
+}
+
+template std::set<automaton::State> UnreachableStates::unreachableStates( const automaton::EpsilonNFA & fsm );
+template std::set<automaton::State> UnreachableStates::unreachableStates( const automaton::NFA & fsm );
+template std::set<automaton::State> UnreachableStates::unreachableStates( const automaton::CompactNFA & fsm );
+template std::set<automaton::State> UnreachableStates::unreachableStates( const automaton::ExtendedNFA & fsm );
+
+template<>
+std::set<automaton::State> UnreachableStates::unreachableStates( const automaton::MultiInitialStateNFA & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ) = fsm.getInitialStates( );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) );
+
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & transition : fsm.getTransitionsFromState( p ) )
+				Qi.at( i ).insert( transition.second.begin(), transition.second.end() );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	return Qi.at( i );
+}
+
+template<>
+std::set<automaton::State> UnreachableStates::unreachableStates( const automaton::DFA & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ). insert( fsm.getInitialState( ) );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) );
+
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & transition : fsm.getTransitionsFromState( p ) )
+				Qi.at( i ).insert( transition.second );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	return Qi.at( i );
+}
+
+void UnreachableStates::Visit(void* data, const EpsilonNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->unreachableStates(automaton));
+}
+
+void UnreachableStates::Visit(void* data, const MultiInitialStateNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->unreachableStates(automaton));
+}
+
+void UnreachableStates::Visit(void* data, const NFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->unreachableStates(automaton));
+}
+
+void UnreachableStates::Visit(void* data, const DFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->unreachableStates(automaton));
+}
+
+void UnreachableStates::Visit(void* data, const ExtendedNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->unreachableStates(automaton));
+}
+
+void UnreachableStates::Visit(void* data, const CompactNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->unreachableStates(automaton));
+}
+
+void UnreachableStates::Visit(void*, const DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void UnreachableStates::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void UnreachableStates::Visit(void*, const InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void UnreachableStates::Visit(void*, const VisiblyPushdownDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
+}
+
+void UnreachableStates::Visit(void*, const VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void UnreachableStates::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
+}
+
+void UnreachableStates::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
+}
+
+void UnreachableStates::Visit(void*, const NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void UnreachableStates::Visit(void*, const SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void UnreachableStates::Visit(void*, const OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const UnreachableStates UnreachableStates::UNREACHABLE_STATES;
+
+}
+
diff --git a/alib2algo/src/automaton/UnreachableStates.h b/alib2algo/src/automaton/UnreachableStates.h
new file mode 100644
index 0000000000000000000000000000000000000000..e18f17aa9d6343a255cc82cbc0a98e54d7264aa4
--- /dev/null
+++ b/alib2algo/src/automaton/UnreachableStates.h
@@ -0,0 +1,53 @@
+/*
+ * UnreachableStates.h
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef UNREACHABLE_STATES_H_
+#define UNREACHABLE_STATES_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <automaton/common/State.h>
+#include <automaton/Automaton.h>
+
+namespace automaton {
+
+class UnreachableStates : public VisitableAutomatonBase::const_visitor_type {
+public:
+	static std::set<automaton::State> unreachableStates( const automaton::Automaton & automaton );
+
+	/**
+	 * Removes dead states from FSM. Melichar 2.29
+	 */
+	template<class T>
+	static std::set<automaton::State> unreachableStates( const T & fsm );
+
+private:
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const MultiInitialStateNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const DPDA& automaton) const;
+	void Visit(void*, const SinglePopDPDA& automaton) const;
+	void Visit(void*, const InputDrivenNPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownDPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const;
+	void Visit(void*, const NPDA& automaton) const;
+	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
+
+	static const UnreachableStates UNREACHABLE_STATES;
+};
+
+}
+
+#endif /* UNREACHABLE_STATES_H_ */
diff --git a/alib2algo/src/automaton/UsefullStates.cpp b/alib2algo/src/automaton/UsefullStates.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68e4837dcad9afc9d4d67a98132ce0a9b076f7c9
--- /dev/null
+++ b/alib2algo/src/automaton/UsefullStates.cpp
@@ -0,0 +1,155 @@
+/*
+ * UsefullStates.cpp
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "UsefullStates.h"
+
+#include <exception/AlibException.h>
+#include <automaton/FSM/ExtendedNFA.h>
+#include <automaton/FSM/CompactNFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <set>
+#include <map>
+#include <queue>
+
+namespace automaton {
+
+std::set<automaton::State> UsefullStates::usefullStates(const Automaton& automaton) {
+	std::set<automaton::State> out;
+	automaton.getData().Accept((void*) &out, UsefullStates::USEFULL_STATES);
+	return out;
+}
+
+template<class T>
+std::set<automaton::State> UsefullStates::usefullStates( const T & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ) = fsm.getFinalStates( );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & t : fsm.getTransitionsToState( p ) )
+				Qi.at( i ).insert( t.first.first );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+	return Qi.at( i );
+}
+
+template std::set<automaton::State> UsefullStates::usefullStates( const automaton::EpsilonNFA & fsm );
+template std::set<automaton::State> UsefullStates::usefullStates( const automaton::NFA & fsm );
+template std::set<automaton::State> UsefullStates::usefullStates( const automaton::CompactNFA & fsm );
+template std::set<automaton::State> UsefullStates::usefullStates( const automaton::ExtendedNFA & fsm );
+
+template<>
+std::set<automaton::State> UsefullStates::usefullStates( const automaton::DFA & fsm ) {
+	// 1a
+	std::deque<std::set<automaton::State>> Qi;
+	Qi.push_back( std::set<automaton::State>( ) );
+	Qi.at( 0 ) = fsm.getFinalStates( );
+
+	int i = 1;
+
+	// 1bc
+	while( true ) {
+		Qi.push_back( Qi.at( i - 1 ) ); // copy Qi-1 into Qi
+		for( const auto & p : Qi.at( i - 1 ) )
+			for( const auto & t : fsm.getTransitionsToState( p ) )
+				Qi.at( i ).insert( t.first.first );
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+	return Qi.at( i );
+}
+
+void UsefullStates::Visit(void* data, const EpsilonNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->usefullStates(automaton));
+}
+
+void UsefullStates::Visit(void* data, const MultiInitialStateNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->usefullStates(automaton));
+}
+
+void UsefullStates::Visit(void* data, const NFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->usefullStates(automaton));
+}
+
+void UsefullStates::Visit(void* data, const DFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->usefullStates(automaton));
+}
+
+void UsefullStates::Visit(void* data, const ExtendedNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->usefullStates(automaton));
+}
+
+void UsefullStates::Visit(void* data, const CompactNFA& automaton) const {
+	std::set<automaton::State> & out = *((std::set<automaton::State>*) data);
+	out = std::move(this->usefullStates(automaton));
+}
+
+void UsefullStates::Visit(void*, const DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void UsefullStates::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void UsefullStates::Visit(void*, const InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void UsefullStates::Visit(void*, const VisiblyPushdownDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
+}
+
+void UsefullStates::Visit(void*, const VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void UsefullStates::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
+}
+
+void UsefullStates::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
+}
+
+void UsefullStates::Visit(void*, const NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void UsefullStates::Visit(void*, const SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void UsefullStates::Visit(void*, const OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const UsefullStates UsefullStates::USEFULL_STATES;
+
+}
+
diff --git a/alib2algo/src/automaton/UsefullStates.h b/alib2algo/src/automaton/UsefullStates.h
new file mode 100644
index 0000000000000000000000000000000000000000..db9a641cb2ca1c0ec1f886d0a1d21570b5597bfa
--- /dev/null
+++ b/alib2algo/src/automaton/UsefullStates.h
@@ -0,0 +1,53 @@
+/*
+ * UsefullStates.h
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef USEFULL_STATES_H_
+#define USEFULL_STATES_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <automaton/common/State.h>
+#include <automaton/Automaton.h>
+
+namespace automaton {
+
+class UsefullStates : public VisitableAutomatonBase::const_visitor_type {
+public:
+	static std::set<automaton::State> usefullStates( const automaton::Automaton & automaton );
+
+	/**
+	 * Removes dead states from FSM. Melichar 2.32
+	 */
+	template<class T>
+	static std::set<automaton::State> usefullStates( const T & fsm );
+
+private:
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const MultiInitialStateNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const DPDA& automaton) const;
+	void Visit(void*, const SinglePopDPDA& automaton) const;
+	void Visit(void*, const InputDrivenNPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownDPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const;
+	void Visit(void*, const NPDA& automaton) const;
+	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
+
+	static const UsefullStates USEFULL_STATES;
+};
+
+}
+
+#endif /* USEFULL_STATES_H_ */
diff --git a/alib2algo/src/trim/automaton/TrimFSM.cpp b/alib2algo/src/trim/automaton/TrimFSM.cpp
index 8e48aff208e0d2e581f62de17ef281eee411573c..2be567b60dbb80b804bc72e3147ae8aad4d54539 100644
--- a/alib2algo/src/trim/automaton/TrimFSM.cpp
+++ b/alib2algo/src/trim/automaton/TrimFSM.cpp
@@ -14,7 +14,8 @@
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
 
-#include "../../automaton/AutomatonPropertiesFSM.h"
+#include "../../automaton/UsefullStates.h"
+#include "../../automaton/UnreachableStates.h"
 
 #include "automaton/common/State.h"
 #include "automaton/Automaton.h"
@@ -24,7 +25,7 @@ namespace trim {
 template<class T>
 T TrimFSM::removeUselessStates( const T & fsm ) {
 	// 1.
-	std::set<automaton::State> Qu = automaton::AutomatonPropertiesFSM::getUsefullStates( fsm );
+	std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm );
 
 	// 2.
 	T M(fsm.getInitialState());
@@ -58,7 +59,7 @@ template automaton::ExtendedNFA TrimFSM::removeUselessStates( const automaton::E
 template<>
 automaton::DFA TrimFSM::removeUselessStates( const automaton::DFA & fsm ) {
 	// 1.
-	std::set<automaton::State> Qu = automaton::AutomatonPropertiesFSM::getUsefullStates( fsm );
+	std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm );
 
 	// 2.
 	automaton::DFA M ( fsm.getInitialState () );
@@ -90,7 +91,7 @@ automaton::DFA TrimFSM::removeUselessStates( const automaton::DFA & fsm ) {
 template<class T>
 T TrimFSM::removeUnreachableStates( const T & fsm ) {
 	// 1a
-	std::set<automaton::State> Qa = automaton::AutomatonPropertiesFSM::getUnreachableStates( fsm );
+	std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm );
 
 	// 2
 	T M(fsm.getInitialState());
@@ -122,7 +123,7 @@ template automaton::ExtendedNFA TrimFSM::removeUnreachableStates( const automato
 template<>
 automaton::DFA TrimFSM::removeUnreachableStates( const automaton::DFA & fsm ) {
 	// 1a
-	std::set<automaton::State> Qa = automaton::AutomatonPropertiesFSM::getUnreachableStates( fsm );
+	std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm );
 
 	// 2
 	automaton::DFA M(fsm.getInitialState() );