From 1c655a49e99ab76a6c7b4df16393d1c97c07f2b6 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 21 Jun 2016 09:11:34 +0200
Subject: [PATCH] continue with templating DFA

---
 aaccess2/src/AutomatonAccess.cpp              |   4 +-
 aaccess2/src/AutomatonAccess.h                |   2 +-
 acompare2/src/AutomatonCompare.cpp            |   8 +-
 acompare2/src/AutomatonCompare.h              |   6 +-
 aconversions2/src/ConversionHandler.cpp       |   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/ToGrammar.cpp |   4 +-
 alib2algo/src/automaton/convert/ToGrammar.h   |   2 +-
 .../src/automaton/convert/ToGrammarLeftRG.cpp |   4 +-
 .../src/automaton/convert/ToGrammarLeftRG.h   |   2 +-
 .../automaton/convert/ToGrammarRightRG.cpp    |   4 +-
 .../src/automaton/convert/ToGrammarRightRG.h  |   2 +-
 alib2algo/src/automaton/convert/ToRegExp.cpp  |   4 +-
 alib2algo/src/automaton/convert/ToRegExp.h    |   2 +-
 .../automaton/convert/ToRegExpAlgebraic.cpp   |   4 +-
 .../src/automaton/convert/ToRegExpAlgebraic.h |   2 +-
 .../convert/ToRegExpStateElimination.cpp      |   2 +-
 .../src/automaton/determinize/Determinize.cpp |   4 +-
 .../src/automaton/determinize/Determinize.h   |   6 +-
 .../determinize/DeterminizeNFAPart.cxx        |  12 +-
 .../properties/AllEpsilonClosure.cpp          |   4 +-
 .../automaton/properties/AllEpsilonClosure.h  |   2 +-
 .../automaton/properties/EpsilonClosure.cpp   |   4 +-
 .../src/automaton/properties/EpsilonClosure.h |   2 +-
 .../automaton/properties/ReachableStates.cpp  |   4 +-
 .../automaton/properties/UsefullStates.cpp    |   4 +-
 alib2algo/src/automaton/run/Accept.cpp        |   4 +-
 alib2algo/src/automaton/run/Accept.h          |   2 +-
 alib2algo/src/automaton/run/Occurrences.cpp   |   4 +-
 alib2algo/src/automaton/run/Occurrences.h     |   2 +-
 alib2algo/src/automaton/run/Result.cpp        |   4 +-
 alib2algo/src/automaton/run/Result.h          |   2 +-
 alib2algo/src/automaton/run/Run.cpp           |   2 +-
 alib2algo/src/automaton/run/Run.h             |   2 +-
 .../simplify/EpsilonRemoverIncoming.cpp       |   4 +-
 .../simplify/EpsilonRemoverIncoming.h         |   2 +-
 .../simplify/EpsilonRemoverOutgoing.cpp       |   4 +-
 .../simplify/EpsilonRemoverOutgoing.h         |   2 +-
 alib2algo/src/automaton/simplify/Minimize.cpp |  10 +-
 alib2algo/src/automaton/simplify/Minimize.h   |   4 +-
 .../automaton/simplify/MinimizeBrzozowski.cpp |   8 +-
 .../automaton/simplify/MinimizeBrzozowski.h   |   4 +-
 .../src/automaton/simplify/Normalize.cpp      |   6 +-
 alib2algo/src/automaton/simplify/Normalize.h  |   2 +-
 alib2algo/src/automaton/simplify/Rename.cpp   |   6 +-
 alib2algo/src/automaton/simplify/Rename.h     |   2 +-
 .../automaton/simplify/SingleInitialState.cpp |   4 +-
 .../automaton/simplify/SingleInitialState.h   |   2 +-
 alib2algo/src/automaton/simplify/Total.cpp    |   6 +-
 alib2algo/src/automaton/simplify/Total.h      |   2 +-
 alib2algo/src/automaton/simplify/Trim.cpp     |   2 +-
 .../simplify/UnreachableStatesRemover.cpp     |   6 +-
 .../simplify/UselessStatesRemover.cpp         |   6 +-
 .../transform/AutomataConcatenation.cpp       |   4 +-
 .../transform/AutomataConcatenation.h         |   2 +-
 ...AutomataConcatenationEpsilonTransition.cpp |   4 +-
 .../AutomataConcatenationEpsilonTransition.h  |   2 +-
 .../AutomataIntersectionCartesianProduct.cpp  |   6 +-
 .../AutomataIntersectionCartesianProduct.h    |   2 +-
 .../AutomataUnionCartesianProduct.cpp         |   6 +-
 .../transform/AutomataUnionCartesianProduct.h |   2 +-
 .../AutomataUnionEpsilonTransition.cpp        |   4 +-
 .../AutomataUnionEpsilonTransition.h          |   2 +-
 .../transform/AutomatonIteration.cpp          |   2 +-
 .../AutomatonIterationEpsilonTransition.cpp   |   2 +-
 .../src/automaton/transform/Compaction.cpp    |   4 +-
 .../src/automaton/transform/Compaction.h      |   2 +-
 alib2algo/src/automaton/transform/Reverse.cpp |   4 +-
 alib2algo/src/automaton/transform/Reverse.h   |   2 +-
 alib2algo/src/grammar/parsing/LR0Parser.cpp   |   4 +-
 alib2algo/src/grammar/parsing/LR0Parser.h     |   2 +-
 .../src/grammar/parsing/SLR1ParseTable.cpp    |   4 +-
 .../regexp/convert/ToAutomatonDerivation.cpp  |  10 +-
 .../regexp/convert/ToAutomatonDerivation.h    |   6 +-
 .../exact/BackwardDAWGMatching.cpp            |   2 +-
 .../exact/BackwardOracleMatching.cpp          |   2 +-
 .../exact/ExactSubsequenceAutomaton.cpp       |   6 +-
 .../exact/ExactSubsequenceAutomaton.h         |   2 +-
 .../exact/FactorOracleAutomaton.cpp           |   8 +-
 .../stringology/exact/FactorOracleAutomaton.h |   4 +-
 .../src/stringology/exact/SuffixAutomaton.cpp |  12 +-
 .../src/stringology/exact/SuffixAutomaton.h   |   6 +-
 .../automaton/determinize/determinizeTest.cpp |   2 +-
 .../simplify/FSMSingleInitialStateTest.cpp    |   4 +-
 .../automaton/simplify/FSMTotalTest.cpp       |   8 +-
 .../simplify/minimizeBrzozowskiTest.cpp       |   6 +-
 .../automaton/simplify/minimizeTest.cpp       |   4 +-
 .../automaton/simplify/normalizeTest.cpp      |   4 +-
 .../test-src/automaton/simplify/trimTest.cpp  |   4 +-
 .../transform/AutomataCompactionTest.cpp      |   6 +-
 .../transform/AutomataConcatenationTest.cpp   |  12 +-
 .../automaton/transform/AutomataUnionTest.cpp |   6 +-
 .../transform/AutomatonIterationTest.cpp      |   2 +-
 .../test-src/grammar/parsing/LR0Parser.cpp    |   2 +-
 alib2algo/test-src/playTest.cpp               |   4 +-
 alib2algo/test-src/playTest.h                 |   2 +-
 .../test-src/regexp/toAutomaton/re2faTest.cpp |  20 +-
 .../exact/FactorOracleAutomatonTest.cpp       |   4 +-
 .../stringology/exact/SuffixAutomatonTest.cpp |   4 +-
 alib2data/src/automaton/AutomatonFeatures.h   |   1 +
 alib2data/src/automaton/FSM/CompactNFA.cpp    |   4 +-
 alib2data/src/automaton/FSM/CompactNFA.h      |   2 +-
 alib2data/src/automaton/FSM/DFA.cpp           | 183 +---------
 alib2data/src/automaton/FSM/DFA.h             | 324 ++++++++++++++----
 alib2data/src/automaton/FSM/EpsilonNFA.cpp    |   4 +-
 alib2data/src/automaton/FSM/EpsilonNFA.h      |   2 +-
 alib2data/src/automaton/FSM/ExtendedNFA.cpp   |   4 +-
 alib2data/src/automaton/FSM/ExtendedNFA.h     |   2 +-
 .../automaton/FSM/MultiInitialStateNFA.cpp    |   4 +-
 .../src/automaton/FSM/MultiInitialStateNFA.h  |   2 +-
 alib2data/src/automaton/FSM/NFA.cpp           |   4 +-
 alib2data/src/automaton/FSM/NFA.h             |   2 +-
 .../test-src/automaton/AutomatonTest.cpp      |   4 +-
 .../efficient/AllEpsilonClosure.cpp           |   4 +-
 .../properties/efficient/AllEpsilonClosure.h  |   2 +-
 .../properties/efficient/ReachableStates.cpp  |   4 +-
 .../properties/efficient/UsefullStates.cpp    |   4 +-
 .../efficient/EpsilonRemoverIncoming.cpp      |   4 +-
 .../efficient/EpsilonRemoverIncoming.h        |   2 +-
 .../efficient/EpsilonRemoverOutgoing.cpp      |   4 +-
 .../efficient/EpsilonRemoverOutgoing.h        |   2 +-
 .../src/automaton/simplify/efficient/Trim.cpp |   2 +-
 .../efficient/UnreachableStatesRemover.cpp    |   6 +-
 .../efficient/UselessStatesRemover.cpp        |   6 +-
 .../automaton/simplify/efficient/trimTest.cpp |   4 +-
 .../automaton/AutomatonFromStringParser.cpp   |   4 +-
 .../src/automaton/AutomatonFromStringParser.h |   2 +-
 .../automaton/AutomatonToStringComposer.cpp   |   6 +-
 .../src/automaton/AutomatonToStringComposer.h |   4 +-
 134 files changed, 535 insertions(+), 513 deletions(-)

