diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
index 37d1d49b8b771cffc328ed53575a7ccf6df7ce6e..064c765b37c2bc512610767e84039ebe6eecb984 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
@@ -7,126 +7,15 @@
 
 #include "AllEpsilonClosure.h"
 
-#include <automaton/FSM/ExtendedNFA.h>
-#include <automaton/FSM/CompactNFA.h>
-#include <automaton/FSM/EpsilonNFA.h>
-#include <automaton/FSM/MultiInitialStateNFA.h>
-#include <automaton/FSM/NFA.h>
-#include <automaton/FSM/DFA.h>
-
-#include <set>
-#include <map>
-#include <deque>
-#include <iostream>
-
-#include "../../regexp/properties/RegExpEpsilon.h"
-
-
 namespace automaton {
 
 namespace properties {
 
-std::map<DefaultStateType, std::set<DefaultStateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::EpsilonNFA < > & fsm) {
-	std::deque<std::map<DefaultStateType, std::set<DefaultStateType>>> Qi;
-
-	Qi.push_back({});
-	for(const DefaultStateType& state : fsm.getStates())
-		Qi.at(0)[state].insert(state);
-
-	int i = 1;
-	while(true) {
-		Qi.push_back( Qi.at( i - 1 ) );
-
-		for( const std::pair<const DefaultStateType, std::set<DefaultStateType>> & p : Qi.at( i - 1 ) )
-			for(const DefaultStateType& pclosure : p.second )
-				for(const auto& transition : fsm.getEpsilonTransitionsFromState(pclosure)) {
-					Qi.at( i )[p.first].insert(transition.second.begin(), transition.second.end());
-				}
-
-		if( Qi.at( i ) == Qi.at( i - 1 ) )
-			break;
-
-		i = i + 1;
-	};
-
-	return Qi.at(i);
-}
-
 auto AllEpsilonClosureEpsilonNFA = AllEpsilonClosure::RegistratorWrapper<std::map<DefaultStateType, std::set<DefaultStateType>>, automaton::EpsilonNFA < > >(AllEpsilonClosure::allEpsilonClosure);
-
-std::map<DefaultStateType, std::set<DefaultStateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::MultiInitialStateNFA < > & fsm) {
-	std::map<DefaultStateType, std::set<DefaultStateType>> closure;
-	for(const DefaultStateType& state : fsm.getStates())
-		closure[state].insert(state);
-	return closure;
-}
-
 auto AllEpsilonClosureMultiInitialStateNFA = AllEpsilonClosure::RegistratorWrapper<std::map<DefaultStateType, std::set<DefaultStateType>>, automaton::MultiInitialStateNFA < > >(AllEpsilonClosure::allEpsilonClosure);
-
-std::map<DefaultStateType, std::set<DefaultStateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::NFA < > & fsm) {
-	std::map<DefaultStateType, std::set<DefaultStateType>> closure;
-	for(const DefaultStateType& state : fsm.getStates())
-		closure[state].insert(state);
-	return closure;
-}
-
 auto AllEpsilonClosureNFA = AllEpsilonClosure::RegistratorWrapper<std::map<DefaultStateType, std::set<DefaultStateType>>, automaton::NFA < > >(AllEpsilonClosure::allEpsilonClosure);
-
-std::map<DefaultStateType, std::set<DefaultStateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::DFA < > & fsm) {
-	std::map<DefaultStateType, std::set<DefaultStateType>> closure;
-	for(const DefaultStateType& state : fsm.getStates())
-		closure[state].insert(state);
-	return closure;
-}
-
 auto AllEpsilonClosureDFA = AllEpsilonClosure::RegistratorWrapper<std::map<DefaultStateType, std::set<DefaultStateType>>, automaton::DFA<>>(AllEpsilonClosure::allEpsilonClosure);
