From f1f8b86ab1ac04adffb9a1a104f1826261e29cca Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Fri, 28 Oct 2016 19:35:57 +0200
Subject: [PATCH] template ExtendedNFA automaton

---
 acompare2/src/AutomatonCompare.cpp            |   8 +-
 acompare2/src/AutomatonCompare.h              |   6 +-
 aconvert2/src/DotConverter.cpp                |   6 +-
 aconvert2/src/DotConverter.h                  |   4 +-
 aconvert2/src/GasTexConverter.cpp             |   6 +-
 aconvert2/src/GasTexConverter.h               |   4 +-
 aconvert2/src/TikZConverter.cpp               |   6 +-
 aconvert2/src/TikZConverter.h                 |   4 +-
 alib2algo/src/automaton/convert/ToRegExp.cpp  |   4 +-
 alib2algo/src/automaton/convert/ToRegExp.h    |   2 +-
 .../convert/ToRegExpStateElimination.cpp      |  12 +-
 .../convert/ToRegExpStateElimination.h        |   6 +-
 .../properties/AllEpsilonClosure.cpp          |   4 +-
 .../automaton/properties/AllEpsilonClosure.h  |   2 +-
 .../automaton/properties/EpsilonClosure.cpp   |   4 +-
 .../src/automaton/properties/EpsilonClosure.h |   2 +-
 .../automaton/properties/ReachableStates.cpp  |   2 +-
 .../automaton/properties/UsefullStates.cpp    |   2 +-
 .../automaton/simplify/SingleInitialState.cpp |   4 +-
 .../automaton/simplify/SingleInitialState.h   |   2 +-
 alib2algo/src/automaton/simplify/Trim.cpp     |   2 +-
 .../simplify/UnreachableStatesRemover.cpp     |   2 +-
 .../simplify/UselessStatesRemover.cpp         |   2 +-
 alib2data/src/automaton/AutomatonFeatures.h   |   1 +
 alib2data/src/automaton/FSM/ExtendedNFA.cpp   | 237 +----------
 alib2data/src/automaton/FSM/ExtendedNFA.h     | 381 ++++++++++++++----
 .../test-src/automaton/AutomatonTest.cpp      |   2 +-
 .../efficient/AllEpsilonClosure.cpp           |   4 +-
 .../properties/efficient/AllEpsilonClosure.h  |   2 +-
 .../properties/efficient/ReachableStates.cpp  |   2 +-
 .../properties/efficient/UsefullStates.cpp    |   2 +-
 .../src/automaton/simplify/efficient/Trim.cpp |   2 +-
 .../efficient/UnreachableStatesRemover.cpp    |   2 +-
 .../efficient/UselessStatesRemover.cpp        |   2 +-
 34 files changed, 377 insertions(+), 356 deletions(-)

diff --git a/acompare2/src/AutomatonCompare.cpp b/acompare2/src/AutomatonCompare.cpp
index 2b2316c638..90d2408299 100644
--- a/acompare2/src/AutomatonCompare.cpp
+++ b/acompare2/src/AutomatonCompare.cpp
@@ -70,7 +70,7 @@ bool AutomatonCompare::testCompare(const automaton::EpsilonNFA < > & a, const au
 			a.getTransitions()    == b.getTransitions()    ;
 }
 
-bool AutomatonCompare::testCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b) {
+bool AutomatonCompare::testCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b) {
 	return  	a.getFinalStates()    == b.getFinalStates()    &&
 			a.getInitialState()   == b.getInitialState()   &&
 //			a.getInputAlphabet()  == b.getInputAlphabet()  &&
@@ -414,7 +414,7 @@ void AutomatonCompare::printCompare(const automaton::EpsilonNFA < > & a, const a
 	}
 }
 
-void AutomatonCompare::printCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b) {
+void AutomatonCompare::printCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b) {
 	std::cout << "AutomatonCompareer" << std::endl;
 
 	if(a.getFinalStates() != b.getFinalStates()){
@@ -1216,7 +1216,7 @@ int AutomatonCompare::compare(const automaton::EpsilonNFA < > & a, const automat
 
 auto AutomatonCompareEpsilonNFA = AutomatonCompare::RegistratorWrapper<int, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > >(AutomatonCompare::compare);
 
-int AutomatonCompare::compare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b) {
+int AutomatonCompare::compare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
 	  AutomatonCompare::printCompare(a, b);
 	  return 1;
@@ -1225,7 +1225,7 @@ int AutomatonCompare::compare(const automaton::ExtendedNFA& a, const automaton::
 	}
 }
 
-auto AutomatonCompareExtendedNFA = AutomatonCompare::RegistratorWrapper<int, automaton::ExtendedNFA, automaton::ExtendedNFA>(AutomatonCompare::compare);
+auto AutomatonCompareExtendedNFA = AutomatonCompare::RegistratorWrapper<int, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(AutomatonCompare::compare);
 
 int AutomatonCompare::compare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
diff --git a/acompare2/src/AutomatonCompare.h b/acompare2/src/AutomatonCompare.h
index 10fdcc9afa..d1870b3a26 100644
--- a/acompare2/src/AutomatonCompare.h
+++ b/acompare2/src/AutomatonCompare.h
@@ -32,8 +32,8 @@ private:
 	static bool testCompare(const automaton::EpsilonNFA < > & a, const automaton::EpsilonNFA < > & b);
 	static void printCompare(const automaton::EpsilonNFA < > & a, const automaton::EpsilonNFA < > & b);
 
-	static bool testCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b);
-	static void printCompare(const automaton::ExtendedNFA& a, const automaton::ExtendedNFA& b);
+	static bool testCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b);
+	static void printCompare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b);
 
 	static bool testCompare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b);
 	static void printCompare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b);
@@ -85,7 +85,7 @@ public:
 	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);
+	static int compare(const automaton::ExtendedNFA < > & a, const automaton::ExtendedNFA < > & b);
 	static int compare(const automaton::CompactNFA < > & a, const automaton::CompactNFA < > & b);
 
 	static int compare(const automaton::DFTA < > & a, const automaton::DFTA < > & b);
diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp
index 88472d793f..88bcd01755 100644
--- a/aconvert2/src/DotConverter.cpp
+++ b/aconvert2/src/DotConverter.cpp
@@ -186,7 +186,7 @@ void DotConverter::convert(std::ostream& out, const automaton::DFA<>& a) {
 
 auto DotConverterDFA = DotConverter::RegistratorWrapper<void, automaton::DFA<>>(DotConverter::convert);
 
-void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) {
+void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA < > & a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -217,7 +217,7 @@ void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) {
 	out << "}";
 }
 
-auto DotConverterExtendedNFA = DotConverter::RegistratorWrapper<void, automaton::ExtendedNFA>(DotConverter::convert);
+auto DotConverterExtendedNFA = DotConverter::RegistratorWrapper<void, automaton::ExtendedNFA < > >(DotConverter::convert);
 
 void DotConverter::convert(std::ostream& out, const automaton::CompactNFA < > & a) {
 	out << "digraph automaton {\n";
@@ -816,7 +816,7 @@ void DotConverter::transitions(const automaton::DFA<>& fsm, const std::map<label
 	}
 }
 
-void DotConverter::transitions(const automaton::ExtendedNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out) {
+void DotConverter::transitions(const automaton::ExtendedNFA < > & 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 20d2ef38b1..feeef85866 100644
--- a/aconvert2/src/DotConverter.h
+++ b/aconvert2/src/DotConverter.h
@@ -24,7 +24,7 @@ class DotConverter : public std::SingleDispatchFirstStaticParam<DotConverter, vo
 	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::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::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);
 	static void transitions(const automaton::NFTA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::DFTA < > & fsm, const std::map<label::Label, int>& states, std::ostream& out);
@@ -46,7 +46,7 @@ public:
 	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::DFA<>& a);
-	static void convert(std::ostream& out, const automaton::ExtendedNFA& a);
+	static void convert(std::ostream& out, const automaton::ExtendedNFA < > & a);
 	static void convert(std::ostream& out, const automaton::CompactNFA < > & a);
 	static void convert(std::ostream& out, const automaton::NFTA < > & a);
 	static void convert(std::ostream& out, const automaton::DFTA < > & a);
diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp
index 7cf18b57fe..b8bf6ef0e6 100644
--- a/aconvert2/src/GasTexConverter.cpp
+++ b/aconvert2/src/GasTexConverter.cpp
@@ -205,7 +205,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::DFA<>& a) {
 
 auto GasTexConverterDFA = GasTexConverter::RegistratorWrapper<void, automaton::DFA<>>(GasTexConverter::convert);
 
-void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) {
+void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA < > & a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -244,7 +244,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a
 	out << "\\end{picture}\n";
 }
 