diff --git a/aaccess2/src/AutomatonAccess.cpp b/aaccess2/src/AutomatonAccess.cpp
index e852f1a753..cc0072e222 100644
--- a/aaccess2/src/AutomatonAccess.cpp
+++ b/aaccess2/src/AutomatonAccess.cpp
@@ -42,7 +42,7 @@ void AutomatonAccess::access ( const automaton::NFA & automaton, const std::set
 
 auto AutomatonAccessNFA = AutomatonAccess::RegistratorWrapper < void, automaton::NFA > ( AutomatonAccess::access );
 
-void AutomatonAccess::access ( const automaton::DFA & automaton, const std::set < AutomatonSettings::Settings > & settings ) {
+void AutomatonAccess::access ( const automaton::DFA<> & 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 ( ) );
@@ -54,7 +54,7 @@ void AutomatonAccess::access ( const automaton::DFA & automaton, const std::set
 	if ( settings.count ( AutomatonSettings::Settings::TRANSITIONS ) ) alib::XmlDataFactory::toStdout ( automaton.getTransitions ( ) );
 }
 
-auto AutomatonAccessDFA = AutomatonAccess::RegistratorWrapper < void, automaton::DFA > ( AutomatonAccess::access );
+auto AutomatonAccessDFA = AutomatonAccess::RegistratorWrapper < void, automaton::DFA<> > ( AutomatonAccess::access );
 
 void AutomatonAccess::access ( const automaton::InputDrivenNPDA & 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 94e50cc8f6..d43ef7d425 100644
--- a/aaccess2/src/AutomatonAccess.h
+++ b/aaccess2/src/AutomatonAccess.h
@@ -21,7 +21,7 @@ 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::DFA & 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 );
 	static void access ( const automaton::InputDrivenDPDA & automaton, const std::set < AutomatonSettings::Settings > & settings );
diff --git a/acompare2/src/AutomatonCompare.cpp b/acompare2/src/AutomatonCompare.cpp
index fd8721d811..d7df17db11 100644
--- a/acompare2/src/AutomatonCompare.cpp
+++ b/acompare2/src/AutomatonCompare.cpp
@@ -38,7 +38,7 @@
 #include "automaton/PDA/SinglePopDPDA.h"
 #include "automaton/TM/OneTapeDTM.h"
 
-bool AutomatonCompare::testCompare(const automaton::DFA& a, const automaton::DFA& b) {
+bool AutomatonCompare::testCompare(const automaton::DFA<>& a, const automaton::DFA<>& b) {
 	return  	a.getFinalStates()    == b.getFinalStates()    &&
 			a.getInitialState()   == b.getInitialState()   &&
 //			a.getInputAlphabet()  == b.getInputAlphabet()  &&
@@ -272,7 +272,7 @@ template <class T, class R> void AutomatonCompare::mapCompare(const std::map<T,
 	}
 }
 
-void AutomatonCompare::printCompare(const automaton::DFA& a, const automaton::DFA& b) {
+void AutomatonCompare::printCompare(const automaton::DFA<>& a, const automaton::DFA<>& b) {
 	std::cout << "AutomatonCompareer" << std::endl;
 
 	if(a.getFinalStates() != b.getFinalStates()){
@@ -1172,7 +1172,7 @@ void AutomatonCompare::printCompare(const automaton::OneTapeDTM<>& a, const auto
 	}
 }
 
-int AutomatonCompare::compare(const automaton::DFA& a, const automaton::DFA& b) {
+int AutomatonCompare::compare(const automaton::DFA<>& a, const automaton::DFA<>& b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
 	  AutomatonCompare::printCompare(a, b);
 	  return 1;
@@ -1181,7 +1181,7 @@ int AutomatonCompare::compare(const automaton::DFA& a, const automaton::DFA& b)
 	}
 }
 
-auto AutomatonCompareDFA = AutomatonCompare::RegistratorWrapper<int, automaton::DFA, automaton::DFA>(AutomatonCompare::compare);
+auto AutomatonCompareDFA = AutomatonCompare::RegistratorWrapper<int, automaton::DFA<>, automaton::DFA<>>(AutomatonCompare::compare);
 
 int AutomatonCompare::compare(const automaton::NFA& a, const automaton::NFA& b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
diff --git a/acompare2/src/AutomatonCompare.h b/acompare2/src/AutomatonCompare.h
index a41607c2e8..85a3c11d16 100644
--- a/acompare2/src/AutomatonCompare.h
+++ b/acompare2/src/AutomatonCompare.h
@@ -20,8 +20,8 @@
 
 class AutomatonCompare : public std::DoubleDispatch<AutomatonCompare, int, automaton::AutomatonBase, automaton::AutomatonBase> {
 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::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);
@@ -81,7 +81,7 @@ private:
 	template <class T> static void listCompare(const std::list<T> a, const std::list<T> b);
 	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::DFA<>& a, const automaton::DFA<>& 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);
diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index 88a8df5a24..6d97f450c3 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -179,10 +179,10 @@ void ConversionHandler::convertREtoFA ( void ) {
 
 	switch ( m_algorithm ) {
 	case BRZOZOWSKI_DERIVATION: {
-		   automaton::DFA automaton = regexp::convert::ToAutomatonDerivation::convert ( regexp );
+		automaton::DFA<> automaton = regexp::convert::ToAutomatonDerivation::convert ( regexp );
 
-		   measurements::end ( );
-		   measurements::start ( "Output write", measurements::Type::AUXILIARY );
+		measurements::end ( );
+		measurements::start ( "Output write", measurements::Type::AUXILIARY );
 
 		   alib::XmlDataFactory::toStdout ( automaton );
 		   break;
diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp
index 2620e4ebb7..8a93361ee7 100644
--- a/aconvert2/src/DotConverter.cpp
+++ b/aconvert2/src/DotConverter.cpp
@@ -151,7 +151,7 @@ void DotConverter::convert(std::ostream& out, const automaton::NFA& a) {
 
 auto DotConverterNFA = DotConverter::RegistratorWrapper<void, automaton::NFA>(DotConverter::convert);
 
-void DotConverter::convert(std::ostream& out, const automaton::DFA& a) {
+void DotConverter::convert(std::ostream& out, const automaton::DFA<>& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -182,7 +182,7 @@ void DotConverter::convert(std::ostream& out, const automaton::DFA& a) {
 	out << "}";
 }
 
-auto DotConverterDFA = DotConverter::RegistratorWrapper<void, automaton::DFA>(DotConverter::convert);
+auto DotConverterDFA = DotConverter::RegistratorWrapper<void, automaton::DFA<>>(DotConverter::convert);
 
 void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) {
 	out << "digraph automaton {\n";
@@ -782,7 +782,7 @@ void DotConverter::transitions(const automaton::NFA& fsm, const std::map<label::
 	}
 }
 
-void DotConverter::transitions(const automaton::DFA& fsm, const std::map<label::Label, int>& states, std::ostream& out) {
+void DotConverter::transitions(const automaton::DFA<>& 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 56538a5027..8199a72b42 100644
--- a/aconvert2/src/DotConverter.h
+++ b/aconvert2/src/DotConverter.h
@@ -23,7 +23,7 @@ class DotConverter : public std::SingleDispatchFirstStaticParam<DotConverter, vo
 	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::DFA& 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);
 	static void transitions(const automaton::NFTA& 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::DFA& 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);
 	static void convert(std::ostream& out, const automaton::NFTA& a);
diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp
index 9ebe828f08..4c9cc068e9 100644
--- a/aconvert2/src/GasTexConverter.cpp
+++ b/aconvert2/src/GasTexConverter.cpp
@@ -161,7 +161,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::NFA& a) {
 
 auto GasTexConverterNFA = GasTexConverter::RegistratorWrapper<void, automaton::NFA>(GasTexConverter::convert);
 
-void GasTexConverter::convert(std::ostream& out, const automaton::DFA& a) {
+void GasTexConverter::convert(std::ostream& out, const automaton::DFA<>& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -200,7 +200,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::DFA& a) {
 	out << "\\end{picture}\n";
 }
 
-auto GasTexConverterDFA = GasTexConverter::RegistratorWrapper<void, automaton::DFA>(GasTexConverter::convert);
+auto GasTexConverterDFA = GasTexConverter::RegistratorWrapper<void, automaton::DFA<>>(GasTexConverter::convert);
 
 void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) {
 	out << "\\begin{center}\n";
@@ -850,7 +850,7 @@ void GasTexConverter::transitions(const automaton::NFA& fsm, std::ostream& out)
 	printTransitionMap(transitionMap, out);
 }
 
-void GasTexConverter::transitions(const automaton::DFA& fsm, std::ostream& out) {
+void GasTexConverter::transitions(const automaton::DFA<>& fsm, std::ostream& out) {
 	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
 	for (const auto& transition : fsm.getTransitions()) {
 		std::pair<std::string, std::string> key((std::string) transition.first.first, (std::string) transition.second);
diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h
index eb896f4b9d..475807cbe6 100644
--- a/aconvert2/src/GasTexConverter.h
+++ b/aconvert2/src/GasTexConverter.h
@@ -24,7 +24,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::DFA& 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);
 	static void transitions(const automaton::NFTA& fsm, std::ostream& out);
@@ -46,7 +46,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::DFA& 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);
 	static void convert(std::ostream& out, const automaton::NFTA& a);
diff --git a/aconvert2/src/TikZConverter.cpp b/aconvert2/src/TikZConverter.cpp
index 07eaefd2f5..f31c3a1bd0 100644
--- a/aconvert2/src/TikZConverter.cpp
+++ b/aconvert2/src/TikZConverter.cpp
@@ -138,7 +138,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::NFA & a ) {
 
 auto TikZConverterNFA = TikZConverter::RegistratorWrapper < void, automaton::NFA > ( TikZConverter::convert );
 
-void TikZConverter::convert ( std::ostream & out, const automaton::DFA & a ) {
+void TikZConverter::convert ( std::ostream & out, const automaton::DFA<> & a ) {
 	out << "\\begin{tikzpicture}\n";
 	int cnt = 1;
 
@@ -165,7 +165,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::DFA & a ) {
 	out << "\\end{tikzpicture}";
 }
 
-auto TikZConverterDFA = TikZConverter::RegistratorWrapper < void, automaton::DFA > ( TikZConverter::convert );
+auto TikZConverterDFA = TikZConverter::RegistratorWrapper < void, automaton::DFA<> > ( TikZConverter::convert );
 
 void TikZConverter::convert ( std::ostream & out, const automaton::ExtendedNFA & a ) {
 	out << "\\begin{tikzpicture}\n";
@@ -727,7 +727,7 @@ void TikZConverter::transitions ( const automaton::NFA & fsm, const std::map < l
 	}
 }
 
-void TikZConverter::transitions ( const automaton::DFA & fsm, const std::map < label::Label, int > & states, std::ostream & out ) {
+void TikZConverter::transitions ( const automaton::DFA<> & 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 8504ef8d45..3f2a7af2b5 100644
--- a/aconvert2/src/TikZConverter.h
+++ b/aconvert2/src/TikZConverter.h
@@ -23,7 +23,7 @@ class TikZConverter : public std::SingleDispatchFirstStaticParam < TikZConverter
 	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::DFA & 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 );
 	static void transitions ( const automaton::NFTA & fsm, const std::map < label::Label, int > & states, std::ostream & out );
@@ -46,7 +46,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::DFA & 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 );
 	static void convert ( std::ostream & out, const automaton::NFTA & a );
diff --git a/alib2algo/src/automaton/convert/ToGrammar.cpp b/alib2algo/src/automaton/convert/ToGrammar.cpp
index f681ce399d..6d73b780cd 100644
--- a/alib2algo/src/automaton/convert/ToGrammar.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammar.cpp
@@ -22,11 +22,11 @@ grammar::Grammar ToGrammar::convert(const automaton::NFA& automaton) {
 
 auto ToGrammarNFA = ToGrammar::RegistratorWrapper<grammar::Grammar, automaton::NFA>(ToGrammar::convert);
 
-grammar::Grammar ToGrammar::convert(const automaton::DFA& automaton) {
+grammar::Grammar ToGrammar::convert(const automaton::DFA<>& automaton) {
 	return grammar::Grammar(ToGrammarRightRG::convert(automaton));
 }
 
-auto ToGrammarDFA = ToGrammar::RegistratorWrapper<grammar::Grammar, automaton::DFA>(ToGrammar::convert);
+auto ToGrammarDFA = ToGrammar::RegistratorWrapper<grammar::Grammar, automaton::DFA<>>(ToGrammar::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h
index 3edef0b4c1..acc2b16f91 100644
--- a/alib2algo/src/automaton/convert/ToGrammar.h
+++ b/alib2algo/src/automaton/convert/ToGrammar.h
@@ -30,7 +30,7 @@ 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 DFA<>& automaton);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
index 42255321bc..d5627b8786 100644
--- a/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
@@ -65,7 +65,7 @@ grammar::LeftRG ToGrammarLeftRG::convert(const automaton::NFA& automaton) {
 
 auto ToGrammarLeftRGNFA = ToGrammarLeftRG::RegistratorWrapper<grammar::LeftRG, automaton::NFA>(ToGrammarLeftRG::convert);
 
-grammar::LeftRG ToGrammarLeftRG::convert(const automaton::DFA& automaton) {
+grammar::LeftRG ToGrammarLeftRG::convert(const automaton::DFA<>& automaton) {
 	std::map<label::Label, alphabet::Symbol> nonterminalMap;
 	// step 2
 	grammar::LeftRG grammar(alphabet::symbolFrom("S"));
@@ -108,7 +108,7 @@ grammar::LeftRG ToGrammarLeftRG::convert(const automaton::DFA& automaton) {
 	return grammar;
 }
 
-auto ToGrammarLeftRGDFA = ToGrammarLeftRG::RegistratorWrapper<grammar::LeftRG, automaton::DFA>(ToGrammarLeftRG::convert);
+auto ToGrammarLeftRGDFA = ToGrammarLeftRG::RegistratorWrapper<grammar::LeftRG, automaton::DFA<>>(ToGrammarLeftRG::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/automaton/convert/ToGrammarLeftRG.h b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
index 4976d12c61..0aed7310a8 100644
--- a/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
+++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
@@ -33,7 +33,7 @@ public:
 	static grammar::LeftRG convert(const automaton::Automaton& automaton);
 
 	static grammar::LeftRG convert(const automaton::NFA& automaton);
-	static grammar::LeftRG convert(const automaton::DFA& automaton);
+	static grammar::LeftRG convert(const automaton::DFA<>& automaton);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
index e5eb74ec9c..2c83a6a831 100644
--- a/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
@@ -59,7 +59,7 @@ grammar::RightRG ToGrammarRightRG::convert(const automaton::NFA& automaton) {
 
 auto ToGrammarRightRGNFA = ToGrammarRightRG::RegistratorWrapper<grammar::RightRG, automaton::NFA>(ToGrammarRightRG::convert);
 
-grammar::RightRG ToGrammarRightRG::convert(const automaton::DFA& automaton) {
+grammar::RightRG ToGrammarRightRG::convert(const automaton::DFA<>& automaton) {
 	std::map<label::Label, alphabet::Symbol> nonterminalMap;
 
 	const label::Label& initState = automaton.getInitialState();
@@ -100,7 +100,7 @@ grammar::RightRG ToGrammarRightRG::convert(const automaton::DFA& automaton) {
 	return grammar;
 }
 
-auto ToGrammarRightRGDFA = ToGrammarRightRG::RegistratorWrapper<grammar::RightRG, automaton::DFA>(ToGrammarRightRG::convert);
+auto ToGrammarRightRGDFA = ToGrammarRightRG::RegistratorWrapper<grammar::RightRG, automaton::DFA<>>(ToGrammarRightRG::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/automaton/convert/ToGrammarRightRG.h b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
index ab57e4b43f..c74a9039ed 100644
--- a/alib2algo/src/automaton/convert/ToGrammarRightRG.h
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
@@ -33,7 +33,7 @@ public:
 	static grammar::RightRG convert(const automaton::Automaton& automaton);
 
 	static grammar::RightRG convert(const automaton::NFA& automaton);
-	static grammar::RightRG convert(const automaton::DFA& automaton);
+	static grammar::RightRG convert(const automaton::DFA<>& automaton);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp
index 37e615ce92..d9e398872c 100644
--- a/alib2algo/src/automaton/convert/ToRegExp.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExp.cpp
@@ -34,11 +34,11 @@ regexp::RegExp ToRegExp::convert(const automaton::NFA& automaton) {
 
 auto ToRegExpNFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::NFA>(ToRegExp::convert);
 
-regexp::RegExp ToRegExp::convert(const automaton::DFA& automaton) {
+regexp::RegExp ToRegExp::convert(const automaton::DFA<>& automaton) {
 	return regexp::RegExp(ToRegExpStateElimination::convert(automaton));
 }
 
-auto ToRegExpDFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::DFA>(ToRegExp::convert);
+auto ToRegExpDFA = ToRegExp::RegistratorWrapper<regexp::RegExp, automaton::DFA<>>(ToRegExp::convert);
 
 regexp::RegExp ToRegExp::convert(const automaton::ExtendedNFA& automaton) {
 	return regexp::RegExp(ToRegExpStateElimination::convert(automaton));
diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h
index a8a272a938..56e9dce86d 100644
--- a/alib2algo/src/automaton/convert/ToRegExp.h
+++ b/alib2algo/src/automaton/convert/ToRegExp.h
@@ -34,7 +34,7 @@ public:
 	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 DFA<>& automaton);
 	static regexp::RegExp convert(const ExtendedNFA& automaton);
 	static regexp::RegExp convert(const CompactNFA& automaton);
 };
diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
index b1c2292a16..8a476c1f93 100644
--- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
@@ -109,7 +109,7 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA & autom
 
 auto ToRegExpAlgebraicNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::NFA>(ToRegExpAlgebraic::convert);
 
-regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA & automaton ) {
+regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA<> & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -128,7 +128,7 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA & autom
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState() ) ) );
 }
 
-auto ToRegExpAlgebraicDFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::DFA>(ToRegExpAlgebraic::convert);
+auto ToRegExpAlgebraicDFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::DFA<>>(ToRegExpAlgebraic::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
index 92af901dff..602999ce8a 100644
--- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
@@ -41,7 +41,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::DFA& automaton);
+	static regexp::UnboundedRegExp convert(const automaton::DFA<>& automaton);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
index 9e5f17667e..cf9b6d5ffd 100644
--- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
@@ -49,7 +49,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 ToRegExpStateEliminationDFA = ToRegExpStateElimination::RegistratorWrapper<regexp::RegExp, automaton::DFA>(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.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp
index 6a46bd6835..6983eae4a6 100644
--- a/alib2algo/src/automaton/determinize/Determinize.cpp
+++ b/alib2algo/src/automaton/determinize/Determinize.cpp
@@ -29,11 +29,11 @@ automaton::Automaton Determinize::determinize(const automaton::Automaton& automa
 	return dispatch(automaton.getData());
 }
 
-DFA Determinize::determinize(const automaton::DFA& automaton) {
+DFA<> Determinize::determinize(const automaton::DFA<>& automaton) {
 	return automaton;
 }
 
-auto DeterminizeDFA = Determinize::RegistratorWrapper<automaton::DFA, automaton::DFA>(Determinize::determinize);
+auto DeterminizeDFA = Determinize::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(Determinize::determinize);
 
 DPDA Determinize::determinize(const automaton::DPDA& automaton) {
 	return automaton;
diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h
index 0bff365476..38008c28c9 100644
--- a/alib2algo/src/automaton/determinize/Determinize.h
+++ b/alib2algo/src/automaton/determinize/Determinize.h
@@ -31,9 +31,9 @@ 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::MultiInitialStateNFA& nfa);
+	static automaton::DFA<> determinize(const automaton::DFA<>& 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);
 	static automaton::SinglePopDPDA determinize(const automaton::SinglePopDPDA& dpda);
diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
index 5f0c8eff27..28bd6e1f47 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
@@ -16,10 +16,10 @@ namespace automaton {
 
 namespace determinize {
 
-automaton::DFA Determinize::determinize ( const automaton::MultiInitialStateNFA & nfa ) {
+automaton::DFA<> Determinize::determinize ( const automaton::MultiInitialStateNFA & nfa ) {
 	 // 1, 4
 	label::Label initialState ( createDFAState ( nfa.getInitialStates ( ) ) );
-	automaton::DFA res ( initialState );
+	automaton::DFA < > res ( initialState );
 
 	res.setInputAlphabet ( nfa.getInputAlphabet ( ) );
 
@@ -67,12 +67,12 @@ automaton::DFA Determinize::determinize ( const automaton::MultiInitialStateNFA
 	return res;
 }
 
-auto DeterminizeMultiInitialStateNFA = Determinize::RegistratorWrapper < automaton::DFA, automaton::MultiInitialStateNFA > ( Determinize::determinize );
+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 );
+	automaton::DFA < > res ( initialState );
 
 	res.setInputAlphabet ( nfa.getInputAlphabet ( ) );
 
@@ -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/properties/AllEpsilonClosure.cpp b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
index 8e2aafbea4..b550052a30 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
@@ -72,14 +72,14 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 
 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>> AllEpsilonClosure::allEpsilonClosure( const automaton::DFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> closure;
 	for(const label::Label& state : fsm.getStates())
 		closure[state].insert(state);
 	return closure;
 }
 
-auto AllEpsilonClosureDFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::DFA>(AllEpsilonClosure::allEpsilonClosure);
+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>> res;
diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.h b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
index fb2360bb68..812af0f6bc 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.h
@@ -30,7 +30,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::DFA & 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 83ea7bbf53..4f4d547d56 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
@@ -75,7 +75,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::NFA & fs
 
 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 ) {
+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");
 
 	std::set<label::Label> closure;
@@ -83,7 +83,7 @@ std::set<label::Label> EpsilonClosure::epsilonClosure( const automaton::DFA & fs
 	return closure;
 }
 
-auto EpsilonClosureDFA = EpsilonClosure::RegistratorWrapper<std::set<label::Label>, automaton::DFA>(EpsilonClosure::epsilonClosure);
+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 ) {
 	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 baa975592b..da079311a2 100644
--- a/alib2algo/src/automaton/properties/EpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.h
@@ -31,7 +31,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::DFA & 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 211d333d4e..aa71135b4b 100644
--- a/alib2algo/src/automaton/properties/ReachableStates.cpp
+++ b/alib2algo/src/automaton/properties/ReachableStates.cpp
@@ -85,7 +85,7 @@ std::set<label::Label> ReachableStates::reachableStates( const automaton::MultiI
 auto ReachableStatesMultiInitialStateNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA>(ReachableStates::reachableStates);
 
 template<>
-std::set<label::Label> ReachableStates::reachableStates( const automaton::DFA & fsm ) {
+std::set<label::Label> ReachableStates::reachableStates( const automaton::DFA < > & fsm ) {
 	// 1a
 	std::deque<std::set<label::Label>> Qi;
 	Qi.push_back( std::set<label::Label>( ) );
@@ -110,7 +110,7 @@ std::set<label::Label> ReachableStates::reachableStates( const automaton::DFA &
 	return Qi.at( i );
 }
 
-auto ReachableStatesDFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA>(ReachableStates::reachableStates);
+auto ReachableStatesDFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(ReachableStates::reachableStates);
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/automaton/properties/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp
index 31a74116a6..a78634424e 100644
--- a/alib2algo/src/automaton/properties/UsefullStates.cpp
+++ b/alib2algo/src/automaton/properties/UsefullStates.cpp
@@ -56,7 +56,7 @@ auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label
 auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA>(UsefullStates::usefullStates);
 
 template<>
-std::set<label::Label> UsefullStates::usefullStates( const automaton::DFA & fsm ) {
+std::set<label::Label> UsefullStates::usefullStates( const automaton::DFA < > & fsm ) {
 	// 1a
 	std::deque<std::set<label::Label>> Qi;
 	Qi.push_back( std::set<label::Label>( ) );
@@ -79,7 +79,7 @@ std::set<label::Label> UsefullStates::usefullStates( const automaton::DFA & fsm
 	return Qi.at( i );
 }
 
-auto UsefullStatesDFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA>(UsefullStates::usefullStates);
+auto UsefullStatesDFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(UsefullStates::usefullStates);
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp
index cddeed7df5..75b6579250 100644
--- a/alib2algo/src/automaton/run/Accept.cpp
+++ b/alib2algo/src/automaton/run/Accept.cpp
@@ -37,13 +37,13 @@ bool Accept::accept ( const automaton::Automaton & automaton, const tree::Ranked
 	return dispatch ( automaton.getData ( ), tree );
 }
 
-bool Accept::accept ( const automaton::DFA & automaton, const string::LinearString & string ) {
+bool Accept::accept ( const automaton::DFA<> & automaton, const string::LinearString & string ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, string );
 
 	return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) );
 }
 
-auto AcceptDFALinearString = Accept::RegistratorWrapper < bool, automaton::DFA, string::LinearString > ( Accept::accept );
+auto AcceptDFALinearString = Accept::RegistratorWrapper < bool, automaton::DFA<>, string::LinearString > ( Accept::accept );
 
 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 );
diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h
index 06b0edb4cb..4ba048d2b4 100644
--- a/alib2algo/src/automaton/run/Accept.h
+++ b/alib2algo/src/automaton/run/Accept.h
@@ -29,7 +29,7 @@ public:
 	static bool accept ( const automaton::Automaton & automaton, const string::LinearString & string );
 	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::DFA<> & 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 );
diff --git a/alib2algo/src/automaton/run/Occurrences.cpp b/alib2algo/src/automaton/run/Occurrences.cpp
index 46e99ccfe4..311a7b55e5 100644
--- a/alib2algo/src/automaton/run/Occurrences.cpp
+++ b/alib2algo/src/automaton/run/Occurrences.cpp
@@ -33,13 +33,13 @@ std::set < unsigned > Occurrences::occurrences ( const automaton::Automaton & au
 	return dispatch ( automaton.getData ( ), tree );
 }
 
-std::set < unsigned > Occurrences::occurrences ( const automaton::DFA & automaton, const string::LinearString & string ) {
+std::set < unsigned > Occurrences::occurrences ( const automaton::DFA < > & automaton, const string::LinearString & string ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, string );
 
 	return std::get < 2 > ( res );
 }
 
-auto OccurrencesDFALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFA, string::LinearString > ( Occurrences::occurrences );
+auto OccurrencesDFALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFA<>, string::LinearString > ( Occurrences::occurrences );
 
 std::set < unsigned > Occurrences::occurrences ( 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/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h
index 7e3e290e92..c89fcad4c3 100644
--- a/alib2algo/src/automaton/run/Occurrences.h
+++ b/alib2algo/src/automaton/run/Occurrences.h
@@ -29,7 +29,7 @@ public:
 	static std::set < unsigned > occurrences ( const automaton::Automaton & automaton, const string::LinearString & string );
 	static std::set < unsigned > occurrences ( const automaton::Automaton & automaton, const tree::RankedTree & string );
 
-	static std::set < unsigned > occurrences ( const automaton::DFA & automaton, const string::LinearString & string );
+	static std::set < unsigned > occurrences ( const automaton::DFA<> & automaton, const string::LinearString & string );
 	static std::set < unsigned > occurrences ( const automaton::DFTA & automaton, const tree::RankedTree & tree );
 	static std::set < unsigned > occurrences ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string );
 	static std::set < unsigned > occurrences ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string );
diff --git a/alib2algo/src/automaton/run/Result.cpp b/alib2algo/src/automaton/run/Result.cpp
index 9170f99d5d..bca3759288 100644
--- a/alib2algo/src/automaton/run/Result.cpp
+++ b/alib2algo/src/automaton/run/Result.cpp
@@ -25,7 +25,7 @@ label::Label Result::result ( const automaton::Automaton & automaton, const alib
 	return dispatch ( automaton.getData ( ), object.getData ( ), failLabel );
 }
 
-label::Label Result::result ( const automaton::DFA & automaton, const string::LinearString & string, const label::Label & failLabel ) {
+label::Label Result::result ( const automaton::DFA < > & automaton, const string::LinearString & string, const label::Label & failLabel ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, string );
 
 	if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res );
@@ -33,7 +33,7 @@ label::Label Result::result ( const automaton::DFA & automaton, const string::Li
 	return failLabel;
 }
 
-auto ResultDFALinearString = Result::RegistratorWrapper < label::Label, automaton::DFA, string::LinearString > ( Result::result );
+auto ResultDFALinearString = Result::RegistratorWrapper < label::Label, automaton::DFA<>, string::LinearString > ( Result::result );
 
 label::Label Result::result ( const automaton::DFTA & automaton, const tree::RankedTree & tree, const label::Label & failLabel ) {
 	std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree );
diff --git a/alib2algo/src/automaton/run/Result.h b/alib2algo/src/automaton/run/Result.h
index 88751a71d8..b8b7f765ee 100644
--- a/alib2algo/src/automaton/run/Result.h
+++ b/alib2algo/src/automaton/run/Result.h
@@ -29,7 +29,7 @@ public:
 	 */
 	static label::Label result ( const automaton::Automaton & automaton, const alib::Object & object, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 
-	static label::Label result ( const automaton::DFA & automaton, const string::LinearString & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
+	static label::Label result ( const automaton::DFA < > & automaton, const string::LinearString & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 	static label::Label result ( const automaton::DFTA & automaton, const tree::RankedTree & tree, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 	static label::Label result ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
 	static label::Label result ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string, const label::Label & failLabel = label::FailStateLabel::FAIL_STATE_LABEL );
diff --git a/alib2algo/src/automaton/run/Run.cpp b/alib2algo/src/automaton/run/Run.cpp
index 14f3161911..9a7baca9a1 100644
--- a/alib2algo/src/automaton/run/Run.cpp
+++ b/alib2algo/src/automaton/run/Run.cpp
@@ -29,7 +29,7 @@ namespace run {
 
 // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-std::tuple < bool, label::Label, std::set < unsigned > > Run::calculateState ( const automaton::DFA & automaton, const string::LinearString & string ) {
+std::tuple < bool, label::Label, std::set < unsigned > > Run::calculateState ( const automaton::DFA < > & 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 c1e73197e2..d33826dc04 100644
--- a/alib2algo/src/automaton/run/Run.h
+++ b/alib2algo/src/automaton/run/Run.h
@@ -25,7 +25,7 @@ class Run {
 	static bool canPop ( const std::deque < alphabet::Symbol > & pushdownStore, const std::vector < alphabet::Symbol > & pop );
 
 public:
-	static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFA & automaton, const string::LinearString & string );
+	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, 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 );
diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp
index 83c32406c1..628d879011 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.cpp
@@ -13,11 +13,11 @@ namespace automaton {
 
 namespace simplify {
 
-automaton::DFA EpsilonRemoverIncoming::remove(const automaton::DFA& origFSM) {
+automaton::DFA<> EpsilonRemoverIncoming::remove(const automaton::DFA<>& origFSM) {
 	return origFSM;
 }
 
-auto EpsilonRemoverIncomingDFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::DFA, automaton::DFA>(EpsilonRemoverIncoming::remove);
+auto EpsilonRemoverIncomingDFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(EpsilonRemoverIncoming::remove);
 
 automaton::MultiInitialStateNFA EpsilonRemoverIncoming::remove(const automaton::MultiInitialStateNFA& origFSM) {
 	return origFSM;
diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h
index 4204bf9396..71476397ed 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverIncoming.h
@@ -30,7 +30,7 @@ public:
 	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::DFA remove( const automaton::DFA & 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 4cf712b895..8bf1155e3a 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.cpp
@@ -13,11 +13,11 @@ namespace automaton {
 
 namespace simplify {
 
-automaton::DFA EpsilonRemoverOutgoing::remove(const automaton::DFA& origFSM) {
+automaton::DFA<> EpsilonRemoverOutgoing::remove(const automaton::DFA<>& origFSM) {
 	return origFSM;
 }
 
-auto EpsilonRemoverOutgoingDFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::DFA, automaton::DFA>(EpsilonRemoverOutgoing::remove);
+auto EpsilonRemoverOutgoingDFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(EpsilonRemoverOutgoing::remove);
 
 automaton::MultiInitialStateNFA EpsilonRemoverOutgoing::remove(const automaton::MultiInitialStateNFA& origFSM) {
 	return origFSM;
diff --git a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h
index 46aab269d6..e6b6adff4d 100644
--- a/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h
+++ b/alib2algo/src/automaton/simplify/EpsilonRemoverOutgoing.h
@@ -30,7 +30,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::DFA remove( const automaton::DFA & fsm );
+	static automaton::DFA<> remove( const automaton::DFA<> & fsm );
 };
 
 } /* namespace simplify */
diff --git a/alib2algo/src/automaton/simplify/Minimize.cpp b/alib2algo/src/automaton/simplify/Minimize.cpp
index f4027e87c3..8b51f0729d 100644
--- a/alib2algo/src/automaton/simplify/Minimize.cpp
+++ b/alib2algo/src/automaton/simplify/Minimize.cpp
@@ -24,9 +24,9 @@ automaton::Automaton Minimize::minimize(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
 }
 
-automaton::DFA Minimize::minimize(const automaton::DFA& dfa) {
+automaton::DFA<> Minimize::minimize(const automaton::DFA<>& dfa) {
 	if(dfa.getFinalStates().size() == 0) {
-		automaton::DFA result(dfa.getInitialState());
+		automaton::DFA < > result(dfa.getInitialState());
 		result.setInputAlphabet(dfa.getInputAlphabet());
 		return result;
 	}
@@ -112,7 +112,7 @@ automaton::DFA Minimize::minimize(const automaton::DFA& dfa) {
 		}
 	}
 
-	automaton::DFA result(*initialState);
+	automaton::DFA<> result(*initialState);
 
 	result.setInputAlphabet(dfa.getInputAlphabet());
 
@@ -134,7 +134,7 @@ automaton::DFA Minimize::minimize(const automaton::DFA& dfa) {
 
 #define RESETSS(x) {(x).clear(); (x).str("");}
 
-void Minimize::print_progress(const automaton::DFA& dfa, const std::map<std::pair<label::Label, std::set<std::pair<alphabet::Symbol, label::Label> > >, std::set<label::Label> >& minimizedTransitionFunction, size_t iter) {
+void Minimize::print_progress(const automaton::DFA<>& dfa, const std::map<std::pair<label::Label, std::set<std::pair<alphabet::Symbol, label::Label> > >, std::set<label::Label> >& minimizedTransitionFunction, size_t iter) {
 	std::clog << "delta " << iter << std::endl;
 
 	//std::map<std::pair<label::Label, std::set<std::pair<alphabet::Symbol, label::Label> > >, std::set<label::Label> > minimizedTransitionFunction1; //mapped to the original state
@@ -219,7 +219,7 @@ void Minimize::print_progress(const automaton::DFA& dfa, const std::map<std::pai
 	std::clog << std::endl;
 }
 
-auto MinimizeNFA = Minimize::RegistratorWrapper<automaton::DFA, automaton::DFA>( Minimize::minimize );
+auto MinimizeNFA = Minimize::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>( Minimize::minimize );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/Minimize.h b/alib2algo/src/automaton/simplify/Minimize.h
index a9453cf77e..953ddf2b69 100644
--- a/alib2algo/src/automaton/simplify/Minimize.h
+++ b/alib2algo/src/automaton/simplify/Minimize.h
@@ -23,10 +23,10 @@ public:
 	 */
 	static automaton::Automaton minimize(const automaton::Automaton& dfa);
 
-	static automaton::DFA minimize(const automaton::DFA& dfa);
+	static automaton::DFA<> minimize(const automaton::DFA<>& dfa);
 
 private:
-	static void print_progress(const automaton::DFA& dfa, const std::map<std::pair<label::Label, std::set<std::pair<alphabet::Symbol, label::Label> > >, std::set<label::Label> >& minimizedTransitionFunction, size_t iter);
+	static void print_progress(const automaton::DFA<>& dfa, const std::map<std::pair<label::Label, std::set<std::pair<alphabet::Symbol, label::Label> > >, std::set<label::Label> >& minimizedTransitionFunction, size_t iter);
 };
 
 } /* namespace simplify */
diff --git a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp
index 6f985c73fb..650964aae0 100644
--- a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp
+++ b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.cpp
@@ -21,17 +21,17 @@ automaton::Automaton MinimizeBrzozowski::minimize(const automaton::Automaton& au
 	return dispatch(automaton.getData());
 }
 
-automaton::DFA MinimizeBrzozowski::minimize(const automaton::DFA& dfa) {
+automaton::DFA<> MinimizeBrzozowski::minimize(const automaton::DFA<>& dfa) {
 	return automaton::determinize::Determinize::determinize(automaton::transform::Reverse::convert(automaton::determinize::Determinize::determinize(automaton::transform::Reverse::convert(dfa))));
 }
 
-auto MinimizeBrzozowskiDFA = MinimizeBrzozowski::RegistratorWrapper<automaton::DFA, automaton::DFA>(MinimizeBrzozowski::minimize);
+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 1ee939df14..50477c27d8 100644
--- a/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h
+++ b/alib2algo/src/automaton/simplify/MinimizeBrzozowski.h
@@ -24,8 +24,8 @@ 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::DFA<>& dfa);
+	static automaton::DFA<> minimize(const automaton::NFA& nfa);
 };
 
 } /* namespace simplify */
diff --git a/alib2algo/src/automaton/simplify/Normalize.cpp b/alib2algo/src/automaton/simplify/Normalize.cpp
index 106a4c753f..483178145f 100644
--- a/alib2algo/src/automaton/simplify/Normalize.cpp
+++ b/alib2algo/src/automaton/simplify/Normalize.cpp
@@ -25,7 +25,7 @@ automaton::Automaton Normalize::normalize(const automaton::Automaton& automaton)
 	return dispatch(automaton.getData());
 }
 
-automaton::DFA Normalize::normalize(const automaton::DFA& fsm) {
+automaton::DFA<> Normalize::normalize(const automaton::DFA<>& fsm) {
 	int counter = 0;
 	std::map<label::Label, int > normalizationData;
 	std::deque<label::Label > processingData;
@@ -52,7 +52,7 @@ automaton::DFA Normalize::normalize(const automaton::DFA& fsm) {
 		throw exception::CommonException("Automaton normalize require minimal deterministic finite automaton");
 	}
 
-	automaton::DFA result(label::labelFrom(normalizationData.find(fsm.getInitialState())->second));
+	automaton::DFA<> result(label::labelFrom(normalizationData.find(fsm.getInitialState())->second));
 
 	result.setInputAlphabet(fsm.getInputAlphabet());
 
@@ -71,7 +71,7 @@ automaton::DFA Normalize::normalize(const automaton::DFA& fsm) {
 	return result;
 }
 
-auto NormalizeDFA = Normalize::RegistratorWrapper<automaton::DFA, automaton::DFA>(Normalize::normalize);
+auto NormalizeDFA = Normalize::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(Normalize::normalize);
 
 automaton::DPDA Normalize::normalize(const automaton::DPDA& pda) {
 	int counterState = 0;
diff --git a/alib2algo/src/automaton/simplify/Normalize.h b/alib2algo/src/automaton/simplify/Normalize.h
index f50df2e1eb..7b6d75d51b 100644
--- a/alib2algo/src/automaton/simplify/Normalize.h
+++ b/alib2algo/src/automaton/simplify/Normalize.h
@@ -24,7 +24,7 @@ public:
 	 */
 	static automaton::Automaton normalize(const automaton::Automaton& dfa);
 
-	static automaton::DFA normalize(const automaton::DFA& dfa);
+	static automaton::DFA<> normalize(const automaton::DFA<>& dfa);
 	static automaton::DPDA normalize(const automaton::DPDA& dfa);
 };
 
diff --git a/alib2algo/src/automaton/simplify/Rename.cpp b/alib2algo/src/automaton/simplify/Rename.cpp
index 38548a0b0d..7066d5783a 100644
--- a/alib2algo/src/automaton/simplify/Rename.cpp
+++ b/alib2algo/src/automaton/simplify/Rename.cpp
@@ -27,7 +27,7 @@ automaton::Automaton Rename::rename(const automaton::Automaton& automaton) {
 	return dispatch(automaton.getData());
 }
 
-automaton::DFA Rename::rename(const automaton::DFA& fsm) {
+automaton::DFA<> Rename::rename(const automaton::DFA<>& fsm) {
 	int counter = 0;
 	std::map<label::Label, int > renamingData;
 
@@ -35,7 +35,7 @@ automaton::DFA Rename::rename(const automaton::DFA& fsm) {
 		renamingData.insert(std::make_pair(*iter, counter++));
 	}
 
-	automaton::DFA result(label::labelFrom(renamingData.find(fsm.getInitialState())->second));
+	automaton::DFA<> result(label::labelFrom(renamingData.find(fsm.getInitialState())->second));
 
 	result.setInputAlphabet(fsm.getInputAlphabet());
 
@@ -54,7 +54,7 @@ automaton::DFA Rename::rename(const automaton::DFA& fsm) {
 	return result;
 }
 
-auto RenameDFA = Rename::RegistratorWrapper<automaton::DFA, automaton::DFA>(Rename::rename);
+auto RenameDFA = Rename::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(Rename::rename);
 
 automaton::DPDA Rename::rename(const automaton::DPDA& pda) {
 	int counterState = 0;
diff --git a/alib2algo/src/automaton/simplify/Rename.h b/alib2algo/src/automaton/simplify/Rename.h
index 6e9ae94d4f..906ef95315 100644
--- a/alib2algo/src/automaton/simplify/Rename.h
+++ b/alib2algo/src/automaton/simplify/Rename.h
@@ -28,7 +28,7 @@ public:
 	 */
 	static automaton::Automaton rename(const automaton::Automaton& dfa);
 
-	static automaton::DFA rename(const automaton::DFA& dfa);
+	static automaton::DFA<> rename(const automaton::DFA<>& dfa);
 	static automaton::DPDA rename(const automaton::DPDA& pda);
 	static automaton::SinglePopDPDA rename(const automaton::SinglePopDPDA& pda);
 	static automaton::InputDrivenDPDA rename(const automaton::InputDrivenDPDA& pda);
diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
index 452cd555b9..a1192e1f2f 100644
--- a/alib2algo/src/automaton/simplify/SingleInitialState.cpp
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
@@ -65,11 +65,11 @@ automaton::NFA SingleInitialState::convert(const automaton::MultiInitialStateNFA
 
 auto SingleInitialStateMultiInitialStateNFA = SingleInitialState::RegistratorWrapper<automaton::NFA, automaton::MultiInitialStateNFA>(SingleInitialState::convert);
 
-automaton::DFA SingleInitialState::convert(const automaton::DFA& automaton) {
+automaton::DFA<> SingleInitialState::convert(const automaton::DFA<>& automaton) {
 	return automaton;
 }
 
-auto SingleInitialStateDFA = SingleInitialState::RegistratorWrapper<automaton::DFA, automaton::DFA>(SingleInitialState::convert);
+auto SingleInitialStateDFA = SingleInitialState::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(SingleInitialState::convert);
 
 automaton::EpsilonNFA SingleInitialState::convert(const automaton::EpsilonNFA& automaton) {
 	return automaton;
diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h
index 83e942c55f..81107c5f1e 100644
--- a/alib2algo/src/automaton/simplify/SingleInitialState.h
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.h
@@ -29,7 +29,7 @@ public:
 
 	static automaton::NFA convert(const automaton::MultiInitialStateNFA& automaton);
 
-	static automaton::DFA convert(const automaton::DFA& automaton);
+	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);
diff --git a/alib2algo/src/automaton/simplify/Total.cpp b/alib2algo/src/automaton/simplify/Total.cpp
index 34c3244647..7d2c47899f 100644
--- a/alib2algo/src/automaton/simplify/Total.cpp
+++ b/alib2algo/src/automaton/simplify/Total.cpp
@@ -43,8 +43,8 @@ automaton::NFA Total::total(const automaton::NFA& automaton) {
 
 auto TotalNFA = Total::RegistratorWrapper<automaton::NFA, automaton::NFA>(Total::total);
 
-automaton::DFA Total::total(const automaton::DFA& automaton) {
-	automaton::DFA res(automaton);
+automaton::DFA < > Total::total(const automaton::DFA < > & automaton) {
+	automaton::DFA < > res(automaton);
 	label::Label nullState = label::createUniqueLabel(label::FailStateLabel::FAIL_STATE_LABEL, automaton.getStates());
 	res.addState(nullState);
 
@@ -59,7 +59,7 @@ automaton::DFA Total::total(const automaton::DFA& automaton) {
 	return res;
 }
 
-auto TotalDFA = Total::RegistratorWrapper<automaton::DFA, automaton::DFA>(Total::total);
+auto TotalDFA = Total::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(Total::total);
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/Total.h b/alib2algo/src/automaton/simplify/Total.h
index 0c1e20d1cb..3a53351c03 100644
--- a/alib2algo/src/automaton/simplify/Total.h
+++ b/alib2algo/src/automaton/simplify/Total.h
@@ -28,7 +28,7 @@ public:
 	static automaton::Automaton total(const automaton::Automaton& automaton);
 
 	static automaton::NFA total(const automaton::NFA& automaton);
-	static automaton::DFA total(const automaton::DFA& automaton);
+	static automaton::DFA<> total(const automaton::DFA<>& automaton);
 };
 
 } /* namespace simplify */
diff --git a/alib2algo/src/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp
index b70cabf558..8cdac15eba 100644
--- a/alib2algo/src/automaton/simplify/Trim.cpp
+++ b/alib2algo/src/automaton/simplify/Trim.cpp
@@ -24,7 +24,7 @@ T Trim::trim( const T & fsm ) {
 	return UnreachableStatesRemover::remove(UselessStatesRemover::remove(fsm));
 }
 
-auto TrimDFA = Trim::RegistratorWrapper<automaton::DFA, automaton::DFA>(Trim::trim);
+auto TrimDFA = Trim::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(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);
diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
index 99583b4d46..c47b55b71d 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
@@ -53,12 +53,12 @@ auto UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorW
 auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove);
 
 template<>
-automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) {
+automaton::DFA<> UnreachableStatesRemover::remove( const automaton::DFA<> & fsm ) {
 	// 1a
 	std::set<label::Label> Qa = automaton::properties::ReachableStates::reachableStates( fsm );
 
 	// 2
-	automaton::DFA M(fsm.getInitialState() );
+	automaton::DFA<> M(fsm.getInitialState() );
 
 	for( const auto & q : Qa )
 		M.addState( q );
@@ -78,7 +78,7 @@ automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) {
 	return M;
 }
 
-auto UnreachableStatesRemoverDFA = UnreachableStatesRemover::RegistratorWrapper<automaton::DFA, automaton::DFA>(UnreachableStatesRemover::remove);
+auto UnreachableStatesRemoverDFA = UnreachableStatesRemover::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(UnreachableStatesRemover::remove);
 
 template<>
 automaton::MultiInitialStateNFA UnreachableStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) {
diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
index cd0d67ba0b..3468a68293 100644
--- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
@@ -54,12 +54,12 @@ auto UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<a
 auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove);
 
 template<>
-automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) {
+automaton::DFA<> UselessStatesRemover::remove( const automaton::DFA<> & fsm ) {
 	// 1.
 	std::set<label::Label> Qu = automaton::properties::UsefullStates::usefullStates( fsm );
 
 	// 2.
-	automaton::DFA M ( fsm.getInitialState () );
+	automaton::DFA<> M ( fsm.getInitialState () );
 
 	for( const auto & a : fsm.getInputAlphabet( ) )
 		M.addInputSymbol( a );
@@ -81,7 +81,7 @@ automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) {
 	return M;
 }
 
-auto UselessStatesRemoverDFA = UselessStatesRemover::RegistratorWrapper<automaton::DFA, automaton::DFA>(UselessStatesRemover::remove);
+auto UselessStatesRemoverDFA = UselessStatesRemover::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(UselessStatesRemover::remove);
 
 template<>
 automaton::MultiInitialStateNFA UselessStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) {
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
index 8cbf236c71..896e3e5184 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
+++ b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
@@ -67,7 +67,7 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::NFA& first,
 
 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()));
 
@@ -107,7 +107,7 @@ automaton::NFA AutomataConcatenation::concatenation(const automaton::DFA& first,
 	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 fc8f028b69..9565fb7655 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenation.h
+++ b/alib2algo/src/automaton/transform/AutomataConcatenation.h
@@ -24,7 +24,7 @@ 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::DFA<>& first, const automaton::DFA<>& second);
 	static automaton::NFA concatenation(const automaton::NFA& first, const automaton::NFA& second);
 };
 
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
index 30394ac844..c99c519273 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
@@ -20,7 +20,7 @@ automaton::Automaton AutomataConcatenationEpsilonTransition::concatenation(const
 	return dispatch(first.getData(), second.getData());
 }
 
-automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::DFA& first, const automaton::DFA& second) {
+automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::DFA<>& first, const automaton::DFA<>& second) {
 	automaton::EpsilonNFA res(pairLabel(label::labelFrom(AUTOMATON_FIRST), first.getInitialState()));
 
 	for(const auto& symbol : first.getInputAlphabet())
@@ -48,7 +48,7 @@ automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(cons
 	return res;
 }
 
-auto AutomataConcatenationEpsilonTransitionDFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA>(AutomataConcatenationEpsilonTransition::concatenation);
+auto AutomataConcatenationEpsilonTransitionDFA = AutomataConcatenationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA<>>(AutomataConcatenationEpsilonTransition::concatenation);
 
 automaton::EpsilonNFA AutomataConcatenationEpsilonTransition::concatenation(const automaton::NFA& first, const automaton::NFA& 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 544c676556..0e94683dbd 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
+++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
@@ -24,7 +24,7 @@ class AutomataConcatenationEpsilonTransition : public std::PromotingDoubleDispat
 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::DFA<>& first, const automaton::DFA<>& 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 f8fbb979f9..8e2766b0b2 100644
--- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
+++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
@@ -19,9 +19,9 @@ automaton::Automaton AutomataIntersectionCartesianProduct::intersection(const au
 	return dispatch(first.getData(), second.getData());
 }
 
-automaton::DFA AutomataIntersectionCartesianProduct::intersection(const automaton::DFA& first, const automaton::DFA& second) {
+automaton::DFA<> AutomataIntersectionCartesianProduct::intersection(const automaton::DFA<>& first, const automaton::DFA<>& second) {
 	label::Label q0(pairLabel(first.getInitialState(), second.getInitialState()));
-	automaton::DFA res(q0);
+	automaton::DFA<> res(q0);
 
 	for(const auto& a : first.getInputAlphabet())
 		res.addInputSymbol(a);
@@ -49,7 +49,7 @@ automaton::DFA AutomataIntersectionCartesianProduct::intersection(const automato
 	return res;
 }
 
-auto AutomataIntersectionCartesianProductDFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::DFA, automaton::DFA>(AutomataIntersectionCartesianProduct::intersection);
+auto AutomataIntersectionCartesianProductDFA = AutomataIntersectionCartesianProduct::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(AutomataIntersectionCartesianProduct::intersection);
 
 automaton::NFA AutomataIntersectionCartesianProduct::intersection(const automaton::NFA& first, const automaton::NFA& second) {
 	label::Label q0(pairLabel(first.getInitialState(), second.getInitialState()));
diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
index 8c7a394f08..2a2e3d710b 100644
--- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
+++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
@@ -25,7 +25,7 @@ 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::DFA intersection(const automaton::DFA& first, const automaton::DFA& second);
+	static automaton::DFA<> intersection(const automaton::DFA<>& first, const automaton::DFA<>& second);
 };
 
 } /* namespace transform */
diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
index 843522a595..568a5aec24 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
+++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
@@ -20,12 +20,12 @@ automaton::Automaton AutomataUnionCartesianProduct::unification(const automaton:
 	return dispatch(first.getData(), second.getData());
 }
 
-automaton::DFA AutomataUnionCartesianProduct::unification(const automaton::DFA& first, const automaton::DFA& second) {
+automaton::DFA<> AutomataUnionCartesianProduct::unification(const automaton::DFA<>& first, const automaton::DFA<>& 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::DFA res(q0);
+	automaton::DFA<> res(q0);
 
 	for(const auto& a : first.getInputAlphabet())
 		res.addInputSymbol(a);
@@ -57,7 +57,7 @@ automaton::DFA AutomataUnionCartesianProduct::unification(const automaton::DFA&
 	return res;
 }
 
-auto AutomataUnionCartesianProductDFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::DFA, automaton::DFA>(AutomataUnionCartesianProduct::unification);
+auto AutomataUnionCartesianProductDFA = AutomataUnionCartesianProduct::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(AutomataUnionCartesianProduct::unification);
 
 automaton::NFA AutomataUnionCartesianProduct::unification(const automaton::NFA& first, const automaton::NFA& second) {
 	if(!first.isTotal() || !second.isTotal())
diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
index 069e17345b..55c7ad7ef2 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
+++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
@@ -25,7 +25,7 @@ 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::DFA unification(const automaton::DFA& first, const automaton::DFA& second);
+	static automaton::DFA<> unification(const automaton::DFA<>& first, const automaton::DFA<>& second);
 };
 
 } /* namespace transform */
diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
index 48b69b3fa7..c2cd21913c 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
@@ -98,7 +98,7 @@ automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automato
 
 auto AutomataUnionEpsilonTransitionNFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomataUnionEpsilonTransition::unification);
 
-automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::DFA& first, const automaton::DFA& second) {
+automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automaton::DFA<>& first, const automaton::DFA<>& second) {
 	std::set<label::Label> states;
 	for(const auto& q : first.getStates())
 		states.insert(pairLabel(label::labelFrom(AUTOMATON_FIRST), q));
@@ -133,7 +133,7 @@ automaton::EpsilonNFA AutomataUnionEpsilonTransition::unification(const automato
 	return res;
 }
 
-auto AutomataUnionEpsilonTransitionDFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA>(AutomataUnionEpsilonTransition::unification);
+auto AutomataUnionEpsilonTransitionDFA = AutomataUnionEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA<>>(AutomataUnionEpsilonTransition::unification);
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
index bde7599945..e0081c530b 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
+++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
@@ -26,7 +26,7 @@ public:
 
 	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::DFA& first, const automaton::DFA& 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 1db8c9ce10..186451ee0c 100644
--- a/alib2algo/src/automaton/transform/AutomatonIteration.cpp
+++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp
@@ -27,7 +27,7 @@ automaton::NFA AutomatonIteration::iteration(const T& automaton) {
 	return res;
 }
 
-auto AutomatonIterationDFA = AutomatonIteration::RegistratorWrapper<automaton::NFA, automaton::DFA>(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/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
index 5688efff85..c402171e1e 100644
--- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
@@ -26,7 +26,7 @@ automaton::EpsilonNFA AutomatonIterationEpsilonTransition::iteration(const T& au
 	return res;
 }
 
-auto AutomatonIterationEpsilonTransitionDFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA>(AutomatonIterationEpsilonTransition::iteration);
+auto AutomatonIterationEpsilonTransitionDFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::DFA<>>(AutomatonIterationEpsilonTransition::iteration);
 auto AutomatonIterationEpsilonTransitionNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::NFA>(AutomatonIterationEpsilonTransition::iteration);
 auto AutomatonIterationEpsilonTransitionEpsilonNFA = AutomatonIterationEpsilonTransition::RegistratorWrapper<automaton::EpsilonNFA, automaton::EpsilonNFA>(AutomatonIterationEpsilonTransition::iteration);
 
diff --git a/alib2algo/src/automaton/transform/Compaction.cpp b/alib2algo/src/automaton/transform/Compaction.cpp
index eae4517f47..7da004598d 100644
--- a/alib2algo/src/automaton/transform/Compaction.cpp
+++ b/alib2algo/src/automaton/transform/Compaction.cpp
@@ -27,7 +27,7 @@ automaton::CompactNFA Compaction::convert(const automaton::CompactNFA& automaton
 
 auto CompactionCompactNFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::CompactNFA>(Compaction::convert);
 
-automaton::CompactNFA Compaction::convert(const automaton::DFA& automaton) {
+automaton::CompactNFA Compaction::convert(const automaton::DFA<>& automaton) {
 	automaton::CompactNFA res(automaton.getInitialState());
 	res.setInputAlphabet(automaton.getInputAlphabet());
 
@@ -73,7 +73,7 @@ automaton::CompactNFA Compaction::convert(const automaton::DFA& automaton) {
 	return res;
 }
 
-auto CompactionDFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::DFA>(Compaction::convert);
+auto CompactionDFA = Compaction::RegistratorWrapper<automaton::CompactNFA, automaton::DFA<>>(Compaction::convert);
 
 automaton::CompactNFA Compaction::convert(const automaton::NFA& automaton) {
 	automaton::CompactNFA res(automaton.getInitialState());
diff --git a/alib2algo/src/automaton/transform/Compaction.h b/alib2algo/src/automaton/transform/Compaction.h
index 15891fb572..65b2e0e68f 100644
--- a/alib2algo/src/automaton/transform/Compaction.h
+++ b/alib2algo/src/automaton/transform/Compaction.h
@@ -21,7 +21,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::DFA<>& 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 8d3e836bd9..31065696b0 100644
--- a/alib2algo/src/automaton/transform/Reverse.cpp
+++ b/alib2algo/src/automaton/transform/Reverse.cpp
@@ -20,7 +20,7 @@ automaton::Automaton Reverse::convert(const Automaton& automaton) {
 	return dispatch(automaton.getData());
 }
 
-automaton::MultiInitialStateNFA Reverse::convert(const automaton::DFA& automaton) {
+automaton::MultiInitialStateNFA Reverse::convert(const automaton::DFA<>& automaton) {
 	automaton::MultiInitialStateNFA res;
 
 	res.setStates(automaton.getStates());
@@ -34,7 +34,7 @@ automaton::MultiInitialStateNFA Reverse::convert(const automaton::DFA& automaton
 	return res;
 }
 
-auto ReverseDFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::DFA>(Reverse::convert);
+auto ReverseDFA = Reverse::RegistratorWrapper<automaton::MultiInitialStateNFA, automaton::DFA<>>(Reverse::convert);
 
 automaton::MultiInitialStateNFA Reverse::convert(const automaton::NFA& automaton) {
 	automaton::MultiInitialStateNFA res;
diff --git a/alib2algo/src/automaton/transform/Reverse.h b/alib2algo/src/automaton/transform/Reverse.h
index 8b5b0dc5b5..d984479c7b 100644
--- a/alib2algo/src/automaton/transform/Reverse.h
+++ b/alib2algo/src/automaton/transform/Reverse.h
@@ -18,7 +18,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::DFA<>& automaton);
 	static automaton::MultiInitialStateNFA convert(const automaton::NFA& automaton);
 	static automaton::MultiInitialStateNFA convert(const automaton::MultiInitialStateNFA& automaton);
 
diff --git a/alib2algo/src/grammar/parsing/LR0Parser.cpp b/alib2algo/src/grammar/parsing/LR0Parser.cpp
index 9aca513ec5..195845853a 100644
--- a/alib2algo/src/grammar/parsing/LR0Parser.cpp
+++ b/alib2algo/src/grammar/parsing/LR0Parser.cpp
@@ -68,7 +68,7 @@ LR0Items LR0Parser::getNextStateItems ( LR0Items items, alphabet::Symbol symbol,
 	return getClosure ( transitionItems, originalGrammar );
 }
 
-automaton::DFA LR0Parser::getAutomaton ( grammar::CFG originalGrammar ) {
+automaton::DFA<> LR0Parser::getAutomaton ( grammar::CFG originalGrammar ) {
 	grammar::CFG augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar );
 	alphabet::Symbol initialSymbol = augmentedGrammar.getInitialSymbol ( );
 	const std::map < alphabet::Symbol, std::set < std::vector < alphabet::Symbol > > > & rules = augmentedGrammar.getRules ( );
@@ -78,7 +78,7 @@ automaton::DFA LR0Parser::getAutomaton ( grammar::CFG originalGrammar ) {
 
 	label::Label initialState ( label::LR0ItemsLabel ( getClosure ( initialItems, augmentedGrammar ) ) );
 
-	automaton::DFA lr0Automaton ( initialState );
+	automaton::DFA<> lr0Automaton ( initialState );
 	lr0Automaton.addInputSymbols ( augmentedGrammar.getNonterminalAlphabet ( ) );
 	lr0Automaton.addInputSymbols ( augmentedGrammar.getTerminalAlphabet ( ) );
 
diff --git a/alib2algo/src/grammar/parsing/LR0Parser.h b/alib2algo/src/grammar/parsing/LR0Parser.h
index e98fa8a66e..84087d677e 100644
--- a/alib2algo/src/grammar/parsing/LR0Parser.h
+++ b/alib2algo/src/grammar/parsing/LR0Parser.h
@@ -22,7 +22,7 @@ public:
 
 	static LR0Items getNextStateItems ( LR0Items items, alphabet::Symbol symbol, grammar::CFG originalGrammar );
 
-	static automaton::DFA getAutomaton ( grammar::CFG originalGrammar );
+	static automaton::DFA<> getAutomaton ( grammar::CFG originalGrammar );
 };
 
 } /* namespace parsing */
diff --git a/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp b/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp
index d9cfd50210..a23c3c3c38 100644
--- a/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp
+++ b/alib2algo/src/grammar/parsing/SLR1ParseTable.cpp
@@ -28,7 +28,7 @@ void SLR1ParseTable::insertToActionTable ( LRActionTable & actionTable, LRAction
 LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG originalGrammar ) {
 	LRActionTable actionTable;
 	grammar::CFG augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar );
-	automaton::DFA parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar );
+	automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar );
 	for ( const label::Label & state : parsingAutomaton.getStates ( ) ) {
 		LR0Items items = static_cast < const label::LR0ItemsLabel & > ( state . getData ( ) ) . getItems ( );
 		std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > transitionsFromCurrentState = parsingAutomaton.getTransitionsFromState ( state );
@@ -70,7 +70,7 @@ LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG originalGrammar ) {
 LRGotoTable SLR1ParseTable::getGotoTable ( grammar::CFG originalGrammar ) {
 	LRGotoTable gotoTable;
 	grammar::CFG augmentedGrammar = LRParser::getAugmentedGrammar ( originalGrammar );
-	automaton::DFA parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar );
+	automaton::DFA<> parsingAutomaton = LR0Parser::getAutomaton ( originalGrammar );
 	for ( const label::Label & state : parsingAutomaton.getStates ( ) ) {
 		std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > transitionsFromCurrentState = parsingAutomaton.getTransitionsFromState ( state );
 		for ( const alphabet::Symbol & nonterminal : augmentedGrammar.getNonterminalAlphabet ( ) ) {
diff --git a/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
index ab72a9df67..662c92a23f 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
@@ -23,12 +23,12 @@ namespace regexp {
 
 namespace convert {
 
-automaton::DFA ToAutomatonDerivation::convert(const regexp::RegExp& regexp) {
+automaton::DFA<> ToAutomatonDerivation::convert(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
 template<class T>
-automaton::DFA ToAutomatonDerivation::convert(const T& regexp) {
+automaton::DFA<> ToAutomatonDerivation::convert(const T& regexp) {
 	// 1.
 	regexp::RegExp V = regexp::RegExp{regexp::simplify::RegExpOptimize::optimize(regexp)};
 
@@ -73,7 +73,7 @@ automaton::DFA ToAutomatonDerivation::convert(const T& regexp) {
 	// ------------------------------------------------------------------------
 	// 3.
 
-	automaton::DFA automaton(stateMap.find(V)->second);
+	automaton::DFA<> automaton(stateMap.find(V)->second);
 
 	for(const auto& r : stateMap) {
 		automaton.addState(r.second);
@@ -101,8 +101,8 @@ automaton::DFA ToAutomatonDerivation::convert(const T& regexp) {
 	return automaton;
 }
 
-auto ToAutomatonDerivationFormalRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA, regexp::FormalRegExp>( ToAutomatonDerivation::convert);
-auto ToAutomatonDerivationUnboundedRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA, regexp::UnboundedRegExp>( ToAutomatonDerivation::convert);
+auto ToAutomatonDerivationFormalRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA<>, regexp::FormalRegExp>( ToAutomatonDerivation::convert);
+auto ToAutomatonDerivationUnboundedRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA<>, regexp::UnboundedRegExp>( ToAutomatonDerivation::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToAutomatonDerivation.h b/alib2algo/src/regexp/convert/ToAutomatonDerivation.h
index 516be2e74a..518bd56df2 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonDerivation.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonDerivation.h
@@ -24,16 +24,16 @@ namespace convert {
  * Converts regular expression to finite automaton using BrzozowskiDerivation algorithm (derivations of regular expressions).
  * Source: Melichar 2.110
  */
-class ToAutomatonDerivation : public std::SingleDispatch<ToAutomatonDerivation, automaton::DFA, regexp::RegExpBase> {
+class ToAutomatonDerivation : public std::SingleDispatch<ToAutomatonDerivation, automaton::DFA<>, regexp::RegExpBase> {
 public:
 	/**
 	 * Performs conversion.
 	 * @return FSM equivalent to original regular expression.
 	 */
-	static automaton::DFA convert(const regexp::RegExp& regexp);
+	static automaton::DFA<> convert(const regexp::RegExp& regexp);
 
 	template<class T>
-	static automaton::DFA convert(const T& regexp);
+	static automaton::DFA<> convert(const T& regexp);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/stringology/exact/BackwardDAWGMatching.cpp b/alib2algo/src/stringology/exact/BackwardDAWGMatching.cpp
index 5a28e15000..15adaa4eb0 100644
--- a/alib2algo/src/stringology/exact/BackwardDAWGMatching.cpp
+++ b/alib2algo/src/stringology/exact/BackwardDAWGMatching.cpp
@@ -32,7 +32,7 @@ std::set < unsigned > BackwardDAWGMatching::match ( const string::LinearString &
 
     const string::LinearString reversedPattern ( std::move ( patternData ) );
 
-    automaton::DFA suffixAutomaton = SuffixAutomaton::construct ( reversedPattern );
+    automaton::DFA<> suffixAutomaton = SuffixAutomaton::construct ( reversedPattern );
 
     measurements::end ( );
 
diff --git a/alib2algo/src/stringology/exact/BackwardOracleMatching.cpp b/alib2algo/src/stringology/exact/BackwardOracleMatching.cpp
index 2f4de8f3d7..1dc04f5c89 100644
--- a/alib2algo/src/stringology/exact/BackwardOracleMatching.cpp
+++ b/alib2algo/src/stringology/exact/BackwardOracleMatching.cpp
@@ -32,7 +32,7 @@ std::set < unsigned > BackwardOracleMatching::match ( const string::LinearString
 
     const string::LinearString reversedPattern ( std::move ( patternData ) );
 
-    automaton::DFA factorOracle = FactorOracleAutomaton::construct ( reversedPattern );
+    automaton::DFA<> factorOracle = FactorOracleAutomaton::construct ( reversedPattern );
 
     measurements::end ( );
 
diff --git a/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.cpp b/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.cpp
index 3f74a10138..1f8e55d7bb 100644
--- a/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.cpp
+++ b/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.cpp
@@ -19,13 +19,13 @@ automaton::Automaton ExactSubsequenceAutomaton::construct(const string::String&
 	return dispatch(text.getData());
 }
 
-automaton::DFA ExactSubsequenceAutomaton::construct(const string::LinearString& text) {
+automaton::DFA<> ExactSubsequenceAutomaton::construct(const string::LinearString& text) {
 	std::map<alphabet::Symbol, int> f;
 	for(const alphabet::Symbol& symbol : text.getAlphabet()) {
 		f[symbol] = 0;
 	}
 
-	automaton::DFA res(label::labelFrom(0));
+	automaton::DFA<> res(label::labelFrom(0));
 	res.addFinalState(label::labelFrom(0));
 	res.setInputAlphabet(text.getAlphabet());
 
@@ -43,7 +43,7 @@ automaton::DFA ExactSubsequenceAutomaton::construct(const string::LinearString&
 	return res;
 }
 
-auto ExactSubsequenceAutomatonLinearString = ExactSubsequenceAutomaton::RegistratorWrapper<automaton::DFA, string::LinearString>(ExactSubsequenceAutomaton::construct);
+auto ExactSubsequenceAutomatonLinearString = ExactSubsequenceAutomaton::RegistratorWrapper<automaton::DFA<>, string::LinearString>(ExactSubsequenceAutomaton::construct);
 
 } /* namespace exact */
 
diff --git a/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.h b/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.h
index 2bda8c0799..371c0c4771 100644
--- a/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.h
+++ b/alib2algo/src/stringology/exact/ExactSubsequenceAutomaton.h
@@ -26,7 +26,7 @@ public:
 	 */
 	static automaton::Automaton construct(const string::String& text);
 
-	static automaton::DFA construct(const string::LinearString& text);
+	static automaton::DFA<> construct(const string::LinearString& text);
 };
 
 } /* namespace exact */
diff --git a/alib2algo/src/stringology/exact/FactorOracleAutomaton.cpp b/alib2algo/src/stringology/exact/FactorOracleAutomaton.cpp
index c20447fbc5..2c11770e9e 100644
--- a/alib2algo/src/stringology/exact/FactorOracleAutomaton.cpp
+++ b/alib2algo/src/stringology/exact/FactorOracleAutomaton.cpp
@@ -13,8 +13,8 @@ automaton::Automaton FactorOracleAutomaton::construct ( const string::String & p
     return dispatch ( pattern.getData ( ) );
 }
 
-automaton::DFA FactorOracleAutomaton::construct ( const string::LinearString & pattern ) {
-    automaton::DFA oracle ( label::labelFrom ( 0 ) );
+automaton::DFA<> FactorOracleAutomaton::construct ( const string::LinearString & pattern ) {
+    automaton::DFA<> oracle ( label::labelFrom ( 0 ) );
 
     oracle.addFinalState ( oracle.getInitialState ( ) );
 
@@ -28,7 +28,7 @@ automaton::DFA FactorOracleAutomaton::construct ( const string::LinearString & p
     return oracle;
 }
 
-void FactorOracleAutomaton::oracleAddLetter ( automaton::DFA & oracle, const alphabet::Symbol & symbol, std::map < label::Label, label::Label > & supplyFunction ) {
+void FactorOracleAutomaton::oracleAddLetter ( automaton::DFA<> & oracle, const alphabet::Symbol & symbol, std::map < label::Label, label::Label > & supplyFunction ) {
     int m = ( int ) oracle.getStates ( ).size ( ) - 1;
 
     label::Label lastState = label::labelFrom ( m );
@@ -53,7 +53,7 @@ void FactorOracleAutomaton::oracleAddLetter ( automaton::DFA & oracle, const alp
     supplyFunction.insert( { newState, supplyState } );
 }
 
-auto FactorOracleAutomatonLinearString = FactorOracleAutomaton::RegistratorWrapper < automaton::DFA, string::LinearString > ( FactorOracleAutomaton::construct );
+auto FactorOracleAutomatonLinearString = FactorOracleAutomaton::RegistratorWrapper < automaton::DFA<>, string::LinearString > ( FactorOracleAutomaton::construct );
 
 } /* namespace exact */
 
diff --git a/alib2algo/src/stringology/exact/FactorOracleAutomaton.h b/alib2algo/src/stringology/exact/FactorOracleAutomaton.h
index 1396d8556c..d72f09681c 100644
--- a/alib2algo/src/stringology/exact/FactorOracleAutomaton.h
+++ b/alib2algo/src/stringology/exact/FactorOracleAutomaton.h
@@ -17,7 +17,7 @@ namespace exact {
 
 class FactorOracleAutomaton : public std::SingleDispatch < FactorOracleAutomaton, automaton::Automaton, string::StringBase > {
 private:
-    static void oracleAddLetter ( automaton::DFA & oracle, const alphabet::Symbol & symbol, std::map < label::Label, label::Label > & supplyFunction );
+    static void oracleAddLetter ( automaton::DFA<> & oracle, const alphabet::Symbol & symbol, std::map < label::Label, label::Label > & supplyFunction );
 
 public:
     /**
@@ -26,7 +26,7 @@ public:
      */
     static automaton::Automaton construct ( const string::String & pattern );
 
-    static automaton::DFA construct ( const string::LinearString & pattern );
+    static automaton::DFA<> construct ( const string::LinearString & pattern );
 
 };
 
diff --git a/alib2algo/src/stringology/exact/SuffixAutomaton.cpp b/alib2algo/src/stringology/exact/SuffixAutomaton.cpp
index db988567db..e9a8d11fd0 100644
--- a/alib2algo/src/stringology/exact/SuffixAutomaton.cpp
+++ b/alib2algo/src/stringology/exact/SuffixAutomaton.cpp
@@ -17,7 +17,7 @@ automaton::Automaton SuffixAutomaton::naiveConstruct ( const string::String & pa
     return dispatch ( pattern.getData ( ) );
 }
 
-automaton::DFA SuffixAutomaton::naiveConstruct ( const string::LinearString & pattern ) {
+automaton::DFA<> SuffixAutomaton::naiveConstruct ( const string::LinearString & pattern ) {
     automaton::EpsilonNFA nfaSuffixAutomaton ( label::labelFrom ( 0 ) );
 
     nfaSuffixAutomaton.setInputAlphabet ( pattern.getAlphabet ( ) );
@@ -33,7 +33,7 @@ automaton::DFA SuffixAutomaton::naiveConstruct ( const string::LinearString & pa
 
     nfaSuffixAutomaton.addFinalState ( label::labelFrom ( i ) );
 
-    automaton::DFA minimalSuffixAutomaton = automaton::simplify::Minimize::minimize ( automaton::determinize::Determinize::determinize ( automaton::simplify::EpsilonRemoverIncoming::remove ( nfaSuffixAutomaton ) ) );
+    automaton::DFA<> minimalSuffixAutomaton = automaton::simplify::Minimize::minimize ( automaton::determinize::Determinize::determinize ( automaton::simplify::EpsilonRemoverIncoming::remove ( nfaSuffixAutomaton ) ) );
 
     label::Label failState = label::Label ( label::LabelSetLabel ( { } ) );
 
@@ -51,8 +51,8 @@ automaton::Automaton SuffixAutomaton::construct ( const string::String & pattern
     return dispatch ( pattern.getData ( ) );
 }
 
-automaton::DFA SuffixAutomaton::construct ( const string::LinearString & pattern ) {
-    automaton::DFA suffixAutomaton ( label::labelFrom ( 0 ) );
+automaton::DFA<> SuffixAutomaton::construct ( const string::LinearString & pattern ) {
+    automaton::DFA<> suffixAutomaton ( label::labelFrom ( 0 ) );
 
     suffixAutomaton.setInputAlphabet ( pattern.getAlphabet ( ) );
 
@@ -70,7 +70,7 @@ automaton::DFA SuffixAutomaton::construct ( const string::LinearString & pattern
     return suffixAutomaton;
 }
 
-void SuffixAutomaton::suffixAutomatonAddSymbol ( automaton::DFA & suffixAutomaton, const alphabet::Symbol & symbol, std::map < label::Label, std::pair < label::Label, int > > & suffixLinks, label::Label & lastState ) {
+void SuffixAutomaton::suffixAutomatonAddSymbol ( automaton::DFA<> & suffixAutomaton, const alphabet::Symbol & symbol, std::map < label::Label, std::pair < label::Label, int > > & suffixLinks, label::Label & lastState ) {
 
     label::Label newState = label::labelFrom ( ( int ) suffixAutomaton.getStates ( ).size ( ) );
 
@@ -122,7 +122,7 @@ void SuffixAutomaton::suffixAutomatonAddSymbol ( automaton::DFA & suffixAutomato
     lastState = newState;
 }
 
-auto SuffixAutomatonLinearString = SuffixAutomaton::RegistratorWrapper < automaton::DFA, string::LinearString > ( SuffixAutomaton::construct );
+auto SuffixAutomatonLinearString = SuffixAutomaton::RegistratorWrapper < automaton::DFA<>, string::LinearString > ( SuffixAutomaton::construct );
 
 } /* namespace exact */
 
diff --git a/alib2algo/src/stringology/exact/SuffixAutomaton.h b/alib2algo/src/stringology/exact/SuffixAutomaton.h
index b0ac139c9f..1e793cb7d3 100644
--- a/alib2algo/src/stringology/exact/SuffixAutomaton.h
+++ b/alib2algo/src/stringology/exact/SuffixAutomaton.h
@@ -18,7 +18,7 @@ namespace exact {
 
 class SuffixAutomaton : public std::SingleDispatch < SuffixAutomaton, automaton::Automaton, string::StringBase > {
 private:
-    static void suffixAutomatonAddSymbol ( automaton::DFA & suffixAutomaton, const alphabet::Symbol & symbol, std::map < label::Label, std::pair<label::Label, int > > & suffixLinks, label::Label & lastState );
+    static void suffixAutomatonAddSymbol ( automaton::DFA<> & suffixAutomaton, const alphabet::Symbol & symbol, std::map < label::Label, std::pair<label::Label, int > > & suffixLinks, label::Label & lastState );
 
 public:
     /**
@@ -27,7 +27,7 @@ public:
      */
     static automaton::Automaton naiveConstruct ( const string::String & pattern );
 
-    static automaton::DFA naiveConstruct ( const string::LinearString & pattern );
+    static automaton::DFA<> naiveConstruct ( const string::LinearString & pattern );
 
      /**
      * Linear time on-line construction of minimal suffix automaton for given pattern.
@@ -35,7 +35,7 @@ public:
      */
     static automaton::Automaton construct ( const string::String & pattern );
 
-    static automaton::DFA construct ( const string::LinearString & pattern );
+    static automaton::DFA<> construct ( const string::LinearString & pattern );
 
 };
 
diff --git a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
index 92c73b5200..aa9c11781a 100644
--- a/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
+++ b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
@@ -35,7 +35,7 @@ void determinizeTest::testDeterminizeNFA() {
 
   automaton.addFinalState(label::labelFrom(3));
 
-  automaton::DFA determinized = automaton::determinize::Determinize::determinize(automaton);
+  automaton::DFA<> determinized = automaton::determinize::Determinize::determinize(automaton);
 
   CPPUNIT_ASSERT(determinized.getStates().size() == 3);
 
diff --git a/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
index c9eccb8bdf..8b275fb931 100644
--- a/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
@@ -49,8 +49,8 @@ void FSMSingleInitialStateTest::testSingleInitialState() {
 	automaton3.addTransition(q1, b, q2);
 	automaton3.addTransition(q2, a, q3);
 
-	automaton::DFA dfa2 = automaton::simplify::Minimize::minimize(automaton::determinize::Determinize::determinize(automaton2));
-	automaton::DFA dfa3 = automaton::simplify::Minimize::minimize(automaton::determinize::Determinize::determinize(automaton3));
+	automaton::DFA<> dfa2 = automaton::simplify::Minimize::minimize(automaton::determinize::Determinize::determinize(automaton2));
+	automaton::DFA<> dfa3 = automaton::simplify::Minimize::minimize(automaton::determinize::Determinize::determinize(automaton3));
 
 	CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(dfa2) == automaton::simplify::Normalize::normalize(dfa3));
 }
diff --git a/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp
index 17a1bbd08d..5349b04434 100644
--- a/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp
@@ -24,7 +24,7 @@ void TotalTest::testTotal() {
 	alphabet::Symbol b = alphabet::symbolFrom('b');
 	alphabet::Symbol c = alphabet::symbolFrom('c');
 
-	automaton::DFA automaton(q0);
+	automaton::DFA<> automaton(q0);
 	automaton.setStates({q0, q1, q2});
 	automaton.setFinalStates({q0, q1, q2});
 	automaton.setInputAlphabet({a, b, c});
@@ -36,11 +36,11 @@ void TotalTest::testTotal() {
 	automaton.addTransition(q1, c, q2);
 	automaton.addTransition(q2, c, q2);
 
-	automaton::DFA totalAutomaton = automaton::simplify::Total::total(automaton);
+	automaton::DFA<> totalAutomaton = automaton::simplify::Total::total(automaton);
 	CPPUNIT_ASSERT(totalAutomaton.isTotal());
 
-	automaton::DFA trimmedAutomaton = automaton::simplify::Trim::trim(automaton);
-	automaton::DFA trimmedTotalAutomaton = automaton::simplify::Trim::trim(totalAutomaton);
+	automaton::DFA<> trimmedAutomaton = automaton::simplify::Trim::trim(automaton);
+	automaton::DFA<> trimmedTotalAutomaton = automaton::simplify::Trim::trim(totalAutomaton);
 
 	CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(trimmedAutomaton) == automaton::simplify::Normalize::normalize(trimmedTotalAutomaton));
 }
diff --git a/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.cpp b/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.cpp
index 08fd490912..52d7cd58eb 100644
--- a/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/minimizeBrzozowskiTest.cpp
@@ -18,7 +18,7 @@ void minimizeBrzozowskiTest::tearDown() {
 }
 
 void minimizeBrzozowskiTest::testMinimizeBrzozowski() {
-  automaton::DFA automaton(label::labelFrom(1));
+  automaton::DFA < > automaton(label::labelFrom(1));
 
   automaton.addState(label::labelFrom(1));
   automaton.addState(label::labelFrom(2));
@@ -31,8 +31,8 @@ void minimizeBrzozowskiTest::testMinimizeBrzozowski() {
 
   automaton.addFinalState(label::labelFrom(3));
   
-  automaton::DFA minimizedHopcroft = automaton::simplify::Minimize::minimize(automaton);
-  automaton::DFA minimizedBrzozowski = automaton::simplify::MinimizeBrzozowski::minimize(automaton);
+  automaton::DFA<> minimizedHopcroft = automaton::simplify::Minimize::minimize(automaton);
+  automaton::DFA<> minimizedBrzozowski = automaton::simplify::MinimizeBrzozowski::minimize(automaton);
 
   CPPUNIT_ASSERT(minimizedHopcroft.getStates().size() == 3);
   CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(minimizedHopcroft)) == automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(minimizedBrzozowski)));
diff --git a/alib2algo/test-src/automaton/simplify/minimizeTest.cpp b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
index 353d0bb731..7d5e5c675d 100644
--- a/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
@@ -15,7 +15,7 @@ void minimizeTest::tearDown() {
 }
 
 void minimizeTest::testMinimize() {
-  automaton::DFA automaton(label::labelFrom(1));
+  automaton::DFA < > automaton(label::labelFrom(1));
 
   automaton.addState(label::labelFrom(1));
   automaton.addState(label::labelFrom(2));
@@ -28,7 +28,7 @@ void minimizeTest::testMinimize() {
 
   automaton.addFinalState(label::labelFrom(3));
   
-  automaton::DFA minimized = automaton::simplify::Minimize::minimize(automaton);
+  automaton::DFA<> minimized = automaton::simplify::Minimize::minimize(automaton);
 
   CPPUNIT_ASSERT(minimized.getStates().size() == 3);
 
diff --git a/alib2algo/test-src/automaton/simplify/normalizeTest.cpp b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp
index 6c08203151..6c4f626a1a 100644
--- a/alib2algo/test-src/automaton/simplify/normalizeTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp
@@ -15,7 +15,7 @@ void normalizeTest::tearDown() {
 }
 
 void normalizeTest::testNormalize() {
-  automaton::DFA automaton(label::labelFrom(0));
+  automaton::DFA < > automaton(label::labelFrom(0));
 
   automaton.addState(label::labelFrom(0));
   automaton.addState(label::labelFrom(1));
@@ -28,7 +28,7 @@ void normalizeTest::testNormalize() {
 
   automaton.addFinalState(label::labelFrom(2));
   
-  automaton::DFA normalized = automaton::simplify::Normalize::normalize(automaton);
+  automaton::DFA<> normalized = automaton::simplify::Normalize::normalize(automaton);
 
   CPPUNIT_ASSERT(normalized.getStates().size() == 3);
 
diff --git a/alib2algo/test-src/automaton/simplify/trimTest.cpp b/alib2algo/test-src/automaton/simplify/trimTest.cpp
index c11075e764..7faae0cf96 100644
--- a/alib2algo/test-src/automaton/simplify/trimTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/trimTest.cpp
@@ -19,7 +19,7 @@ void trimTest::tearDown() {
 }
 
 void trimTest::testTrimAutomaton() {
-  automaton::DFA automaton(label::labelFrom(1));
+  automaton::DFA < > automaton(label::labelFrom(1));
 
   automaton.addState(label::labelFrom(1));
   automaton.addState(label::labelFrom(2));
@@ -33,7 +33,7 @@ void trimTest::testTrimAutomaton() {
 
   automaton.addFinalState(label::labelFrom(1));
   
-  automaton::DFA trimed = automaton::simplify::Trim::trim(automaton);
+  automaton::DFA<> trimed = automaton::simplify::Trim::trim(automaton);
 
   CPPUNIT_ASSERT(trimed.getStates().size() == 2);
 }
diff --git a/alib2algo/test-src/automaton/transform/AutomataCompactionTest.cpp b/alib2algo/test-src/automaton/transform/AutomataCompactionTest.cpp
index 9075c07085..e4139d1674 100644
--- a/alib2algo/test-src/automaton/transform/AutomataCompactionTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomataCompactionTest.cpp
@@ -27,7 +27,7 @@ void AutomataCompactionTest::testAutomataCompaction1() {
 	label::Label q5 = label::labelFrom("5");
 	alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b'));
 
-	automaton::DFA m1(q0);
+	automaton::DFA<> m1(q0);
 	automaton::CompactNFA m2(q0);
 
 	m1.setInputAlphabet({a, b});
@@ -59,7 +59,7 @@ void AutomataCompactionTest::testAutomataCompaction2() {
 	label::Label q5 = label::labelFrom("5");
 	alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b'));
 
-	automaton::DFA m1(q0);
+	automaton::DFA<> m1(q0);
 	automaton::CompactNFA m2(q0);
 
 	m1.setInputAlphabet({a, b});
@@ -94,7 +94,7 @@ void AutomataCompactionTest::testAutomataCompaction3() {
 	label::Label q6 = label::labelFrom("6");
 	alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b'));
 
-	automaton::DFA m1(q0);
+	automaton::DFA<> m1(q0);
 	automaton::CompactNFA m2(q0);
 
 	m1.setInputAlphabet({a, b});
diff --git a/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp b/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp
index 30a769a25b..21dead1c52 100644
--- a/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomataConcatenationTest.cpp
@@ -34,8 +34,8 @@ void AutomataConcatenationTest::testAutomataConcatenation() {
 	label::Label q0102 = label::labelFrom("q0102");
 	alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b'));
 
-	automaton::DFA m1(q1a);
-	automaton::DFA m2(q1b);
+	automaton::DFA<> m1(q1a);
+	automaton::DFA<> m2(q1b);
 	automaton::NFA m3(q1a);
 
 	m1.setInputAlphabet({a, b});
@@ -72,10 +72,10 @@ 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 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 u22 = automaton::transform::AutomataConcatenation::concatenation(automaton::Automaton(automaton::DFA(m1)), automaton::Automaton(automaton::DFA(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 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)))));
 	automaton::Automaton umdfa11(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemoverIncoming::remove(u11)))));
diff --git a/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp b/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
index 2966938730..4302996d54 100644
--- a/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
@@ -38,9 +38,9 @@ void AutomataUnionTest::testAutomataUnion() {
 	label::Label q02 = label::labelFrom("02");
 	alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b'));
 
-	automaton::DFA m1(q1a);
-	automaton::DFA m2(q1b);
-	automaton::DFA m3(q11);
+	automaton::DFA<> m1(q1a);
+	automaton::DFA<> m2(q1b);
+	automaton::DFA<> m3(q11);
 
 	m1.setInputAlphabet({a, b});
 	m1.setStates({q1a, q2a, q0a});
diff --git a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp
index a5b70f30bb..be4104b8ed 100644
--- a/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomatonIterationTest.cpp
@@ -30,7 +30,7 @@ void AutomatonIterationTest::testAutomatonIteration() {
 	label::Label q3 = label::labelFrom(3);
 	alphabet::Symbol a(alphabet::symbolFrom('a')), b(alphabet::symbolFrom('b'));
 
-	automaton::DFA m1(q1);
+	automaton::DFA<> m1(q1);
 	m1.setStates({q1, q2, q3});
 	m1.addFinalState(q3);
 	m1.setInputAlphabet({a, b});
diff --git a/alib2algo/test-src/grammar/parsing/LR0Parser.cpp b/alib2algo/test-src/grammar/parsing/LR0Parser.cpp
index 8c1add82f2..818f5ed0aa 100644
--- a/alib2algo/test-src/grammar/parsing/LR0Parser.cpp
+++ b/alib2algo/test-src/grammar/parsing/LR0Parser.cpp
@@ -309,7 +309,7 @@ void LR0Parser::testAutomaton ( ) {
 		states.emplace_back( label::Label ( label::LR0ItemsLabel ( currentItems ) ) );
 	}
 	
-	automaton::DFA parsingAutomaton ( states[0] );
+	automaton::DFA<> parsingAutomaton ( states[0] );
 	parsingAutomaton.addInputSymbols ( augmentedExpressionGrammar.getNonterminalAlphabet ( ) );
 	parsingAutomaton.addInputSymbols ( augmentedExpressionGrammar.getTerminalAlphabet ( ) );
 	
diff --git a/alib2algo/test-src/playTest.cpp b/alib2algo/test-src/playTest.cpp
index 4cd2f224b0..acf63862c7 100644
--- a/alib2algo/test-src/playTest.cpp
+++ b/alib2algo/test-src/playTest.cpp
@@ -37,11 +37,11 @@ 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);
     nfa = automaton::simplify::Trim::trim(nfa);
-    automaton::DFA dfa = automaton::determinize::Determinize::determinize(nfa);
+    automaton::DFA<> dfa = automaton::determinize::Determinize::determinize(nfa);
     dfa = automaton::simplify::Trim::trim(dfa);
     dfa = automaton::simplify::Minimize::minimize(dfa);
     dfa = automaton::simplify::Normalize::normalize(dfa);
diff --git a/alib2algo/test-src/playTest.h b/alib2algo/test-src/playTest.h
index 45d8cdc9c1..b6e7281849 100644
--- a/alib2algo/test-src/playTest.h
+++ b/alib2algo/test-src/playTest.h
@@ -20,7 +20,7 @@ public:
 
 private:
     automaton::NFA randomNFA(void) const;
-    automaton::DFA mDFA(const automaton::NFA& automaton) 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 8df98391a8..45a770864c 100644
--- a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
+++ b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
@@ -59,11 +59,11 @@ void re2faTest::testGlushkov() {
 
 	automaton::NFA nfa2 = regexp::convert::ToAutomatonGlushkov::convert(regexp2);
 
-	automaton::DFA dfa1 = automaton::determinize::Determinize::determinize(nfa1);
-	automaton::DFA dfa2 = automaton::determinize::Determinize::determinize(nfa2);
+	automaton::DFA<> dfa1 = automaton::determinize::Determinize::determinize(nfa1);
+	automaton::DFA<> dfa2 = automaton::determinize::Determinize::determinize(nfa2);
 
-	automaton::DFA mdfa1 = automaton::simplify::Normalize::normalize(automaton::simplify::Minimize::minimize(dfa1));
-	automaton::DFA mdfa2 = automaton::simplify::Normalize::normalize(automaton::simplify::Minimize::minimize(dfa2));
+	automaton::DFA<> mdfa1 = automaton::simplify::Normalize::normalize(automaton::simplify::Minimize::minimize(dfa1));
+	automaton::DFA<> mdfa2 = automaton::simplify::Normalize::normalize(automaton::simplify::Minimize::minimize(dfa2));
 
 	std::cout << mdfa1 << std::endl;
 	std::cout << mdfa2 << std::endl;
@@ -75,17 +75,17 @@ void re2faTest::testBrzozowski() {
 	std::string input = "a+a* b*";
 	regexp::RegExp regexp1 = alib::StringDataFactory::fromString<regexp::RegExp>(input);
 
-	automaton::DFA dfa1 = regexp::convert::ToAutomatonDerivation::convert(regexp1);
+	automaton::DFA<> dfa1 = regexp::convert::ToAutomatonDerivation::convert(regexp1);
 
 	regexp::RegExp regexp2( automaton::convert::ToRegExpAlgebraic::convert(dfa1));
 
-	automaton::DFA dfa2 = regexp::convert::ToAutomatonDerivation::convert(regexp2);
+	automaton::DFA<> dfa2 = regexp::convert::ToAutomatonDerivation::convert(regexp2);
 
-	automaton::DFA mdfa1_2 = automaton::simplify::Minimize::minimize(dfa1);
-	automaton::DFA mdfa1_3 = automaton::simplify::Normalize::normalize(mdfa1_2);
+	automaton::DFA<> mdfa1_2 = automaton::simplify::Minimize::minimize(dfa1);
+	automaton::DFA<> mdfa1_3 = automaton::simplify::Normalize::normalize(mdfa1_2);
 
-	automaton::DFA mdfa2_2 = automaton::simplify::Minimize::minimize(dfa2);
-	automaton::DFA mdfa2_3 = automaton::simplify::Normalize::normalize(mdfa2_2);
+	automaton::DFA<> mdfa2_2 = automaton::simplify::Minimize::minimize(dfa2);
+	automaton::DFA<> mdfa2_3 = automaton::simplify::Normalize::normalize(mdfa2_2);
 
 	CPPUNIT_ASSERT( mdfa1_3 == mdfa2_3);
 }
diff --git a/alib2algo/test-src/stringology/exact/FactorOracleAutomatonTest.cpp b/alib2algo/test-src/stringology/exact/FactorOracleAutomatonTest.cpp
index 4dec610937..6ab3780e61 100644
--- a/alib2algo/test-src/stringology/exact/FactorOracleAutomatonTest.cpp
+++ b/alib2algo/test-src/stringology/exact/FactorOracleAutomatonTest.cpp
@@ -23,9 +23,9 @@ void FactorOracleAutomatonTest::testFactorOracleConstruction ( ) {
 
     string::LinearString pattern ( "atatac" );
 
-    automaton::DFA oracle = stringology::exact::FactorOracleAutomaton::construct ( pattern );
+    automaton::DFA<> oracle = stringology::exact::FactorOracleAutomaton::construct ( pattern );
 
-    automaton::DFA refOracle ( label::labelFrom ( 0 ) );
+    automaton::DFA<> refOracle ( label::labelFrom ( 0 ) );
 
     refOracle.addFinalState ( label::labelFrom ( 0 ) );
 
diff --git a/alib2algo/test-src/stringology/exact/SuffixAutomatonTest.cpp b/alib2algo/test-src/stringology/exact/SuffixAutomatonTest.cpp
index 013310f936..b26ae278c7 100644
--- a/alib2algo/test-src/stringology/exact/SuffixAutomatonTest.cpp
+++ b/alib2algo/test-src/stringology/exact/SuffixAutomatonTest.cpp
@@ -23,9 +23,9 @@ void SuffixAutomatonTest::testSuffixAutomatonConstruction ( ) {
 
     string::LinearString pattern ( "atatac" );
 
-    automaton::DFA suffixAutomaton = stringology::exact::SuffixAutomaton::construct ( pattern );
+    automaton::DFA<> suffixAutomaton = stringology::exact::SuffixAutomaton::construct ( pattern );
 
-    automaton::DFA refSuffixAutomaton ( label::labelFrom ( 0 ) );
+    automaton::DFA<> refSuffixAutomaton ( label::labelFrom ( 0 ) );
 
     refSuffixAutomaton.setInputAlphabet ( pattern.getAlphabet ( ) );
 
diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h
index 6892a67bcc..a5060e1f12 100644
--- a/alib2data/src/automaton/AutomatonFeatures.h
+++ b/alib2data/src/automaton/AutomatonFeatures.h
@@ -42,6 +42,7 @@ enum class Shift;
 class EpsilonNFA;
 class NFA;
 class MultiInitialStateNFA;
+template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label >
 class DFA;
 class CompactNFA;
 class ExtendedNFA;
diff --git a/alib2data/src/automaton/FSM/CompactNFA.cpp b/alib2data/src/automaton/FSM/CompactNFA.cpp
index c7264183a0..cd8368d42c 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.cpp
+++ b/alib2data/src/automaton/FSM/CompactNFA.cpp
@@ -60,7 +60,7 @@ CompactNFA::CompactNFA ( const NFA & other ) : CompactNFA ( other.getStates ( ),
 	}
 }
 
-CompactNFA::CompactNFA ( const DFA & other ) : CompactNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+CompactNFA::CompactNFA ( const DFA<> & 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].insert ( transition.second );
@@ -220,7 +220,7 @@ 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 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 > ( );
diff --git a/alib2data/src/automaton/FSM/CompactNFA.h b/alib2data/src/automaton/FSM/CompactNFA.h
index bd0b1b0977..d6b3a56649 100644
--- a/alib2data/src/automaton/FSM/CompactNFA.h
+++ b/alib2data/src/automaton/FSM/CompactNFA.h
@@ -41,7 +41,7 @@ public:
 	explicit CompactNFA ( const EpsilonNFA & other );
 	explicit CompactNFA ( const MultiInitialStateNFA & other );
 	explicit CompactNFA ( const NFA & other );
-	explicit CompactNFA ( const DFA & 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 c9248776e2..56cea8b98a 100644
--- a/alib2data/src/automaton/FSM/DFA.cpp
+++ b/alib2data/src/automaton/FSM/DFA.cpp
@@ -6,190 +6,11 @@
  */
 
 #include "DFA.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>
-
-namespace automaton {
-
-DFA::DFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates ) : std::Components < DFA, 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 ) ) ) {
-}
-
-DFA::DFA ( label::Label initialState ) : DFA ( std::set < label::Label > { initialState }, std::set < alphabet::Symbol > { }, initialState, std::set < label::Label > { } ) {
-}
-
-AutomatonBase * DFA::clone ( ) const {
-	return new DFA ( * this );
-}
-
-AutomatonBase * DFA::plunder ( ) && {
-	return new DFA ( std::move ( * this ) );
-}
-
-bool DFA::addTransition ( label::Label from, alphabet::Symbol input, label::Label to ) {
-	if ( !getStates ( ).count ( from ) )
-		throw AutomatonException ( "State \"" + ( std::string ) from + "\" doesn't exist." );
-
-	if ( !getInputAlphabet ( ).count ( input ) )
-		throw AutomatonException ( "Input symbol \"" + ( std::string ) input + "\" doesn't exist." );
-
-	if ( !getStates ( ).count ( to ) )
-		throw AutomatonException ( "State \"" + ( std::string ) to + "\" doesn't exist." );
-
-	std::pair < label::Label, alphabet::Symbol > key = std::make_pair ( std::move ( from ), std::move ( input ) );
-
-	if ( transitions.find ( key ) != transitions.end ( ) ) {
-		if ( transitions.find ( key )->second == to )
-			return false;
-		else
-			throw AutomatonException ( "Transition from this state and symbol already exists (\"" + ( std::string ) key.first + "\", \"" + ( std::string ) key.second + "\") -> \"" + ( std::string ) to + "\"." );
-	}
-
-	transitions.insert ( std::make_pair ( std::move ( key ), std::move ( to ) ) );
-	return true;
-}
-
-bool DFA::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 );
-
-	if ( transitions.find ( key ) == transitions.end ( ) )
-		return false;
-
-	if ( transitions.find ( key )->second != to )
-		throw AutomatonException ( "Transition (\"" + ( std::string ) from + "\", \"" + ( std::string ) input + "\") -> \"" + ( std::string ) to + "\" doesn't exist." );
-
-	transitions.erase ( key );
-	return true;
-}
-
-const std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > & DFA::getTransitions ( ) const {
-	return transitions;
-}
-
-std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > DFA::getTransitionsFromState ( const label::Label & from ) const {
-	if ( !getStates ( ).count ( from ) )
-		throw AutomatonException ( "State \"" + ( std::string ) from + "\" doesn't exist" );
-
-	std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > transitionsFromState;
-
-	for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, label::Label > & transition : transitions )
-		if ( transition.first.first == from )
-			transitionsFromState.insert ( transition );
-
-	return transitionsFromState;
-}
-
-std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > DFA::getTransitionsToState ( const label::Label & to ) const {
-	if ( !getStates ( ).count ( to ) )
-		throw AutomatonException ( "State \"" + ( std::string ) to + "\" doesn't exist" );
-
-	std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > transitionsToState;
-
-	for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, label::Label > & transition : transitions )
-		if ( transition.second == to )
-			transitionsToState.insert ( transition );
-
-	return transitionsToState;
-}
-
-bool DFA::isTotal ( ) const {
-	return transitions.size ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( );
-}
-
-int DFA::compare ( const DFA & other ) const {
-	auto first = std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions );
-	auto second = std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.transitions );
-
-	std::compare < decltype ( first ) > comp;
-
-	return comp ( first, second );
-}
-
-void DFA::operator >>( std::ostream & out ) const {
-	out << "(DFA "
-	    << " states = " << getStates ( )
-	    << " inputAlphabet = " << getInputAlphabet ( )
-	    << " initialState = " << getInitialState ( )
-	    << " finalStates = " << getFinalStates ( )
-	    << " transitions = " << transitions
-	    << ")";
-}
-
-DFA::operator std::string ( ) const {
-	std::stringstream ss;
-	ss << * this;
-	return ss.str ( );
-}
-
-DFA DFA::parse ( std::deque < sax::Token >::iterator & input ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, DFA::getXmlTagName() );
-
-	std::set < label::Label > states = AutomatonFromXMLParser::parseStates ( input );
-	std::set < alphabet::Symbol > inputSymbols = AutomatonFromXMLParser::parseInputAlphabet ( input );
-	label::Label initialState = AutomatonFromXMLParser::parseInitialState ( input );
-	std::set < label::Label > finalStates = AutomatonFromXMLParser::parseFinalStates ( input );
-
-	DFA automaton ( std::move ( initialState ) );
-
-	automaton.setStates ( std::move ( states ) );
-	automaton.setInputAlphabet ( std::move ( inputSymbols ) );
-	automaton.setFinalStates ( std::move ( finalStates ) );
-
-	AutomatonFromXMLParser::parseTransitions < DFA > ( input, automaton );
-
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, DFA::getXmlTagName() );
-	return automaton;
-}
-
-void DFA::parseTransition ( std::deque < sax::Token >::iterator & input, DFA & automaton ) {
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" );
-	label::Label from = AutomatonFromXMLParser::parseTransitionFrom ( input );
-	alphabet::Symbol inputSymbol = AutomatonFromXMLParser::parseTransitionInputSymbol ( input );
-	label::Label to = AutomatonFromXMLParser::parseTransitionTo ( input );
-	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "transition" );
-
-	automaton.addTransition ( std::move ( from ), std::move ( inputSymbol ), std::move ( to ) );
-}
-
-void DFA::compose ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( DFA::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 ( DFA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
-}
-
-void DFA::composeTransitions ( std::deque < sax::Token > & out ) const {
-	out.emplace_back ( "transitions", sax::Token::TokenType::START_ELEMENT );
-
-	for ( const auto & transition : this->getTransitions ( ) ) {
-		out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT );
-
-		AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first );
-		AutomatonToXMLComposer::composeTransitionInputSymbol ( out, transition.first.second );
-		AutomatonToXMLComposer::composeTransitionTo ( out, transition.second );
-
-		out.emplace_back ( "transition", sax::Token::TokenType::END_ELEMENT );
-	}
-
-	out.emplace_back ( "transitions", sax::Token::TokenType::END_ELEMENT );
-}
-
-} /* namespace automaton */
 
 namespace alib {
 
-auto DFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::DFA > ( );
-auto DFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::DFA > ( );
+auto DFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::DFA<> > ( );
+auto DFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::DFA<> > ( );
 
 } /* namespace alib */
diff --git a/alib2data/src/automaton/FSM/DFA.h b/alib2data/src/automaton/FSM/DFA.h
index 940b49febb..9212b987f7 100644
--- a/alib2data/src/automaton/FSM/DFA.h
+++ b/alib2data/src/automaton/FSM/DFA.h
@@ -15,6 +15,17 @@
 #include "../../alphabet/Symbol.h"
 #include "../../label/Label.h"
 
+#include "../AutomatonException.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>
+
 namespace automaton {
 
 /**
@@ -26,76 +37,77 @@ class States;
 class FinalStates;
 class InitialState;
 
-class DFA : public AutomatonBase, public std::Components < DFA, alphabet::Symbol, std::tuple < InputAlphabet >, std::tuple < >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
+template<class SymbolType, class StateType >
+class DFA : public AutomatonBase, public std::Components < DFA < 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 >, label::Label > transitions;
+	std::map < std::pair < StateType, SymbolType >, StateType > transitions;
 
 public:
-	explicit DFA ( label::Label initialState );
-	explicit DFA ( std::set < label::Label > states, std::set < alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates );
+	explicit DFA ( StateType initialState );
+	explicit DFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates );
 
 	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 );
 	}
 
 	/**
@@ -105,29 +117,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, const label::Label next );
+	bool addTransition ( StateType current, SymbolType input, const 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 >, label::Label > & getTransitions ( ) const;
+	const std::map < std::pair < StateType, SymbolType >, StateType > & getTransitions ( ) const;
 
 	/**
 	 * @return automaton transitions from state
 	 */
-	std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > getTransitionsFromState ( const label::Label & from ) const;
+	std::map < std::pair < StateType, SymbolType >, StateType > getTransitionsFromState ( const StateType & from ) const;
 
 	/**
 	 * @return automaton transitions to state
 	 */
-	std::map < std::pair < label::Label, alphabet::Symbol >, label::Label > getTransitionsToState ( const label::Label & from ) const;
+	std::map < std::pair < StateType, SymbolType >, StateType > getTransitionsToState ( const StateType & from ) const;
 
 	/**
 	 * Determines whether DFA is total deterministic
@@ -163,78 +175,266 @@ public:
 	void composeTransitions ( std::deque < sax::Token > & out ) const;
 };
 
+template<class SymbolType, class StateType >
+DFA<SymbolType, StateType>::DFA ( std::set < StateType > states, std::set < SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates ) : std::Components < DFA, 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 >
+DFA<SymbolType, StateType>::DFA ( StateType initialState ) : DFA ( std::set < StateType > { initialState }, std::set < SymbolType > { }, initialState, std::set < StateType > { } ) {
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase * DFA<SymbolType, StateType>::clone ( ) const {
+	return new DFA<SymbolType, StateType> ( * this );
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase * DFA<SymbolType, StateType>::plunder ( ) && {
+	return new DFA<SymbolType, StateType> ( std::move ( * this ) );
+}
+
+template<class SymbolType, class StateType >
+bool DFA<SymbolType, StateType>::addTransition ( StateType from, SymbolType input, StateType to ) {
+	if ( !getStates ( ).count ( from ) )
+		throw AutomatonException ( "State \"" + ( std::string ) from + "\" doesn't exist." );
+
+	if ( !getInputAlphabet ( ).count ( input ) )
+		throw AutomatonException ( "Input symbol \"" + ( std::string ) input + "\" doesn't exist." );
+
+	if ( !getStates ( ).count ( to ) )
+		throw AutomatonException ( "State \"" + ( std::string ) to + "\" doesn't exist." );
+
+	std::pair < StateType, SymbolType > key = std::make_pair ( std::move ( from ), std::move ( input ) );
+
+	if ( transitions.find ( key ) != transitions.end ( ) ) {
+		if ( transitions.find ( key )->second == to )
+			return false;
+		else
+			throw AutomatonException ( "Transition from this state and symbol already exists (\"" + ( std::string ) key.first + "\", \"" + ( std::string ) key.second + "\") -> \"" + ( std::string ) to + "\"." );
+	}
+
+	transitions.insert ( std::make_pair ( std::move ( key ), std::move ( to ) ) );
+	return true;
+}
+
+template<class SymbolType, class StateType >
+bool DFA<SymbolType, StateType>::removeTransition ( const StateType & from, const SymbolType & input, const StateType & to ) {
+	std::pair < StateType, SymbolType > key = std::make_pair ( from, input );
+
+	if ( transitions.find ( key ) == transitions.end ( ) )
+		return false;
+
+	if ( transitions.find ( key )->second != to )
+		throw AutomatonException ( "Transition (\"" + ( std::string ) from + "\", \"" + ( std::string ) input + "\") -> \"" + ( std::string ) to + "\" doesn't exist." );
+
+	transitions.erase ( key );
+	return true;
+}
+
+template<class SymbolType, class StateType >
+const std::map < std::pair < StateType, SymbolType >, StateType > & DFA<SymbolType, StateType>::getTransitions ( ) const {
+	return transitions;
+}
+
+template<class SymbolType, class StateType >
+std::map < std::pair < StateType, SymbolType >, StateType > DFA<SymbolType, StateType>::getTransitionsFromState ( const StateType & from ) const {
+	if ( !getStates ( ).count ( from ) )
+		throw AutomatonException ( "State \"" + ( std::string ) from + "\" doesn't exist" );
+
+	std::map < std::pair < StateType, SymbolType >, StateType > transitionsFromState;
+
+	for ( const std::pair < const std::pair < StateType, SymbolType >, StateType > & transition : transitions )
+		if ( transition.first.first == from )
+			transitionsFromState.insert ( transition );
+
+	return transitionsFromState;
+}
+
+template<class SymbolType, class StateType >
+std::map < std::pair < StateType, SymbolType >, StateType > DFA<SymbolType, StateType>::getTransitionsToState ( const StateType & to ) const {
+	if ( !getStates ( ).count ( to ) )
+		throw AutomatonException ( "State \"" + ( std::string ) to + "\" doesn't exist" );
+
+	std::map < std::pair < StateType, SymbolType >, StateType > transitionsToState;
+
+	for ( const std::pair < const std::pair < StateType, SymbolType >, StateType > & transition : transitions )
+		if ( transition.second == to )
+			transitionsToState.insert ( transition );
+
+	return transitionsToState;
+}
+
+template<class SymbolType, class StateType >
+bool DFA<SymbolType, StateType>::isTotal ( ) const {
+	return transitions.size ( ) == getInputAlphabet ( ).size ( ) * getStates ( ).size ( );
+}
+
+template<class SymbolType, class StateType >
+int DFA<SymbolType, StateType>::compare ( const DFA & other ) const {
+	auto first = std::tie ( getStates ( ), getInputAlphabet ( ), getInitialState ( ), getFinalStates ( ), transitions );
+	auto second = std::tie ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ), other.transitions );
+
+	std::compare < decltype ( first ) > comp;
+
+	return comp ( first, second );
+}
+
+template<class SymbolType, class StateType >
+void DFA<SymbolType, StateType>::operator >>( std::ostream & out ) const {
+	out << "(DFA "
+	    << " states = " << getStates ( )
+	    << " inputAlphabet = " << getInputAlphabet ( )
+	    << " initialState = " << getInitialState ( )
+	    << " finalStates = " << getFinalStates ( )
+	    << " transitions = " << transitions
+	    << ")";
+}
+
+template<class SymbolType, class StateType >
+DFA<SymbolType, StateType>::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << * this;
+	return ss.str ( );
+}
+
+template<class SymbolType, class StateType >
+DFA<SymbolType, StateType> DFA<SymbolType, StateType>::parse ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, DFA::getXmlTagName() );
+
+	std::set < StateType > states = AutomatonFromXMLParser::parseStates ( input );
+	std::set < SymbolType > inputSymbols = AutomatonFromXMLParser::parseInputAlphabet ( input );
+	StateType initialState = AutomatonFromXMLParser::parseInitialState ( input );
+	std::set < StateType > finalStates = AutomatonFromXMLParser::parseFinalStates ( input );
+
+	DFA<SymbolType, StateType> automaton ( std::move ( initialState ) );
+
+	automaton.setStates ( std::move ( states ) );
+	automaton.setInputAlphabet ( std::move ( inputSymbols ) );
+	automaton.setFinalStates ( std::move ( finalStates ) );
+
+	AutomatonFromXMLParser::parseTransitions < DFA > ( input, automaton );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, DFA::getXmlTagName() );
+	return automaton;
+}
+
+template<class SymbolType, class StateType >
+void DFA<SymbolType, StateType>::parseTransition ( std::deque < sax::Token >::iterator & input, DFA<SymbolType, StateType> & automaton ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "transition" );
+	StateType from = AutomatonFromXMLParser::parseTransitionFrom ( input );
+	SymbolType inputSymbol = AutomatonFromXMLParser::parseTransitionInputSymbol ( input );
+	StateType to = AutomatonFromXMLParser::parseTransitionTo ( 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 DFA<SymbolType, StateType>::compose ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( DFA::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 ( DFA::getXmlTagName(), sax::Token::TokenType::END_ELEMENT );
+}
+
+template<class SymbolType, class StateType >
+void DFA<SymbolType, StateType>::composeTransitions ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( "transitions", sax::Token::TokenType::START_ELEMENT );
+
+	for ( const auto & transition : this->getTransitions ( ) ) {
+		out.emplace_back ( "transition", sax::Token::TokenType::START_ELEMENT );
+
+		AutomatonToXMLComposer::composeTransitionFrom ( out, transition.first.first );
+		AutomatonToXMLComposer::composeTransitionInputSymbol ( out, transition.first.second );
+		AutomatonToXMLComposer::composeTransitionTo ( out, transition.second );
+
+		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::DFA, alphabet::Symbol, automaton::InputAlphabet > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::DFA<SymbolType, StateType>, SymbolType, automaton::InputAlphabet > {
 public:
-	static bool used ( const automaton::DFA & automaton, const alphabet::Symbol & symbol ) {
-		for ( const std::pair < const std::pair < label::Label, alphabet::Symbol >, label::Label > & transition : automaton.getTransitions ( ) )
+	static bool used ( const automaton::DFA<SymbolType, StateType> & automaton, const SymbolType & symbol ) {
+		for ( const std::pair < const std::pair < StateType, SymbolType >, StateType > & transition : automaton.getTransitions ( ) )
 			if ( transition.first.second == symbol )
 				return true;
 
 		return false;
 	}
 
-	static bool available ( const automaton::DFA &, const alphabet::Symbol & ) {
+	static bool available ( const automaton::DFA<SymbolType, StateType> &, const SymbolType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::DFA &, const alphabet::Symbol & ) {
+	static void valid ( const automaton::DFA<SymbolType, StateType> &, const SymbolType & ) {
 	}
+
 };
 
-template < >
-class ComponentConstraint< automaton::DFA, label::Label, automaton::States > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::DFA<SymbolType, StateType>, StateType, automaton::States > {
 public:
-	static bool used ( const automaton::DFA & automaton, const label::Label & state ) {
+	static bool used ( const automaton::DFA<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 >, label::Label > & t : automaton.getTransitions ( ) )
+		for ( const std::pair < const std::pair < StateType, SymbolType >, StateType > & t : automaton.getTransitions ( ) )
 			if ( ( t.first.first == state ) || ( t.second == state ) )
 				return true;
 
 		return false;
 	}
 
-	static bool available ( const automaton::DFA &, const label::Label & ) {
+	static bool available ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::DFA &, const label::Label & ) {
+	static void valid ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
 	}
+
 };
 
-template < >
-class ComponentConstraint< automaton::DFA, label::Label, automaton::FinalStates > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::DFA<SymbolType, StateType>, StateType, automaton::FinalStates > {
 public:
-	static bool used ( const automaton::DFA &, const label::Label & ) {
+	static bool used ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
 		return false;
 	}
 
-	static bool available ( const automaton::DFA & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::DFA<SymbolType, StateType> & automaton, const StateType & state ) {
+		return automaton.getStates ( ).count ( state );
 	}
 
-	static void valid ( const automaton::DFA &, const label::Label & ) {
+	static void valid ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
 	}
+
 };
 
-template < >
-class ElementConstraint< automaton::DFA, label::Label, automaton::InitialState > {
+template<class SymbolType, class StateType >
+class ElementConstraint< automaton::DFA<SymbolType, StateType>, StateType, automaton::InitialState > {
 public:
-	static bool available ( const automaton::DFA & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::DFA<SymbolType, StateType> & automaton, const StateType & state ) {
+		return automaton.getStates ( ).count ( state );
 	}
 
-	static void valid ( const automaton::DFA &, const label::Label & ) {
+	static void valid ( const automaton::DFA<SymbolType, StateType> &, const StateType & ) {
 	}
+
 };
 
 } /* namespace std */
diff --git a/alib2data/src/automaton/FSM/EpsilonNFA.cpp b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
index 14acc6af9f..6c6253b3b3 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.cpp
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.cpp
@@ -46,7 +46,7 @@ EpsilonNFA::EpsilonNFA ( const NFA & other ) : EpsilonNFA ( other.getStates ( ),
 	}
 }
 
-EpsilonNFA::EpsilonNFA ( const DFA & other ) : EpsilonNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+EpsilonNFA::EpsilonNFA ( const DFA<> & 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].insert ( transition.second );
@@ -316,7 +316,7 @@ namespace alib {
 auto epsilonNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::EpsilonNFA > ( );
 auto epsilonNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::EpsilonNFA > ( );
 
-auto EpsilonNFAFromDFA = castApi::CastRegister < automaton::EpsilonNFA, automaton::DFA > ( );
+auto EpsilonNFAFromDFA = castApi::CastRegister < automaton::EpsilonNFA, automaton::DFA < > > ( );
 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 923ff7de07..bc560cacc1 100644
--- a/alib2data/src/automaton/FSM/EpsilonNFA.h
+++ b/alib2data/src/automaton/FSM/EpsilonNFA.h
@@ -40,7 +40,7 @@ public:
 	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 DFA & 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 c0e8dd76c6..5cf9706cc7 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.cpp
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.cpp
@@ -69,7 +69,7 @@ ExtendedNFA::ExtendedNFA ( const NFA & other ) : ExtendedNFA ( other.getStates (
 	}
 }
 
-ExtendedNFA::ExtendedNFA ( const DFA & other ) : ExtendedNFA ( other.getStates ( ), other.getInputAlphabet ( ), other.getInitialState ( ), other.getFinalStates ( ) ) {
+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::RegExp > key = std::make_pair ( transition.first.first, regexp::RegExp ( regexp::regexpFrom ( transition.first.second ) ) );
 		transitions[key].insert ( transition.second );
@@ -229,7 +229,7 @@ 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 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 > ( );
diff --git a/alib2data/src/automaton/FSM/ExtendedNFA.h b/alib2data/src/automaton/FSM/ExtendedNFA.h
index 4b2d133c90..67f6cd1145 100644
--- a/alib2data/src/automaton/FSM/ExtendedNFA.h
+++ b/alib2data/src/automaton/FSM/ExtendedNFA.h
@@ -42,7 +42,7 @@ public:
 	explicit ExtendedNFA ( const EpsilonNFA & other );
 	explicit ExtendedNFA ( const MultiInitialStateNFA & other );
 	explicit ExtendedNFA ( const NFA & other );
-	explicit ExtendedNFA ( const DFA & 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 92243808c4..6912e5ee5f 100644
--- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
+++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.cpp
@@ -27,7 +27,7 @@ MultiInitialStateNFA::MultiInitialStateNFA ( std::set < label::Label > states, s
 MultiInitialStateNFA::MultiInitialStateNFA ( ) : MultiInitialStateNFA ( std::set < label::Label > { }, std::set < alphabet::Symbol > { }, std::set < label::Label > { }, std::set < label::Label > { } ) {
 }
 
-MultiInitialStateNFA::MultiInitialStateNFA ( const DFA & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) {
+MultiInitialStateNFA::MultiInitialStateNFA ( const DFA<> & other ) : MultiInitialStateNFA ( other.getStates ( ), other.getInputAlphabet ( ), { other.getInitialState ( ) }, other.getFinalStates ( ) ) {
 	for ( const auto & transition : other.getTransitions ( ) )
 		transitions[transition.first].insert ( transition.second );
 }
@@ -209,7 +209,7 @@ namespace alib {
 auto multiInitialStateNFAParserRegister = xmlApi < automaton::Automaton >::ParserRegister < automaton::MultiInitialStateNFA > ( );
 auto multiInitialStateNFAParserRegister2 = xmlApi < alib::Object >::ParserRegister < automaton::MultiInitialStateNFA > ( );
 
-auto MultiInitialStateNFAFromDFA = castApi::CastRegister < automaton::MultiInitialStateNFA, automaton::DFA > ( );
+auto MultiInitialStateNFAFromDFA = castApi::CastRegister < automaton::MultiInitialStateNFA, automaton::DFA < > > ( );
 auto MultiInitialStateNFAFromNFA = castApi::CastRegister < automaton::MultiInitialStateNFA, automaton::NFA > ( );
 auto MultiInitialStateNFACastBinder = castApi::CastPoolStringBinder < automaton::MultiInitialStateNFA > ( automaton::MultiInitialStateNFA::getXmlTagName() );
 
diff --git a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
index 331f07532c..057d6af687 100644
--- a/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
+++ b/alib2data/src/automaton/FSM/MultiInitialStateNFA.h
@@ -36,7 +36,7 @@ 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 DFA & 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 a3d3363ccd..ea9a8f33e9 100644
--- a/alib2data/src/automaton/FSM/NFA.cpp
+++ b/alib2data/src/automaton/FSM/NFA.cpp
@@ -25,7 +25,7 @@ NFA::NFA ( std::set < label::Label > states, std::set < alphabet::Symbol > input
 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 ( ) ) {
+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 );
 }
@@ -201,7 +201,7 @@ namespace alib {
 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 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 d85657225f..e4a740320e 100644
--- a/alib2data/src/automaton/FSM/NFA.h
+++ b/alib2data/src/automaton/FSM/NFA.h
@@ -35,7 +35,7 @@ protected:
 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 ( const DFA<> & other );
 
 	virtual AutomatonBase * clone ( ) const;
 
diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp
index 48f84367e3..925b389348 100644
--- a/alib2data/test-src/automaton/AutomatonTest.cpp
+++ b/alib2data/test-src/automaton/AutomatonTest.cpp
@@ -34,7 +34,7 @@ void AutomatonTest::tearDown() {
 }
 
 void AutomatonTest::testDFAParser() {
-	automaton::DFA automaton(label::labelFrom(1));
+	automaton::DFA<> automaton(label::labelFrom(1));
 
 	automaton.addState(label::labelFrom(1));
 	automaton.addState(label::labelFrom(2));
@@ -55,7 +55,7 @@ void AutomatonTest::testDFAParser() {
 
 		std::deque<sax::Token> tokens2;
 		sax::SaxParseInterface::parseMemory(tmp, tokens2);
-		automaton::DFA automaton2 = alib::XmlDataFactory::fromTokens<automaton::DFA>(std::move(tokens2));
+		automaton::DFA<> automaton2 = alib::XmlDataFactory::fromTokens<automaton::DFA<>>(std::move(tokens2));
 
 		CPPUNIT_ASSERT( automaton == automaton2 );
 	}
diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
index b3429eb5a3..30a8eb2cd3 100644
--- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
@@ -85,14 +85,14 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 
 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>> AllEpsilonClosure::allEpsilonClosure( const automaton::DFA < > & fsm) {
 	std::map<label::Label, std::set<label::Label>> closure;
 	for(const label::Label& state : fsm.getStates())
 		closure[state].insert(state);
 	return closure;
 }
 
-auto AllEpsilonClosureDFA = AllEpsilonClosure::RegistratorWrapper<std::map<label::Label, std::set<label::Label>>, automaton::DFA>(AllEpsilonClosure::allEpsilonClosure);
+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>> res;
diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
index 7ab595e8bb..dc6c20f367 100644
--- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
+++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.h
@@ -33,7 +33,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::DFA & 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 f9e14f5492..456a307a10 100644
--- a/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/ReachableStates.cpp
@@ -79,7 +79,7 @@ std::set<label::Label> ReachableStates::reachableStates( const automaton::MultiI
 auto ReachableStatesMultiInitialStateNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA>(ReachableStates::reachableStates);
 
 template<>
-std::set<label::Label> ReachableStates::reachableStates( const automaton::DFA & fsm ) {
+std::set<label::Label> ReachableStates::reachableStates( const automaton::DFA < > & fsm ) {
 	std::map<label::Label, std::set<label::Label>> transitions;
 	for(const auto& transition : fsm.getTransitions())
 		transitions[transition.first.first].insert(transition.second);
@@ -100,7 +100,7 @@ std::set<label::Label> ReachableStates::reachableStates( const automaton::DFA &
 	return visited;
 }
 
-auto ReachableStatesDFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA>(ReachableStates::reachableStates);
+auto ReachableStatesDFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(ReachableStates::reachableStates);
 
 } /* namespace efficient */
 
diff --git a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
index d7b919241f..fc77c6e575 100644
--- a/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/UsefullStates.cpp
@@ -57,7 +57,7 @@ auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label
 auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA>(UsefullStates::usefullStates);
 
 template<>
-std::set<label::Label> UsefullStates::usefullStates( const automaton::DFA & fsm ) {
+std::set<label::Label> UsefullStates::usefullStates( const automaton::DFA < > & fsm ) {
 	std::map<label::Label, std::set<label::Label>> reversedTransitions;
 	for(const auto& transition : fsm.getTransitions())
 		reversedTransitions[transition.second].insert(transition.first.first);
@@ -78,7 +78,7 @@ std::set<label::Label> UsefullStates::usefullStates( const automaton::DFA & fsm
 	return visited;
 }
 
-auto UsefullStatesDFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA>(UsefullStates::usefullStates);
+auto UsefullStatesDFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(UsefullStates::usefullStates);
 
 } /* namespace efficient */
 
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp
index 315cdf09bf..7696d9566b 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.cpp
@@ -15,11 +15,11 @@ namespace simplify {
 
 namespace efficient {
 
-automaton::DFA EpsilonRemoverIncoming::remove(const automaton::DFA& origFSM) {
+automaton::DFA<> EpsilonRemoverIncoming::remove(const automaton::DFA<>& origFSM) {
 	return origFSM;
 }
 
-auto EpsilonRemoverIncomingDFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::DFA, automaton::DFA>(EpsilonRemoverIncoming::remove);
+auto EpsilonRemoverIncomingDFA = EpsilonRemoverIncoming::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(EpsilonRemoverIncoming::remove);
 
 automaton::MultiInitialStateNFA EpsilonRemoverIncoming::remove(const automaton::MultiInitialStateNFA& origFSM) {
 	return origFSM;
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h
index 3107407867..08f2897608 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverIncoming.h
@@ -35,7 +35,7 @@ public:
 	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::DFA remove( const automaton::DFA & fsm );
+	static automaton::DFA<> remove( const automaton::DFA<> & fsm );
 };
 
 } /* namespace efficient */
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp
index d957ab3b49..1922edc084 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.cpp
@@ -15,11 +15,11 @@ namespace simplify {
 
 namespace efficient {
 
-automaton::DFA EpsilonRemoverOutgoing::remove(const automaton::DFA& origFSM) {
+automaton::DFA<> EpsilonRemoverOutgoing::remove(const automaton::DFA<>& origFSM) {
 	return origFSM;
 }
 
-auto EpsilonRemoverOutgoingDFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::DFA, automaton::DFA>(EpsilonRemoverOutgoing::remove);
+auto EpsilonRemoverOutgoingDFA = EpsilonRemoverOutgoing::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(EpsilonRemoverOutgoing::remove);
 
 automaton::MultiInitialStateNFA EpsilonRemoverOutgoing::remove(const automaton::MultiInitialStateNFA& origFSM) {
 	return origFSM;
diff --git a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h
index c2449e1fa0..e2e595cf70 100644
--- a/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h
+++ b/alib2elgo/src/automaton/simplify/efficient/EpsilonRemoverOutgoing.h
@@ -35,7 +35,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::DFA remove( const automaton::DFA & fsm );
+	static automaton::DFA<> remove( const automaton::DFA<> & fsm );
 };
 
 } /* namespace efficient */
diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
index 8cda3ef4e0..85963a2587 100644
--- a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
@@ -28,7 +28,7 @@ T Trim::trim( const T & fsm ) {
 	return UnreachableStatesRemover::remove(UselessStatesRemover::remove(fsm));
 }
 
-auto TrimDFA = Trim::RegistratorWrapper<automaton::DFA, automaton::DFA>(Trim::trim);
+auto TrimDFA = Trim::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(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);
diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
index 679e817e85..73ea75b005 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
@@ -57,12 +57,12 @@ auto UnreachableStatesRemoverCompactNFA = UnreachableStatesRemover::RegistratorW
 auto UnreachableStatesRemoverExtendedNFA = UnreachableStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UnreachableStatesRemover::remove);
 
 template<>
-automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) {
+automaton::DFA<> UnreachableStatesRemover::remove( const automaton::DFA<> & fsm ) {
 	// 1a
 	std::set<label::Label> Qa = automaton::properties::efficient::ReachableStates::reachableStates( fsm );
 
 	// 2
-	automaton::DFA M(fsm.getInitialState() );
+	automaton::DFA<> M(fsm.getInitialState() );
 
 	for( const auto & q : Qa )
 		M.addState( q );
@@ -82,7 +82,7 @@ automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) {
 	return M;
 }
 
-auto UnreachableStatesRemoverDFA = UnreachableStatesRemover::RegistratorWrapper<automaton::DFA, automaton::DFA>(UnreachableStatesRemover::remove);
+auto UnreachableStatesRemoverDFA = UnreachableStatesRemover::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(UnreachableStatesRemover::remove);
 
 template<>
 automaton::MultiInitialStateNFA UnreachableStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) {
diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
index 346ddcdf98..91705d4600 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
@@ -59,12 +59,12 @@ auto UselessStatesRemoverCompactNFA = UselessStatesRemover::RegistratorWrapper<a
 auto UselessStatesRemoverExtendedNFA = UselessStatesRemover::RegistratorWrapper<automaton::ExtendedNFA, automaton::ExtendedNFA>(UselessStatesRemover::remove);
 
 template<>
-automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) {
+automaton::DFA<> UselessStatesRemover::remove( const automaton::DFA<> & fsm ) {
 	// 1.
 	std::set<label::Label> Qu = automaton::properties::efficient::UsefullStates::usefullStates( fsm );
 
 	// 2.
-	automaton::DFA M ( fsm.getInitialState () );
+	automaton::DFA<> M ( fsm.getInitialState () );
 
 	for( const auto & a : fsm.getInputAlphabet( ) )
 		M.addInputSymbol( a );
@@ -86,7 +86,7 @@ automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) {
 	return M;
 }
 
-auto UselessStatesRemoverDFA = UselessStatesRemover::RegistratorWrapper<automaton::DFA, automaton::DFA>(UselessStatesRemover::remove);
+auto UselessStatesRemoverDFA = UselessStatesRemover::RegistratorWrapper<automaton::DFA<>, automaton::DFA<>>(UselessStatesRemover::remove);
 
 template<>
 automaton::MultiInitialStateNFA UselessStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) {
diff --git a/alib2elgo/test-src/automaton/simplify/efficient/trimTest.cpp b/alib2elgo/test-src/automaton/simplify/efficient/trimTest.cpp
index 0a2810eedc..5b99df1faf 100644
--- a/alib2elgo/test-src/automaton/simplify/efficient/trimTest.cpp
+++ b/alib2elgo/test-src/automaton/simplify/efficient/trimTest.cpp
@@ -17,7 +17,7 @@ void trimTest::tearDown() {
 }
 
 void trimTest::testTrimAutomaton() {
-  automaton::DFA automaton(label::labelFrom(1));
+  automaton::DFA<> automaton(label::labelFrom(1));
 
   automaton.addState(label::labelFrom(1));
   automaton.addState(label::labelFrom(2));
@@ -31,7 +31,7 @@ void trimTest::testTrimAutomaton() {
 
   automaton.addFinalState(label::labelFrom(1));
   
-  automaton::DFA trimed = automaton::simplify::Trim::trim(automaton);
+  automaton::DFA<> trimed = automaton::simplify::Trim::trim(automaton);
 
   CPPUNIT_ASSERT(trimed.getStates().size() == 2);
 }
diff --git a/alib2str/src/automaton/AutomatonFromStringParser.cpp b/alib2str/src/automaton/AutomatonFromStringParser.cpp
index 57bc025f29..64dadae7b5 100644
--- a/alib2str/src/automaton/AutomatonFromStringParser.cpp
+++ b/alib2str/src/automaton/AutomatonFromStringParser.cpp
@@ -190,7 +190,7 @@ NFA AutomatonFromStringParser::parseNFA(std::istream& input) const {
 	return  res;
 }
 
-DFA AutomatonFromStringParser::parseDFA(std::istream& input) const {
+DFA<> AutomatonFromStringParser::parseDFA(std::istream& input) const {
 	AutomatonFromStringLexer::Token token = m_AutomatonLexer.next(input);
 	if(token.type != AutomatonFromStringLexer::TokenType::DFA) {
 		throw exception::CommonException("Unrecognised DFA token.");
@@ -227,7 +227,7 @@ DFA AutomatonFromStringParser::parseDFA(std::istream& input) const {
 
 	if(initialState == NULL) throw exception::CommonException("No initial state recognised.");
 
-	DFA res(*initialState);
+	DFA<> 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 29f7035870..cf0e1a1e11 100644
--- a/alib2str/src/automaton/AutomatonFromStringParser.h
+++ b/alib2str/src/automaton/AutomatonFromStringParser.h
@@ -49,7 +49,7 @@ private:
 	EpsilonNFA parseEpsilonNFA(std::istream& input) const;
 	NFA parseNFA(std::istream& input) const;
 	MultiInitialStateNFA parseMultiInitialStateNFA(std::istream& input) const;
-	DFA parseDFA(std::istream& input) const;
+	DFA<> parseDFA(std::istream& input) const;
 
 	template<typename T> friend struct alib::stringApi;
 };
diff --git a/alib2str/src/automaton/AutomatonToStringComposer.cpp b/alib2str/src/automaton/AutomatonToStringComposer.cpp
index 21755302ae..2ecd955d52 100644
--- a/alib2str/src/automaton/AutomatonToStringComposer.cpp
+++ b/alib2str/src/automaton/AutomatonToStringComposer.cpp
@@ -16,7 +16,7 @@
 
 namespace automaton {
 
-void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const DFA& automaton, const label::Label& from) {
+void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const DFA<>& automaton, const label::Label& from) {
 	std::map<std::pair<label::Label, alphabet::Symbol>, label::Label> symbolTransitionsFromState = automaton.getTransitionsFromState(from);
 
 	for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) {
@@ -96,7 +96,7 @@ void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, c
 	}
 }
 
-void AutomatonToStringComposer::compose(std::ostream& out, const DFA& automaton) {
+void AutomatonToStringComposer::compose(std::ostream& out, const DFA<>& automaton) {
 	out << "DFA";
 	for(const auto& symbol : automaton.getInputAlphabet()) {
 		out << " ";
@@ -120,7 +120,7 @@ void AutomatonToStringComposer::compose(std::ostream& out, const DFA& automaton)
 	}
 }
 
-AutomatonToStringComposer::RegistratorWrapper<void, DFA> AutomatonToStringComposerDFA = AutomatonToStringComposer::RegistratorWrapper<void, DFA>(AutomatonToStringComposer::compose);
+AutomatonToStringComposer::RegistratorWrapper<void, DFA<>> AutomatonToStringComposerDFA = AutomatonToStringComposer::RegistratorWrapper<void, DFA<>>(AutomatonToStringComposer::compose);
 
 void AutomatonToStringComposer::compose(std::ostream& out, const NFA& automaton) {
 	out << "NFA";
diff --git a/alib2str/src/automaton/AutomatonToStringComposer.h b/alib2str/src/automaton/AutomatonToStringComposer.h
index b6715505bc..cc261b7136 100644
--- a/alib2str/src/automaton/AutomatonToStringComposer.h
+++ b/alib2str/src/automaton/AutomatonToStringComposer.h
@@ -17,7 +17,7 @@
 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 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,7 +30,7 @@ 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 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);
-- 
GitLab