-
-std::map<DefaultStateType, std::set<DefaultStateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA < > & fsm) {
-	std::map<DefaultStateType, std::set<DefaultStateType>> res;
-	std::map<DefaultStateType, std::set<DefaultStateType>> step;
-
-	for(const std::pair<const std::pair<DefaultStateType, regexp::UnboundedRegExpStructure < DefaultSymbolType > >, std::set<DefaultStateType> >& transition : fsm.getTransitions() )
-		if( regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
-			step[transition.first.first].insert(transition.second.begin(), transition.second.end());
-
-	for(const DefaultStateType& state : fsm.getStates())
-		step[state].insert(state);
-
-	do {
-		res = step;
-
-		for(const std::pair<const DefaultStateType, std::set<DefaultStateType>>& item : res)
-			for(const DefaultStateType& to : item.second)
-				step[item.first].insert(res[to].begin(), res[to].end());
-	} while(res != step);
-
-	return res;
-}
-
 auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<DefaultStateType, std::set<DefaultStateType>>, automaton::ExtendedNFA < > >(AllEpsilonClosure::allEpsilonClosure);
-
-std::map<DefaultStateType, std::set<DefaultStateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::CompactNFA < > & fsm) {
-	std::map<DefaultStateType, std::set<DefaultStateType>> res;
-	std::map<DefaultStateType, std::set<DefaultStateType>> step;
-
-	for(const std::pair<const std::pair<DefaultStateType, std::vector < DefaultSymbolType > >, std::set<DefaultStateType> >& transition : fsm.getTransitions() )
-		if( transition.first.second.size() == 0 )
-			step[transition.first.first].insert(transition.second.begin(), transition.second.end());
-
-	for(const DefaultStateType& state : fsm.getStates())
-		step[state].insert(state);
-
-	do {
-		res = step;
-
-		for(const std::pair<const DefaultStateType, std::set<DefaultStateType>>& item : res)
-			for(const DefaultStateType& to : item.second)
-				step[item.first].insert(res[to].begin(), res[to].end());
-	} while(res != step);
-
-	return res;
-}
-
 auto AllEpsilonClosureCompactNFA = AllEpsilonClosure::RegistratorWrapper<std::map<DefaultStateType, std::set<DefaultStateType>>, automaton::CompactNFA < > >(AllEpsilonClosure::allEpsilonClosure);
 
 std::map<DefaultStateType, std::set<DefaultStateType>> AllEpsilonClosure::allEpsilonClosure(const Automaton& automaton) {
diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.h b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
index e6e2cebce0784360244adcc5f63e4069bb2c5bb6..4a4f8a3fd720400613466e39e8863c4d5661fe90 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
@@ -11,10 +11,20 @@
 #include <core/multipleDispatch.hpp>
 #include <set>
 #include <map>
+#include <deque>
+#include <iostream>
 
 #include "automaton/Automaton.h"
 #include "automaton/AutomatonFeatures.h"
-#include <label/Label.h>
+
+#include <automaton/FSM/ExtendedNFA.h>
+#include <automaton/FSM/CompactNFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <automaton/FSM/MultiInitialStateNFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include "../../regexp/properties/RegExpEpsilon.h"
 
 namespace automaton {
 
@@ -27,14 +37,117 @@ public:
 	/**
 	 * Computes allEpsilon closure of a state in allEpsilon nonfree automaton
 	 */
-	static std::map<DefaultStateType, std::set<DefaultStateType>> allEpsilonClosure( const automaton::EpsilonNFA < > & fsm);
-	static std::map<DefaultStateType, std::set<DefaultStateType>> allEpsilonClosure( const automaton::MultiInitialStateNFA < > & fsm);
-	static std::map<DefaultStateType, std::set<DefaultStateType>> allEpsilonClosure( const automaton::NFA < > & fsm);
-	static std::map<DefaultStateType, std::set<DefaultStateType>> allEpsilonClosure( const automaton::DFA < > & fsm);
-	static std::map<DefaultStateType, std::set<DefaultStateType>> allEpsilonClosure( const automaton::ExtendedNFA < > & fsm);
-	static std::map<DefaultStateType, std::set<DefaultStateType>> allEpsilonClosure( const automaton::CompactNFA < > & fsm);
+	template < class SymbolType, class EpsilonType, class StateType >
+	static std::map<StateType, std::set<StateType>> allEpsilonClosure( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm);
+	template < class SymbolType, class StateType >
+	static std::map<StateType, std::set<StateType>> allEpsilonClosure( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm);
+	template < class SymbolType, class StateType >
+	static std::map<StateType, std::set<StateType>> allEpsilonClosure( const automaton::NFA < SymbolType, StateType > & fsm);
+	template < class SymbolType, class StateType >
+	static std::map<StateType, std::set<StateType>> allEpsilonClosure( const automaton::DFA < SymbolType, StateType > & fsm);
+	template < class SymbolType, class StateType >
+	static std::map<StateType, std::set<StateType>> allEpsilonClosure( const automaton::ExtendedNFA < SymbolType, StateType > & fsm);
+	template < class SymbolType, class StateType >
+	static std::map<StateType, std::set<StateType>> allEpsilonClosure( const automaton::CompactNFA < SymbolType, StateType > & fsm);
 };
 
+template < class SymbolType, class EpsilonType, class StateType >
+std::map<StateType, std::set<StateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm) {
+	std::deque<std::map<StateType, std::set<StateType>>> Qi;
+
+	Qi.push_back({});
+	for(const StateType& state : fsm.getStates())
+		Qi.at(0)[state].insert(state);
+
+	int i = 1;
+	while(true) {
+		Qi.push_back( Qi.at( i - 1 ) );
+
+		for( const std::pair<const StateType, std::set<StateType>> & p : Qi.at( i - 1 ) )
+			for(const StateType& pclosure : p.second )
+				for(const auto& transition : fsm.getEpsilonTransitionsFromState(pclosure)) {
+					Qi.at( i )[p.first].insert(transition.second.begin(), transition.second.end());
+				}
+
+		if( Qi.at( i ) == Qi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	};
+
+	return Qi.at(i);
+}
+
+template < class SymbolType, class StateType >
+std::map<StateType, std::set<StateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm) {
+	std::map<StateType, std::set<StateType>> closure;
+	for(const StateType& state : fsm.getStates())
+		closure[state].insert(state);
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::map<StateType, std::set<StateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::NFA < SymbolType, StateType > & fsm) {
+	std::map<StateType, std::set<StateType>> closure;
+	for(const StateType& state : fsm.getStates())
+		closure[state].insert(state);
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::map<StateType, std::set<StateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::DFA < SymbolType, StateType > & fsm) {
+	std::map<StateType, std::set<StateType>> closure;
+	for(const StateType& state : fsm.getStates())
+		closure[state].insert(state);
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::map<StateType, std::set<StateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA < SymbolType, StateType > & fsm) {
+	std::map<StateType, std::set<StateType>> res;
+	std::map<StateType, std::set<StateType>> step;
+
+	for(const std::pair<const std::pair<StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set<StateType> >& transition : fsm.getTransitions() )
+		if( regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
+			step[transition.first.first].insert(transition.second.begin(), transition.second.end());
+
+	for(const StateType& state : fsm.getStates())
+		step[state].insert(state);
+
+	do {
+		res = step;
+
+		for(const std::pair<const StateType, std::set<StateType>>& item : res)
+			for(const StateType& to : item.second)
+				step[item.first].insert(res[to].begin(), res[to].end());
+	} while(res != step);
+
+	return res;
+}
+
+template < class SymbolType, class StateType >
+std::map<StateType, std::set<StateType>> AllEpsilonClosure::allEpsilonClosure( const automaton::CompactNFA < SymbolType, StateType > & fsm) {
+	std::map<StateType, std::set<StateType>> res;
+	std::map<StateType, std::set<StateType>> step;
+
+	for(const std::pair<const std::pair<StateType, std::vector < SymbolType > >, std::set<StateType> >& transition : fsm.getTransitions() )
+		if( transition.first.second.size() == 0 )
+			step[transition.first.first].insert(transition.second.begin(), transition.second.end());
+
+	for(const StateType& state : fsm.getStates())
+		step[state].insert(state);
+
+	do {
+		res = step;
+
+		for(const std::pair<const StateType, std::set<StateType>>& item : res)
+			for(const StateType& to : item.second)
+				step[item.first].insert(res[to].begin(), res[to].end());
+	} while(res != step);
+
+	return res;
+}
+
 } /* namespace properties */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.cpp b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