-auto GasTexConverterExtendedNFA = GasTexConverter::RegistratorWrapper<void, automaton::ExtendedNFA>(GasTexConverter::convert);
+auto GasTexConverterExtendedNFA = GasTexConverter::RegistratorWrapper<void, automaton::ExtendedNFA < > >(GasTexConverter::convert);
 
 void GasTexConverter::convert(std::ostream& out, const automaton::CompactNFA < > & a) {
 	out << "\\begin{center}\n";
@@ -870,7 +870,7 @@ void GasTexConverter::transitions(const automaton::DFA<>& fsm, std::ostream& out
 	printTransitionMap(transitionMap, out);
 }
 
-void GasTexConverter::transitions(const automaton::ExtendedNFA& fsm, std::ostream& out) {
+void GasTexConverter::transitions(const automaton::ExtendedNFA < > & fsm, std::ostream& out) {
 	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
 
 	for (const auto& transition : fsm.getTransitions()) {
diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h
index 41a455309d..baacda7c34 100644
--- a/aconvert2/src/GasTexConverter.h
+++ b/aconvert2/src/GasTexConverter.h
@@ -25,7 +25,7 @@ class GasTexConverter : public std::SingleDispatchFirstStaticParam<GasTexConvert
 	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::DFA<>& fsm, std::ostream& out);
-	static void transitions(const automaton::ExtendedNFA& fsm, std::ostream& out);
+	static void transitions(const automaton::ExtendedNFA < > & fsm, std::ostream& out);
 	static void transitions(const automaton::CompactNFA < > & fsm, std::ostream& out);
 	static void transitions(const automaton::NFTA < > & fsm, std::ostream& out);
 	static void transitions(const automaton::DFTA < > & fsm, std::ostream& out);
@@ -47,7 +47,7 @@ public:
 	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::DFA<>& a);
-	static void convert(std::ostream& out, const automaton::ExtendedNFA& a);
+	static void convert(std::ostream& out, const automaton::ExtendedNFA < > & a);
 	static void convert(std::ostream& out, const automaton::CompactNFA < > & a);
 	static void convert(std::ostream& out, const automaton::NFTA < > & a);
 	static void convert(std::ostream& out, const automaton::DFTA < > & a);
diff --git a/aconvert2/src/TikZConverter.cpp b/aconvert2/src/TikZConverter.cpp
index 3f697750f6..1df53520ec 100644
--- a/aconvert2/src/TikZConverter.cpp
+++ b/aconvert2/src/TikZConverter.cpp
@@ -169,7 +169,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::DFA<> & a ) {
 
 auto TikZConverterDFA = TikZConverter::RegistratorWrapper < void, automaton::DFA<> > ( TikZConverter::convert );
 
-void TikZConverter::convert ( std::ostream & out, const automaton::ExtendedNFA & a ) {
+void TikZConverter::convert ( std::ostream & out, const automaton::ExtendedNFA < > & a ) {
 	out << "\\begin{tikzpicture}\n";
 	int cnt = 1;
 
@@ -196,7 +196,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::ExtendedNFA &
 	out << "\\end{tikzpicture}";
 }
 
-auto TikZConverterExtendedNFA = TikZConverter::RegistratorWrapper < void, automaton::ExtendedNFA > ( TikZConverter::convert );
+auto TikZConverterExtendedNFA = TikZConverter::RegistratorWrapper < void, automaton::ExtendedNFA < > > ( TikZConverter::convert );
 
 void TikZConverter::convert ( std::ostream & out, const automaton::CompactNFA < > & a ) {
 	out << "\\begin{tikzpicture}\n";
@@ -769,7 +769,7 @@ void TikZConverter::transitions ( const automaton::DFA<> & fsm, const std::map <
 	}
 }
 
-void TikZConverter::transitions ( const automaton::ExtendedNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out ) {
+void TikZConverter::transitions ( const automaton::ExtendedNFA < > & 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 6507240a06..f63decadb2 100644
--- a/aconvert2/src/TikZConverter.h
+++ b/aconvert2/src/TikZConverter.h
@@ -24,7 +24,7 @@ class TikZConverter : public std::SingleDispatchFirstStaticParam < TikZConverter
 	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::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::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 );
 	static void transitions ( const automaton::NFTA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::DFTA < > & fsm, const std::map < label::Label, int > & states, std::ostream & out );
@@ -47,7 +47,7 @@ public:
 	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::DFA<> & a );
-	static void convert ( std::ostream & out, const automaton::ExtendedNFA & a );
+	static void convert ( std::ostream & out, const automaton::ExtendedNFA < > & a );
 	static void convert ( std::ostream & out, const automaton::CompactNFA < > & a );
 	static void convert ( std::ostream & out, const automaton::NFTA < > & a );
 	static void convert ( std::ostream & out, const automaton::DFTA < > & a );
diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp
index 549048bca0..81515b68fc 100644
--- a/alib2algo/src/automaton/convert/ToRegExp.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExp.cpp
@@ -40,11 +40,11 @@ regexp::RegExp ToRegExp::convert(const automaton::DFA<>& automaton) {
 
 auto ToRegExpDFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::DFA<>>(ToRegExp::convert);
 
-regexp::RegExp ToRegExp::convert(const automaton::ExtendedNFA& automaton) {
+regexp::RegExp ToRegExp::convert(const automaton::ExtendedNFA < > & automaton) {
 	return regexp::RegExp(ToRegExpStateElimination::convert(automaton));
 }
 
-auto ToRegExpExtendedNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::ExtendedNFA>(ToRegExp::convert);
+auto ToRegExpExtendedNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::ExtendedNFA < > >(ToRegExp::convert);
 
 regexp::RegExp ToRegExp::convert(const automaton::CompactNFA < > & automaton) {
 	return regexp::RegExp(ToRegExpStateElimination::convert(automaton));
diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h
index bff129ed05..e433bc8029 100644
--- a/alib2algo/src/automaton/convert/ToRegExp.h
+++ b/alib2algo/src/automaton/convert/ToRegExp.h
@@ -35,7 +35,7 @@ public:
 	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::ExtendedNFA < > & automaton);
 	static regexp::RegExp convert(const automaton::CompactNFA < > & automaton);
 };
 
diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
index 46b0d7fe9c..17b6d64bf7 100644
--- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
@@ -26,7 +26,7 @@ regexp::UnboundedRegExp < > ToRegExpStateElimination::convert(const T& automaton
 		return regexp::UnboundedRegExp < > (regexp::UnboundedRegExpStructure < alphabet::Symbol > (regexp::UnboundedRegExpEmpty < alphabet::Symbol > ()));
 
 	// steps 1 + 2
-	automaton::ExtendedNFA extendedAutomaton(automaton);
+	automaton::ExtendedNFA < > extendedAutomaton(automaton);
 	extendExtendedNFA(extendedAutomaton);
 
 	// step 3 - Exterminate!
@@ -48,11 +48,11 @@ auto ToRegExpStateEliminationEpsilonNFA = ToRegExpStateElimination::RegistratorW
 auto ToRegExpStateEliminationMultiInitialStateNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::MultiInitialStateNFA < > >(ToRegExpStateElimination::convert);
 auto ToRegExpStateEliminationNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::NFA < > >(ToRegExpStateElimination::convert);
 auto ToRegExpStateEliminationDFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::DFA<>>(ToRegExpStateElimination::convert);
-auto ToRegExpStateEliminationExtendedNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::ExtendedNFA>(ToRegExpStateElimination::convert);
+auto ToRegExpStateEliminationExtendedNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::ExtendedNFA < > >(ToRegExpStateElimination::convert);
 auto ToRegExpStateEliminationCompactNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::CompactNFA < > >(ToRegExpStateElimination::convert);
 
-automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const label::Label& q) {
-	automaton::ExtendedNFA newAutomaton(extendedAutomaton.getInitialState()); // sure that q is neither initial nor final (follows from step 2 - extending ExtendedNFA)
+automaton::ExtendedNFA < > ToRegExpStateElimination::eliminateState(const automaton::ExtendedNFA < > & extendedAutomaton, const label::Label& q) {
+	automaton::ExtendedNFA < > newAutomaton(extendedAutomaton.getInitialState()); // sure that q is neither initial nor final (follows from step 2 - extending ExtendedNFA)
 	newAutomaton.setStates(extendedAutomaton.getStates());
 	newAutomaton.removeState(q); // preserve all states but q (the one to eliminate)
 	newAutomaton.setInputAlphabet(extendedAutomaton.getInputAlphabet());
@@ -73,7 +73,7 @@ automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton:
 	return newAutomaton;
 }
 
-const regexp::UnboundedRegExpStructure < alphabet::Symbol > ToRegExpStateElimination::transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to) {
+const regexp::UnboundedRegExpStructure < alphabet::Symbol > ToRegExpStateElimination::transition(const automaton::ExtendedNFA < > & automaton, const label::Label& from, const label::Label& to) {
 	regexp::UnboundedRegExpStructure < alphabet::Symbol > ret(regexp::UnboundedRegExpEmpty < alphabet::Symbol > { });
 
 	for(const auto& transition: automaton.getTransitionsFromState(from))
@@ -83,7 +83,7 @@ const regexp::UnboundedRegExpStructure < alphabet::Symbol > ToRegExpStateElimina
 	return regexp::simplify::RegExpOptimize::optimize(ret);
 }
 
-void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton) {
+void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA < > & automaton) {
 	const label::Label& initState = automaton.getInitialState();
 	if(automaton.getFinalStates().count(initState) > 0 || automaton.getTransitionsToState(initState).size() > 0 ) {
 		label::Label q0 = label::createUniqueLabel(initState, automaton.getStates());
diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.h b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
index 070566a241..7febd74cdf 100644
--- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
@@ -41,11 +41,11 @@ public:
 	static regexp::UnboundedRegExp < > convert(const T& automaton);
 
 private:
-	static void extendExtendedNFA(automaton::ExtendedNFA& automaton);
+	static void extendExtendedNFA(automaton::ExtendedNFA < > & automaton);
 
-	static const regexp::UnboundedRegExpStructure < alphabet::Symbol > transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to);
+	static const regexp::UnboundedRegExpStructure < alphabet::Symbol > transition(const automaton::ExtendedNFA < > & automaton, const label::Label& from, const label::Label& to);
 
-	static automaton::ExtendedNFA eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const label::Label& state);
+	static automaton::ExtendedNFA < > eliminateState(const automaton::ExtendedNFA < > & extendedAutomaton, const label::Label& state);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
index cff859cd7a..7d8a08f3d1 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
@@ -81,7 +81,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 
 auto AllEpsilonClosureDFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::DFA<>>(AllEpsilonClosure::allEpsilonClosure);
 
-std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA & fsm) {
+std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> res;
 	std::map<label::Label, std::set<label::Label>> step;
 
@@ -103,7 +103,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 	return res;
 }
 
-auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA>(AllEpsilonClosure::allEpsilonClosure);
+auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA < > >(AllEpsilonClosure::allEpsilonClosure);
 
 std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::CompactNFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> res;
diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.h b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
index bc40ae920e..2e8194dcac 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
@@ -31,7 +31,7 @@ public:
 	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::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::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 6260c7e60d..aabf4c6dfe 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
@@ -85,7 +85,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::DFA < >
 
 auto EpsilonClosureDFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(EpsilonClosure::epsilonClosure);
 
-std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::ExtendedNFA & fsm, const label::Label & q ) {
+std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::ExtendedNFA < > & fsm, const label::Label & q ) {
 	if(! fsm.getStates().count(q) ) throw exception::CommonException("State is not in the automaton");
 
 	std::set<label::Label> closure;
@@ -113,7 +113,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::Extended
 	return closure;
 }
 
-auto EpsilonClosureExtendedNFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(EpsilonClosure::epsilonClosure);
+auto EpsilonClosureExtendedNFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(EpsilonClosure::epsilonClosure);
 
 std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::CompactNFA < > & 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 56458df5cd..9b98436f99 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.h
@@ -32,7 +32,7 @@ public:
 	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::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::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 029f340865..ee19d16be9 100644
--- a/alib2algo/src/automaton/properties/ReachableStates.cpp
+++ b/alib2algo/src/automaton/properties/ReachableStates.cpp
@@ -54,7 +54,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 ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(ReachableStates::reachableStates);
-auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(ReachableStates::reachableStates);
+auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(ReachableStates::reachableStates);
 
 template<>
 std::set<label::Label> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < > & fsm ) {
diff --git a/alib2algo/src/automaton/properties/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp
index 1fd4061f41..539f0ec059 100644
--- a/alib2algo/src/automaton/properties/UsefullStates.cpp
+++ b/alib2algo/src/automaton/properties/UsefullStates.cpp
@@ -52,7 +52,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 UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(UsefullStates::usefullStates);
-auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(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);
 
 template<>
diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
index 7cdf8e9b1d..e3ff39b45b 100644
--- a/alib2algo/src/automaton/simplify/SingleInitialState.cpp
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
@@ -89,11 +89,11 @@ automaton::CompactNFA < > SingleInitialState::convert(const automaton::CompactNF
 
 auto SingleInitialStateCompactNFA = SingleInitialState::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(SingleInitialState::convert);
 
-automaton::ExtendedNFA SingleInitialState::convert(const automaton::ExtendedNFA& automaton) {
+automaton::ExtendedNFA < > SingleInitialState::convert(const automaton::ExtendedNFA < > & automaton) {
 	return automaton;
 }
 
-auto SingleInitialStateExtendedNFA = SingleInitialState::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(SingleInitialState::convert);
+auto SingleInitialStateExtendedNFA = SingleInitialState::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(SingleInitialState::convert);
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h
index de59ea0e24..74941f6285 100644
--- a/alib2algo/src/automaton/simplify/SingleInitialState.h
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.h
@@ -32,7 +32,7 @@ public:
 	static automaton::DFA<> convert(const automaton::DFA<>& 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::ExtendedNFA < > convert(const automaton::ExtendedNFA < > & automaton);
 	static automaton::CompactNFA < > convert(const automaton::CompactNFA < > & automaton);
 };
 
diff --git a/alib2algo/src/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp
index 615af0b54b..f159f5a202 100644
--- a/alib2algo/src/automaton/simplify/Trim.cpp
+++ b/alib2algo/src/automaton/simplify/Trim.cpp
@@ -29,7 +29,7 @@ auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA < > , automaton::NFA < >
 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);
-auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(Trim::trim);
+auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(Trim::trim);
 
 automaton::Automaton Trim::trim(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
index 8e55235054..5b6e6b6e75 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
@@ -50,7 +50,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 UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UnreachableStatesRemover::remove);
-auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove);
+auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UnreachableStatesRemover::remove);
 
 template<>
 automaton::DFA<> UnreachableStatesRemover::remove( const automaton::DFA<> & fsm ) {
diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
index f3a42af5e2..871f6804aa 100644
--- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
@@ -51,7 +51,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 UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UselessStatesRemover::remove);
-auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove);
+auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UselessStatesRemover::remove);
 
 template<>
 automaton::DFA<> UselessStatesRemover::remove( const automaton::DFA<> & fsm ) {
diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h
index a12f3729fd..dcde75948d 100644
--- a/alib2data/src/automaton/AutomatonFeatures.h
+++ b/alib2data/src/automaton/AutomatonFeatures.h
@@ -51,6 +51,7 @@ template<class SymbolType = typename alphabet::Symbol, class StateType = typenam
 class DFA;
 template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label >
 class CompactNFA;
+template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label >
 class ExtendedNFA;
 template<class SymbolType = typename alphabet::Symbol, class EpsilonType = typename string::Epsilon < SymbolType >, class StateType = typename label::Label >
 class DPDA;
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.cpp b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
index 87242abcfe..6e777e0172 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
@@ -6,241 +6,22 @@
  */
 
 #include "ExtendedNFA.h"
-#include "CompactNFA.h"
-#include "EpsilonNFA.h"
-#include "MultiInitialStateNFA.h"
-#include "NFA.h"
-#include "DFA.h"
-#include "../../regexp/unbounded/UnboundedRegExpStructure.h"
-#include "../../regexp/unbounded/UnboundedRegExpConcatenation.h"
-#include "../../regexp/unbounded/UnboundedRegExpSymbol.h"
-#include <ostream>
-#include <algorithm>
-#include <sstream>
-
-#include <sax/FromXMLParserHelper.h>
-#include "../common/AutomatonFromXMLParser.h"
-#include "../common/AutomatonToXMLComposer.h"
 #include "../Automaton.h"
 #include <object/Object.h>
 #include <core/xmlApi.hpp>
-#include <core/castApi.hpp>
-#include "../../label/InitialStateLabel.h"
-
-namespace automaton {
-
-ExtendedNFA::ExtendedNFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates ) : std::Components < ExtendedNFA, 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 ) ) ) {
-}
-
-ExtendedNFA::ExtendedNFA ( label::Label initialState ) : ExtendedNFA ( std::set < label::Label > { initialState }, std::set < alphabet::Symbol > { }, initialState, std::set < label::Label > { } ) {
-}
-
-ExtendedNFA::ExtendedNFA ( const CompactNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
-	for ( const auto & transition : other.getTransitions ( ) ) {
-		regexp::UnboundedRegExpConcatenation < alphabet::Symbol > con;
-
-		for ( auto & symbol : transition.first.second )
-			con.appendElement ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( symbol ) );
-
-		std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( std::move ( con ) ) );
-		transitions[key] = transition.second;
-	}
-}
-
-ExtendedNFA::ExtendedNFA ( const EpsilonNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
-	for ( const auto & transition : other.getTransitions ( ) ) {
-		if ( transition.first.second.is < string::Epsilon < > > ( ) ) {
-			std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( ) );
-			transitions[key] = transition.second;
-		} else {
-			std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second.get < alphabet::Symbol > ( ) ) ) );
-			transitions[key] = transition.second;
-		}
-	}
-}
-
-ExtendedNFA::ExtendedNFA ( const MultiInitialStateNFA < > & other ) : ExtendedNFA ( other.getStates ( ) + std::set < label::Label > { label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ) }, other.getInputAlphabet ( ), label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ), other.getFinalStates ( ) ) {
-	for ( const auto & transition : other.getTransitions ( ) ) {
-		std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second ) ) );
-		transitions[key] = transition.second;
-	}
-
-	std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( this->getInitialState ( ), regexp::UnboundedRegExpStructure < alphabet::Symbol > ( ) );
-	transitions[key] = other.getInitialStates ( );
-}
-
-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::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second ) ) );
-		transitions[key] = transition.second;
-	}
-}
-
-ExtendedNFA::ExtendedNFA ( const DFA<> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
-	for ( const auto & transition : other.getTransitions ( ) ) {
-		std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < alphabet::Symbol > ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( transition.first.second ) ) );
-		transitions[key].insert ( transition.second );
-	}
-}
-
-AutomatonBase * ExtendedNFA::clone ( ) const {
-	return new ExtendedNFA ( * this );
-}
-
-AutomatonBase * ExtendedNFA::plunder ( ) && {
-	return new ExtendedNFA ( std::move ( * this ) );
-}
-
-bool ExtendedNFA::addTransition ( label::Label from, regexp::UnboundedRegExpStructure < alphabet::Symbol > input, label::Label to ) {
-	if ( !getStates ( ).count ( from ) )
-		throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist." );
-
-	std::set < alphabet::Symbol > inputRegExpAlphabet = input.getStructure ( ).computeMinimalAlphabet ( );
-
-	 // Transition regexp's alphabet must be subset of automaton's alphabet
-	if ( !std::includes ( getInputAlphabet ( ).begin ( ), getInputAlphabet ( ).end ( ), inputRegExpAlphabet.begin ( ), inputRegExpAlphabet.end ( ) ) )
-		throw AutomatonException ( "Input string is over different alphabet than automaton" );
-
-	if ( !getStates ( ).count ( to ) )
-		throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist." );
-
-	std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( std::move ( from ), std::move ( input ) );
-
-	return transitions[std::move ( key )].insert ( std::move ( to ) ).second;
-}
-
-bool ExtendedNFA::removeTransition ( const label::Label & from, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & input, const label::Label & to ) {
-	std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > > key = std::make_pair ( from, input );
-
-	return transitions[key].erase ( to );
-}
-
-const std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & ExtendedNFA::getTransitions ( ) const {
-	return transitions;
-}
-
-std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > ExtendedNFA::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, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > transitionsFromState;
-
-	for ( const std::pair < const std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : transitions )
-		if ( transition.first.first == from )
-			transitionsFromState.insert ( make_pair ( transition.first, transition.second ) );
 
