diff --git a/aaccess2/src/AutomatonAccess.cpp b/aaccess2/src/AutomatonAccess.cpp
index cc0072e2229a715053ceee9c74986882615d2989..2176f9e6006dd89c4263d30ccdc7a721f9d4467f 100644
--- a/aaccess2/src/AutomatonAccess.cpp
+++ b/aaccess2/src/AutomatonAccess.cpp
@@ -28,7 +28,7 @@ void AutomatonAccess::access ( const automaton::Automaton & automaton, const std
 	dispatch ( automaton.getData ( ), settings );
 }
 
-void AutomatonAccess::access ( const automaton::NFA & automaton, const std::set < AutomatonSettings::Settings > & settings ) {
+void AutomatonAccess::access ( const automaton::NFA < >  & automaton, const std::set < AutomatonSettings::Settings > & settings ) {
 	if ( settings.count ( AutomatonSettings::Settings::STATES ) ) alib::XmlDataFactory::toStdout ( automaton.getStates ( ) );
 
 	if ( settings.count ( AutomatonSettings::Settings::FINAL_STATES ) ) alib::XmlDataFactory::toStdout ( automaton.getFinalStates ( ) );
@@ -40,7 +40,7 @@ void AutomatonAccess::access ( const automaton::NFA & automaton, const std::set
 	if ( settings.count ( AutomatonSettings::Settings::TRANSITIONS ) ) alib::XmlDataFactory::toStdout ( automaton.getTransitions ( ) );
 }
 
-auto AutomatonAccessNFA = AutomatonAccess::RegistratorWrapper < void, automaton::NFA > ( AutomatonAccess::access );
+auto AutomatonAccessNFA = AutomatonAccess::RegistratorWrapper < void, automaton::NFA < >  > ( AutomatonAccess::access );
 
 void AutomatonAccess::access ( const automaton::DFA<> & automaton, const std::set < AutomatonSettings::Settings > & settings ) {
 	if ( settings.count ( AutomatonSettings::Settings::STATES ) ) alib::XmlDataFactory::toStdout ( automaton.getStates ( ) );
diff --git a/aaccess2/src/AutomatonAccess.h b/aaccess2/src/AutomatonAccess.h
index d43ef7d425281e45a5468c6ec8242878a73cbd2a..a68eb2eac34dd4fa845345dee9b247a05147bb4a 100644
--- a/aaccess2/src/AutomatonAccess.h
+++ b/aaccess2/src/AutomatonAccess.h
@@ -20,7 +20,7 @@ class AutomatonAccess : public std::SingleDispatchLastStaticParam < AutomatonAcc
 public:
 	static void access ( const automaton::Automaton & automaton, const std::set < AutomatonSettings::Settings > & settings );
 
-	static void access ( const automaton::NFA & automaton, const std::set < AutomatonSettings::Settings > & settings );
+	static void access ( const automaton::NFA < >  & automaton, const std::set < AutomatonSettings::Settings > & settings );
 	static void access ( const automaton::DFA<> & automaton, const std::set < AutomatonSettings::Settings > & settings );
 
 	static void access ( const automaton::InputDrivenNPDA & automaton, const std::set < AutomatonSettings::Settings > & settings );
diff --git a/acompare2/src/AutomatonCompare.cpp b/acompare2/src/AutomatonCompare.cpp
index d7df17db11c434a1a47f1da7ae0f3e69343e78ee..199b767af458b5192c465d749f21de0553016a89 100644
--- a/acompare2/src/AutomatonCompare.cpp
+++ b/acompare2/src/AutomatonCompare.cpp
@@ -54,7 +54,7 @@ bool AutomatonCompare::testCompare(const automaton::MultiInitialStateNFA& a, con
 			a.getTransitions()    == b.getTransitions()    ;
 }
 
-bool AutomatonCompare::testCompare(const automaton::NFA& a, const automaton::NFA& b) {
+bool AutomatonCompare::testCompare(const automaton::NFA < > & a, const automaton::NFA < > & b) {
 	return  	a.getFinalStates()    == b.getFinalStates()    &&
 			a.getInitialState()   == b.getInitialState()   &&
 //			a.getInputAlphabet()  == b.getInputAlphabet()  &&
@@ -342,7 +342,7 @@ void AutomatonCompare::printCompare(const automaton::MultiInitialStateNFA& a, co
 	}
 }
 
-void AutomatonCompare::printCompare(const automaton::NFA& a, const automaton::NFA& b) {
+void AutomatonCompare::printCompare(const automaton::NFA < > & a, const automaton::NFA < > & b) {
 	std::cout << "AutomatonCompareer" << std::endl;
 
 	if(a.getFinalStates() != b.getFinalStates()){
@@ -1183,7 +1183,7 @@ int AutomatonCompare::compare(const automaton::DFA<>& a, const automaton::DFA<>&
 
 auto AutomatonCompareDFA = AutomatonCompare::RegistratorWrapper<int, automaton::DFA<>, automaton::DFA<>>(AutomatonCompare::compare);
 
-int AutomatonCompare::compare(const automaton::NFA& a, const automaton::NFA& b) {
+int AutomatonCompare::compare(const automaton::NFA < > & a, const automaton::NFA < > & b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
 	  AutomatonCompare::printCompare(a, b);
 	  return 1;
@@ -1192,7 +1192,7 @@ int AutomatonCompare::compare(const automaton::NFA& a, const automaton::NFA& b)
 	}
 }
 
-auto AutomatonCompareNFA = AutomatonCompare::RegistratorWrapper<int, automaton::NFA, automaton::NFA>(AutomatonCompare::compare);
+auto AutomatonCompareNFA = AutomatonCompare::RegistratorWrapper<int, automaton::NFA < > , automaton::NFA < > >(AutomatonCompare::compare);
 
 int AutomatonCompare::compare(const automaton::MultiInitialStateNFA& a, const automaton::MultiInitialStateNFA& b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
diff --git a/acompare2/src/AutomatonCompare.h b/acompare2/src/AutomatonCompare.h
index 85a3c11d1669f913cad4198b4e7d353c89807077..c9d61aa7a1c174d47fb3709cd55b942a25ef9e74 100644
--- a/acompare2/src/AutomatonCompare.h
+++ b/acompare2/src/AutomatonCompare.h
@@ -23,8 +23,8 @@ private:
 	static bool testCompare(const automaton::DFA<>& a, const automaton::DFA<>& b);
 	static void printCompare(const automaton::DFA<>& a, const automaton::DFA<>& b);
 
-	static bool testCompare(const automaton::NFA& a, const automaton::NFA& b);
-	static void printCompare(const automaton::NFA& a, const automaton::NFA& b);
+	static bool testCompare(const automaton::NFA < > & a, const automaton::NFA < > & b);
+	static void printCompare(const automaton::NFA < > & a, const automaton::NFA < > & b);
 
 	static bool testCompare(const automaton::MultiInitialStateNFA& a, const automaton::MultiInitialStateNFA& b);
 	static void printCompare(const automaton::MultiInitialStateNFA& a, const automaton::MultiInitialStateNFA& b);
@@ -82,7 +82,7 @@ private:
 	template <class T, class R> static void mapCompare(const std::map<T, R> a, const std::map<T, R> b);
 public:
 	static int compare(const automaton::DFA<>& a, const automaton::DFA<>& b);
-	static int compare(const automaton::NFA& a, const automaton::NFA& b);
+	static int compare(const automaton::NFA < > & a, const automaton::NFA < > & b);
 	static int compare(const automaton::MultiInitialStateNFA& a, const automaton::MultiInitialStateNFA& b);
 	static int compare(const automaton::EpsilonNFA& a, const automaton::EpsilonNFA& b);
 	static int compare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b);
diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index 6d97f450c3f8b66c68316a5824f160be75e9f6ac..a1baeadd723b6f8d5e403e638d4d8c8566a37d5d 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -200,7 +200,7 @@ void ConversionHandler::convertREtoFA ( void ) {
 
 	case GLUSHKOV_NFA:
 	case DEFAULT: {
-		   automaton::NFA automaton = regexp::convert::ToAutomatonGlushkov::convert ( regexp );
+		   automaton::NFA < > automaton = regexp::convert::ToAutomatonGlushkov::convert ( regexp );
 
 		   measurements::end ( );
 		   measurements::start ( "Output write", measurements::Type::AUXILIARY );
diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp
index 22c3fed9012f6e967f18e04cd919265ee48eb23f..ec20082df5bbb16bc0b4fd8e5a90cc3083da672a 100644
--- a/aconvert2/src/DotConverter.cpp
+++ b/aconvert2/src/DotConverter.cpp
@@ -118,7 +118,7 @@ void DotConverter::convert(std::ostream& out, const automaton::MultiInitialState
 
 auto DotConverterMultiInitialStateNFA = DotConverter::RegistratorWrapper<void, automaton::MultiInitialStateNFA>(DotConverter::convert);
 
-void DotConverter::convert(std::ostream& out, const automaton::NFA& a) {
+void DotConverter::convert(std::ostream& out, const automaton::NFA < > & a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -149,7 +149,7 @@ void DotConverter::convert(std::ostream& out, const automaton::NFA& a) {
 	out << "}";
 }
 
-auto DotConverterNFA = DotConverter::RegistratorWrapper<void, automaton::NFA>(DotConverter::convert);
+auto DotConverterNFA = DotConverter::RegistratorWrapper<void, automaton::NFA < > >(DotConverter::convert);
 
 void DotConverter::convert(std::ostream& out, const automaton::DFA<>& a) {
 	out << "digraph automaton {\n";
@@ -748,7 +748,7 @@ void DotConverter::transitions(const automaton::MultiInitialStateNFA& fsm, const
 	}
 }
 
-void DotConverter::transitions(const automaton::NFA& fsm, const std::map<label::Label, int>& states, std::ostream& out) {
+void DotConverter::transitions(const automaton::NFA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out) {
 	std::map<std::pair<int, int>, std::string> transitions;
 
 	//put transitions from automaton to "transitions"
diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h
index 8199a72b4246458cc48cef278ec267713adb6c76..ecdc358020121c7b7b290bf6cd922708a50e3335 100644
--- a/aconvert2/src/DotConverter.h
+++ b/aconvert2/src/DotConverter.h
@@ -22,7 +22,7 @@
 class DotConverter : public std::SingleDispatchFirstStaticParam<DotConverter, void, std::ostream&, automaton::AutomatonBase> {
 	static void transitions(const automaton::EpsilonNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::MultiInitialStateNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
-	static void transitions(const automaton::NFA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
+	static void transitions(const automaton::NFA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::DFA<>& fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::ExtendedNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::CompactNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out);
@@ -44,7 +44,7 @@ public:
 
 	static void convert(std::ostream& out, const automaton::EpsilonNFA& a);
 	static void convert(std::ostream& out, const automaton::MultiInitialStateNFA& a);
-	static void convert(std::ostream& out, const automaton::NFA& a);
+	static void convert(std::ostream& out, const automaton::NFA < > & a);
 	static void convert(std::ostream& out, const automaton::DFA<>& a);
 	static void convert(std::ostream& out, const automaton::ExtendedNFA& a);
 	static void convert(std::ostream& out, const automaton::CompactNFA& a);
diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp
index 4c9cc068e9a00d1490f27cb64c6211ccaf2bdb2d..6c678c075e6b086759f7b376517746cc812df75b 100644
--- a/aconvert2/src/GasTexConverter.cpp
+++ b/aconvert2/src/GasTexConverter.cpp
@@ -120,7 +120,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::MultiInitialSt
 
 auto GasTexConverterMultiInitialStateNFA = GasTexConverter::RegistratorWrapper<void, automaton::MultiInitialStateNFA>(GasTexConverter::convert);
 
-void GasTexConverter::convert(std::ostream& out, const automaton::NFA& a) {
+void GasTexConverter::convert(std::ostream& out, const automaton::NFA < > & a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -159,7 +159,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::NFA& a) {
 	out << "\\end{picture}\n";
 }
 
-auto GasTexConverterNFA = GasTexConverter::RegistratorWrapper<void, automaton::NFA>(GasTexConverter::convert);
+auto GasTexConverterNFA = GasTexConverter::RegistratorWrapper<void, automaton::NFA < > >(GasTexConverter::convert);
 
 void GasTexConverter::convert(std::ostream& out, const automaton::DFA<>& a) {
 	out << "\\begin{center}\n";
@@ -831,7 +831,7 @@ void GasTexConverter::transitions(const automaton::MultiInitialStateNFA& fsm, st
 	printTransitionMap(transitionMap, out);
 }
 
-void GasTexConverter::transitions(const automaton::NFA& fsm, std::ostream& out) {
+void GasTexConverter::transitions(const automaton::NFA < > & fsm, std::ostream& out) {
 	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
 	for (const auto& transition : fsm.getTransitions()) {
 		for(const auto& to : transition.second) {
diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h
index 475807cbe6de9f4b24e6c86375963253248b505e..a38923b839693e799ece3c380df4c4974395a477 100644
--- a/aconvert2/src/GasTexConverter.h
+++ b/aconvert2/src/GasTexConverter.h
@@ -23,7 +23,7 @@ class GasTexConverter : public std::SingleDispatchFirstStaticParam<GasTexConvert
 
 	static void transitions(const automaton::EpsilonNFA& fsm, std::ostream& out);
 	static void transitions(const automaton::MultiInitialStateNFA& fsm, std::ostream& out);
-	static void transitions(const automaton::NFA& fsm, std::ostream& out);
+	static void transitions(const automaton::NFA < > & fsm, std::ostream& out);
 	static void transitions(const automaton::DFA<>& fsm, std::ostream& out);
 	static void transitions(const automaton::ExtendedNFA& fsm, std::ostream& out);
 	static void transitions(const automaton::CompactNFA& fsm, std::ostream& out);
@@ -45,7 +45,7 @@ public:
 
 	static void convert(std::ostream& out, const automaton::EpsilonNFA& a);
 	static void convert(std::ostream& out, const automaton::MultiInitialStateNFA& a);
-	static void convert(std::ostream& out, const automaton::NFA& a);
+	static void convert(std::ostream& out, const automaton::NFA < > & a);
 	static void convert(std::ostream& out, const automaton::DFA<>& a);
 	static void convert(std::ostream& out, const automaton::ExtendedNFA& a);
 	static void convert(std::ostream& out, const automaton::CompactNFA& a);
diff --git a/aconvert2/src/TikZConverter.cpp b/aconvert2/src/TikZConverter.cpp
index d2763873c366001d93654d0088714ad053597b5e..cbeaf72d1e7a38fee2537ab5550cd5dd828821cd 100644
--- a/aconvert2/src/TikZConverter.cpp
+++ b/aconvert2/src/TikZConverter.cpp
@@ -109,7 +109,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::MultiInitialS
 
 auto TikZConverterMultiInitialStateNFA = TikZConverter::RegistratorWrapper < void, automaton::MultiInitialStateNFA > ( TikZConverter::convert );
 
-void TikZConverter::convert ( std::ostream & out, const automaton::NFA & a ) {
+void TikZConverter::convert ( std::ostream & out, const automaton::NFA < >  & a ) {
 	out << "\\begin{tikzpicture}\n";
 	int cnt = 1;
 
@@ -136,7 +136,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::NFA & a ) {
 	out << "\\end{tikzpicture}";
 }
 
-auto TikZConverterNFA = TikZConverter::RegistratorWrapper < void, automaton::NFA > ( TikZConverter::convert );
+auto TikZConverterNFA = TikZConverter::RegistratorWrapper < void, automaton::NFA < >  > ( TikZConverter::convert );
 
 void TikZConverter::convert ( std::ostream & out, const automaton::DFA<> & a ) {
 	out << "\\begin{tikzpicture}\n";
@@ -685,7 +685,7 @@ void TikZConverter::transitions ( const automaton::MultiInitialStateNFA & fsm, c
 	}
 }
 
-void TikZConverter::transitions ( const automaton::NFA & fsm, const std::map < label::Label, int > & states, std::ostream & out ) {
+void TikZConverter::transitions ( const automaton::NFA < >  & fsm, const std::map < label::Label, int > & states, std::ostream & out ) {
 	std::map < std::pair < int, int >, std::string > transitions;
 
 	 // put transitions from automaton to "transitions"
diff --git a/aconvert2/src/TikZConverter.h b/aconvert2/src/TikZConverter.h
index 3f2a7af2b551536644003b71bfffba0e728bc01d..2704daf7c7f953cc0f8cb207d1babbacb6d5e1d2 100644
--- a/aconvert2/src/TikZConverter.h
+++ b/aconvert2/src/TikZConverter.h
@@ -22,7 +22,7 @@
 class TikZConverter : public std::SingleDispatchFirstStaticParam < TikZConverter, void, std::ostream &, automaton::AutomatonBase > {
 	static void transitions ( const automaton::EpsilonNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::MultiInitialStateNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
-	static void transitions ( const automaton::NFA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
+	static void transitions ( const automaton::NFA < >  & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::DFA<> & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::ExtendedNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::CompactNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
@@ -45,7 +45,7 @@ public:
 
 	static void convert ( std::ostream & out, const automaton::EpsilonNFA & a );
 	static void convert ( std::ostream & out, const automaton::MultiInitialStateNFA & a );
-	static void convert ( std::ostream & out, const automaton::NFA & a );
+	static void convert ( std::ostream & out, const automaton::NFA < >  & a );
 	static void convert ( std::ostream & out, const automaton::DFA<> & a );
 	static void convert ( std::ostream & out, const automaton::ExtendedNFA & a );
 	static void convert ( std::ostream & out, const automaton::CompactNFA & a );
diff --git a/alib2algo/src/automaton/convert/ToGrammar.cpp b/alib2algo/src/automaton/convert/ToGrammar.cpp
index 6d73b780cd86099ee6a423e874c34d2bfa4155db..d494233250ea16df52855848b486e930c5978fb9 100644
--- a/alib2algo/src/automaton/convert/ToGrammar.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammar.cpp
@@ -16,11 +16,11 @@ grammar::Grammar ToGrammar::convert(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
 }
 
-grammar::Grammar ToGrammar::convert(const automaton::NFA& automaton) {
+grammar::Grammar ToGrammar::convert(const automaton::NFA < > & automaton) {
 	return grammar::Grammar(ToGrammarRightRG::convert(automaton));
 }
 
-auto ToGrammarNFA = ToGrammar::RegistratorWrapper<grammar::Grammar, automaton::NFA>(ToGrammar::convert);
+auto ToGrammarNFA = ToGrammar::RegistratorWrapper<grammar::Grammar, automaton::NFA < > >(ToGrammar::convert);
 
 grammar::Grammar ToGrammar::convert(const automaton::DFA<>& automaton) {
 	return grammar::Grammar(ToGrammarRightRG::convert(automaton));
diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h
index acc2b16f91aeef5545cd9526b2e8017e020ca855..dabe05359e579da3802f380c9a7d5a40074e4aca 100644
--- a/alib2algo/src/automaton/convert/ToGrammar.h
+++ b/alib2algo/src/automaton/convert/ToGrammar.h
@@ -29,8 +29,8 @@ public:
 	 */
 	static grammar::Grammar convert(const automaton::Automaton& automaton);
 
-	static grammar::Grammar convert(const NFA& automaton);
-	static grammar::Grammar convert(const DFA<>& automaton);
+	static grammar::Grammar convert(const automaton::NFA<>& automaton);
+	static grammar::Grammar convert(const automaton::DFA<>& automaton);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
index d5627b87868843caa81eb1c84e7788a4f195a76f..6827092dea3fc62d19562257af54a3f0d583b230 100644
--- a/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
@@ -18,7 +18,7 @@ grammar::LeftRG ToGrammarLeftRG::convert(const automaton::Automaton& automaton)
 	return dispatch(automaton.getData());
 }
 
-grammar::LeftRG ToGrammarLeftRG::convert(const automaton::NFA& automaton) {
+grammar::LeftRG ToGrammarLeftRG::convert(const automaton::NFA < > & automaton) {
 	std::map<label::Label, alphabet::Symbol> nonterminalMap;
 	// step 2
 	grammar::LeftRG grammar(alphabet::symbolFrom("S"));
@@ -63,7 +63,7 @@ grammar::LeftRG ToGrammarLeftRG::convert(const automaton::NFA& automaton) {
 	return grammar;
 }
 
-auto ToGrammarLeftRGNFA = ToGrammarLeftRG::RegistratorWrapper<grammar::LeftRG, automaton::NFA>(ToGrammarLeftRG::convert);
+auto ToGrammarLeftRGNFA = ToGrammarLeftRG::RegistratorWrapper<grammar::LeftRG, automaton::NFA < > >(ToGrammarLeftRG::convert);
 
 grammar::LeftRG ToGrammarLeftRG::convert(const automaton::DFA<>& automaton) {
 	std::map<label::Label, alphabet::Symbol> nonterminalMap;
diff --git a/alib2algo/src/automaton/convert/ToGrammarLeftRG.h b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
index 0aed7310a8ded7ef38be3588c4ccb0732fa4cc20..2a49eaaf6f2c3e8ee90476bb4e20857da0367f32 100644
--- a/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
+++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
@@ -32,7 +32,7 @@ public:
 	 */
 	static grammar::LeftRG convert(const automaton::Automaton& automaton);
 
-	static grammar::LeftRG convert(const automaton::NFA& automaton);
+	static grammar::LeftRG convert(const automaton::NFA < > & automaton);
 	static grammar::LeftRG convert(const automaton::DFA<>& automaton);
 };
 
diff --git a/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
index 2c83a6a831f86416d0900f8bb3e0c4fefb5b9e55..081f9c2fe5f4878ec4ec4d4dfc51e5cff5d5e2ed 100644
--- a/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
@@ -16,7 +16,7 @@ grammar::RightRG ToGrammarRightRG::convert(const automaton::Automaton& automaton
 	return dispatch(automaton.getData());
 }
 
-grammar::RightRG ToGrammarRightRG::convert(const automaton::NFA& automaton) {
+grammar::RightRG ToGrammarRightRG::convert(const automaton::NFA < > & automaton) {
 	std::map<label::Label, alphabet::Symbol> nonterminalMap;
 
 	const label::Label& initState = automaton.getInitialState();
@@ -57,7 +57,7 @@ grammar::RightRG ToGrammarRightRG::convert(const automaton::NFA& automaton) {
 	return grammar;
 }
 
-auto ToGrammarRightRGNFA = ToGrammarRightRG::RegistratorWrapper<grammar::RightRG, automaton::NFA>(ToGrammarRightRG::convert);
+auto ToGrammarRightRGNFA = ToGrammarRightRG::RegistratorWrapper<grammar::RightRG, automaton::NFA < > >(ToGrammarRightRG::convert);
 
 grammar::RightRG ToGrammarRightRG::convert(const automaton::DFA<>& automaton) {
 	std::map<label::Label, alphabet::Symbol> nonterminalMap;
diff --git a/alib2algo/src/automaton/convert/ToGrammarRightRG.h b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
index c74a9039ede7381725f4c2fadea31a85065e7f2f..c96e590d69d4f6a7cdbd2c5688aa78b2d3d19f68 100644
--- a/alib2algo/src/automaton/convert/ToGrammarRightRG.h
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
@@ -32,7 +32,7 @@ public:
 	 */
 	static grammar::RightRG convert(const automaton::Automaton& automaton);
 
-	static grammar::RightRG convert(const automaton::NFA& automaton);
+	static grammar::RightRG convert(const automaton::NFA < > & automaton);
 	static grammar::RightRG convert(const automaton::DFA<>& automaton);
 };
 
diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp
index d9e398872c946ee0f1397a4e67cce4ce3dbb1fe1..640c8312de95f7a3e252a1e3192b7f5293b0b18a 100644
--- a/alib2algo/src/automaton/convert/ToRegExp.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExp.cpp
@@ -28,11 +28,11 @@ regexp::RegExp ToRegExp::convert(const automaton::MultiInitialStateNFA& automato
 
 auto ToRegExpMultiInitialStateNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::MultiInitialStateNFA>(ToRegExp::convert);
 
-regexp::RegExp ToRegExp::convert(const automaton::NFA& automaton) {
+regexp::RegExp ToRegExp::convert(const automaton::NFA < > & automaton) {
 	return regexp::RegExp(ToRegExpStateElimination::convert(automaton));
 }
 
-auto ToRegExpNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::NFA>(ToRegExp::convert);
+auto ToRegExpNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::NFA < > >(ToRegExp::convert);
 
 regexp::RegExp ToRegExp::convert(const automaton::DFA<>& automaton) {
 	return regexp::RegExp(ToRegExpStateElimination::convert(automaton));
diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h
index 56e9dce86de0c9a6cc853091fc211fa5dc171d2d..2187f142fa7924e3644f11f0bbbcd1e413b3ccf4 100644
--- a/alib2algo/src/automaton/convert/ToRegExp.h
+++ b/alib2algo/src/automaton/convert/ToRegExp.h
@@ -31,12 +31,12 @@ public:
 	 */
 	static regexp::RegExp convert(const automaton::Automaton& automaton);
 
-	static regexp::RegExp convert(const EpsilonNFA& automaton);
-	static regexp::RegExp convert(const MultiInitialStateNFA& automaton);
-	static regexp::RegExp convert(const NFA& automaton);
-	static regexp::RegExp convert(const DFA<>& automaton);
-	static regexp::RegExp convert(const ExtendedNFA& automaton);
-	static regexp::RegExp convert(const CompactNFA& automaton);
+	static regexp::RegExp convert(const automaton::EpsilonNFA& automaton);
+	static regexp::RegExp convert(const automaton::MultiInitialStateNFA& automaton);
+	static regexp::RegExp convert(const automaton::NFA<>& automaton);
+	static regexp::RegExp convert(const automaton::DFA<>& automaton);
+	static regexp::RegExp convert(const automaton::ExtendedNFA& automaton);
+	static regexp::RegExp convert(const automaton::CompactNFA& automaton);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
index 8a476c1f936f8eef6823e74f5a868524a94fcabc..b0271a49819fe21b0ece17f3874e5ee44402a7da 100644
--- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
@@ -86,7 +86,7 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::MultiInitia
 
 auto ToRegExpAlgebraicMultiInitialStateNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::MultiInitialStateNFA>(ToRegExpAlgebraic::convert);
 
-regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA & automaton ) {
+regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA < >  & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -107,7 +107,7 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA & autom
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState() ) ) );
 }
 
-auto ToRegExpAlgebraicNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::NFA>(ToRegExpAlgebraic::convert);
+auto ToRegExpAlgebraicNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::NFA < > >(ToRegExpAlgebraic::convert);
 
 regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA<> & automaton ) {
 	equations::RightRegularEquationSolver solver;
diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
index 602999ce8a2543c28f84684a870c46be16920839..34087eee6d103988f7805aa5e324f719e6dc06d0 100644
--- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
@@ -40,7 +40,7 @@ public:
 
 	static regexp::UnboundedRegExp convert(const automaton::EpsilonNFA& automaton);
 	static regexp::UnboundedRegExp convert(const automaton::MultiInitialStateNFA& automaton);
-	static regexp::UnboundedRegExp convert(const automaton::NFA& automaton);
+	static regexp::UnboundedRegExp convert(const automaton::NFA < > & automaton);
 	static regexp::UnboundedRegExp convert(const automaton::DFA<>& automaton);
 };
 
diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
index cf9b6d5ffd97c0cb34cfae11f6d6d7dcb308bdcf..8203c5562364d168a8082be7fac917739d1d4a30 100644
--- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
@@ -48,7 +48,7 @@ regexp::RegExp ToRegExpStateElimination::convert(const T& automaton) {
 
 auto ToRegExpStateEliminationEpsilonNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::EpsilonNFA>(ToRegExpStateElimination::convert);
 auto ToRegExpStateEliminationMultiInitialStateNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::MultiInitialStateNFA>(ToRegExpStateElimination::convert);
-auto ToRegExpStateEliminationNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::NFA>(ToRegExpStateElimination::convert);
+auto ToRegExpStateEliminationNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::NFA < > >(ToRegExpStateElimination::convert);
 auto ToRegExpStateEliminationDFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::DFA<>>(ToRegExpStateElimination::convert);
 auto ToRegExpStateEliminationExtendedNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::ExtendedNFA>(ToRegExpStateElimination::convert);
 auto ToRegExpStateEliminationCompactNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::CompactNFA>(ToRegExpStateElimination::convert);
diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h
index 38008c28c99200a59043f9846a6e01a643bdece3..2dbf75862559cbd3517fd3857df11a17e737d969 100644
--- a/alib2algo/src/automaton/determinize/Determinize.h
+++ b/alib2algo/src/automaton/determinize/Determinize.h
@@ -32,7 +32,7 @@ public:
 	static automaton::Automaton determinize(const automaton::Automaton& nfa);
 
 	static automaton::DFA<> determinize(const automaton::DFA<>& nfa);
-	static automaton::DFA<> determinize(const automaton::NFA& nfa);
+	static automaton::DFA<> determinize(const automaton::NFA < > & nfa);
 	static automaton::DFA<> determinize(const automaton::MultiInitialStateNFA& nfa);
 	static automaton::DPDA determinize(const automaton::DPDA& dpda);
 	static automaton::DPDA determinize(const automaton::NPDA& dpda);
diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
index 28bd6e1f4747f61283ac9d2ae410f54eceb7bffa..c66411bea58cbe4834a8ecad5e876ab2454e139f 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
@@ -69,7 +69,7 @@ automaton::DFA<> Determinize::determinize ( const automaton::MultiInitialStateNF
 
 auto DeterminizeMultiInitialStateNFA = Determinize::RegistratorWrapper < automaton::DFA<>, automaton::MultiInitialStateNFA > ( Determinize::determinize );
 
-automaton::DFA<> Determinize::determinize ( const automaton::NFA & nfa ) {
+automaton::DFA<> Determinize::determinize ( const automaton::NFA < >  & nfa ) {
 	 // 1, 4
 	label::Label initialState ( createDFAState ( { nfa.getInitialState ( ) } ) );
 	automaton::DFA < > res ( initialState );
@@ -120,7 +120,7 @@ automaton::DFA<> Determinize::determinize ( const automaton::NFA & nfa ) {
 	return res;
 }
 
-auto DeterminizeNFA = Determinize::RegistratorWrapper < automaton::DFA<>, automaton::NFA > ( Determinize::determinize );
+auto DeterminizeNFA = Determinize::RegistratorWrapper < automaton::DFA<>, automaton::NFA < >  > ( Determinize::determinize );
 
 } /* namespace determinize */
 
diff --git a/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp b/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp
index d0c33b59e6014d682b967228591d539928bd0967..987302b638993d6f11cbeff6f9377745f8f82302 100644
--- a/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp
+++ b/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp
@@ -16,14 +16,14 @@ namespace automaton {
 
 namespace generate {
 
-automaton::NFA RandomAutomatonFactory::generateNFA( size_t statesCount, std::set<alphabet::Symbol> alphabet, double density ) {
+automaton::NFA < >  RandomAutomatonFactory::generateNFA( size_t statesCount, std::set<alphabet::Symbol> alphabet, double density ) {
 	std::deque<alphabet::Symbol> alphabet2;
 	for( const auto & s : alphabet )
 		alphabet2.push_back( s );
 	return RandomAutomatonFactory::LeslieConnectedNFA( statesCount, alphabet2, density );
 }
 
-automaton::NFA RandomAutomatonFactory::generateNFA( size_t statesCount, size_t alphabetSize, bool randomizedAlphabet, double density ) {
+automaton::NFA < >  RandomAutomatonFactory::generateNFA( size_t statesCount, size_t alphabetSize, bool randomizedAlphabet, double density ) {
 	if(alphabetSize > 26)
 		throw exception::CommonException("Too big alphabet.");
 
@@ -35,7 +35,7 @@ automaton::NFA RandomAutomatonFactory::generateNFA( size_t statesCount, size_t a
 	return RandomAutomatonFactory::LeslieConnectedNFA( statesCount, alphabet, density );
 }
 
-automaton::NFA RandomAutomatonFactory::LeslieConnectedNFA( size_t n, const std::deque<alphabet::Symbol> & alphabet, double density ) {
+automaton::NFA < >  RandomAutomatonFactory::LeslieConnectedNFA( size_t n, const std::deque<alphabet::Symbol> & alphabet, double density ) {
 	if( alphabet.size( ) <= 0 )
 		throw exception::CommonException( "Alphabet size must be greater than 0." );
 
@@ -43,7 +43,7 @@ automaton::NFA RandomAutomatonFactory::LeslieConnectedNFA( size_t n, const std::
 	std::deque<label::Label> Q;
 	int unvisited;
 
-	automaton::NFA automaton( label::labelFrom( 0 ) );
+	automaton::NFA < >  automaton( label::labelFrom( 0 ) );
 
 	for( const auto & s : alphabet )
 		automaton.addInputSymbol( s );
diff --git a/alib2algo/src/automaton/generate/RandomAutomatonFactory.h b/alib2algo/src/automaton/generate/RandomAutomatonFactory.h
index 69375f17e6f243d689bfd02d983e48d1f1cf536a..86b6fd8b8d54c7654235a7a797c2d97e69038a58 100644
--- a/alib2algo/src/automaton/generate/RandomAutomatonFactory.h
+++ b/alib2algo/src/automaton/generate/RandomAutomatonFactory.h
@@ -19,11 +19,11 @@ namespace generate {
 
 class RandomAutomatonFactory {
 public:
-	static automaton::NFA generateNFA( size_t statesCount, std::set<alphabet::Symbol> alphabet, double density );
-	static automaton::NFA generateNFA( size_t statesCount, size_t alphabetSize, bool randomizedAlphabet, double density );
+	static automaton::NFA < >  generateNFA( size_t statesCount, std::set<alphabet::Symbol> alphabet, double density );
+	static automaton::NFA < >  generateNFA( size_t statesCount, size_t alphabetSize, bool randomizedAlphabet, double density );
 
 private:
-	static automaton::NFA LeslieConnectedNFA( size_t n, const std::deque<alphabet::Symbol> & alphabet, double density );
+	static automaton::NFA < >  LeslieConnectedNFA( size_t n, const std::deque<alphabet::Symbol> & alphabet, double density );
 };
 
 } /* namespace generate */
diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
index b550052a30449c3ee084cdbb1fbb3f6e08427ad4..91c2a9bec446dadad7aa7cc8ec0bf83d37ded2d4 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
@@ -63,14 +63,14 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 
 auto AllEpsilonClosureMultiInitialStateNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::MultiInitialStateNFA>(AllEpsilonClosure::allEpsilonClosure);
 
-std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::NFA & fsm) {
+std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::NFA < >  & fsm) {
 	std::map<label::Label, std::set<label::Label>> closure;
 	for(const label::Label& state : fsm.getStates())
 		closure[state].insert(state);
 	return closure;
 }
 
-auto AllEpsilonClosureNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::NFA>(AllEpsilonClosure::allEpsilonClosure);
+auto AllEpsilonClosureNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::NFA < > >(AllEpsilonClosure::allEpsilonClosure);
 
 std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::DFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> closure;
diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.h b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
index 812af0f6bc63e973ecd3f7033b3800de32cf6e04..90690c45579df214cae78857b61db6b3748bc11f 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
@@ -29,7 +29,7 @@ public:
 	 */
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::EpsilonNFA & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::MultiInitialStateNFA & fsm);
-	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::NFA & fsm);
+	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::NFA < >  & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::DFA < > & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::ExtendedNFA & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::CompactNFA & fsm);
diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.cpp b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
index 4f4d547d5690aa0ee46ef7723f5ce93d881d3da1..73bf26a77ce09f75f97382cd6fc8c7fa61741d79 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
@@ -65,7 +65,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::MultiIni
 
 auto EpsilonClosureMultiInitialStateNFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA>(EpsilonClosure::epsilonClosure);
 
-std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::NFA & fsm, const label::Label & q ) {
+std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::NFA < >  & fsm, const label::Label & q ) {
 	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
 
 	std::set<label::Label> closure;
@@ -73,7 +73,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::NFA & fs
 	return closure;
 }
 
-auto EpsilonClosureNFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::NFA>(EpsilonClosure::epsilonClosure);
+auto EpsilonClosureNFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(EpsilonClosure::epsilonClosure);
 
 std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::DFA < > & fsm, const label::Label & q ) {
 	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
diff --git a/alib2algo/src/automaton/properties/EpsilonClosure.h b/alib2algo/src/automaton/properties/EpsilonClosure.h
index da079311a2e87aa7c6de1f12aed97feae013ec29..1a108a30669803eb3757510900222776503f617a 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.h
@@ -30,7 +30,7 @@ public:
 	 */
 	static std::set<label::Label> epsilonClosure( const automaton::EpsilonNFA & fsm, const label::Label & state );
 	static std::set<label::Label> epsilonClosure( const automaton::MultiInitialStateNFA & fsm, const label::Label & state );
-	static std::set<label::Label> epsilonClosure( const automaton::NFA & fsm, const label::Label & state );
+	static std::set<label::Label> epsilonClosure( const automaton::NFA < >  & fsm, const label::Label & state );
 	static std::set<label::Label> epsilonClosure( const automaton::DFA < > & fsm, const label::Label & state );
 	static std::set<label::Label> epsilonClosure( const automaton::ExtendedNFA & fsm, const label::Label & state );
 	static std::set<label::Label> epsilonClosure( const automaton::CompactNFA & fsm, const label::Label & state );
diff --git a/alib2algo/src/automaton/properties/ReachableStates.cpp b/alib2algo/src/automaton/properties/ReachableStates.cpp
index aa71135b4be7ac2b2bf0599d50325ab73253a35e..d2907b9c3de9147add2d1067b816e76667f2dd47 100644
--- a/alib2algo/src/automaton/properties/ReachableStates.cpp
+++ b/alib2algo/src/automaton/properties/ReachableStates.cpp
@@ -52,7 +52,7 @@ std::set<label::Label> ReachableStates::reachableStates( const T & fsm ) {
 }
 
 auto ReachableStatesEpsilonNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA>(ReachableStates::reachableStates);
-auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA>(ReachableStates::reachableStates);
+auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(ReachableStates::reachableStates);
 auto ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA>(ReachableStates::reachableStates);
 auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(ReachableStates::reachableStates);
 
diff --git a/alib2algo/src/automaton/properties/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp
index a78634424e343da7f72d76d78a0aab63427d1fae..cb6a8c6ae74b1841e05b2402497a7e1873723614 100644
--- a/alib2algo/src/automaton/properties/UsefullStates.cpp
+++ b/alib2algo/src/automaton/properties/UsefullStates.cpp
@@ -50,7 +50,7 @@ std::set<label::Label> UsefullStates::usefullStates( const T & fsm ) {
 }
 
 auto UsefullStatesEpsilonNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA>(UsefullStates::usefullStates);
-auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA>(UsefullStates::usefullStates);
+auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(UsefullStates::usefullStates);
 auto UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA>(UsefullStates::usefullStates);
 auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(UsefullStates::usefullStates);
 auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA>(UsefullStates::usefullStates);
diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp
index 75b65792502a4e2c0dda5040c556dbd9eb339a99..7b79191c9db32e9936238b2329775d2c05020f05 100644
--- a/alib2algo/src/automaton/run/Accept.cpp
+++ b/alib2algo/src/automaton/run/Accept.cpp
@@ -45,7 +45,7 @@ bool Accept::accept ( const automaton::DFA<> & automaton, const string::LinearSt
 
 auto AcceptDFALinearString = Accept::RegistratorWrapper < bool, automaton::DFA<>, string::LinearString > ( Accept::accept );
 
-bool Accept::accept ( const automaton::NFA & automaton, const string::LinearString & string ) {
+bool Accept::accept ( const automaton::NFA < >  & automaton, const string::LinearString & string ) {
 	std::tuple < bool, std::set < label::Label >, std::set < unsigned > > res = Run::calculateStates ( automaton, string );
 
 	return std::get < 0 > ( res ) && std::any_of ( std::get < 1 > ( res ).begin ( ), std::get < 1 > ( res ).end ( ), [&] ( const label::Label & state ) {
@@ -53,7 +53,7 @@ bool Accept::accept ( const automaton::NFA & automaton, const string::LinearStri
 			} );
 }
 
-auto AcceptNFALinearString = Accept::RegistratorWrapper < bool, automaton::NFA, string::LinearString > ( Accept::accept );
+auto AcceptNFALinearString = Accept::RegistratorWrapper < bool, automaton::NFA < > , string::LinearString > ( Accept::accept );
 
 bool Accept::accept ( const automaton::DFTA & automaton, const tree::RankedTree & tree ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree );
diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h
index 4ba048d2b4dafb85e0f872c5f53fa1d0fbc9a889..753adbe889066884d5e6466d6c6ff948f57e9468 100644
--- a/alib2algo/src/automaton/run/Accept.h
+++ b/alib2algo/src/automaton/run/Accept.h
@@ -30,7 +30,7 @@ public:
 	static bool accept ( const automaton::Automaton & automaton, const tree::RankedTree & string );
 
 	static bool accept ( const automaton::DFA<> & automaton, const string::LinearString & string );
-	static bool accept ( const automaton::NFA & automaton, const string::LinearString & string );
+	static bool accept ( const automaton::NFA < >  & automaton, const string::LinearString & string );
 	static bool accept ( const automaton::DFTA & automaton, const tree::RankedTree & tree );
 	static bool accept ( const automaton::NFTA & automaton, const tree::RankedTree & tree );
 	static bool accept ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string );
diff --git a/alib2algo/src/automaton/run/Run.cpp b/alib2algo/src/automaton/run/Run.cpp
index 9a7baca9a1c0810db00afe7ea8386e558fcae378..c11820091ba605a73d2b6b388583504230dcb1ae 100644
--- a/alib2algo/src/automaton/run/Run.cpp
+++ b/alib2algo/src/automaton/run/Run.cpp
@@ -64,7 +64,7 @@ std::tuple < bool, label::Label, std::set < unsigned > > Run::calculateState ( c
 
 // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-std::tuple < bool, std::set < label::Label >, std::set < unsigned > > Run::calculateStates ( const automaton::NFA & automaton, const string::LinearString & string ) {
+std::tuple < bool, std::set < label::Label >, std::set < unsigned > > Run::calculateStates ( const automaton::NFA < >  & automaton, const string::LinearString & string ) {
 	bool res = true;
 	unsigned i = 0;
 	std::set < unsigned > occurrences;
diff --git a/alib2algo/src/automaton/run/Run.h b/alib2algo/src/automaton/run/Run.h
index d33826dc04e5ef47d6cda725eddea2b9fe83c153..6875f78118296b2cea7a59479d118ce568d8b287 100644
--- a/alib2algo/src/automaton/run/Run.h
+++ b/alib2algo/src/automaton/run/Run.h
@@ -26,7 +26,7 @@ class Run {
 
 public:
 	static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFA < > & automaton, const string::LinearString & string );
-	static std::tuple < bool, std::set < label::Label >, std::set < unsigned > > calculateStates ( const automaton::NFA & automaton, const string::LinearString & string );
+	static std::tuple < bool, std::set < label::Label >, std::set < unsigned > > calculateStates ( const automaton::NFA < >  & automaton, const string::LinearString & string );
 	static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFTA & automaton, const tree::RankedTree & tree );
 	static std::tuple < bool, std::set < label::Label >, std::set < unsigned > > calculateStates ( const automaton::NFTA & automaton, const tree::RankedTree & tree );
 	static std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string );
diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp
index 628d879011c7a23f955922fa5baad64934fadcbe..39a4e43bbf969e828866a713a8153e49b62cee7d 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp
@@ -25,14 +25,14 @@ automaton::MultiInitialStateNFA EpsilonRemoverIncoming::remove(const automaton::
 
 auto EpsilonRemoverIncomingMultiInitialStateNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::MultiInitialStateNFA>(EpsilonRemoverIncoming::remove);
 
-automaton::NFA EpsilonRemoverIncoming::remove(const automaton::NFA& origFSM) {
+automaton::NFA < >  EpsilonRemoverIncoming::remove(const automaton::NFA < > & origFSM) {
 	return origFSM;
 }
 
-auto EpsilonRemoverIncomingNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA, automaton::NFA>(EpsilonRemoverIncoming::remove);
+auto EpsilonRemoverIncomingNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(EpsilonRemoverIncoming::remove);
 
-automaton::NFA EpsilonRemoverIncoming::remove( const automaton::EpsilonNFA & origFSM ) {
-	automaton::NFA fsm(origFSM.getInitialState());
+automaton::NFA < >  EpsilonRemoverIncoming::remove( const automaton::EpsilonNFA & origFSM ) {
+	automaton::NFA < >  fsm(origFSM.getInitialState());
 
 	fsm.setStates( origFSM.getStates() );
 	fsm.setInputAlphabet( origFSM.getInputAlphabet() );
@@ -69,7 +69,7 @@ automaton::NFA EpsilonRemoverIncoming::remove( const automaton::EpsilonNFA & ori
 	return fsm;
 }
 
-auto EpsilonRemoverIncomingEpsilonNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA, automaton::EpsilonNFA>(EpsilonRemoverIncoming::remove);
+auto EpsilonRemoverIncomingEpsilonNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA < > , automaton::EpsilonNFA>(EpsilonRemoverIncoming::remove);
 
 automaton::Automaton EpsilonRemoverIncoming::remove(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h
index 71476397ed68bb07fc13ad793c27f2b6f6b428ba..164a219edeb6dcc0f594c833072ee0c8b62cd88a 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h
@@ -27,9 +27,9 @@ public:
 	/**
 	 * Computes epsilon closure of a state in epsilon nonfree automaton
 	 */
-	static automaton::NFA remove( const automaton::EpsilonNFA & fsm );
+	static automaton::NFA < >  remove( const automaton::EpsilonNFA & fsm );
 	static automaton::MultiInitialStateNFA remove( const automaton::MultiInitialStateNFA & fsm );
-	static automaton::NFA remove( const automaton::NFA & fsm );
+	static automaton::NFA < >  remove( const automaton::NFA < >  & fsm );
 	static automaton::DFA<> remove( const automaton::DFA<> & fsm );
 
 };
diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp
index 8bf1155e3ae96eef81250e45ae8f618a120651cf..6ff4e5b601c7ad48b18750bc9d66e3f7648a46fd 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp
@@ -25,11 +25,11 @@ automaton::MultiInitialStateNFA EpsilonRemoverOutgoing::remove(const automaton::
 
 auto EpsilonRemoverOutgoingMultiInitialStateNFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::MultiInitialStateNFA>(EpsilonRemoverOutgoing::remove);
 
-automaton::NFA EpsilonRemoverOutgoing::remove(const automaton::NFA& origFSM) {
+automaton::NFA < >  EpsilonRemoverOutgoing::remove(const automaton::NFA < > & origFSM) {
 	return origFSM;
 }
 
-auto EpsilonRemoverOutgoingNFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::NFA, automaton::NFA>(EpsilonRemoverOutgoing::remove);
+auto EpsilonRemoverOutgoingNFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(EpsilonRemoverOutgoing::remove);
 
 automaton::MultiInitialStateNFA EpsilonRemoverOutgoing::remove( const automaton::EpsilonNFA & origFSM ) {
 	automaton::MultiInitialStateNFA fsm;
diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h
index e6b6adff4dbe0c0065a3c5442b5e0bc01675280c..7d6ed22165956ac79e8ea0a7008154d5f0b4ff23 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h
@@ -29,7 +29,7 @@ public:
 	 */
 	static automaton::MultiInitialStateNFA remove( const automaton::EpsilonNFA & fsm );
 	static automaton::MultiInitialStateNFA remove( const automaton::MultiInitialStateNFA & fsm );
-	static automaton::NFA remove( const automaton::NFA & fsm );
+	static automaton::NFA < >  remove( const automaton::NFA < >  & fsm );
 	static automaton::DFA<> remove( const automaton::DFA<> & fsm );
 };
 
diff --git a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp
index 650964aae0bc049a4956b2f2f9b1c0482b762c76..418879205e97d0361f87eb7e01954285adab6eb9 100644
--- a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp
+++ b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp
@@ -27,11 +27,11 @@ automaton::DFA<> MinimizeBrzozowski::minimize(const automaton::DFA<>& dfa) {
 
 auto MinimizeBrzozowskiDFA = MinimizeBrzozowski::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(MinimizeBrzozowski::minimize);
 
-automaton::DFA<> MinimizeBrzozowski::minimize(const automaton::NFA& nfa) {
+automaton::DFA<> MinimizeBrzozowski::minimize(const automaton::NFA < > & nfa) {
 	return automaton::determinize::Determinize::determinize(automaton::transform::Reverse::convert(automaton::determinize::Determinize::determinize(automaton::transform::Reverse::convert(nfa))));
 }
 
-auto MinimizeBrzozowskiNFA = MinimizeBrzozowski::RegistratorWrapper<automaton::DFA<>, automaton::NFA>(MinimizeBrzozowski::minimize);
+auto MinimizeBrzozowskiNFA = MinimizeBrzozowski::RegistratorWrapper<automaton::DFA<>, automaton::NFA < > >(MinimizeBrzozowski::minimize);
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h
index 50477c27d8e4d470161c699412ef4722c7a004f7..6f9768feab1be313f6d1ef41b09d7257510282e1 100644
--- a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h
+++ b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h
@@ -25,7 +25,7 @@ public:
 	static automaton::Automaton minimize(const automaton::Automaton& dfa);
 
 	static automaton::DFA<> minimize(const automaton::DFA<>& dfa);
-	static automaton::DFA<> minimize(const automaton::NFA& nfa);
+	static automaton::DFA<> minimize(const automaton::NFA < > & nfa);
 };
 
 } /* namespace simplify */
diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
index a1192e1f2f4a95580681ecdc743038870fbb13d2..48e4f04ca97e39b9447d9e580e06fe6e006dd6a8 100644
--- a/alib2algo/src/automaton/simplify/SingleInitialState.cpp
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
@@ -27,11 +27,11 @@ automaton::Automaton SingleInitialState::convert(const Automaton& automaton) {
 	return dispatch(automaton.getData());
 }
 
-automaton::NFA SingleInitialState::convert(const automaton::MultiInitialStateNFA& automaton) {
+automaton::NFA < >  SingleInitialState::convert(const automaton::MultiInitialStateNFA& automaton) {
 	// step 1, 3
 	label::Label q0(label::LabelSetLabel(automaton.getInitialStates()));
 
-	automaton::NFA res(q0);
+	automaton::NFA < >  res(q0);
 	res.setInputAlphabet(automaton.getInputAlphabet());
 	for(const auto& q : automaton.getStates())
 		res.addState(q);
@@ -63,7 +63,7 @@ automaton::NFA SingleInitialState::convert(const automaton::MultiInitialStateNFA
 	return res;
 }
 
-auto SingleInitialStateMultiInitialStateNFA = SingleInitialState::RegistratorWrapper<automaton::NFA, automaton::MultiInitialStateNFA>(SingleInitialState::convert);
+auto SingleInitialStateMultiInitialStateNFA = SingleInitialState::RegistratorWrapper<automaton::NFA < > , automaton::MultiInitialStateNFA>(SingleInitialState::convert);
 
 automaton::DFA<> SingleInitialState::convert(const automaton::DFA<>& automaton) {
 	return automaton;
@@ -77,11 +77,11 @@ automaton::EpsilonNFA SingleInitialState::convert(const automaton::EpsilonNFA& a
 
 auto SingleInitialStateEpsilonNFA = SingleInitialState::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(SingleInitialState::convert);
 
-automaton::NFA SingleInitialState::convert(const automaton::NFA& automaton) {
+automaton::NFA < >  SingleInitialState::convert(const automaton::NFA < > & automaton) {
 	return automaton;
 }
 
-auto SingleInitialStateNFA = SingleInitialState::RegistratorWrapper<automaton::NFA, automaton::NFA>(SingleInitialState::convert);
+auto SingleInitialStateNFA = SingleInitialState::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(SingleInitialState::convert);
 
 automaton::CompactNFA SingleInitialState::convert(const automaton::CompactNFA& automaton) {
 	return automaton;
diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h
index 81107c5f1e39dc372515001039efb966189227a1..a49897e1ba91d72fafda3c83627928d57cc27e70 100644
--- a/alib2algo/src/automaton/simplify/SingleInitialState.h
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.h
@@ -27,10 +27,10 @@ public:
 	 */
 	static automaton::Automaton convert(const automaton::Automaton& automaton);
 
-	static automaton::NFA convert(const automaton::MultiInitialStateNFA& automaton);
+	static automaton::NFA < >  convert(const automaton::MultiInitialStateNFA& automaton);
 
 	static automaton::DFA<> convert(const automaton::DFA<>& automaton);
-	static automaton::NFA convert(const automaton::NFA& automaton);
+	static automaton::NFA < >  convert(const automaton::NFA < > & automaton);
 	static automaton::EpsilonNFA convert(const automaton::EpsilonNFA& automaton);
 	static automaton::ExtendedNFA convert(const automaton::ExtendedNFA& automaton);
 	static automaton::CompactNFA convert(const automaton::CompactNFA& automaton);
diff --git a/alib2algo/src/automaton/simplify/Total.cpp b/alib2algo/src/automaton/simplify/Total.cpp
index 7d2c47899f94460fa3b1b88674f1026f755e12e4..27778899714341ff7ea446ade30e3333ac6e9852 100644
--- a/alib2algo/src/automaton/simplify/Total.cpp
+++ b/alib2algo/src/automaton/simplify/Total.cpp
@@ -21,12 +21,12 @@ automaton::Automaton Total::total(const Automaton& automaton) {
 	return dispatch(automaton.getData());
 }
 
-automaton::NFA Total::total(const automaton::NFA& automaton) {
+automaton::NFA < >  Total::total(const automaton::NFA < > & automaton) {
 	if(! automaton.isDeterministic()) {
 		throw exception::CommonException("Automaton must be deterministic to make its transition function total");
 	}
 
-	automaton::NFA res(automaton);
+	automaton::NFA < >  res(automaton);
 	label::Label nullState = label::createUniqueLabel(label::FailStateLabel::FAIL_STATE_LABEL, automaton.getStates());
 	res.addState(nullState);
 
@@ -41,7 +41,7 @@ automaton::NFA Total::total(const automaton::NFA& automaton) {
 	return res;
 }
 
-auto TotalNFA = Total::RegistratorWrapper<automaton::NFA, automaton::NFA>(Total::total);
+auto TotalNFA = Total::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(Total::total);
 
 automaton::DFA < > Total::total(const automaton::DFA < > & automaton) {
 	automaton::DFA < > res(automaton);
diff --git a/alib2algo/src/automaton/simplify/Total.h b/alib2algo/src/automaton/simplify/Total.h
index 3a53351c0340e661bf7d707b3ac28e5fb65df699..ca9b67081ad90ad586a68bdd7fa620f8bfa09696 100644
--- a/alib2algo/src/automaton/simplify/Total.h
+++ b/alib2algo/src/automaton/simplify/Total.h
@@ -27,7 +27,7 @@ public:
 	 */
 	static automaton::Automaton total(const automaton::Automaton& automaton);
 
-	static automaton::NFA total(const automaton::NFA& automaton);
+	static automaton::NFA < >  total(const automaton::NFA < > & automaton);
 	static automaton::DFA<> total(const automaton::DFA<>& automaton);
 };
 
diff --git a/alib2algo/src/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp
index 8cdac15eba1c40e3220a285f465c43a86d4f55f3..fe2da339b9102b95f078573e1c2e3004080626ae 100644
--- a/alib2algo/src/automaton/simplify/Trim.cpp
+++ b/alib2algo/src/automaton/simplify/Trim.cpp
@@ -25,7 +25,7 @@ T Trim::trim( const T & fsm ) {
 }
 
 auto TrimDFA = Trim::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(Trim::trim);
-auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA, automaton::NFA>(Trim::trim);
+auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(Trim::trim);
 auto TrimMultiInitialStateNFA = Trim::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::MultiInitialStateNFA>(Trim::trim);
 auto TrimEpsilonNFA = Trim::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(Trim::trim);
 auto TrimCompactNFA = Trim::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(Trim::trim);
diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
index c47b55b71d5eec33ccdb614b7ddcd1c12a948d05..02e12a2ce4646eab525454c4bbf54c4e57494514 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
@@ -48,7 +48,7 @@ T UnreachableStatesRemover::remove( const T & fsm ) {
 }
 
 auto UnreachableStatesRemoverEpsilonNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(UnreachableStatesRemover::remove);
-auto UnreachableStatesRemoverNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::NFA, automaton::NFA>(UnreachableStatesRemover::remove);
+auto UnreachableStatesRemoverNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UnreachableStatesRemover::remove);
 auto UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(UnreachableStatesRemover::remove);
 auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove);
 
diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
index 3468a68293e9ee79a7ed48d3a5fd0c53a9966ff2..0207258e469fb7587b9eeee87f0e438cc5e566c0 100644
--- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
@@ -49,7 +49,7 @@ T UselessStatesRemover::remove( const T & fsm ) {
 }
 
 auto UselessStatesRemoverEpsilonNFA = UselessStatesRemover::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(UselessStatesRemover::remove);
-auto UselessStatesRemoverNFA = UselessStatesRemover::RegistratorWrapper<automaton::NFA, automaton::NFA>(UselessStatesRemover::remove);
+auto UselessStatesRemoverNFA = UselessStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UselessStatesRemover::remove);
 auto UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(UselessStatesRemover::remove);
 auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove);
 
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
index 896e3e5184a504d6b704384f535e537da25c9bac..c7c3120a8de15ae4989c3189f818d182604d5808 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
+++ b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
@@ -20,9 +20,9 @@ automaton::Automaton AutomataConcatenation::concatenation(const automaton::Autom
 	return dispatch(first.getData(), second.getData());
 }
 
-automaton::NFA AutomataConcatenation::concatenation(const automaton::NFA& first, const automaton::NFA& second) {
+automaton::NFA < >  AutomataConcatenation::concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second) {
 	label::Label q01q02(pairLabel(first.getInitialState(), second.getInitialState()));
-	automaton::NFA res(pairLabel(AUTOMATON_FIRST, first.getInitialState()));
+	automaton::NFA < >  res(pairLabel(AUTOMATON_FIRST, first.getInitialState()));
 
 	for(const auto& q : first.getStates())
 		res.addState(pairLabel(AUTOMATON_FIRST, q));
@@ -65,11 +65,11 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::NFA& first,
 	return res;
 }
 
-auto AutomataConcatenationNFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomataConcatenation::concatenation);
+auto AutomataConcatenationNFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomataConcatenation::concatenation);
 
-automaton::NFA AutomataConcatenation::concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second) {
+automaton::NFA < >  AutomataConcatenation::concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second) {
 	label::Label q01q02(pairLabel(first.getInitialState(), second.getInitialState()));
-	automaton::NFA res(pairLabel(AUTOMATON_FIRST, first.getInitialState()));
+	automaton::NFA < >  res(pairLabel(AUTOMATON_FIRST, first.getInitialState()));
 
 	for(const auto& q : first.getStates())
 		res.addState(pairLabel(AUTOMATON_FIRST, q));
@@ -107,7 +107,7 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::DFA<>& firs
 	return res;
 }
 
-auto AutomataConcatenationDFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA, automaton::DFA<>>(AutomataConcatenation::concatenation);
+auto AutomataConcatenationDFA = AutomataConcatenation::RegistratorWrapper<automaton::NFA < > , automaton::DFA<>>(AutomataConcatenation::concatenation);
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.h b/alib2algo/src/automaton/transform/AutomataConcatenation.h
index 9565fb7655db6b455f3c1486e7c029cda4963daf..06635fee73141baab0ad0f52ab06f912bfd5da9e 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenation.h
+++ b/alib2algo/src/automaton/transform/AutomataConcatenation.h
@@ -24,8 +24,8 @@ class AutomataConcatenation : public std::PromotingDoubleDispatch<AutomataConcat
 public:
 	static automaton::Automaton concatenation(const automaton::Automaton& first, const automaton::Automaton& second);
 
-	static automaton::NFA concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second);
-	static automaton::NFA concatenation(const automaton::NFA& first, const automaton::NFA& second);
+	static automaton::NFA < >  concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second);
+	static automaton::NFA < >  concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second);
 };
 
 } /* namespace transform */
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
index c99c5192734aa7db57f7554055e6e4bd5b585330..df1e5d47a943054f9c0b39f06600d37cd07e08ad 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
@@ -50,7 +50,7 @@ automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(cons
 
 auto AutomataConcatenationEpsilonTransitionDFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA<>>(AutomataConcatenationEpsilonTransition::concatenation);
 
-automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::NFA& first, const automaton::NFA& second) {
+automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second) {
 	automaton::EpsilonNFA res(pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState()));
 
 	for(const auto& symbol : first.getInputAlphabet())
@@ -80,7 +80,7 @@ automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(cons
 	return res;
 }
 
-auto AutomataConcatenationEpsilonTransitionNFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomataConcatenationEpsilonTransition::concatenation);
+auto AutomataConcatenationEpsilonTransitionNFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA < > >(AutomataConcatenationEpsilonTransition::concatenation);
 
 automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second) {
 	automaton::EpsilonNFA res(pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState()));
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
index 0e94683dbd8fb0b3f064b79f2f417144a1e0b28b..64f2bfb8056809134ac0bd1d82cece2fcc79e33b 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
+++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
@@ -25,7 +25,7 @@ public:
 	static automaton::Automaton concatenation(const automaton::Automaton& first, const automaton::Automaton& second);
 
 	static automaton::EpsilonNFA concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second);
-	static automaton::EpsilonNFA concatenation(const automaton::NFA& first, const automaton::NFA& second);
+	static automaton::EpsilonNFA concatenation(const automaton::NFA < > & first, const automaton::NFA < > & second);
 	static automaton::EpsilonNFA concatenation(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second);
 };
 
diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
index 8e2766b0b2e56b6b70c9e3ea89b88d2c765f99ae..ada9cc54967d30cc27cc94ccba6b5bb1572f51cf 100644
--- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
+++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
@@ -51,9 +51,9 @@ automaton::DFA<> AutomataIntersectionCartesianProduct::intersection(const automa
 
 auto AutomataIntersectionCartesianProductDFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(AutomataIntersectionCartesianProduct::intersection);
 
-automaton::NFA AutomataIntersectionCartesianProduct::intersection(const automaton::NFA& first, const automaton::NFA& second) {
+automaton::NFA < >  AutomataIntersectionCartesianProduct::intersection(const automaton::NFA < > & first, const automaton::NFA < > & second) {
 	label::Label q0(pairLabel(first.getInitialState(), second.getInitialState()));
-	automaton::NFA res(q0);
+	automaton::NFA < >  res(q0);
 
 	for(const auto& a : first.getInputAlphabet())
 		res.addInputSymbol(a);
@@ -83,7 +83,7 @@ automaton::NFA AutomataIntersectionCartesianProduct::intersection(const automato
 	return res;
 }
 
-auto AutomataIntersectionCartesianProductNFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomataIntersectionCartesianProduct::intersection);
+auto AutomataIntersectionCartesianProductNFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomataIntersectionCartesianProduct::intersection);
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
index 2a2e3d710b2d1f5aabc8eb40fe777329b9ebdb30..941630ee833ba2bdb8d35fc44d2beac213f04450 100644
--- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
+++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
@@ -24,7 +24,7 @@ class AutomataIntersectionCartesianProduct : public std::PromotingDoubleDispatch
 public:
 	static automaton::Automaton intersection(const automaton::Automaton& first, const automaton::Automaton& second);
 
-	static automaton::NFA intersection(const automaton::NFA& first, const automaton::NFA& second);
+	static automaton::NFA < >  intersection(const automaton::NFA < > & first, const automaton::NFA < > & second);
 	static automaton::DFA<> intersection(const automaton::DFA<>& first, const automaton::DFA<>& second);
 };
 
diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
index 568a5aec24dc132cced70c278a3cc86f303374ee..2ac3b647f238e54e7acc92232d29de37cd6b7586 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
+++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
@@ -59,12 +59,12 @@ automaton::DFA<> AutomataUnionCartesianProduct::unification(const automaton::DFA
 
 auto AutomataUnionCartesianProductDFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(AutomataUnionCartesianProduct::unification);
 
-automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA& first, const automaton::NFA& second) {
+automaton::NFA < >  AutomataUnionCartesianProduct::unification(const automaton::NFA < > & first, const automaton::NFA < > & second) {
 	if(!first.isTotal() || !second.isTotal())
 		throw exception::CommonException("Automata must be total to unify with cartesian product");
 
 	label::Label q0(pairLabel(first.getInitialState(), second.getInitialState()));
-	automaton::NFA res(q0);
+	automaton::NFA < >  res(q0);
 
 	for(const auto& a : first.getInputAlphabet())
 		res.addInputSymbol(a);
@@ -98,7 +98,7 @@ automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA&
 	return res;
 }
 
-auto AutomataUnionCartesianProductNFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomataUnionCartesianProduct::unification);
+auto AutomataUnionCartesianProductNFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomataUnionCartesianProduct::unification);
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
index 55c7ad7ef2c1d84c9808db80803017191bb362ba..85161d73f72e97c743667d98cd97829d36f23fa7 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
+++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
@@ -24,7 +24,7 @@ class AutomataUnionCartesianProduct : public std::PromotingDoubleDispatch<Automa
 public:
 	static automaton::Automaton unification(const automaton::Automaton& first, const automaton::Automaton& second);
 
-	static automaton::NFA unification(const automaton::NFA& first, const automaton::NFA& second);
+	static automaton::NFA < >  unification(const automaton::NFA < > & first, const automaton::NFA < > & second);
 	static automaton::DFA<> unification(const automaton::DFA<>& first, const automaton::DFA<>& second);
 };
 
diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
index c2cd21913c8480240488410b49e1be0c096482e6..c19e109b631c4d223d573f78ad93945f9ab9041b 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
@@ -59,7 +59,7 @@ automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automato
 
 auto AutomataUnionEpsilonTransitionEpsilonNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(AutomataUnionEpsilonTransition::unification);
 
-automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::NFA& first, const automaton::NFA& second) {
+automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::NFA < > & first, const automaton::NFA < > & second) {
 	std::set<label::Label> states;
 	for(const auto& q : first.getStates())
 		states.insert(pairLabel(label::labelFrom(AUTOMATON_FIRST), q));
@@ -96,7 +96,7 @@ automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automato
 	return res;
 }
 
-auto AutomataUnionEpsilonTransitionNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomataUnionEpsilonTransition::unification);
+auto AutomataUnionEpsilonTransitionNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA < > >(AutomataUnionEpsilonTransition::unification);
 
 automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::DFA<>& first, const automaton::DFA<>& second) {
 	std::set<label::Label> states;
diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
index e0081c530bfc59ff5948281cea6e2f8ddb2986dc..87a60f1eee3c934f2374fb56afb88f1f5c22ac00 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
+++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
@@ -25,7 +25,7 @@ public:
 	static automaton::Automaton unification(const automaton::Automaton& first, const automaton::Automaton& second);
 
 	static automaton::EpsilonNFA unification(const automaton::EpsilonNFA& first, const automaton::EpsilonNFA& second);
-	static automaton::EpsilonNFA unification(const automaton::NFA& first, const automaton::NFA& second);
+	static automaton::EpsilonNFA unification(const automaton::NFA < > & first, const automaton::NFA < > & second);
 	static automaton::EpsilonNFA unification(const automaton::DFA<>& first, const automaton::DFA<>& second);
 
 };
diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp
index 186451ee0c2fed79645c018c954e44875ceab506..22dba9e66203f38bd78723d9e22ab59c45ec2f29 100644
--- a/alib2algo/src/automaton/transform/AutomatonIteration.cpp
+++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp
@@ -16,8 +16,8 @@ automaton::Automaton AutomatonIteration::iteration(const automaton::Automaton& a
 }
 
 template<class T>
-automaton::NFA AutomatonIteration::iteration(const T& automaton) {
-	automaton::NFA res(automaton);
+automaton::NFA < >  AutomatonIteration::iteration(const T& automaton) {
+	automaton::NFA < >  res(automaton);
 
 	for(const auto& qf : res.getFinalStates())
 		for(const auto& t : res.getTransitionsToState(qf))
@@ -27,8 +27,8 @@ automaton::NFA AutomatonIteration::iteration(const T& automaton) {
 	return res;
 }
 
-auto AutomatonIterationDFA = AutomatonIteration::RegistratorWrapper<automaton::NFA, automaton::DFA<>>(AutomatonIteration::iteration);
-auto AutomatonIterationNFA = AutomatonIteration::RegistratorWrapper<automaton::NFA, automaton::NFA>(AutomatonIteration::iteration);
+auto AutomatonIterationDFA = AutomatonIteration::RegistratorWrapper<automaton::NFA < > , automaton::DFA<>>(AutomatonIteration::iteration);
+auto AutomatonIterationNFA = AutomatonIteration::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(AutomatonIteration::iteration);
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.h b/alib2algo/src/automaton/transform/AutomatonIteration.h
index f5d2319e4f6452bea286f459169e766111714210..0f3c111524cec629b979f1989b1f368a8d73117b 100644
--- a/alib2algo/src/automaton/transform/AutomatonIteration.h
+++ b/alib2algo/src/automaton/transform/AutomatonIteration.h
@@ -25,7 +25,7 @@ public:
 	static automaton::Automaton iteration(const automaton::Automaton& automaton);
 
 	template<class T>
-	static automaton::NFA iteration(const T& automaton);
+	static automaton::NFA < >  iteration(const T& automaton);
 };
 
 } /* namespace transform */
diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
index c402171e1ebb8547e474be46e762c8f7fc31b175..54707362b0fc2d7c3f52b82c3dba8ced8cbd7883 100644
--- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
@@ -27,7 +27,7 @@ automaton::EpsilonNFA AutomatonIterationEpsilonTransition::iteration(const T& au
 }
 
 auto AutomatonIterationEpsilonTransitionDFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA<>>(AutomatonIterationEpsilonTransition::iteration);
-auto AutomatonIterationEpsilonTransitionNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomatonIterationEpsilonTransition::iteration);
+auto AutomatonIterationEpsilonTransitionNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA < > >(AutomatonIterationEpsilonTransition::iteration);
 auto AutomatonIterationEpsilonTransitionEpsilonNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(AutomatonIterationEpsilonTransition::iteration);
 
 } /* namespace transform */
diff --git a/alib2algo/src/automaton/transform/Compaction.cpp b/alib2algo/src/automaton/transform/Compaction.cpp
index 7da004598d0aa28ab40bdba05c70326c04bb48fa..32a0a47911ba3f972877a3d4856732f08bddb6c1 100644
--- a/alib2algo/src/automaton/transform/Compaction.cpp
+++ b/alib2algo/src/automaton/transform/Compaction.cpp
@@ -75,13 +75,13 @@ automaton::CompactNFA Compaction::convert(const automaton::DFA<>& automaton) {
 
 auto CompactionDFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::DFA<>>(Compaction::convert);
 
-automaton::CompactNFA Compaction::convert(const automaton::NFA& automaton) {
+automaton::CompactNFA Compaction::convert(const automaton::NFA < > & automaton) {
 	automaton::CompactNFA res(automaton.getInitialState());
 	// TODO
 	return res;
 }
 
-auto CompactionNFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::NFA>(Compaction::convert);
+auto CompactionNFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::NFA < > >(Compaction::convert);
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/Compaction.h b/alib2algo/src/automaton/transform/Compaction.h
index 65b2e0e68f4001af91cfa715cafe40ac094756a0..f0260e4a46989795f14728195f4548c63b772aba 100644
--- a/alib2algo/src/automaton/transform/Compaction.h
+++ b/alib2algo/src/automaton/transform/Compaction.h
@@ -22,7 +22,7 @@ namespace transform {
 class Compaction : public std::SingleDispatch<Compaction, automaton::Automaton, automaton::AutomatonBase> {
 public:
 	static automaton::CompactNFA convert( const automaton::DFA<>& automaton);
-	static automaton::CompactNFA convert( const automaton::NFA& automaton);
+	static automaton::CompactNFA convert( const automaton::NFA < > & automaton);
 	static automaton::CompactNFA convert( const automaton::CompactNFA& automaton);
 
 	/**
diff --git a/alib2algo/src/automaton/transform/Reverse.cpp b/alib2algo/src/automaton/transform/Reverse.cpp
index 31065696b0f13bf55a808872c68a35b8d04ffc43..fd7edf1e7b804cccb01a696874873b939d42af3b 100644
--- a/alib2algo/src/automaton/transform/Reverse.cpp
+++ b/alib2algo/src/automaton/transform/Reverse.cpp
@@ -36,7 +36,7 @@ automaton::MultiInitialStateNFA Reverse::convert(const automaton::DFA<>& automat
 
 auto ReverseDFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::DFA<>>(Reverse::convert);
 
-automaton::MultiInitialStateNFA Reverse::convert(const automaton::NFA& automaton) {
+automaton::MultiInitialStateNFA Reverse::convert(const automaton::NFA < > & automaton) {
 	automaton::MultiInitialStateNFA res;
 
 	res.setStates(automaton.getStates());
@@ -51,7 +51,7 @@ automaton::MultiInitialStateNFA Reverse::convert(const automaton::NFA& automaton
 	return res;
 }
 
-auto ReverseNFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::NFA>(Reverse::convert);
+auto ReverseNFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::NFA < > >(Reverse::convert);
 
 automaton::MultiInitialStateNFA Reverse::convert(const automaton::MultiInitialStateNFA& automaton) {
 	automaton::MultiInitialStateNFA res;
diff --git a/alib2algo/src/automaton/transform/Reverse.h b/alib2algo/src/automaton/transform/Reverse.h
index d984479c7b50e8f00a3dfa27d0d7a559f317ae09..2dacd27679733c62dacacb0d40a9a9ab7f807b75 100644
--- a/alib2algo/src/automaton/transform/Reverse.h
+++ b/alib2algo/src/automaton/transform/Reverse.h
@@ -19,7 +19,7 @@ namespace transform {
 class Reverse : public std::SingleDispatch<Reverse, automaton::Automaton, automaton::AutomatonBase> {
 public:
 	static automaton::MultiInitialStateNFA convert(const automaton::DFA<>& automaton);
-	static automaton::MultiInitialStateNFA convert(const automaton::NFA& automaton);
+	static automaton::MultiInitialStateNFA convert(const automaton::NFA < > & automaton);
 	static automaton::MultiInitialStateNFA convert(const automaton::MultiInitialStateNFA& automaton);
 
 	/**
diff --git a/alib2algo/src/grammar/convert/ToAutomaton.cpp b/alib2algo/src/grammar/convert/ToAutomaton.cpp
index 686f755d4c995908909cc832c8d591a07b335bd7..71fb672ba4ce271e62b69ab0aa8873f0296bf219 100644
--- a/alib2algo/src/grammar/convert/ToAutomaton.cpp
+++ b/alib2algo/src/grammar/convert/ToAutomaton.cpp
@@ -19,7 +19,7 @@ automaton::Automaton ToAutomaton::convert(const grammar::Grammar& grammar) {
 	 return dispatch(grammar.getData());
 }
 
-automaton::NFA ToAutomaton::convert(const grammar::LeftRG& grammar) {
+automaton::NFA < >  ToAutomaton::convert(const grammar::LeftRG& grammar) {
 	std::map<alphabet::Symbol, label::Label> stateMap;
 	std::set<label::Label> states;
 
@@ -33,7 +33,7 @@ automaton::NFA ToAutomaton::convert(const grammar::LeftRG& grammar) {
 	// step 1, 4
 	label::Label q0 = label::createUniqueLabel(label::InitialStateLabel::INITIAL_STATE_LABEL, states);
 	states.insert(q0);
-	automaton::NFA automaton(q0);
+	automaton::NFA < >  automaton(q0);
 	automaton.setInputAlphabet(grammar.getTerminalAlphabet());
 	automaton.setStates(states);
 
@@ -60,9 +60,9 @@ automaton::NFA ToAutomaton::convert(const grammar::LeftRG& grammar) {
 	return automaton;
 }
 
-auto ToAutomatonLeftRG = ToAutomaton::RegistratorWrapper<automaton::NFA, grammar::LeftRG>(ToAutomaton::convert);
+auto ToAutomatonLeftRG = ToAutomaton::RegistratorWrapper<automaton::NFA < > , grammar::LeftRG>(ToAutomaton::convert);
 
-automaton::NFA ToAutomaton::convert(const grammar::RightRG& grammar) {
+automaton::NFA < >  ToAutomaton::convert(const grammar::RightRG& grammar) {
 	std::map<alphabet::Symbol, label::Label> stateMap;
 	std::set<label::Label> states;
 
@@ -76,7 +76,7 @@ automaton::NFA ToAutomaton::convert(const grammar::RightRG& grammar) {
 	// step 1, 4
 	label::Label AState = label::createUniqueLabel(label::FinalStateLabel::FINAL_STATE_LABEL, states);
 	states.insert(AState);
-	automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second);
+	automaton::NFA < >  automaton(stateMap.find(grammar.getInitialSymbol())->second);
 	automaton.setStates(states);
 
 	automaton.setInputAlphabet(grammar.getTerminalAlphabet());
@@ -104,7 +104,7 @@ automaton::NFA ToAutomaton::convert(const grammar::RightRG& grammar) {
 	return automaton;
 }
 
-auto ToAutomatonRightRG = ToAutomaton::RegistratorWrapper<automaton::NFA, grammar::RightRG>(ToAutomaton::convert);
+auto ToAutomatonRightRG = ToAutomaton::RegistratorWrapper<automaton::NFA < > , grammar::RightRG>(ToAutomaton::convert);
 
 template <class T>
 automaton::NPDA ToAutomaton::convert(const T& grammar) {
diff --git a/alib2algo/src/grammar/convert/ToAutomaton.h b/alib2algo/src/grammar/convert/ToAutomaton.h
index 02bf64047f3f847ed51a06702d5bc48ef909a394..9a8b8b9cf69acb44ac5f12f6d5ab2d5c106326e0 100644
--- a/alib2algo/src/grammar/convert/ToAutomaton.h
+++ b/alib2algo/src/grammar/convert/ToAutomaton.h
@@ -37,8 +37,8 @@ public:
 	 */
 	static automaton::Automaton convert(const grammar::Grammar& grammar);
 
-	static automaton::NFA convert(const grammar::LeftRG& grammar);
-	static automaton::NFA convert(const grammar::RightRG& grammar);
+	static automaton::NFA < >  convert(const grammar::LeftRG& grammar);
+	static automaton::NFA < >  convert(const grammar::RightRG& grammar);
 
 	template <class T>
 	static automaton::NPDA convert(const T& grammar);
diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
index 9dd2c8f3f446a247598aa9479022bce177d02476..8621b93ec37be1b52a1301f81806a4efb40859d3 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
@@ -23,13 +23,13 @@ namespace regexp {
 
 namespace convert {
 
-automaton::NFA ToAutomatonGlushkov::convert ( const regexp::RegExp & regexp ) {
+automaton::NFA < >  ToAutomatonGlushkov::convert ( const regexp::RegExp & regexp ) {
 	return dispatch ( regexp.getData ( ) );
 }
 
-automaton::NFA ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp & regexp ) {
+automaton::NFA < >  ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp & regexp ) {
 	label::Label q0 ( label::LabelPairLabel ( std::make_pair ( label::labelFrom ( 'q' ), label::labelFrom ( 0 ) ) ) );
-	automaton::NFA automaton ( q0 );
+	automaton::NFA < >  automaton ( q0 );
 
 	 // step 1
 	automaton.setInputAlphabet ( regexp.getAlphabet ( ) );
@@ -69,13 +69,13 @@ automaton::NFA ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp & re
 	return automaton;
 }
 
-auto ToAutomatonGlushkovUnboundedRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA, regexp::UnboundedRegExp > ( ToAutomatonGlushkov::convert );
+auto ToAutomatonGlushkovUnboundedRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA < > , regexp::UnboundedRegExp > ( ToAutomatonGlushkov::convert );
 
-automaton::NFA ToAutomatonGlushkov::convert ( const regexp::FormalRegExp & /* regexp */ ) {
+automaton::NFA < >  ToAutomatonGlushkov::convert ( const regexp::FormalRegExp & /* regexp */ ) {
 	throw exception::CommonException ( "Glushkov: Converting FormalRegExp NYI" ); // TODO
 }
 
-auto ToAutomatonGlushkovFormalRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA, regexp::FormalRegExp > ( ToAutomatonGlushkov::convert );
+auto ToAutomatonGlushkovFormalRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA < > , regexp::FormalRegExp > ( ToAutomatonGlushkov::convert );
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
index f1448081413ed5c59660293a07dc383198744a33..8c876eeaae054fcbbbf0f2214f853f2860b2cd3f 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
@@ -24,17 +24,17 @@ namespace convert {
  * Converts regular expression to finite automaton using Glushkov's NFA construction algorithm.
  * Source: Melichar 2.107
  */
-class ToAutomatonGlushkov : public std::SingleDispatch<ToAutomatonGlushkov, automaton::NFA, regexp::RegExpBase> {
+class ToAutomatonGlushkov : public std::SingleDispatch<ToAutomatonGlushkov, automaton::NFA < > , regexp::RegExpBase> {
 public:
 	/**
 	 * Performs conversion.
 	 * @param re Original regular expression.
 	 * @return NFA equivalent to original regular expression.
 	 */
-	static automaton::NFA convert(const regexp::RegExp& re);
+	static automaton::NFA < >  convert(const regexp::RegExp& re);
 
-	static automaton::NFA convert(const regexp::UnboundedRegExp& re);
-	static automaton::NFA convert(const regexp::FormalRegExp& re);
+	static automaton::NFA < >  convert(const regexp::UnboundedRegExp& re);
+	static automaton::NFA < >  convert(const regexp::FormalRegExp& re);
 
 };
 
diff --git a/alib2algo/src/stringology/exact/ExactMatchingAutomaton.cpp b/alib2algo/src/stringology/exact/ExactMatchingAutomaton.cpp
index 630b056b3f6d732d66fc959ef3629dd8471360aa..3e4ef76185957ffd7cc57265c17f1f2e4a178276 100644
--- a/alib2algo/src/stringology/exact/ExactMatchingAutomaton.cpp
+++ b/alib2algo/src/stringology/exact/ExactMatchingAutomaton.cpp
@@ -19,8 +19,8 @@ automaton::Automaton ExactMatchingAutomaton::construct(const string::String& pat
 	return dispatch(pattern.getData());
 }
 
-automaton::NFA ExactMatchingAutomaton::construct(const string::LinearString& pattern) {
-	automaton::NFA res(label::labelFrom(0));
+automaton::NFA < >  ExactMatchingAutomaton::construct(const string::LinearString& pattern) {
+	automaton::NFA < >  res(label::labelFrom(0));
 	res.setInputAlphabet(pattern.getAlphabet());
 	for(const alphabet::Symbol& symbol : pattern.getAlphabet()) {
 		res.addTransition(label::labelFrom(0), symbol, label::labelFrom(0));
@@ -35,7 +35,7 @@ automaton::NFA ExactMatchingAutomaton::construct(const string::LinearString& pat
 	return res;
 }
 
-auto ExactMatchingAutomatonLinearString = ExactMatchingAutomaton::RegistratorWrapper<automaton::NFA, string::LinearString>(ExactMatchingAutomaton::construct);
+auto ExactMatchingAutomatonLinearString = ExactMatchingAutomaton::RegistratorWrapper<automaton::NFA < > , string::LinearString>(ExactMatchingAutomaton::construct);
 
 } /* namespace exact */
 
diff --git a/alib2algo/src/stringology/exact/ExactMatchingAutomaton.h b/alib2algo/src/stringology/exact/ExactMatchingAutomaton.h
index 5c8e77e722ea9525c38b2c9e00bf3999252f5b05..13af098928c98dfe54609f9c5cd91df4d3d5a8dc 100644
--- a/alib2algo/src/stringology/exact/ExactMatchingAutomaton.h
+++ b/alib2algo/src/stringology/exact/ExactMatchingAutomaton.h
@@ -26,7 +26,7 @@ public:
 	 */
 	static automaton::Automaton construct(const string::String& pattern);
 
-	static automaton::NFA construct(const string::LinearString& pattern);
+	static automaton::NFA < >  construct(const string::LinearString& pattern);
 };
 
 } /* namespace exact */
diff --git a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
index aa9c11781a7b9d146dd1d9cdd346999c60cd557c..e7aa09c4212f38d7eaa88dae5dc27487c2746243 100644
--- a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
+++ b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
@@ -22,7 +22,7 @@ void determinizeTest::tearDown() {
 }
 
 void determinizeTest::testDeterminizeNFA() {
-  automaton::NFA automaton(label::labelFrom(1));
+  automaton::NFA < >  automaton(label::labelFrom(1));
 
   automaton.addState(label::labelFrom(1));
   automaton.addState(label::labelFrom(2));
diff --git a/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
index 8b275fb931fddbd5c85ca9a1896b2aac46c124f5..e53d5d86116994b44bcea6b5183623f96f1106f3 100644
--- a/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
@@ -37,9 +37,9 @@ void FSMSingleInitialStateTest::testSingleInitialState() {
 	automaton1.addTransition(q1, b, q2);
 	automaton1.addTransition(q2, a, q3);
 
-	automaton::NFA automaton2 = automaton::simplify::SingleInitialState::convert(automaton1);
+	automaton::NFA < >  automaton2 = automaton::simplify::SingleInitialState::convert(automaton1);
 
-	automaton::NFA automaton3(q);
+	automaton::NFA < >  automaton3(q);
 	automaton3.setStates({q, q1, q2, q3});
 	automaton3.setFinalStates({q3});
 	automaton3.setInputAlphabet({a, b});
diff --git a/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp b/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp
index 21dead1c52f1400340cdff8ed18150be3fc18b73..1c02bc5407287f050f1f0192769d93682669c2ef 100644
--- a/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp
@@ -36,7 +36,7 @@ void AutomataConcatenationTest::testAutomataConcatenation() {
 
 	automaton::DFA<> m1(q1a);
 	automaton::DFA<> m2(q1b);
-	automaton::NFA m3(q1a);
+	automaton::NFA < >  m3(q1a);
 
 	m1.setInputAlphabet({a, b});
 	m1.setStates({q1a, q2a, q0a});
@@ -72,9 +72,9 @@ void AutomataConcatenationTest::testAutomataConcatenation() {
 	m3.addTransition(q0b, b, q0b);
 	m3.setFinalStates({q2b});
 
-	auto u11 = automaton::transform::AutomataConcatenationEpsilonTransition::concatenation(automaton::Automaton(automaton::DFA<>(m1)), automaton::Automaton(automaton::NFA(m2)));
+	auto u11 = automaton::transform::AutomataConcatenationEpsilonTransition::concatenation(automaton::Automaton(automaton::DFA<>(m1)), automaton::Automaton(automaton::NFA < > (m2)));
 	auto u12 = automaton::transform::AutomataConcatenationEpsilonTransition::concatenation(automaton::Automaton(automaton::DFA<>(m1)), automaton::Automaton(automaton::DFA<>(m2)));
-	auto u21 = automaton::transform::AutomataConcatenation::concatenation(automaton::Automaton(automaton::DFA<>(m1)), automaton::Automaton(automaton::NFA(m2)));
+	auto u21 = automaton::transform::AutomataConcatenation::concatenation(automaton::Automaton(automaton::DFA<>(m1)), automaton::Automaton(automaton::NFA < > (m2)));
 	auto u22 = automaton::transform::AutomataConcatenation::concatenation(automaton::Automaton(automaton::DFA<>(m1)), automaton::Automaton(automaton::DFA<>(m2)));
 
 	automaton::Automaton umdfa  (automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemoverIncoming::remove(m3)))));
diff --git a/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp b/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
index 4302996d54f36597a4273654ec08ea2a331a2452..34658445faa81d5869cf0c2a44303cdd037fce50 100644
--- a/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
@@ -72,7 +72,7 @@ void AutomataUnionTest::testAutomataUnion() {
 
 	auto u1 = automaton::transform::AutomataUnionEpsilonTransition::unification(automaton::Automaton(m1), automaton::Automaton(m2));
 	CPPUNIT_ASSERT_THROW(automaton::transform::AutomataUnionCartesianProduct::unification(automaton::Automaton(m1), automaton::Automaton(m2)), exception::CommonException);
-	CPPUNIT_ASSERT_THROW(automaton::transform::AutomataUnionCartesianProduct::unification(automaton::Automaton(automaton::NFA(m1)), automaton::Automaton(m2)), exception::CommonException);
+	CPPUNIT_ASSERT_THROW(automaton::transform::AutomataUnionCartesianProduct::unification(automaton::Automaton(automaton::NFA < > (m1)), automaton::Automaton(m2)), exception::CommonException);
 	auto u2 = automaton::transform::AutomataUnionEpsilonTransition::unification(automaton::Automaton(automaton::simplify::Total::total(m1)), automaton::Automaton(automaton::simplify::Total::total(m2)));
 
 	automaton::Automaton umdfa(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemoverIncoming::remove(m3)))));
diff --git a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp
index be4104b8ed3abaaae094f23ff8a41b62c7991588..d059e5cfa020eaa509383d560777cf5fd7ff7d47 100644
--- a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp
@@ -38,7 +38,7 @@ void AutomatonIterationTest::testAutomatonIteration() {
 	m1.addTransition(q2, b, q2);
 	m1.addTransition(q2, a, q3);
 
-	automaton::NFA res(q1);
+	automaton::NFA < >  res(q1);
 	res.setStates({q1, q2, q3});
 	res.setInputAlphabet({a, b});
 	res.setFinalStates({q1, q3});
diff --git a/alib2algo/test-src/playTest.cpp b/alib2algo/test-src/playTest.cpp
index acf63862c7dae4988d0a21cba73534669aae0a32..5de1dc0384f5bb6049e51dc9c0a8f9fb3585265e 100644
--- a/alib2algo/test-src/playTest.cpp
+++ b/alib2algo/test-src/playTest.cpp
@@ -27,7 +27,7 @@ void playTest::setUp()
 
 void playTest::tearDown(){}
 
-automaton::NFA playTest::randomNFA(void) const
+automaton::NFA < >  playTest::randomNFA(void) const
 {
     return automaton::generate::RandomAutomatonFactory::generateNFA(
             rand() % TEST_AUTOMATON_STATES_MAX + 1,
@@ -37,9 +37,9 @@ automaton::NFA playTest::randomNFA(void) const
             );
 }
 
-automaton::DFA<> playTest::mDFA(const automaton::NFA& automaton) const
+automaton::DFA<> playTest::mDFA(const automaton::NFA < > & automaton) const
 {
-    automaton::NFA nfa = automaton::simplify::EpsilonRemoverIncoming::remove(automaton);
+    automaton::NFA < >  nfa = automaton::simplify::EpsilonRemoverIncoming::remove(automaton);
     nfa = automaton::simplify::Trim::trim(nfa);
     automaton::DFA<> dfa = automaton::determinize::Determinize::determinize(nfa);
     dfa = automaton::simplify::Trim::trim(dfa);
@@ -69,8 +69,8 @@ void playTest::case1a(void) const
     rg2rg::RightToLeftRegularGrammar rrg2lrg;
     rg2fa::LRGtoFAConverter lrg2fa;
 
-    automaton::NFA a1 = this->randomNFA();
-    automaton::NFA a2 = lrg2fa.convert(rrg2lrg.convert(fa2rrg.convert(a1)));
+    automaton::NFA < >  a1 = this->randomNFA();
+    automaton::NFA < >  a2 = lrg2fa.convert(rrg2lrg.convert(fa2rrg.convert(a1)));
 
     CPPUNIT_ASSERT(this->mDFA(a1) == this->mDFA(a2));
     */
@@ -83,8 +83,8 @@ void playTest::case1b(void) const
     rg2rg::LeftToRightRegularGrammar lrg2rrg;
     rg2fa::RRGtoFAConverter rrg2fa;
 
-    automaton::NFA a1 = this->randomNFA();
-    automaton::NFA a2 = rrg2fa.convert(lrg2rrg.convert(fa2lrg.convert(a1)));
+    automaton::NFA < >  a1 = this->randomNFA();
+    automaton::NFA < >  a2 = rrg2fa.convert(lrg2rrg.convert(fa2lrg.convert(a1)));
 
     CPPUNIT_ASSERT(this->mDFA(a1) == this->mDFA(a2));
     */
diff --git a/alib2algo/test-src/playTest.h b/alib2algo/test-src/playTest.h
index b6e728184943a4cc75ce91b34061f5568c7c74b5..812bd917da2ac2fdd6196f7e5e6dffe413ed8ad8 100644
--- a/alib2algo/test-src/playTest.h
+++ b/alib2algo/test-src/playTest.h
@@ -19,8 +19,8 @@ public:
   void testPlay1();
 
 private:
-    automaton::NFA randomNFA(void) const;
-    automaton::DFA<> mDFA(const automaton::NFA& automaton) const;
+    automaton::NFA < >  randomNFA(void) const;
+    automaton::DFA<> mDFA(const automaton::NFA < > & automaton) const;
 
     void case1a(void) const;
     void case1b(void) const;
diff --git a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
index 45a770864cc0bd73aebc01848a0a5f334dc8476d..47ba5958726f778eefc61076373f5dff6d107fa2 100644
--- a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
+++ b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
@@ -50,14 +50,14 @@ void re2faTest::testGlushkov() {
 	std::string input = "a+a*b*";
 	regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
 
-	automaton::NFA nfa1 = regexp::convert::ToAutomatonGlushkov::convert(regexp1);
+	automaton::NFA < >  nfa1 = regexp::convert::ToAutomatonGlushkov::convert(regexp1);
 
 	regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( automaton::convert::ToRegExpAlgebraic::convert(nfa1) ) );
 
 	std::cout << regexp1 << std::endl;
 	std::cout << regexp2 << std::endl;
 
-	automaton::NFA nfa2 = regexp::convert::ToAutomatonGlushkov::convert(regexp2);
+	automaton::NFA < >  nfa2 = regexp::convert::ToAutomatonGlushkov::convert(regexp2);
 
 	automaton::DFA<> dfa1 = automaton::determinize::Determinize::determinize(nfa1);
 	automaton::DFA<> dfa2 = automaton::determinize::Determinize::determinize(nfa2);
diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h
index a5060e1f127abc057bede8f930dbc146160173df..2e48cdbe5105f3dd56bd61232333f533aaca7829 100644
--- a/alib2data/src/automaton/AutomatonFeatures.h
+++ b/alib2data/src/automaton/AutomatonFeatures.h
@@ -40,6 +40,7 @@ class AutomatonBase;
 enum class Shift;
 
 class EpsilonNFA;
+template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label >
 class NFA;
 class MultiInitialStateNFA;
 template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label >
diff --git a/alib2data/src/automaton/FSM/CompactNFA.cpp b/alib2data/src/automaton/FSM/CompactNFA.cpp
index 7d716fc3281044db8d47ed2318263a9b0d8d3104..3732f6caab6b74194e5d40372829505e6c415b20 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.cpp
+++ b/alib2data/src/automaton/FSM/CompactNFA.cpp
@@ -53,7 +53,7 @@ CompactNFA::CompactNFA ( const MultiInitialStateNFA & other ) : CompactNFA ( oth
 	transitions[key] = other.getInitialStates ( );
 }
 
-CompactNFA::CompactNFA ( const NFA & other ) : CompactNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+CompactNFA::CompactNFA ( const NFA <> & other ) : CompactNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
 	for ( const auto & transition : other.getTransitions ( ) ) {
 		std::pair < label::Label, string::LinearString > key = std::make_pair ( transition.first.first, string::LinearString ( std::vector < alphabet::Symbol > { transition.first.second } ) );
 		transitions[key] = transition.second;
@@ -220,8 +220,8 @@ namespace alib {
 auto compactNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::CompactNFA > ( );
 auto compactNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::CompactNFA > ( );
 
-auto CompactNFAFromDFA = castApi::CastRegister < automaton::CompactNFA, automaton::DFA<> > ( );
-auto CompactNFAFromNFA = castApi::CastRegister < automaton::CompactNFA, automaton::NFA > ( );
+auto CompactNFAFromDFA = castApi::CastRegister < automaton::CompactNFA, automaton::DFA < > > ( );
+auto CompactNFAFromNFA = castApi::CastRegister < automaton::CompactNFA, automaton::NFA < > > ( );
 auto CompactNFAFromMultiInitialStateNFA = castApi::CastRegister < automaton::CompactNFA, automaton::MultiInitialStateNFA > ( );
 auto CompactNFAEpsilonNFA = castApi::CastRegister < automaton::CompactNFA, automaton::EpsilonNFA > ( );
 auto CompactNFACastBinder = castApi::CastPoolStringBinder < automaton::CompactNFA > ( automaton::CompactNFA::getXmlTagName() );
diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h
index d6b3a56649ccb3ff52a322d6182610d241bfa2c8..bf5f9e2a2fb77b017b97d292ccf74998eb644c88 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.h
+++ b/alib2data/src/automaton/FSM/CompactNFA.h
@@ -40,7 +40,7 @@ public:
 	explicit CompactNFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates );
 	explicit CompactNFA ( const EpsilonNFA & other );
 	explicit CompactNFA ( const MultiInitialStateNFA & other );
-	explicit CompactNFA ( const NFA & other );
+	explicit CompactNFA ( const NFA<> & other );
 	explicit CompactNFA ( const DFA<> & other );
 
 	virtual AutomatonBase * clone ( ) const;
diff --git a/alib2data/src/automaton/FSM/DFA.cpp b/alib2data/src/automaton/FSM/DFA.cpp
index 56cea8b98aedb20a6398d031de1c5d025f5809ab..6321fc145fb122ff46a3f0683076d018b5e524c5 100644
--- a/alib2data/src/automaton/FSM/DFA.cpp
+++ b/alib2data/src/automaton/FSM/DFA.cpp
@@ -7,6 +7,8 @@
 
 #include "DFA.h"
 #include "../Automaton.h"
+#include <object/Object.h>
+#include <XmlApi.hpp>
 
 namespace alib {
 
diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h
index 09c95584e3af19e0b0ac034ab1fb00e457e9397a..e43fcdfa4629bcbb29743a9f083a1fdcfc5456d6 100644
--- a/alib2data/src/automaton/FSM/DFA.h
+++ b/alib2data/src/automaton/FSM/DFA.h
@@ -8,24 +8,18 @@
 #ifndef DFA_H_
 #define DFA_H_
 
-#include "../AutomatonException.h"
 #include <map>
-#include <core/components.hpp>
-#include "../AutomatonBase.h"
-#include "../AutomatonFeatures.h"
-#include "../../alphabet/Symbol.h"
-#include "../../label/Label.h"
-
-#include "../AutomatonException.h"
 #include <ostream>
 #include <sstream>
 
+#include <core/components.hpp>
 #include <sax/FromXMLParserHelper.h>
+
+#include "../AutomatonBase.h"
+#include "../AutomatonFeatures.h"
+#include "../AutomatonException.h"
 #include "../common/AutomatonFromXMLParser.h"
 #include "../common/AutomatonToXMLComposer.h"
-#include "../Automaton.h"
-#include <object/Object.h>
-#include <XmlApi.hpp>
 
 namespace automaton {
 
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.cpp b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
index ef890980ef9274093b19725d76cc6718ab3344e4..9741e61246feb92359b0d8d4fd9ea701ee52e09f 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.cpp
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
@@ -39,7 +39,7 @@ EpsilonNFA::EpsilonNFA ( const MultiInitialStateNFA & other ) : EpsilonNFA ( oth
 	transitions[key] = other.getInitialStates ( );
 }
 
-EpsilonNFA::EpsilonNFA ( const NFA & other ) : EpsilonNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+EpsilonNFA::EpsilonNFA ( const NFA <> & other ) : EpsilonNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
 	for ( const auto & transition : other.getTransitions ( ) ) {
 		std::pair < label::Label, std::variant < string::Epsilon, alphabet::Symbol > > key = std::make_pair ( transition.first.first, std::variant < string::Epsilon, alphabet::Symbol > ( transition.first.second ) );
 		transitions[key] = transition.second;
@@ -317,7 +317,7 @@ auto epsilonNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister
 auto epsilonNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::EpsilonNFA > ( );
 
 auto EpsilonNFAFromDFA = castApi::CastRegister < automaton::EpsilonNFA, automaton::DFA < > > ( );
-auto EpsilonNFAFromNFA = castApi::CastRegister < automaton::EpsilonNFA, automaton::NFA > ( );
+auto EpsilonNFAFromNFA = castApi::CastRegister < automaton::EpsilonNFA, automaton::NFA < > > ( );
 auto EpsilonNFAFromMultiInitialStateNFA = castApi::CastRegister < automaton::EpsilonNFA, automaton::MultiInitialStateNFA > ( );
 auto EpsilonNFACastBinder = castApi::CastPoolStringBinder < automaton::EpsilonNFA > ( automaton::EpsilonNFA::getXmlTagName() );
 
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.h b/alib2data/src/automaton/FSM/EpsilonNFA.h
index bc560cacc1273771ee59885660ea6051f5778098..de1ca2bdc8e37c0282cf0e81c7ac393dd2907771 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.h
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.h
@@ -39,7 +39,7 @@ public:
 	explicit EpsilonNFA ( label::Label initialState );
 	explicit EpsilonNFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates );
 	explicit EpsilonNFA ( const MultiInitialStateNFA & other );
-	explicit EpsilonNFA ( const NFA & other );
+	explicit EpsilonNFA ( const NFA<> & other );
 	explicit EpsilonNFA ( const DFA<> & other );
 
 	virtual AutomatonBase * clone ( ) const;
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
index 21c8c4d4019dbab55ca9ba6d376e0a8e6bd24334..109687569f1fd4f4389fcdd8380676bcd64fb1bd 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
@@ -62,7 +62,7 @@ ExtendedNFA::ExtendedNFA ( const MultiInitialStateNFA & other ) : ExtendedNFA (
 	transitions[key] = other.getInitialStates ( );
 }
 
-ExtendedNFA::ExtendedNFA ( const NFA & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+ExtendedNFA::ExtendedNFA ( const NFA <> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
 	for ( const auto & transition : other.getTransitions ( ) ) {
 		std::pair < label::Label, regexp::RegExp > key = std::make_pair ( transition.first.first, regexp::RegExp ( regexp::regexpFrom ( transition.first.second ) ) );
 		transitions[key] = transition.second;
@@ -229,8 +229,8 @@ namespace alib {
 auto extendedNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::ExtendedNFA > ( );
 auto extendedNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::ExtendedNFA > ( );
 
-auto ExtendedNFAFromDFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::DFA < >> ( );
-auto ExtendedNFAFromNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::NFA > ( );
+auto ExtendedNFAFromDFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::DFA < > > ( );
+auto ExtendedNFAFromNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::NFA < > > ( );
 auto ExtendedNFAFromMultiInitialStateNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::MultiInitialStateNFA > ( );
 auto ExtendedNFAEpsilonNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::EpsilonNFA > ( );
 auto ExtendedNFACompactNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::CompactNFA > ( );
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h
index 67f6cd114505983b7f7eced597a484b45116c259..ae85e7f18837eb86110c46dcfdf9d2ff05ef8a59 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.h
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.h
@@ -41,7 +41,7 @@ public:
 	explicit ExtendedNFA ( const CompactNFA & other );
 	explicit ExtendedNFA ( const EpsilonNFA & other );
 	explicit ExtendedNFA ( const MultiInitialStateNFA & other );
-	explicit ExtendedNFA ( const NFA & other );
+	explicit ExtendedNFA ( const NFA<> & other );
 	explicit ExtendedNFA ( const DFA<> & other );
 
 	virtual AutomatonBase * clone ( ) const;
diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
index 94aeb4c499d5dc279f5748cc7057de86c8306575..5244ecc1370f82a9121e31e92c877b316dc9c870 100644
--- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
+++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
@@ -32,7 +32,7 @@ MultiInitialStateNFA::MultiInitialStateNFA ( const DFA<> & other ) : MultiInitia
 		transitions[transition.first].insert ( transition.second );
 }
 
-MultiInitialStateNFA::MultiInitialStateNFA ( const NFA & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) {
+MultiInitialStateNFA::MultiInitialStateNFA ( const NFA <> & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) {
 	for ( const auto & transition : other.getTransitions ( ) )
 		transitions[transition.first] = transition.second;
 }
@@ -210,7 +210,7 @@ auto multiInitialStateNFAParserRegister = xmlApi < automaton::Automaton >::Parse
 auto multiInitialStateNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::MultiInitialStateNFA > ( );
 
 auto MultiInitialStateNFAFromDFA = castApi::CastRegister < automaton::MultiInitialStateNFA, automaton::DFA < > > ( );
-auto MultiInitialStateNFAFromNFA = castApi::CastRegister < automaton::MultiInitialStateNFA, automaton::NFA > ( );
+auto MultiInitialStateNFAFromNFA = castApi::CastRegister < automaton::MultiInitialStateNFA, automaton::NFA < > > ( );
 auto MultiInitialStateNFACastBinder = castApi::CastPoolStringBinder < automaton::MultiInitialStateNFA > ( automaton::MultiInitialStateNFA::getXmlTagName() );
 
 } /* namespace alib */
diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
index 057d6af687a866625406cc0ce84758c7ae28d776..e6d05e26e4fc181a8c7000110f267eba1c8ca70c 100644
--- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
+++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
@@ -35,7 +35,7 @@ protected:
 public:
 	explicit MultiInitialStateNFA ( );
 	explicit MultiInitialStateNFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, std::set < label::Label > initialStates, std::set < label::Label > finalStates );
-	explicit MultiInitialStateNFA ( const NFA & other );
+	explicit MultiInitialStateNFA ( const NFA<> & other );
 	explicit MultiInitialStateNFA ( const DFA<> & other );
 
 	virtual AutomatonBase * clone ( ) const;
diff --git a/alib2data/src/automaton/FSM/NFA.cpp b/alib2data/src/automaton/FSM/NFA.cpp
index 66daffdc1c7064fc5552dce6d40b4c2a20c36bae..c7274205ce7d9d360b3118eb9099d522623b0b84 100644
--- a/alib2data/src/automaton/FSM/NFA.cpp
+++ b/alib2data/src/automaton/FSM/NFA.cpp
@@ -6,202 +6,18 @@
  */
 
 #include "NFA.h"
-#include <ostream>
-#include <sstream>
-
-#include <sax/FromXMLParserHelper.h>
-#include "../common/AutomatonFromXMLParser.h"
-#include "../common/AutomatonToXMLComposer.h"
 #include "../Automaton.h"
 #include <object/Object.h>
 #include <XmlApi.hpp>
-#include <cast/CastApi.hpp>
-
-namespace automaton {
-
-NFA::NFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates ) : std::Components < NFA, alphabet::Symbol, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > ( std::make_tuple ( std::move ( inputAlphabet ) ), std::tuple < > ( ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::make_tuple ( std::move ( initialState ) ) ) {
-}
-
-NFA::NFA ( label::Label initialState ) : NFA ( std::set < label::Label > { initialState }, std::set < alphabet::Symbol > { }, initialState, std::set < label::Label > { } ) {
-}
-
-NFA::NFA ( const DFA<> & other ) : NFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
-	for ( const auto & transition : other.getTransitions ( ) )
-		transitions[transition.first].insert ( transition.second );
-}
-
-AutomatonBase * NFA::clone ( ) const {
-	return new NFA ( * this );
-}
-
-AutomatonBase * NFA::plunder ( ) && {
-	return new NFA ( std::move ( * this ) );
-}
-
-bool NFA::addTransition ( label::Label from, alphabet::Symbol input, label::Label to ) {
-	if ( !getStates ( ).count ( from ) )
-		throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist." );
-
-	if ( !getInputAlphabet ( ).count ( input ) )
-		throw AutomatonException ( "Input symbol \"" + std::to_string ( input ) + "\" doesn't exist." );
-
-	if ( !getStates ( ).count ( to ) )
-		throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist." );
-
-	std::pair < label::Label, alphabet::Symbol > key = std::make_pair ( std::move ( from ), std::move ( input ) );
-
-	return transitions[std::move ( key )].insert ( std::move ( to ) ).second;
-}
-
-bool NFA::removeTransition ( const label::Label & from, const alphabet::Symbol & input, const label::Label & to ) {
-	std::pair < label::Label, alphabet::Symbol > key = std::make_pair ( from, input );
-
-	return transitions[key].erase ( to );
-}
-
-const std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > & NFA::getTransitions ( ) const {
-	return transitions;
-}
-
-std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > NFA::getTransitionsFromState ( const label::Label & from ) const {
-	if ( !getStates ( ).count ( from ) )
-		throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist" );
-
-	std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > transitionsFromState;
-
-	for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > & transition : transitions )
-		if ( transition.first.first == from )
-			transitionsFromState[transition.first].insert ( transition.second.begin ( ), transition.second.end ( ) );
-
-	return transitionsFromState;
-}
-
-std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > NFA::getTransitionsToState ( const label::Label & to ) const {
-	if ( !getStates ( ).count ( to ) )
-		throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist" );
-
-	std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > transitionsToState;
-
-	for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > & transition : transitions )
-		if ( transition.second.find ( to ) != transition.second.end ( ) )
-			transitionsToState[transition.first].insert ( transition.second.begin ( ), transition.second.end ( ) );
-
-	return transitionsToState;
-}
-
-bool NFA::isDeterministic ( ) const {
-	for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > & transition : transitions )
-		if ( transition.second.size ( ) > 1 )
-			return false;
-
-	return true;
-}
 
-bool NFA::isTotal ( ) const {
-	return isDeterministic ( ) && transitionsSize ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( );
-}
-
-unsigned NFA::transitionsSize ( ) const {
-	int res = 0;
-
-	for ( const auto & transition : transitions )
-		res += transition.second.size ( );
-
-	return res;
-}
-
-int NFA::compare ( const NFA & other ) const {
-	auto first = std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions );
-	auto second = std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.getTransitions ( ) );
-
-	std::compare < decltype ( first ) > comp;
-
-	return comp ( first, second );
-}
-
-void NFA::operator >>( std::ostream & out ) const {
-	out << "(NFA "
-	    << "states = " << getStates ( )
-	    << "inputAlphabet = " << getInputAlphabet ( )
-	    << "initialState = " << getInitialState ( )
-	    << "finalStates = " << getFinalStates ( )
-	    << "transitions = " << transitions
-	    << ")";
-}
-
-NFA::operator std::string ( ) const {
-	std::stringstream ss;
-	ss << * this;
-	return ss.str ( );
-}
-
-NFA NFA::parse ( std::deque < sax::Token >::iterator & input ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, NFA::getXmlTagName() );
-
-	std::set < label::Label > states = AutomatonFromXMLParser::parseStates < label::Label > ( input );
-	std::set < alphabet::Symbol > inputSymbols = AutomatonFromXMLParser::parseInputAlphabet < alphabet::Symbol > ( input );
-	label::Label initialState = AutomatonFromXMLParser::parseInitialState < label::Label > ( input );
-	std::set < label::Label > finalStates = AutomatonFromXMLParser::parseFinalStates < label::Label > ( input );
-
-	NFA automaton ( std::move ( initialState ) );
-
-	automaton.setStates ( std::move ( states ) );
-	automaton.setInputAlphabet ( std::move ( inputSymbols ) );
-	automaton.setFinalStates ( std::move ( finalStates ) );
-
-	AutomatonFromXMLParser::parseTransitions < NFA > ( input, automaton );
-
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, NFA::getXmlTagName() );
-	return automaton;
-}
-
-void NFA::parseTransition ( std::deque < sax::Token >::iterator & input, NFA & automaton ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" );
-	label::Label from = AutomatonFromXMLParser::parseTransitionFrom < label::Label > ( input );
-	alphabet::Symbol inputSymbol = AutomatonFromXMLParser::parseTransitionInputSymbol < alphabet::Symbol > ( input );
-	label::Label to = AutomatonFromXMLParser::parseTransitionTo < label::Label > ( input );
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "transition" );
-
-	automaton.addTransition ( std::move ( from ), std::move ( inputSymbol ), std::move ( to ) );
-}
-
-void NFA::compose ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( NFA::getXmlTagName(), sax::Token::TokenType::START_ELEMENT );
-
-	AutomatonToXMLComposer::composeStates ( out, this->getStates ( ) );
-	AutomatonToXMLComposer::composeInputAlphabet ( out, this->getInputAlphabet ( ) );
-	AutomatonToXMLComposer::composeInitialState ( out, this->getInitialState ( ) );
-	AutomatonToXMLComposer::composeFinalStates ( out, this->getFinalStates ( ) );
-	composeTransitions ( out );
-
-	out.emplace_back ( NFA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
-}
-
-void NFA::composeTransitions ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( "transitions", sax::Token::TokenType::START_ELEMENT );
-
-	for ( const auto & transition : this->getTransitions ( ) )
-		for ( const auto & targetState : transition.second ) {
-			out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT );
-
-			AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first );
-			AutomatonToXMLComposer::composeTransitionInputSymbol ( out, transition.first.second );
-			AutomatonToXMLComposer::composeTransitionTo ( out, targetState );
-
-			out.emplace_back ( "transition", sax::Token::TokenType::END_ELEMENT );
-		}
-
-	out.emplace_back ( "transitions", sax::Token::TokenType::END_ELEMENT );
-}
-
-} /* namespace automaton */
+#include <cast/CastApi.hpp>
 
 namespace alib {
 
-auto NFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::NFA > ( );
-auto NFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::NFA > ( );
+auto NFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::NFA < > > ( );
+auto NFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::NFA < > > ( );
 
-auto NFAFromDFA = castApi::CastRegister < automaton::NFA, automaton::DFA < > > ( );
-auto NFACastBinder = castApi::CastPoolStringBinder < automaton::NFA > ( automaton::NFA::getXmlTagName() );
+auto NFAFromDFA = castApi::CastRegister < automaton::NFA < >, automaton::DFA < > > ( );
+auto NFACastBinder = castApi::CastPoolStringBinder < automaton::NFA < > > ( automaton::NFA < >::getXmlTagName() );
 
 } /* namespace alib */
diff --git a/alib2data/src/automaton/FSM/NFA.h b/alib2data/src/automaton/FSM/NFA.h
index e4a740320e884e519fd8355979a1dd197269aea0..8ebebfcea0289576431983a840faa896cea91dc2 100644
--- a/alib2data/src/automaton/FSM/NFA.h
+++ b/alib2data/src/automaton/FSM/NFA.h
@@ -8,12 +8,16 @@
 #ifndef NFA_H_
 #define NFA_H_
 
-#include "../AutomatonException.h"
 #include <map>
+
 #include <core/components.hpp>
+#include <sax/FromXMLParserHelper.h>
+
+#include "../AutomatonException.h"
 #include "../AutomatonBase.h"
-#include "../../alphabet/Symbol.h"
-#include "../../label/Label.h"
+#include "../AutomatonFeatures.h"
+#include "../common/AutomatonFromXMLParser.h"
+#include "../common/AutomatonToXMLComposer.h"
 
 #include "DFA.h"
 
@@ -28,77 +32,78 @@ class States;
 class FinalStates;
 class InitialState;
 
-class NFA : public AutomatonBase, public std::Components < NFA, alphabet::Symbol, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
+template<class SymbolType, class StateType >
+class NFA : public AutomatonBase, public std::Components < NFA < SymbolType, StateType >, SymbolType, std::tuple < InputAlphabet >, std::tuple < >, StateType, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
 protected:
-	std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > transitions;
+	std::map < std::pair < StateType, SymbolType >, std::set < StateType > > transitions;
 
 public:
-	explicit NFA ( label::Label initialState );
-	explicit NFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates );
-	explicit NFA ( const DFA<> & other );
+	explicit NFA ( StateType initialState );
+	explicit NFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates );
+	explicit NFA ( const DFA < SymbolType, StateType > & other );
 
 	virtual AutomatonBase * clone ( ) const;
 
 	virtual AutomatonBase * plunder ( ) &&;
 
-	const label::Label & getInitialState ( ) const {
-		return accessElement < InitialState > ( ).get ( );
+	const StateType & getInitialState ( ) const {
+		return this->template accessElement < InitialState > ( ).get ( );
 	}
 
-	bool setInitialState ( label::Label state ) {
-		return accessElement < InitialState > ( ).set ( std::move ( state ) );
+	bool setInitialState ( StateType state ) {
+		return this->template accessElement < InitialState > ( ).set ( std::move ( state ) );
 	}
 
-	const std::set < label::Label > & getStates ( ) const {
-		return accessComponent < States > ( ).get ( );
+	const std::set < StateType > & getStates ( ) const {
+		return this->template accessComponent < States > ( ).get ( );
 	}
 
-	bool addState ( label::Label state ) {
-		return accessComponent < States > ( ).add ( std::move ( state ) );
+	bool addState ( StateType state ) {
+		return this->template accessComponent < States > ( ).add ( std::move ( state ) );
 	}
 
-	void setStates ( std::set < label::Label > states ) {
-		accessComponent < States > ( ).set ( std::move ( states ) );
+	void setStates ( std::set < StateType > states ) {
+		this->template accessComponent < States > ( ).set ( std::move ( states ) );
 	}
 
-	void removeState ( const label::Label & state ) {
-		accessComponent < States > ( ).remove ( state );
+	void removeState ( const StateType & state ) {
+		this->template accessComponent < States > ( ).remove ( state );
 	}
 
-	const std::set < label::Label > & getFinalStates ( ) const {
-		return accessComponent < FinalStates > ( ).get ( );
+	const std::set < StateType > & getFinalStates ( ) const {
+		return this->template accessComponent < FinalStates > ( ).get ( );
 	}
 
-	bool addFinalState ( label::Label state ) {
-		return accessComponent < FinalStates > ( ).add ( std::move ( state ) );
+	bool addFinalState ( StateType state ) {
+		return this->template accessComponent < FinalStates > ( ).add ( std::move ( state ) );
 	}
 
-	void setFinalStates ( std::set < label::Label > states ) {
-		accessComponent < FinalStates > ( ).set ( std::move ( states ) );
+	void setFinalStates ( std::set < StateType > states ) {
+		this->template accessComponent < FinalStates > ( ).set ( std::move ( states ) );
 	}
 
-	void removeFinalState ( const label::Label & state ) {
-		accessComponent < FinalStates > ( ).remove ( state );
+	void removeFinalState ( const StateType & state ) {
+		this->template accessComponent < FinalStates > ( ).remove ( state );
 	}
 
-	const std::set < alphabet::Symbol > & getInputAlphabet ( ) const {
-		return accessComponent < InputAlphabet > ( ).get ( );
+	const std::set < SymbolType > & getInputAlphabet ( ) const {
+		return this->template accessComponent < InputAlphabet > ( ).get ( );
 	}
 
-	bool addInputSymbol ( alphabet::Symbol symbol ) {
-		return accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
+	bool addInputSymbol ( SymbolType symbol ) {
+		return this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbol ) );
 	}
 
-	void addInputSymbols ( std::set < alphabet::Symbol > symbols ) {
-		accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
+	void addInputSymbols ( std::set < SymbolType > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).add ( std::move ( symbols ) );
 	}
 
-	void setInputAlphabet ( std::set < alphabet::Symbol > symbols ) {
-		accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
+	void setInputAlphabet ( std::set < SymbolType > symbols ) {
+		this->template accessComponent < InputAlphabet > ( ).set ( std::move ( symbols ) );
 	}
 
-	void removeInputSymbol ( const alphabet::Symbol & symbol ) {
-		accessComponent < InputAlphabet > ( ).remove ( symbol );
+	void removeInputSymbol ( const SymbolType & symbol ) {
+		this->template accessComponent < InputAlphabet > ( ).remove ( symbol );
 	}
 
 	/**
@@ -108,29 +113,29 @@ public:
 	 * @param next next state
 	 * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton
 	 */
-	bool addTransition ( label::Label current, alphabet::Symbol input, label::Label next );
+	bool addTransition ( StateType current, SymbolType input, StateType next );
 
 	/**
 	 * Removes transition from the automaton.
 	 * @param transition transition to remove
 	 * @throws AutomatonException when transition doesn't exists.
 	 */
-	bool removeTransition ( const label::Label & current, const alphabet::Symbol & input, const label::Label & next );
+	bool removeTransition ( const StateType & current, const SymbolType & input, const StateType & next );
 
 	/**
 	 * @return automaton transitions
 	 */
-	const std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > & getTransitions ( ) const;
+	const std::map < std::pair < StateType, SymbolType >, std::set < StateType > > & getTransitions ( ) const;
 
 	/**
 	 * @return automaton transitions from state
 	 */
-	std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > getTransitionsFromState ( const label::Label & from ) const;
+	std::map < std::pair < StateType, SymbolType >, std::set < StateType > > getTransitionsFromState ( const StateType & from ) const;
 
 	/**
 	 * @return automaton transitions to state
 	 */
-	std::map < std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > getTransitionsToState ( const label::Label & from ) const;
+	std::map < std::pair < StateType, SymbolType >, std::set < StateType > > getTransitionsToState ( const StateType & from ) const;
 
 	/**
 	 * Determines whether NFA is deterministic.
@@ -177,77 +182,272 @@ public:
 	void composeTransitions ( std::deque < sax::Token > & out ) const;
 };
 
+template<class SymbolType, class StateType >
+NFA < SymbolType, StateType >::NFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates ) : std::Components < NFA < SymbolType, StateType >, SymbolType, std::tuple < InputAlphabet >, std::tuple < >, StateType, std::tuple < States, FinalStates >, std::tuple < InitialState > > ( std::make_tuple ( std::move ( inputAlphabet ) ), std::tuple < > ( ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::make_tuple ( std::move ( initialState ) ) ) {
+}
+
+template<class SymbolType, class StateType >
+NFA < SymbolType, StateType >::NFA ( StateType initialState ) : NFA ( std::set < StateType > { initialState }, std::set < SymbolType > { }, initialState, std::set < StateType > { } ) {
+}
+
+template<class SymbolType, class StateType >
+NFA < SymbolType, StateType >::NFA ( const DFA < SymbolType, StateType > & other ) : NFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+	for ( const auto & transition : other.getTransitions ( ) )
+		transitions[transition.first].insert ( transition.second );
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase * NFA < SymbolType, StateType >::clone ( ) const {
+	return new NFA ( * this );
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase * NFA < SymbolType, StateType >::plunder ( ) && {
+	return new NFA ( std::move ( * this ) );
+}
+
+template<class SymbolType, class StateType >
+bool NFA < SymbolType, StateType >::addTransition ( StateType from, SymbolType input, StateType to ) {
+	if ( !getStates ( ).count ( from ) )
+		throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist." );
+
+	if ( !getInputAlphabet ( ).count ( input ) )
+		throw AutomatonException ( "Input symbol \"" + std::to_string ( input ) + "\" doesn't exist." );
+
+	if ( !getStates ( ).count ( to ) )
+		throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist." );
+
+	std::pair < StateType, SymbolType > key = std::make_pair ( std::move ( from ), std::move ( input ) );
+
+	return transitions[std::move ( key )].insert ( std::move ( to ) ).second;
+}
+
+template<class SymbolType, class StateType >
+bool NFA < SymbolType, StateType >::removeTransition ( const StateType & from, const SymbolType & input, const StateType & to ) {
+	std::pair < StateType, SymbolType > key = std::make_pair ( from, input );
+
+	return transitions[key].erase ( to );
+}
+
+template<class SymbolType, class StateType >
+const std::map < std::pair < StateType, SymbolType >, std::set < StateType > > & NFA < SymbolType, StateType >::getTransitions ( ) const {
+	return transitions;
+}
+
+template<class SymbolType, class StateType >
+std::map < std::pair < StateType, SymbolType >, std::set < StateType > > NFA < SymbolType, StateType >::getTransitionsFromState ( const StateType & from ) const {
+	if ( !getStates ( ).count ( from ) )
+		throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist" );
+
+	std::map < std::pair < StateType, SymbolType >, std::set < StateType > > transitionsFromState;
+
+	for ( const std::pair < const std::pair < StateType, SymbolType >, std::set < StateType > > & transition : transitions )
+		if ( transition.first.first == from )
+			transitionsFromState[transition.first].insert ( transition.second.begin ( ), transition.second.end ( ) );
+
+	return transitionsFromState;
+}
+
+template<class SymbolType, class StateType >
+std::map < std::pair < StateType, SymbolType >, std::set < StateType > > NFA < SymbolType, StateType >::getTransitionsToState ( const StateType & to ) const {
+	if ( !getStates ( ).count ( to ) )
+		throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist" );
+
+	std::map < std::pair < StateType, SymbolType >, std::set < StateType > > transitionsToState;
+
+	for ( const std::pair < const std::pair < StateType, SymbolType >, std::set < StateType > > & transition : transitions )
+		if ( transition.second.find ( to ) != transition.second.end ( ) )
+			transitionsToState[transition.first].insert ( transition.second.begin ( ), transition.second.end ( ) );
+
+	return transitionsToState;
+}
+
+template<class SymbolType, class StateType >
+bool NFA < SymbolType, StateType >::isDeterministic ( ) const {
+	for ( const std::pair < const std::pair < StateType, SymbolType >, std::set < StateType > > & transition : transitions )
+		if ( transition.second.size ( ) > 1 )
+			return false;
+
+	return true;
+}
+
+template<class SymbolType, class StateType >
+bool NFA < SymbolType, StateType >::isTotal ( ) const {
+	return isDeterministic ( ) && transitionsSize ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( );
+}
+
+template<class SymbolType, class StateType >
+unsigned NFA < SymbolType, StateType >::transitionsSize ( ) const {
+	int res = 0;
+
+	for ( const auto & transition : transitions )
+		res += transition.second.size ( );
+
+	return res;
+}
+
+template<class SymbolType, class StateType >
+int NFA < SymbolType, StateType >::compare ( const NFA & other ) const {
+	auto first = std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions );
+	auto second = std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.getTransitions ( ) );
+
+	std::compare < decltype ( first ) > comp;
+
+	return comp ( first, second );
+}
+
+template<class SymbolType, class StateType >
+void NFA < SymbolType, StateType >::operator >>( std::ostream & out ) const {
+	out << "(NFA "
+	    << "states = " << getStates ( )
+	    << "inputAlphabet = " << getInputAlphabet ( )
+	    << "initialState = " << getInitialState ( )
+	    << "finalStates = " << getFinalStates ( )
+	    << "transitions = " << transitions
+	    << ")";
+}
+
+template<class SymbolType, class StateType >
+NFA < SymbolType, StateType >::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << * this;
+	return ss.str ( );
+}
+
+template<class SymbolType, class StateType >
+NFA < SymbolType, StateType > NFA < SymbolType, StateType >::parse ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, NFA < SymbolType, StateType >::getXmlTagName() );
+
+	std::set < StateType > states = AutomatonFromXMLParser::parseStates < StateType > ( input );
+	std::set < SymbolType > inputSymbols = AutomatonFromXMLParser::parseInputAlphabet < SymbolType > ( input );
+	StateType initialState = AutomatonFromXMLParser::parseInitialState < StateType > ( input );
+	std::set < StateType > finalStates = AutomatonFromXMLParser::parseFinalStates < StateType > ( input );
+
+	NFA automaton ( std::move ( initialState ) );
+
+	automaton.setStates ( std::move ( states ) );
+	automaton.setInputAlphabet ( std::move ( inputSymbols ) );
+	automaton.setFinalStates ( std::move ( finalStates ) );
+
+	AutomatonFromXMLParser::parseTransitions < NFA > ( input, automaton );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, NFA < SymbolType, StateType >::getXmlTagName() );
+	return automaton;
+}
+
+template<class SymbolType, class StateType >
+void NFA < SymbolType, StateType >::parseTransition ( std::deque < sax::Token >::iterator & input, NFA & automaton ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" );
+	StateType from = AutomatonFromXMLParser::parseTransitionFrom < StateType > ( input );
+	SymbolType inputSymbol = AutomatonFromXMLParser::parseTransitionInputSymbol < SymbolType > ( input );
+	StateType to = AutomatonFromXMLParser::parseTransitionTo < StateType > ( input );
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "transition" );
+
+	automaton.addTransition ( std::move ( from ), std::move ( inputSymbol ), std::move ( to ) );
+}
+
+template<class SymbolType, class StateType >
+void NFA < SymbolType, StateType >::compose ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( NFA < SymbolType, StateType >::getXmlTagName(), sax::Token::TokenType::START_ELEMENT );
+
+	AutomatonToXMLComposer::composeStates ( out, this->getStates ( ) );
+	AutomatonToXMLComposer::composeInputAlphabet ( out, this->getInputAlphabet ( ) );
+	AutomatonToXMLComposer::composeInitialState ( out, this->getInitialState ( ) );
+	AutomatonToXMLComposer::composeFinalStates ( out, this->getFinalStates ( ) );
+	composeTransitions ( out );
+
+	out.emplace_back ( NFA < SymbolType, StateType >::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
+}
+
+template<class SymbolType, class StateType >
+void NFA < SymbolType, StateType >::composeTransitions ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( "transitions", sax::Token::TokenType::START_ELEMENT );
+
+	for ( const auto & transition : this->getTransitions ( ) )
+		for ( const auto & targetState : transition.second ) {
+			out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT );
+
+			AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first );
+			AutomatonToXMLComposer::composeTransitionInputSymbol ( out, transition.first.second );
+			AutomatonToXMLComposer::composeTransitionTo ( out, targetState );
+
+			out.emplace_back ( "transition", sax::Token::TokenType::END_ELEMENT );
+		}
+
+	out.emplace_back ( "transitions", sax::Token::TokenType::END_ELEMENT );
+}
+
 } /* namespace automaton */
 
 namespace std {
 
-template < >
-class ComponentConstraint< automaton::NFA, alphabet::Symbol, automaton::InputAlphabet > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::NFA < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > {
 public:
-	static bool used ( const automaton::NFA & automaton, const alphabet::Symbol & symbol ) {
-		for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > & transition : automaton.getTransitions ( ) )
+	static bool used ( const automaton::NFA < SymbolType, StateType > & automaton, const SymbolType & symbol ) {
+		for ( const std::pair < const std::pair < StateType, SymbolType >, std::set < StateType > > & transition : automaton.getTransitions ( ) )
 			if ( transition.first.second == symbol )
 				return true;
 
 		return false;
 	}
 
-	static bool available ( const automaton::NFA &, const alphabet::Symbol & ) {
+	static bool available ( const automaton::NFA < SymbolType, StateType > &, const SymbolType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::NFA &, const alphabet::Symbol & ) {
+	static void valid ( const automaton::NFA < SymbolType, StateType > &, const SymbolType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::NFA, label::Label, automaton::States > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::NFA < SymbolType, StateType >, StateType, automaton::States > {
 public:
-	static bool used ( const automaton::NFA & automaton, const label::Label & state ) {
+	static bool used ( const automaton::NFA < SymbolType, StateType > & automaton, const StateType & state ) {
 		if ( automaton.getInitialState ( ) == state )
 			return true;
 
 		if ( automaton.getFinalStates ( ).count ( state ) )
 			return true;
 
-		for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, std::set < label::Label > > & transition : automaton.getTransitions ( ) )
+		for ( const std::pair < const std::pair < StateType, SymbolType >, std::set < StateType > > & transition : automaton.getTransitions ( ) )
 			if ( ( transition.first.first == state ) || ( transition.second.find ( state ) != transition.second.end ( ) ) )
 				return true;
 
 		return false;
 	}
 
-	static bool available ( const automaton::NFA &, const label::Label & ) {
+	static bool available ( const automaton::NFA < SymbolType, StateType > &, const StateType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::NFA &, const label::Label & ) {
+	static void valid ( const automaton::NFA < SymbolType, StateType > &, const StateType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::NFA, label::Label, automaton::FinalStates > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::NFA < SymbolType, StateType >, StateType, automaton::FinalStates > {
 public:
-	static bool used ( const automaton::NFA &, const label::Label & ) {
+	static bool used ( const automaton::NFA < SymbolType, StateType > &, const StateType & ) {
 		return false;
 	}
 
-	static bool available ( const automaton::NFA & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::NFA < SymbolType, StateType > & automaton, const StateType & state ) {
+		return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
 	}
 
-	static void valid ( const automaton::NFA &, const label::Label & ) {
+	static void valid ( const automaton::NFA < SymbolType, StateType > &, const StateType & ) {
 	}
 };
 
-template < >
-class ElementConstraint< automaton::NFA, label::Label, automaton::InitialState > {
+template<class SymbolType, class StateType >
+class ElementConstraint< automaton::NFA < SymbolType, StateType >, StateType, automaton::InitialState > {
 public:
-	static bool available ( const automaton::NFA & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::NFA < SymbolType, StateType > & automaton, const StateType & state ) {
+		return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
 	}
 
-	static void valid ( const automaton::NFA &, const label::Label & ) {
+	static void valid ( const automaton::NFA < SymbolType, StateType > &, const StateType & ) {
 	}
 };
 
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.cpp b/alib2data/src/automaton/TM/OneTapeDTM.cpp
index 3bba04f24958f47b7b9abc923a50f05d5bd72cbe..d58ed992f9351299ed2ce9d3207a7df04724f077 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.cpp
+++ b/alib2data/src/automaton/TM/OneTapeDTM.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "OneTapeDTM.h"
+
 #include <automaton/Automaton.h>
 #include <object/Object.h>
 #include <XmlApi.hpp>
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.h b/alib2data/src/automaton/TM/OneTapeDTM.h
index 7bb7de51d16c6fe36f3b7364ccbc832eb76af18f..fe2f2e447a6dc4db53b439f41e161bff43afd154 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.h
+++ b/alib2data/src/automaton/TM/OneTapeDTM.h
@@ -9,21 +9,21 @@
 #ifndef ONE_TAPE_DTM_H_
 #define ONE_TAPE_DTM_H_
 
+#include <map>
+#include <set>
+#include <tuple>
+#include <sstream>
+
+#include <core/components.hpp>
+#include <sax/FromXMLParserHelper.h>
+
 #include "../AutomatonException.h"
 #include "../AutomatonBase.h"
 #include "../AutomatonFeatures.h"
-#include <core/components.hpp>
 #include "../common/Shift.h"
-#include "../AutomatonException.h"
-#include <sax/FromXMLParserHelper.h>
 #include "../common/AutomatonFromXMLParser.h"
 #include "../common/AutomatonToXMLComposer.h"
 
-#include <map>
-#include <set>
-#include <tuple>
-#include <sstream>
-
 namespace automaton {
 
 class TapeAlphabet;
diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
index 30a8eb2cd37588c0a329a676526f50b2564350d7..64accab1890ec5a20d4da031e91c44433211ad39 100644
--- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
@@ -76,14 +76,14 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 
 auto AllEpsilonClosureMultiInitialStateNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::MultiInitialStateNFA>(AllEpsilonClosure::allEpsilonClosure);
 
-std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::NFA & fsm) {
+std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::NFA < >  & fsm) {
 	std::map<label::Label, std::set<label::Label>> closure;
 	for(const label::Label& state : fsm.getStates())
 		closure[state].insert(state);
 	return closure;
 }
 
-auto AllEpsilonClosureNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::NFA>(AllEpsilonClosure::allEpsilonClosure);
+auto AllEpsilonClosureNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::NFA < > >(AllEpsilonClosure::allEpsilonClosure);
 
 std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::DFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> closure;
diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
index dc6c20f367da955a4ea25aa493fb35ea25d8f203..d0bbb401875fd99e339391c9d50e5ed993c2e28b 100644
--- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
+++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
@@ -32,7 +32,7 @@ public:
 	 */
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::EpsilonNFA & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::MultiInitialStateNFA & fsm);
-	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::NFA & fsm);
+	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::NFA < >  & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::DFA < > & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::ExtendedNFA & fsm);
 	static std::map<label::Label, std::set<label::Label>> allEpsilonClosure( const automaton::CompactNFA & fsm);
diff --git a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp b/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp
index 456a307a101faf4e8f2adfcf42af973a0a8de783..c6848203709a8523acfe6991e9c4738bea93fb85 100644
--- a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp
@@ -50,7 +50,7 @@ std::set<label::Label> ReachableStates::reachableStates( const T & fsm ) {
 }
 
 auto ReachableStatesEpsilonNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA>(ReachableStates::reachableStates);
-auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA>(ReachableStates::reachableStates);
+auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(ReachableStates::reachableStates);
 auto ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA>(ReachableStates::reachableStates);
 auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(ReachableStates::reachableStates);
 
diff --git a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
index fc77c6e5752c4d3bcebf3f6f085e6901b7ea698c..f198c134dbe898e4f9a1bdb2fd13d03b98bc5bce 100644
--- a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
@@ -51,7 +51,7 @@ std::set<label::Label> UsefullStates::usefullStates( const T & fsm ) {
 }
 
 auto UsefullStatesEpsilonNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA>(UsefullStates::usefullStates);
-auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA>(UsefullStates::usefullStates);
+auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(UsefullStates::usefullStates);
 auto UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA>(UsefullStates::usefullStates);
 auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(UsefullStates::usefullStates);
 auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA>(UsefullStates::usefullStates);
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp
index 7696d9566be46c578ca01a1eed4b141bccfe2607..56ba68442e251868569b29ab3299ee07350106c1 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp
@@ -27,15 +27,15 @@ automaton::MultiInitialStateNFA EpsilonRemoverIncoming::remove(const automaton::
 
 auto EpsilonRemoverIncomingMultiInitialStateNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::MultiInitialStateNFA>(EpsilonRemoverIncoming::remove);
 
-automaton::NFA EpsilonRemoverIncoming::remove(const automaton::NFA& origFSM)
+automaton::NFA < >  EpsilonRemoverIncoming::remove(const automaton::NFA < > & origFSM)
 {
 	return origFSM;
 }
 
-auto EpsilonRemoverIncomingNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA, automaton::NFA>(EpsilonRemoverIncoming::remove);
+auto EpsilonRemoverIncomingNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(EpsilonRemoverIncoming::remove);
 
-automaton::NFA EpsilonRemoverIncoming::remove( const automaton::EpsilonNFA & origFSM ) {
-	automaton::NFA fsm(origFSM.getInitialState());
+automaton::NFA < >  EpsilonRemoverIncoming::remove( const automaton::EpsilonNFA & origFSM ) {
+	automaton::NFA < >  fsm(origFSM.getInitialState());
 
 	fsm.setStates( origFSM.getStates() );
 	fsm.setInputAlphabet( origFSM.getInputAlphabet() );
@@ -74,7 +74,7 @@ automaton::NFA EpsilonRemoverIncoming::remove( const automaton::EpsilonNFA & ori
 	return fsm;
 }
 
-auto EpsilonRemoverIncomingEpsilonNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA, automaton::EpsilonNFA>(EpsilonRemoverIncoming::remove);
+auto EpsilonRemoverIncomingEpsilonNFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::NFA < > , automaton::EpsilonNFA>(EpsilonRemoverIncoming::remove);
 
 automaton::Automaton EpsilonRemoverIncoming::remove(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h
index 08f289760878b67ad4fbab1c09a01c2104dfebd4..0e159107ded51bcf51898c7e965e3d64b1ac93ea 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h
@@ -32,9 +32,9 @@ public:
 	/**
 	 * Computes epsilon closure of a state in epsilon nonfree automaton
 	 */
-	static automaton::NFA remove( const automaton::EpsilonNFA & fsm );
+	static automaton::NFA < >  remove( const automaton::EpsilonNFA & fsm );
 	static automaton::MultiInitialStateNFA remove( const automaton::MultiInitialStateNFA & fsm );
-	static automaton::NFA remove( const automaton::NFA & fsm );
+	static automaton::NFA < >  remove( const automaton::NFA < >  & fsm );
 	static automaton::DFA<> remove( const automaton::DFA<> & fsm );
 };
 
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp
index 1922edc0843df7c4a24aab423a3339a4b7da7473..9993078dc73fb5425031fc330a443bba49c596a2 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp
@@ -27,12 +27,12 @@ automaton::MultiInitialStateNFA EpsilonRemoverOutgoing::remove(const automaton::
 
 auto EpsilonRemoverOutgoingMultiInitialStateNFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::MultiInitialStateNFA>(EpsilonRemoverOutgoing::remove);
 
-automaton::NFA EpsilonRemoverOutgoing::remove(const automaton::NFA& origFSM)
+automaton::NFA < >  EpsilonRemoverOutgoing::remove(const automaton::NFA < > & origFSM)
 {
 	return origFSM;
 }
 
-auto EpsilonRemoverOutgoingNFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::NFA, automaton::NFA>(EpsilonRemoverOutgoing::remove);
+auto EpsilonRemoverOutgoingNFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(EpsilonRemoverOutgoing::remove);
 
 automaton::MultiInitialStateNFA EpsilonRemoverOutgoing::remove( const automaton::EpsilonNFA & origFSM ) {
 	automaton::MultiInitialStateNFA fsm;
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h
index e2e595cf7027b55e0ac6f9460e79228226665d7c..4ad4076b28f242ed10475fe5368a955954b88898 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h
@@ -34,7 +34,7 @@ public:
 	 */
 	static automaton::MultiInitialStateNFA remove( const automaton::EpsilonNFA & fsm );
 	static automaton::MultiInitialStateNFA remove( const automaton::MultiInitialStateNFA & fsm );
-	static automaton::NFA remove( const automaton::NFA & fsm );
+	static automaton::NFA < >  remove( const automaton::NFA < >  & fsm );
 	static automaton::DFA<> remove( const automaton::DFA<> & fsm );
 };
 
diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
index 85963a25871d06be87a24e9a0159ce823e5cae33..13ec67ce62eb15f6684f0f6bab54df154fbd6afa 100644
--- a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
@@ -29,7 +29,7 @@ T Trim::trim( const T & fsm ) {
 }
 
 auto TrimDFA = Trim::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(Trim::trim);
-auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA, automaton::NFA>(Trim::trim);
+auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(Trim::trim);
 auto TrimMultiInitialStateNFA = Trim::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::MultiInitialStateNFA>(Trim::trim);
 auto TrimEpsilonNFA = Trim::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(Trim::trim);
 auto TrimCompactNFA = Trim::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(Trim::trim);
diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
index 73ea75b005bd778337df09341a257c19f6b64e05..703c9196fd20911dc4d21abee74215fe0f1188eb 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
@@ -52,7 +52,7 @@ T UnreachableStatesRemover::remove( const T & fsm ) {
 }
 
 auto UnreachableStatesRemoverEpsilonNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(UnreachableStatesRemover::remove);
-auto UnreachableStatesRemoverNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::NFA, automaton::NFA>(UnreachableStatesRemover::remove);
+auto UnreachableStatesRemoverNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UnreachableStatesRemover::remove);
 auto UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(UnreachableStatesRemover::remove);
 auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove);
 
diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
index 91705d4600eb7d2b9380fa6898060de1244db63e..f247267c4c042adc003f8768f5cde4e23d52f3b4 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
@@ -54,7 +54,7 @@ T UselessStatesRemover::remove( const T & fsm ) {
 }
 
 auto UselessStatesRemoverEpsilonNFA = UselessStatesRemover::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(UselessStatesRemover::remove);
-auto UselessStatesRemoverNFA = UselessStatesRemover::RegistratorWrapper<automaton::NFA, automaton::NFA>(UselessStatesRemover::remove);
+auto UselessStatesRemoverNFA = UselessStatesRemover::RegistratorWrapper<automaton::NFA < > , automaton::NFA < > >(UselessStatesRemover::remove);
 auto UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(UselessStatesRemover::remove);
 auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove);
 
diff --git a/alib2str/src/automaton/AutomatonFromStringParser.cpp b/alib2str/src/automaton/AutomatonFromStringParser.cpp
index 64dadae7b5ee82d322683359fdfb5dd0af5f1ddc..f5a05295a16978a6a0d002980de721857f1684a1 100644
--- a/alib2str/src/automaton/AutomatonFromStringParser.cpp
+++ b/alib2str/src/automaton/AutomatonFromStringParser.cpp
@@ -140,7 +140,7 @@ MultiInitialStateNFA AutomatonFromStringParser::parseMultiInitialStateNFA(std::i
 	return  res;
 }
 
-NFA AutomatonFromStringParser::parseNFA(std::istream& input) const {
+NFA<> AutomatonFromStringParser::parseNFA(std::istream& input) const {
 	AutomatonFromStringLexer::Token token = m_AutomatonLexer.next(input);
 	if(token.type != AutomatonFromStringLexer::TokenType::NFA) {
 		throw exception::CommonException("Unrecognised NFA token.");
@@ -177,7 +177,7 @@ NFA AutomatonFromStringParser::parseNFA(std::istream& input) const {
 
 	if(initialState == NULL) throw exception::CommonException("No initial state recognised.");
 
-	NFA res(*initialState);
+	NFA<> res(*initialState);
 	delete initialState;
 
 	res.setInputAlphabet(std::set<alphabet::Symbol>(symbols.begin(), symbols.end()));
diff --git a/alib2str/src/automaton/AutomatonFromStringParser.h b/alib2str/src/automaton/AutomatonFromStringParser.h
index cf0e1a1e11c1a265957f7265e783494117f41556..5130401058c499c296695caa122e9102f8afff2a 100644
--- a/alib2str/src/automaton/AutomatonFromStringParser.h
+++ b/alib2str/src/automaton/AutomatonFromStringParser.h
@@ -47,7 +47,7 @@ private:
 	Automaton parseAutomaton(std::istream& input, const std::set<FEATURES>& features) const;
 
 	EpsilonNFA parseEpsilonNFA(std::istream& input) const;
-	NFA parseNFA(std::istream& input) const;
+	NFA<> parseNFA(std::istream& input) const;
 	MultiInitialStateNFA parseMultiInitialStateNFA(std::istream& input) const;
 	DFA<> parseDFA(std::istream& input) const;
 
diff --git a/alib2str/src/automaton/AutomatonToStringComposer.cpp b/alib2str/src/automaton/AutomatonToStringComposer.cpp
index 2ecd955d52750f0882749ad87b50ab47b88ea38c..58def9bcbf127d1933ac466c743768832dc3002f 100644
--- a/alib2str/src/automaton/AutomatonToStringComposer.cpp
+++ b/alib2str/src/automaton/AutomatonToStringComposer.cpp
@@ -30,7 +30,7 @@ void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, c
 	}
 }
 
-void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const NFA& automaton, const label::Label& from) {
+void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const NFA < > & automaton, const label::Label& from) {
 	std::map<std::pair<label::Label, alphabet::Symbol>, std::set<label::Label> > symbolTransitionsFromState = automaton.getTransitionsFromState(from);
 
 	for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) {
@@ -122,7 +122,7 @@ void AutomatonToStringComposer::compose(std::ostream& out, const DFA<>& automato
 
 AutomatonToStringComposer::RegistratorWrapper<void, DFA<>> AutomatonToStringComposerDFA = AutomatonToStringComposer::RegistratorWrapper<void, DFA<>>(AutomatonToStringComposer::compose);
 
-void AutomatonToStringComposer::compose(std::ostream& out, const NFA& automaton) {
+void AutomatonToStringComposer::compose(std::ostream& out, const NFA < > & automaton) {
 	out << "NFA";
 	for(const auto& symbol : automaton.getInputAlphabet()) {
 		out << " ";
@@ -146,7 +146,7 @@ void AutomatonToStringComposer::compose(std::ostream& out, const NFA& automaton)
 	}
 }
 
-AutomatonToStringComposer::RegistratorWrapper<void, NFA> AutomatonToStringComposerNFA = AutomatonToStringComposer::RegistratorWrapper<void, NFA>(AutomatonToStringComposer::compose);
+AutomatonToStringComposer::RegistratorWrapper<void, NFA < > > AutomatonToStringComposerNFA = AutomatonToStringComposer::RegistratorWrapper<void, NFA < > >(AutomatonToStringComposer::compose);
 
 void AutomatonToStringComposer::compose(std::ostream& out, const MultiInitialStateNFA& automaton) {
 	out << "MISNFA";
diff --git a/alib2str/src/automaton/AutomatonToStringComposer.h b/alib2str/src/automaton/AutomatonToStringComposer.h
index cc261b713682e1c4b99bd092277f30f58ab57bae..5b693686d3579c2b026cb84f2e22ba68d5b3fe85 100644
--- a/alib2str/src/automaton/AutomatonToStringComposer.h
+++ b/alib2str/src/automaton/AutomatonToStringComposer.h
@@ -17,8 +17,8 @@
 namespace automaton {
 
 class AutomatonToStringComposer : public std::SingleDispatchFirstStaticParam<AutomatonToStringComposer, void, std::ostream&, AutomatonBase> {
-	static void composeTransitionsFromState(std::ostream& out, const DFA<>& automaton, const label::Label& from);
-	static void composeTransitionsFromState(std::ostream& out, const NFA& automaton, const label::Label& from);
+	static void composeTransitionsFromState(std::ostream& out, const DFA < > & automaton, const label::Label& from);
+	static void composeTransitionsFromState(std::ostream& out, const NFA < > & automaton, const label::Label& from);
 	static void composeTransitionsFromState(std::ostream& out, const MultiInitialStateNFA& automaton, const label::Label& from);
 	static void composeTransitionsFromState(std::ostream& out, const EpsilonNFA& automaton, const label::Label& from);
 
@@ -30,8 +30,8 @@ public:
 	 */
 	static void compose(std::ostream& output, const Automaton& automaton);
 
-	static void compose(std::ostream& output, const DFA<>& automaton);
-	static void compose(std::ostream& output, const NFA& automaton);
+	static void compose(std::ostream& output, const DFA < > & automaton);
+	static void compose(std::ostream& output, const NFA < > & automaton);
 	static void compose(std::ostream& output, const MultiInitialStateNFA& automaton);
 	static void compose(std::ostream& output, const EpsilonNFA& automaton);
 };
diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp
index e2d030c848c434057bf539c014a596e78546a9f0..4a0916882101246f0ec760620560d7b869314c13 100644
--- a/arand2/src/arand.cpp
+++ b/arand2/src/arand.cpp
@@ -106,7 +106,7 @@ int main ( int argc, char * argv[] ) {
 
 			measurements::start ( "Algorithm", measurements::Type::MAIN );
 
-			automaton::NFA res = automaton::generate::RandomAutomatonFactory::generateNFA ( states.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), density.getValue ( ) );
+			automaton::NFA < >  res = automaton::generate::RandomAutomatonFactory::generateNFA ( states.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), density.getValue ( ) );
 
 			measurements::end ( );
 			measurements::start ( "Output write", measurements::Type::AUXILIARY );