index b47a135fe16e3d43841d726f896f2c2e93526efc..6061c6c0adcb24d76d6d888ad69e01a123b5b46c 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
@@ -7,142 +7,15 @@
 
 #include "EpsilonClosure.h"
 
-#include <automaton/FSM/ExtendedNFA.h>
-#include <automaton/FSM/CompactNFA.h>
-#include <automaton/FSM/EpsilonNFA.h>
-#include <automaton/FSM/MultiInitialStateNFA.h>
-#include <automaton/FSM/NFA.h>
-#include <automaton/FSM/DFA.h>
-
-#include <set>
-#include <map>
-#include <queue>
-
-#include "../../regexp/properties/RegExpEpsilon.h"
-
 namespace automaton {
 
 namespace properties {
 
-std::set<DefaultStateType> EpsilonClosure::epsilonClosure( const automaton::EpsilonNFA < > & fsm, const DefaultStateType & q ) {
-	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
-
-	std::set<DefaultStateType> closure;
-	std::queue<DefaultStateType> queue;
-	std::map<DefaultStateType, bool> visited;
-
-	for( const auto & p : fsm.getStates( ) )
-		visited[ p ] = false;
-
-	queue.push( q );
-	while( ! queue.empty( ) )
-	{
-		DefaultStateType p = queue.front( );
-		queue.pop( );
-		visited[ p ] = true;
-		closure.insert( p );
-
-		auto tos = fsm.getTransitions( ).find(std::make_pair(p, std::variant<string::Epsilon < >, DefaultSymbolType>(string::Epsilon < >::EPSILON) ) );
-		if(tos == fsm.getTransitions().end()) continue;
-
-		for( const auto & to : tos->second )
-			if( visited [ to ] == false )
-				queue.push( to );
-	}
-
-	return closure;
-}
-
 auto EpsilonClosureEpsilonNFA = EpsilonClosure::RegistratorWrapper<std::set<DefaultStateType>, automaton::EpsilonNFA < > >(EpsilonClosure::epsilonClosure);
-
-std::set<DefaultStateType> EpsilonClosure::epsilonClosure( const automaton::MultiInitialStateNFA < > & fsm, const DefaultStateType & q ) {
-	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
-
-	std::set<DefaultStateType> closure;
-	closure.insert(q);
-	return closure;
-}
-
 auto EpsilonClosureMultiInitialStateNFA = EpsilonClosure::RegistratorWrapper<std::set<DefaultStateType>, automaton::MultiInitialStateNFA < > >(EpsilonClosure::epsilonClosure);
-
-std::set<DefaultStateType> EpsilonClosure::epsilonClosure( const automaton::NFA < > & fsm, const DefaultStateType & q ) {
-	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
-
-	std::set<DefaultStateType> closure;
-	closure.insert(q);
-	return closure;
-}
-
 auto EpsilonClosureNFA = EpsilonClosure::RegistratorWrapper<std::set<DefaultStateType>, automaton::NFA < > >(EpsilonClosure::epsilonClosure);
-
-std::set<DefaultStateType> EpsilonClosure::epsilonClosure( const automaton::DFA < > & fsm, const DefaultStateType & q ) {
-	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
-
-	std::set<DefaultStateType> closure;
-	closure.insert(q);
-	return closure;
-}
-
 auto EpsilonClosureDFA = EpsilonClosure::RegistratorWrapper<std::set<DefaultStateType>, automaton::DFA<>>(EpsilonClosure::epsilonClosure);
-
-std::set<DefaultStateType> EpsilonClosure::epsilonClosure( const automaton::ExtendedNFA < > & fsm, const DefaultStateType & q ) {
-	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
-
-	std::set<DefaultStateType> closure;
-	std::queue<DefaultStateType> queue;
-	std::map<DefaultStateType, bool> visited;
-
-	for( const auto & p : fsm.getStates( ) )
-		visited[ p ] = false;
-
-	queue.push( q );
-	while( ! queue.empty( ) )
-	{
-		DefaultStateType p = queue.front( );
-		queue.pop( );
-		visited[ p ] = true;
-		closure.insert( p );
-
-		for( const auto & transition : fsm.getTransitionsFromState( p ) )
-			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
-				for (const auto & to : transition.second )
-					if( visited [ to ] == false )
-						queue.push( to );
-	}
-
-	return closure;
-}
-
 auto EpsilonClosureExtendedNFA = EpsilonClosure::RegistratorWrapper<std::set<DefaultStateType>, automaton::ExtendedNFA < > >(EpsilonClosure::epsilonClosure);
-
-std::set<DefaultStateType> EpsilonClosure::epsilonClosure( const automaton::CompactNFA < > & fsm, const DefaultStateType & q ) {
-	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
-
-	std::set<DefaultStateType> closure;
-	std::queue<DefaultStateType> queue;
-	std::map<DefaultStateType, bool> visited;
-
-	for( const auto & p : fsm.getStates( ) )
-		visited[ p ] = false;
-
-	queue.push( q );
-	while( ! queue.empty( ) )
-	{
-		DefaultStateType p = queue.front( );
-		queue.pop( );
-		visited[ p ] = true;
-		closure.insert( p );
-
-		for( const auto & transition : fsm.getTransitionsFromState( p ) )
-			if( transition.first.second.size() == 0 )
-				for (const auto & to : transition.second )
-					if( visited [ to ] == false )
-						queue.push( to );
-	}
-
-	return closure;
-}
-
 auto EpsilonClosureCompactNFA = EpsilonClosure::RegistratorWrapper<std::set<DefaultStateType>, automaton::CompactNFA < > >(EpsilonClosure::epsilonClosure);
 
 std::set<DefaultStateType> EpsilonClosure::epsilonClosure(const Automaton& automaton, const DefaultStateType& q) {
diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.h b/alib2algo/src/automaton/properties/EpsilonClosure.h
index 3b01ecc5d75572b9a8a940743d3e86286c6ee4ed..b1998622163667d65879d8e0a9b9f488ae8cc010 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.h
@@ -11,11 +11,21 @@
 #include <core/multipleDispatch.hpp>
 #include <algorithm>
 #include <deque>
+#include <queue>
 #include <set>
+#include <map>
 
 #include "automaton/Automaton.h"
 #include "automaton/AutomatonFeatures.h"
-#include <label/Label.h>
+
+#include <automaton/FSM/ExtendedNFA.h>
+#include <automaton/FSM/CompactNFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <automaton/FSM/MultiInitialStateNFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include "../../regexp/properties/RegExpEpsilon.h"
 
 namespace automaton {
 
@@ -28,14 +38,132 @@ public:
 	/**
 	 * Computes epsilon closure of a state in epsilon nonfree automaton
 	 */
-	static std::set<DefaultStateType> epsilonClosure( const automaton::EpsilonNFA < > & fsm, const DefaultStateType & state );
-	static std::set<DefaultStateType> epsilonClosure( const automaton::MultiInitialStateNFA < > & fsm, const DefaultStateType & state );
-	static std::set<DefaultStateType> epsilonClosure( const automaton::NFA < > & fsm, const DefaultStateType & state );
-	static std::set<DefaultStateType> epsilonClosure( const automaton::DFA < > & fsm, const DefaultStateType & state );
-	static std::set<DefaultStateType> epsilonClosure( const automaton::ExtendedNFA < > & fsm, const DefaultStateType & state );
-	static std::set<DefaultStateType> epsilonClosure( const automaton::CompactNFA < > & fsm, const DefaultStateType & state );
+	template < class SymbolType, class EpsilonType, class StateType >
+	static std::set<StateType> epsilonClosure( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm, const StateType & state );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> epsilonClosure( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm, const StateType & state );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> epsilonClosure( const automaton::NFA < SymbolType, StateType > & fsm, const StateType & state );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> epsilonClosure( const automaton::DFA < SymbolType, StateType > & fsm, const StateType & state );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> epsilonClosure( const automaton::ExtendedNFA < SymbolType, StateType > & fsm, const StateType & state );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> epsilonClosure( const automaton::CompactNFA < SymbolType, StateType > & fsm, const StateType & state );
 };
 
+template < class SymbolType, class EpsilonType, class StateType >
+std::set<StateType> EpsilonClosure::epsilonClosure( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & fsm, const StateType & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
+
+	std::set<StateType> closure;
+	std::queue<StateType> queue;
+	std::map<StateType, bool> visited;
+
+	for( const auto & p : fsm.getStates( ) )
+		visited[ p ] = false;
+
+	queue.push( q );
+	while( ! queue.empty( ) ) {
+		StateType p = queue.front( );
+		queue.pop( );
+		visited[ p ] = true;
+		closure.insert( p );
+
+		auto tos = fsm.getTransitions( ).find(std::make_pair ( p, std::variant < EpsilonType, SymbolType >::template from < EpsilonType > ( ) ) );
+		if(tos == fsm.getTransitions().end()) continue;
+
+		for( const auto & to : tos->second )
+			if( visited [ to ] == false )
+				queue.push( to );
+	}
+
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::set<StateType> EpsilonClosure::epsilonClosure( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm, const StateType & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
+
+	std::set<StateType> closure;
+	closure.insert(q);
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::set<StateType> EpsilonClosure::epsilonClosure( const automaton::NFA < SymbolType, StateType > & fsm, const StateType & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
+
+	std::set<StateType> closure;
+	closure.insert(q);
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::set<StateType> EpsilonClosure::epsilonClosure( const automaton::DFA < SymbolType, StateType > & fsm, const StateType & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
+
+	std::set<StateType> closure;
+	closure.insert(q);
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::set<StateType> EpsilonClosure::epsilonClosure( const automaton::ExtendedNFA < SymbolType, StateType > & fsm, const StateType & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
+
+	std::set<StateType> closure;
+	std::queue<StateType> queue;
+	std::map<StateType, bool> visited;
+
+	for( const auto & p : fsm.getStates( ) )
+		visited[ p ] = false;
+
+	queue.push( q );
+	while( ! queue.empty( ) ) {
+		StateType p = queue.front( );
+		queue.pop( );
+		visited[ p ] = true;
+		closure.insert( p );
+
+		for( const auto & transition : fsm.getTransitionsFromState( p ) )
+			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
+				for (const auto & to : transition.second )
+					if( visited [ to ] == false )
+						queue.push( to );
+	}
+
+	return closure;
+}
+
+template < class SymbolType, class StateType >
+std::set<StateType> EpsilonClosure::epsilonClosure( const automaton::CompactNFA < SymbolType, StateType > & fsm, const StateType & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
+
+	std::set<StateType> closure;
+	std::queue<StateType> queue;
+	std::map<StateType, bool> visited;
+
+	for( const auto & p : fsm.getStates( ) )
+		visited[ p ] = false;
+
+	queue.push( q );
+	while( ! queue.empty( ) ) {
+		StateType p = queue.front( );
+		queue.pop( );
+		visited[ p ] = true;
+		closure.insert( p );
+
+		for( const auto & transition : fsm.getTransitionsFromState( p ) )
+			if( transition.first.second.size() == 0 )
+				for (const auto & to : transition.second )
+					if( visited [ to ] == false )
+						queue.push( to );
+	}
+
+	return closure;
+}
+
 } /* namespace properties */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/properties/ReachableStates.cpp b/alib2algo/src/automaton/properties/ReachableStates.cpp
index 833ca31c7fb14d869ee7fe4d3d75209c97748dd5..5130b8555c29c9457e8e04b5b8bb4b019a56c5f0 100644
--- a/alib2algo/src/automaton/properties/ReachableStates.cpp
+++ b/alib2algo/src/automaton/properties/ReachableStates.cpp
@@ -7,16 +7,6 @@
 
 #include "ReachableStates.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 {
 
 namespace properties {
@@ -25,91 +15,11 @@ std::set<DefaultStateType> ReachableStates::reachableStates(const Automaton& aut
 	return dispatch(automaton.getData());
 }
 
-template<class T>
-std::set<DefaultStateType> ReachableStates::reachableStates( const T & fsm ) {
-	// 1a
-	std::deque<std::set<DefaultStateType>> Qi;
-	Qi.push_back( std::set<DefaultStateType>( ) );
-	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 );
-}
-
 auto ReachableStatesEpsilonNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::EpsilonNFA < > >(ReachableStates::reachableStates);
 auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::NFA < > >(ReachableStates::reachableStates);
 auto ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::CompactNFA < > >(ReachableStates::reachableStates);
 auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::ExtendedNFA < > >(ReachableStates::reachableStates);
-
-template<>
-std::set<DefaultStateType> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < > & fsm ) {
-	// 1a
-	std::deque<std::set<DefaultStateType>> Qi;
-	Qi.push_back( std::set<DefaultStateType>( ) );
-	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 );
-}
-
 auto ReachableStatesMultiInitialStateNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::MultiInitialStateNFA < > >(ReachableStates::reachableStates);
-
-template<>
-std::set<DefaultStateType> ReachableStates::reachableStates( const automaton::DFA < > & fsm ) {
-	// 1a
-	std::deque<std::set<DefaultStateType>> Qi;
-	Qi.push_back( std::set<DefaultStateType>( ) );
-	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 );
-}
-
 auto ReachableStatesDFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::DFA<>>(ReachableStates::reachableStates);
 
 } /* namespace properties */
diff --git a/alib2algo/src/automaton/properties/ReachableStates.h b/alib2algo/src/automaton/properties/ReachableStates.h
index 8e25478e3bc709d3f7e484b0daba5ce81987495a..dacbfbc378f4302cff02571f14abdf74a337ea2d 100644
--- a/alib2algo/src/automaton/properties/ReachableStates.h
+++ b/alib2algo/src/automaton/properties/ReachableStates.h
@@ -12,10 +12,17 @@
 #include <algorithm>
 #include <deque>
 #include <set>
+#include <map>
+#include <queue>
 
 #include <automaton/Automaton.h>
 #include <automaton/AutomatonFeatures.h>
-#include <label/Label.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>
 
 namespace automaton {
 
@@ -28,10 +35,92 @@ public:
 	/**
 	 * Removes dead states from FSM. Melichar 2.29
 	 */
-	template<class T>
-	static std::set<DefaultStateType> reachableStates( const T & fsm );
+	template < class T, class SymbolType = typename automaton::SymbolTypeOfAutomaton < T >, class StateType = typename automaton::StateTypeOfAutomaton < T > >
+	static std::set<StateType> reachableStates( const T & fsm );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> reachableStates( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> reachableStates( const automaton::DFA < SymbolType, StateType > & fsm );
 };
 
+template < class T, class SymbolType, class StateType >
+std::set<StateType> ReachableStates::reachableStates( const T & fsm ) {
+	// 1a
+	std::deque<std::set<StateType>> Qi;
+	Qi.push_back( std::set<StateType>( ) );
+	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 < class SymbolType, class StateType >
+std::set<StateType> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ) {
+	// 1a
+	std::deque<std::set<StateType>> Qi;
+	Qi.push_back( std::set<StateType>( ) );
+	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 < class SymbolType, class StateType >
+std::set<StateType> ReachableStates::reachableStates( const automaton::DFA < SymbolType, StateType > & fsm ) {
+	// 1a
+	std::deque<std::set<StateType>> Qi;
+	Qi.push_back( std::set<StateType>( ) );
+	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 );
+}
+
 } /* namespace properties */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/properties/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp
index 05fb5eacc37ba9d6b9a8323616bacb8e459fa516..353e9c23a5d9de4814bbb20ae69919aef985ac7a 100644
--- a/alib2algo/src/automaton/properties/UsefullStates.cpp
+++ b/alib2algo/src/automaton/properties/UsefullStates.cpp
@@ -7,16 +7,6 @@
 
 #include "UsefullStates.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 {
 
 namespace properties {
@@ -25,60 +15,11 @@ std::set<DefaultStateType> UsefullStates::usefullStates(const Automaton& automat
 	return dispatch(automaton.getData());
 }
 
-template<class T>
-std::set<DefaultStateType> UsefullStates::usefullStates( const T & fsm ) {
-	// 1a
-	std::deque<std::set<DefaultStateType>> Qi;
-	Qi.push_back( std::set<DefaultStateType>( ) );
-	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 );
-}
-
 auto UsefullStatesEpsilonNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::EpsilonNFA < > >(UsefullStates::usefullStates);
 auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::NFA < > >(UsefullStates::usefullStates);
 auto UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::CompactNFA < > >(UsefullStates::usefullStates);
 auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::ExtendedNFA < > >(UsefullStates::usefullStates);
 auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::MultiInitialStateNFA < > >(UsefullStates::usefullStates);
-
-template<>
-std::set<DefaultStateType> UsefullStates::usefullStates( const automaton::DFA < > & fsm ) {
-	// 1a
-	std::deque<std::set<DefaultStateType>> Qi;
-	Qi.push_back( std::set<DefaultStateType>( ) );
-	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 );
-}
-
 auto UsefullStatesDFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::DFA<>>(UsefullStates::usefullStates);
 
 } /* namespace properties */