-	return transitionsFromState;
-}
-
-std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > ExtendedNFA::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, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > transitionsToState;
-
-	for ( const std::pair < const std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : transitions )
-		if ( transition.second.find ( to ) != transition.second.end ( ) )
-			transitionsToState.insert ( make_pair ( transition.first, transition.second ) );
-
-	return transitionsToState;
-}
-
-int ExtendedNFA::compare ( const ExtendedNFA & 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 ExtendedNFA::operator >>( std::ostream & out ) const {
-	out << "(ExtendedNFA "
-	    << "states = " << getStates ( )
-	    << "inputAlphabet = " << getInputAlphabet ( )
-	    << "initialState = " << getInitialState ( )
-	    << "finalStates = " << getFinalStates ( )
-	    << "transitions = " << transitions
-	    << ")";
-}
-
-ExtendedNFA::operator std::string ( ) const {
-	std::stringstream ss;
-	ss << * this;
-	return ss.str ( );
-}
-
-ExtendedNFA ExtendedNFA::parse ( std::deque < sax::Token >::iterator & input ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, ExtendedNFA::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 );
-
-	ExtendedNFA automaton ( std::move ( initialState ) );
-
-	automaton.setStates ( std::move ( states ) );
-	automaton.setInputAlphabet ( std::move ( inputSymbols ) );
-	automaton.setFinalStates ( std::move ( finalStates ) );
-
-	AutomatonFromXMLParser::parseTransitions < ExtendedNFA > ( input, automaton );
-
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, ExtendedNFA::getXmlTagName() );
-	return automaton;
-}
-
-void ExtendedNFA::parseTransition ( std::deque < sax::Token >::iterator & input, ExtendedNFA & automaton ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" );
-	label::Label from = AutomatonFromXMLParser::parseTransitionFrom < label::Label > ( input );
-	regexp::UnboundedRegExpStructure < alphabet::Symbol > inputRegexp = AutomatonFromXMLParser::parseTransitionInputRegexp < 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 ( inputRegexp ), std::move ( to ) );
-}
-
-void ExtendedNFA::compose ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( ExtendedNFA::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 ( ExtendedNFA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
-}
-
-void ExtendedNFA::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::composeTransitionInputRegexp ( 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 <core/castApi.hpp>
 
 namespace alib {
 
-auto extendedNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::ExtendedNFA > ( );
-auto extendedNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::ExtendedNFA > ( );
+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 ExtendedNFAFromMultiInitialStateNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::MultiInitialStateNFA < > > ( );
-auto ExtendedNFAEpsilonNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::EpsilonNFA < > > ( );
-auto ExtendedNFACompactNFA = castApi::CastRegister < automaton::ExtendedNFA, automaton::CompactNFA < > > ( );
-auto ExtendedNFACastBinder = castApi::CastPoolStringBinder < automaton::ExtendedNFA > ( automaton::ExtendedNFA::getXmlTagName() );
+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 < > > ( );
+auto ExtendedNFACastBinder = castApi::CastPoolStringBinder < automaton::ExtendedNFA < > > ( automaton::ExtendedNFA < >::getXmlTagName() );
 
 } /* namespace alib */
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h
index dc3486f726..a99b3a9970 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.h
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.h
@@ -8,17 +8,24 @@
 #ifndef EXTENDED_NFA_H_
 #define EXTENDED_NFA_H_
 
-#include "../AutomatonException.h"
 #include <map>
+#include <ostream>
+#include <algorithm>
+#include <sstream>
+
+#include <sax/FromXMLParserHelper.h>
 #include <core/components.hpp>
+
+#include "../AutomatonException.h"
 #include "../AutomatonBase.h"
-#include "../../regexp/RegExp.h"
-#include "../../label/Label.h"
-#include "CompactNFA.h"
-#include "EpsilonNFA.h"
-#include "MultiInitialStateNFA.h"
-#include "NFA.h"
-#include "DFA.h"
+#include "../AutomatonFeatures.h"
+#include "../common/AutomatonFromXMLParser.h"
+#include "../common/AutomatonToXMLComposer.h"
+
+#include "../../label/InitialStateLabel.h"
+#include "../../regexp/unbounded/UnboundedRegExpStructure.h"
+#include "../../regexp/unbounded/UnboundedRegExpConcatenation.h"
+#include "../../regexp/unbounded/UnboundedRegExpSymbol.h"
 
 namespace automaton {
 
@@ -31,13 +38,14 @@ class States;
 class FinalStates;
 class InitialState;
 
-class ExtendedNFA : public AutomatonBase, public std::Components < ExtendedNFA, alphabet::Symbol, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
+template<class SymbolType, class StateType >
+class ExtendedNFA : public AutomatonBase, public std::Components < ExtendedNFA < SymbolType, StateType >, SymbolType, std::tuple < InputAlphabet >, std::tuple < >, StateType, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
 protected:
-	std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > transitions;
+	std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > transitions;
 
 public:
-	explicit ExtendedNFA ( label::Label initialState );
-	explicit ExtendedNFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates );
+	explicit ExtendedNFA ( StateType initialState );
+	explicit ExtendedNFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates );
 	explicit ExtendedNFA ( const CompactNFA < > & other );
 	explicit ExtendedNFA ( const EpsilonNFA < > & other );
 	explicit ExtendedNFA ( const MultiInitialStateNFA < > & other );
@@ -48,64 +56,64 @@ public:
 
 	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 );
 	}
 
 	/**
@@ -115,29 +123,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, regexp::UnboundedRegExpStructure < alphabet::Symbol > input, label::Label next );
+	bool addTransition ( StateType current, regexp::UnboundedRegExpStructure < 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 regexp::UnboundedRegExpStructure < alphabet::Symbol > & input, const label::Label & next );
+	bool removeTransition ( const StateType & current, const regexp::UnboundedRegExpStructure < SymbolType > & input, const StateType & next );
 
 	/**
 	 * @return automaton transitions
 	 */