diff --git a/alib2algo/src/automaton/properties/UsefullStates.h b/alib2algo/src/automaton/properties/UsefullStates.h
index 6bdf867f3c9b55c6f18de3c47c5e7a5643b7e616..936fecd2001b272c080bfd29e304f8b09013bdb6 100644
--- a/alib2algo/src/automaton/properties/UsefullStates.h
+++ b/alib2algo/src/automaton/properties/UsefullStates.h
@@ -12,10 +12,16 @@
 #include <algorithm>
 #include <deque>
 #include <set>
+#include <map>
 
 #include <automaton/Automaton.h>
 #include <automaton/AutomatonFeatures.h>
-#include <label/Label.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>
 
 namespace automaton {
 
@@ -28,10 +34,60 @@ public:
 	/**
 	 * Removes dead states from FSM. Melichar 2.32
 	 */
-	template<class T>
-	static std::set<DefaultStateType> usefullStates( const T & fsm );
+	template < class T, class SymbolType = typename automaton::SymbolTypeOfAutomaton < T >, class StateType = typename automaton::StateTypeOfAutomaton < T > >
+	static std::set<StateType> usefullStates( const T & fsm );
+	template < class SymbolType, class StateType >
+	static std::set<StateType> usefullStates( const automaton::DFA < SymbolType, StateType > & fsm );
 };
 
+template < class T, class SymbolType, class StateType >
+std::set<StateType> UsefullStates::usefullStates( const T & fsm ) {
+	// 1a
+	std::deque<std::set<StateType>> Qi;
+	Qi.push_back( std::set<StateType>( ) );
+	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 SymbolType, class StateType >
+std::set<StateType> UsefullStates::usefullStates( const automaton::DFA < SymbolType, StateType > & fsm ) {
+	// 1a
+	std::deque<std::set<StateType>> Qi;
+	Qi.push_back( std::set<StateType>( ) );
+	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 );
+}
+
 } /* namespace properties */
 
 } /* namespace automaton */