-	const std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & getTransitions ( ) const;
+	const std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & getTransitions ( ) const;
 
 	/**
 	 * @return automaton transitions from state
 	 */
-	std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > getTransitionsFromState ( const label::Label & from ) const;
+	std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > getTransitionsFromState ( const StateType & from ) const;
 
 	/**
 	 * @return automaton transitions to state
 	 */
-	std::map < std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > getTransitionsToState ( const label::Label & from ) const;
+	std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > getTransitionsToState ( const StateType & from ) const;
 
 	virtual int compare ( const ObjectBase & other ) const {
 		if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other );
@@ -166,14 +174,245 @@ public:
 
 } /* namespace automaton */
 
+#include "DFA.h"
+#include "NFA.h"
+#include "CompactNFA.h"
+#include "EpsilonNFA.h"
+#include "MultiInitialStateNFA.h"
+
+namespace automaton {
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates ) : std::Components < ExtendedNFA, 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 >
+ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( StateType initialState ) : ExtendedNFA ( std::set < StateType > { initialState }, std::set < SymbolType > { }, initialState, std::set < StateType > { } ) {
+}
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const CompactNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+	for ( const auto & transition : other.getTransitions ( ) ) {
+		regexp::UnboundedRegExpConcatenation < SymbolType > con;
+
+		for ( auto & symbol : transition.first.second )
+			con.appendElement ( regexp::UnboundedRegExpSymbol < SymbolType > ( symbol ) );
+
+		std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( std::move ( con ) ) );
+		transitions[key] = transition.second;
+	}
+}
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const EpsilonNFA < > & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+	for ( const auto & transition : other.getTransitions ( ) ) {
+		if ( transition.first.second.is < string::Epsilon < > > ( ) ) {
+			std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( ) );
+			transitions[key] = transition.second;
+		} else {
+			std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second.get < SymbolType > ( ) ) ) );
+			transitions[key] = transition.second;
+		}
+	}
+}
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const MultiInitialStateNFA < > & other ) : ExtendedNFA ( other.getStates ( ) + std::set < StateType > { label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ) }, other.getInputAlphabet ( ), label::createUniqueLabel ( label::InitialStateLabel::INITIAL_STATE_LABEL, other.getStates ( ) ), other.getFinalStates ( ) ) {
+	for ( const auto & transition : other.getTransitions ( ) ) {
+		std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second ) ) );
+		transitions[key] = transition.second;
+	}
+
+	std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( this->getInitialState ( ), regexp::UnboundedRegExpStructure < SymbolType > ( ) );
+	transitions[key] = other.getInitialStates ( );
+}
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const NFA <> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+	for ( const auto & transition : other.getTransitions ( ) ) {
+		std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second ) ) );
+		transitions[key] = transition.second;
+	}
+}
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType >::ExtendedNFA ( const DFA<> & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+	for ( const auto & transition : other.getTransitions ( ) ) {
+		std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( transition.first.first, regexp::UnboundedRegExpStructure < SymbolType > ( regexp::UnboundedRegExpSymbol < SymbolType > ( transition.first.second ) ) );
+		transitions[key].insert ( transition.second );
+	}
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase * ExtendedNFA < SymbolType, StateType >::clone ( ) const {
+	return new ExtendedNFA ( * this );
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase * ExtendedNFA < SymbolType, StateType >::plunder ( ) && {
+	return new ExtendedNFA ( std::move ( * this ) );
+}
+
+template<class SymbolType, class StateType >
+bool ExtendedNFA < SymbolType, StateType >::addTransition ( StateType from, regexp::UnboundedRegExpStructure < SymbolType > input, StateType to ) {
+	if ( !getStates ( ).count ( from ) )
+		throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist." );
+
+	std::set < SymbolType > inputRegExpAlphabet = input.getStructure ( ).computeMinimalAlphabet ( );
+
+	 // Transition regexp's alphabet must be subset of automaton's alphabet
+	if ( !std::includes ( getInputAlphabet ( ).begin ( ), getInputAlphabet ( ).end ( ), inputRegExpAlphabet.begin ( ), inputRegExpAlphabet.end ( ) ) )
+		throw AutomatonException ( "Input string is over different alphabet than automaton" );
+
+	if ( !getStates ( ).count ( to ) )
+		throw AutomatonException ( "State \"" + std::to_string ( to ) + "\" doesn't exist." );
+
+	std::pair < StateType, regexp::UnboundedRegExpStructure < 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 ExtendedNFA < SymbolType, StateType >::removeTransition ( const StateType & from, const regexp::UnboundedRegExpStructure < SymbolType > & input, const StateType & to ) {
+	std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > > key = std::make_pair ( from, input );
+
+	return transitions[key].erase ( to );
+}
+
+template<class SymbolType, class StateType >
+const std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & ExtendedNFA < SymbolType, StateType >::getTransitions ( ) const {
+	return transitions;
+}
+
+template<class SymbolType, class StateType >
+std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > ExtendedNFA < 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, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > transitionsFromState;
+
+	for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & transition : transitions )
+		if ( transition.first.first == from )
+			transitionsFromState.insert ( make_pair ( transition.first, transition.second ) );
+
+	return transitionsFromState;
+}
+
+template<class SymbolType, class StateType >
+std::map < std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > ExtendedNFA < 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, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > transitionsToState;
+
+	for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & transition : transitions )
+		if ( transition.second.find ( to ) != transition.second.end ( ) )
+			transitionsToState.insert ( make_pair ( transition.first, transition.second ) );
+
+	return transitionsToState;
+}
+
+template<class SymbolType, class StateType >
+int ExtendedNFA < SymbolType, StateType >::compare ( const ExtendedNFA & 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 ExtendedNFA < SymbolType, StateType >::operator >>( std::ostream & out ) const {
+	out << "(ExtendedNFA "
+	    << "states = " << getStates ( )
+	    << "inputAlphabet = " << getInputAlphabet ( )
+	    << "initialState = " << getInitialState ( )
+	    << "finalStates = " << getFinalStates ( )
+	    << "transitions = " << transitions
+	    << ")";
+}
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType >::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << * this;
+	return ss.str ( );
+}
+
+template<class SymbolType, class StateType >
+ExtendedNFA < SymbolType, StateType > ExtendedNFA < SymbolType, StateType >::parse ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, ExtendedNFA::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 );
+
+	ExtendedNFA < SymbolType, StateType > automaton ( std::move ( initialState ) );
+
+	automaton.setStates ( std::move ( states ) );
+	automaton.setInputAlphabet ( std::move ( inputSymbols ) );
+	automaton.setFinalStates ( std::move ( finalStates ) );
+
+	AutomatonFromXMLParser::parseTransitions < ExtendedNFA > ( input, automaton );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, ExtendedNFA::getXmlTagName() );
+	return automaton;
+}
+
+template<class SymbolType, class StateType >
+void ExtendedNFA < SymbolType, StateType >::parseTransition ( std::deque < sax::Token >::iterator & input, ExtendedNFA & automaton ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" );
+	StateType from = AutomatonFromXMLParser::parseTransitionFrom < StateType > ( input );
+	regexp::UnboundedRegExpStructure < SymbolType > inputRegexp = AutomatonFromXMLParser::parseTransitionInputRegexp < 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 ( inputRegexp ), std::move ( to ) );
+}
+
+template<class SymbolType, class StateType >
+void ExtendedNFA < SymbolType, StateType >::compose ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( ExtendedNFA::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 ( ExtendedNFA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
+}
+
+template<class SymbolType, class StateType >
+void ExtendedNFA < 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::composeTransitionInputRegexp ( 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::ExtendedNFA, alphabet::Symbol, automaton::InputAlphabet > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, SymbolType, automaton::InputAlphabet > {
 public:
-	static bool used ( const automaton::ExtendedNFA & automaton, const alphabet::Symbol & symbol ) {
-		for ( const std::pair < const std::pair < label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : automaton.getTransitions ( ) ) {
-			std::set < alphabet::Symbol > alphabet = transition.first.second.getStructure ( ).computeMinimalAlphabet ( );
+	static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const SymbolType & symbol ) {
+		for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < SymbolType > >, std::set < StateType > > & transition : automaton.getTransitions ( ) ) {
+			std::set < SymbolType > alphabet = transition.first.second.getStructure ( ).computeMinimalAlphabet ( );
 			if ( alphabet.count ( symbol ) )
 				return true;
 		}
@@ -181,62 +420,62 @@ public:
 		return false;
 	}
 
-	static bool available ( const automaton::ExtendedNFA &, const alphabet::Symbol & ) {
+	static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > &, const SymbolType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::ExtendedNFA &, const alphabet::Symbol & ) {
+	static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const SymbolType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::ExtendedNFA, label::Label, automaton::States > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::States > {
 public:
-	static bool used ( const automaton::ExtendedNFA & automaton, const label::Label & state ) {
+	static bool used ( const automaton::ExtendedNFA < 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, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set < label::Label > > & transition : automaton.getTransitions ( ) )
+		for ( const std::pair < const std::pair < StateType, regexp::UnboundedRegExpStructure < 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::ExtendedNFA &, const label::Label & ) {
+	static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::ExtendedNFA &, const label::Label & ) {
+	static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::ExtendedNFA, label::Label, automaton::FinalStates > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::FinalStates > {
 public:
-	static bool used ( const automaton::ExtendedNFA &, const label::Label & ) {
+	static bool used ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) {
 	return false;
 }
 
-	static bool available ( const automaton::ExtendedNFA & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) {
+		return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
 	}
 
-	static void valid ( const automaton::ExtendedNFA &, const label::Label & ) {
+	static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) {
 	}
 };
 
-template < >
-class ElementConstraint< automaton::ExtendedNFA, label::Label, automaton::InitialState > {
+template<class SymbolType, class StateType >
+class ElementConstraint< automaton::ExtendedNFA < SymbolType, StateType >, StateType, automaton::InitialState > {
 public:
-	static bool available ( const automaton::ExtendedNFA & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::ExtendedNFA < SymbolType, StateType > & automaton, const StateType & state ) {
+		return automaton.template accessComponent < automaton::States > ( ).get ( ).count ( state );
 	}
 
-	static void valid ( const automaton::ExtendedNFA &, const label::Label & ) {
+	static void valid ( const automaton::ExtendedNFA < SymbolType, StateType > &, const StateType & ) {
 	}
 };
 
diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp
index be37250b6b..837d74bd24 100644
--- a/alib2data/test-src/automaton/AutomatonTest.cpp
+++ b/alib2data/test-src/automaton/AutomatonTest.cpp
@@ -153,7 +153,7 @@ void AutomatonTest::DPDATransitions() {
 }
 
 void AutomatonTest::testExtendedNFAAlphabet() {
-	automaton::ExtendedNFA automaton (label::labelFrom(0));
+	automaton::ExtendedNFA < > automaton (label::labelFrom(0));
 	label::Label s0 = label::labelFrom(0);
 	label::Label s1 = label::labelFrom(1);
 	automaton.addState(s0);
diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
index 1f2b3181ba..ac6e066589 100644
--- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
@@ -94,7 +94,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 
 auto AllEpsilonClosureDFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::DFA<>>(AllEpsilonClosure::allEpsilonClosure);
 
-std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA & fsm) {
+std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::ExtendedNFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> res;
 
 	for(const label::Label& state : fsm.getStates())
@@ -121,7 +121,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 	return res;
 }
 
-auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA>(AllEpsilonClosure::allEpsilonClosure);
+auto AllEpsilonClosureExtendedNFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::ExtendedNFA < > >(AllEpsilonClosure::allEpsilonClosure);
 
 std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClosure( const automaton::CompactNFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> res;
diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
index 4b5ecbf867..a0e51e4af1 100644
--- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
+++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
@@ -34,7 +34,7 @@ public:
 	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::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::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 3356f62823..9fb30fc6b1 100644
--- a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/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 ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(ReachableStates::reachableStates);
-auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(ReachableStates::reachableStates);
+auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(ReachableStates::reachableStates);
 
 template<>
 std::set<label::Label> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < > & fsm ) {
diff --git a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
index d922e099ad..4804bd174c 100644
--- a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
@@ -53,7 +53,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 UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(UsefullStates::usefullStates);
-auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA>(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);
 
 template<>
diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
index a638881a29..9ac969dbd7 100644
--- a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
@@ -33,7 +33,7 @@ auto TrimNFA = Trim::RegistratorWrapper<automaton::NFA < > , automaton::NFA < >
 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);
-auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(Trim::trim);
+auto TrimExtendedNFA = Trim::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(Trim::trim);
 
 automaton::Automaton Trim::trim(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
index c7f6b19eb2..4ea8ef0b67 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
@@ -54,7 +54,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 UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UnreachableStatesRemover::remove);
-auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove);
+auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UnreachableStatesRemover::remove);
 
 template<>
 automaton::DFA<> UnreachableStatesRemover::remove( const automaton::DFA<> & fsm ) {
diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
index e87376c701..40dae88f1e 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
@@ -56,7 +56,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 UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<automaton::CompactNFA < >, automaton::CompactNFA < > >(UselessStatesRemover::remove);
-auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove);
+auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA < >, automaton::ExtendedNFA < > >(UselessStatesRemover::remove);
 
 template<>
 automaton::DFA<> UselessStatesRemover::remove( const automaton::DFA<> & fsm ) {
-- 
GitLab