From cd3cd41469aaf5c8cb02029292c6074757e0636c Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 21 Aug 2016 20:59:00 +0200
Subject: [PATCH] make OneTapeDTM templated + minimal needed changes

---
 acompare2/src/AutomatonCompare.cpp            |   8 +-
 acompare2/src/AutomatonCompare.h              |   6 +-
 aconvert2/src/DotConverter.cpp                |   6 +-
 aconvert2/src/DotConverter.h                  |   4 +-
 aconvert2/src/GasTexConverter.cpp             |   6 +-
 aconvert2/src/GasTexConverter.h               |   4 +-
 aconvert2/src/TikZConverter.cpp               |   6 +-
 aconvert2/src/TikZConverter.h                 |   4 +-
 .../src/automaton/determinize/Determinize.cpp |   4 +-
 .../src/automaton/determinize/Determinize.h   |   3 +-
 alib2data/src/automaton/AutomatonFeatures.h   |   4 +
 alib2data/src/automaton/TM/OneTapeDTM.cpp     | 174 +--------
 alib2data/src/automaton/TM/OneTapeDTM.h       | 351 +++++++++++++-----
 13 files changed, 298 insertions(+), 282 deletions(-)

diff --git a/acompare2/src/AutomatonCompare.cpp b/acompare2/src/AutomatonCompare.cpp
index 0f8133e70f..fd8721d811 100644
--- a/acompare2/src/AutomatonCompare.cpp
+++ b/acompare2/src/AutomatonCompare.cpp
@@ -214,7 +214,7 @@ bool AutomatonCompare::testCompare(const automaton::SinglePopNPDA& a, const auto
 			a.getTransitions()    == b.getTransitions()    ;
 }
 
-bool AutomatonCompare::testCompare(const automaton::OneTapeDTM& a, const automaton::OneTapeDTM& b) {
+bool AutomatonCompare::testCompare(const automaton::OneTapeDTM<>& a, const automaton::OneTapeDTM<>& b) {
 	return  	a.getBlankSymbol()    == b.getBlankSymbol()    &&
 			a.getFinalStates()    == b.getFinalStates()    &&
 			a.getInitialState()   == b.getInitialState()   &&
@@ -1122,7 +1122,7 @@ void AutomatonCompare::printCompare(const automaton::SinglePopNPDA& a, const aut
 	}
 }
 
-void AutomatonCompare::printCompare(const automaton::OneTapeDTM& a, const automaton::OneTapeDTM& b) {
+void AutomatonCompare::printCompare(const automaton::OneTapeDTM<>& a, const automaton::OneTapeDTM<>& b) {
 	std::cout << "AutomatonCompareer" << std::endl;
 
 	if(a.getBlankSymbol() != b.getBlankSymbol()) {
@@ -1370,7 +1370,7 @@ int AutomatonCompare::compare(const automaton::SinglePopNPDA& a, const automaton
 
 auto AutomatonCompareSinglePopNPDA = AutomatonCompare::RegistratorWrapper<int, automaton::SinglePopNPDA, automaton::SinglePopNPDA>(AutomatonCompare::compare);
 
-int AutomatonCompare::compare(const automaton::OneTapeDTM& a, const automaton::OneTapeDTM& b) {
+int AutomatonCompare::compare(const automaton::OneTapeDTM<>& a, const automaton::OneTapeDTM<>& b) {
 	if(!AutomatonCompare::testCompare(a, b)) {
 	  AutomatonCompare::printCompare(a, b);
 	  return 1;
@@ -1379,7 +1379,7 @@ int AutomatonCompare::compare(const automaton::OneTapeDTM& a, const automaton::O
 	}
 }
 
-auto AutomatonCompareOneTapeDTM = AutomatonCompare::RegistratorWrapper<int, automaton::OneTapeDTM, automaton::OneTapeDTM>(AutomatonCompare::compare);
+auto AutomatonCompareOneTapeDTM = AutomatonCompare::RegistratorWrapper<int, automaton::OneTapeDTM<>, automaton::OneTapeDTM<>>(AutomatonCompare::compare);
 
 int AutomatonCompare::compare(const automaton::Automaton& a, const automaton::Automaton& b) {
 	return dispatch(a.getData(), b.getData());
diff --git a/acompare2/src/AutomatonCompare.h b/acompare2/src/AutomatonCompare.h
index 9a9f3d1e65..a41607c2e8 100644
--- a/acompare2/src/AutomatonCompare.h
+++ b/acompare2/src/AutomatonCompare.h
@@ -74,8 +74,8 @@ private:
 	static bool testCompare(const automaton::SinglePopNPDA& a, const automaton::SinglePopNPDA& b);
 	static void printCompare(const automaton::SinglePopNPDA& a, const automaton::SinglePopNPDA& b);
 
-	static bool testCompare(const automaton::OneTapeDTM& a, const automaton::OneTapeDTM& b);
-	static void printCompare(const automaton::OneTapeDTM& a, const automaton::OneTapeDTM& b);
+	static bool testCompare(const automaton::OneTapeDTM<>& a, const automaton::OneTapeDTM<>& b);
+	static void printCompare(const automaton::OneTapeDTM<>& a, const automaton::OneTapeDTM<>& b);
 
 	template <class T> static void setCompare(const std::set<T> a, const std::set<T> b);
 	template <class T> static void listCompare(const std::list<T> a, const std::list<T> b);
@@ -102,7 +102,7 @@ public:
 	static int compare(const automaton::VisiblyPushdownDPDA& a, const automaton::VisiblyPushdownDPDA& b);
 	static int compare(const automaton::VisiblyPushdownNPDA& a, const automaton::VisiblyPushdownNPDA& b);
 
-	static int compare(const automaton::OneTapeDTM& a, const automaton::OneTapeDTM& b);
+	static int compare(const automaton::OneTapeDTM<>& a, const automaton::OneTapeDTM<>& b);
 
 	static int compare(const automaton::Automaton& a, const automaton::Automaton& b);
 };
diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp
index 49ea9acfe4..2620e4ebb7 100644
--- a/aconvert2/src/DotConverter.cpp
+++ b/aconvert2/src/DotConverter.cpp
@@ -642,7 +642,7 @@ void DotConverter::convert(std::ostream& out, const automaton::SinglePopNPDA& a)
 
 auto DotConverterSinglePopNPDA = DotConverter::RegistratorWrapper<void, automaton::SinglePopNPDA>(DotConverter::convert);
 
-void DotConverter::convert(std::ostream& out, const automaton::OneTapeDTM& a) {
+void DotConverter::convert(std::ostream& out, const automaton::OneTapeDTM<>& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -673,7 +673,7 @@ void DotConverter::convert(std::ostream& out, const automaton::OneTapeDTM& a) {
 	out << "}";
 }
 
-auto DotConverterOneTapeDTM = DotConverter::RegistratorWrapper<void, automaton::OneTapeDTM>(DotConverter::convert);
+auto DotConverterOneTapeDTM = DotConverter::RegistratorWrapper<void, automaton::OneTapeDTM<>>(DotConverter::convert);
 
 void DotConverter::transitions(const automaton::EpsilonNFA& fsm, const std::map<label::Label, int>& states, std::ostream& out) {
 	std::map<std::pair<int, int>, std::string> transitions;
@@ -1829,7 +1829,7 @@ void DotConverter::transitions(const automaton::SinglePopNPDA& pda, const std::m
 	}
 }
 
-void DotConverter::transitions(const automaton::OneTapeDTM& tm, const std::map<label::Label, int>& states, std::ostream& out) {
+void DotConverter::transitions(const automaton::OneTapeDTM<>& tm, const std::map<label::Label, int>& states, std::ostream& out) {
 	std::map<std::pair<int, int>, std::string> transitions;
 	for (const auto& transition : tm.getTransitions()) {
 		std::string symbol;
diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h
index 1def7ec4b9..56538a5027 100644
--- a/aconvert2/src/DotConverter.h
+++ b/aconvert2/src/DotConverter.h
@@ -38,7 +38,7 @@ class DotConverter : public std::SingleDispatchFirstStaticParam<DotConverter, vo
 	static void transitions(const automaton::RealTimeHeightDeterministicNPDA& tm, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::NPDA& pda, const std::map<label::Label, int>& states, std::ostream& out);
 	static void transitions(const automaton::SinglePopNPDA& tm, const std::map<label::Label, int>& states, std::ostream& out);
-	static void transitions(const automaton::OneTapeDTM& tm, const std::map<label::Label, int>& states, std::ostream& out);
+	static void transitions(const automaton::OneTapeDTM<>& tm, const std::map<label::Label, int>& states, std::ostream& out);
 public:
 	static void convert(std::ostream& out, const automaton::Automaton& a);
 
@@ -60,7 +60,7 @@ public:
 	static void convert(std::ostream& out, const automaton::RealTimeHeightDeterministicNPDA& a);
 	static void convert(std::ostream& out, const automaton::NPDA& a);
 	static void convert(std::ostream& out, const automaton::SinglePopNPDA& a);
-	static void convert(std::ostream& out, const automaton::OneTapeDTM& a);
+	static void convert(std::ostream& out, const automaton::OneTapeDTM<>& a);
 };
 
 #endif /* DOT_CONVERTER_H_ */
diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp
index c0912ca943..9ebe828f08 100644
--- a/aconvert2/src/GasTexConverter.cpp
+++ b/aconvert2/src/GasTexConverter.cpp
@@ -706,7 +706,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::SinglePopNPDA&
 
 auto GasTexConverterSinglePopNPDA = GasTexConverter::RegistratorWrapper<void, automaton::SinglePopNPDA>(GasTexConverter::convert);
 
-void GasTexConverter::convert(std::ostream& out, const automaton::OneTapeDTM& a) {
+void GasTexConverter::convert(std::ostream& out, const automaton::OneTapeDTM<>& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -745,7 +745,7 @@ void GasTexConverter::convert(std::ostream& out, const automaton::OneTapeDTM& a)
 	out << "\\end{picture}\n";
 }
 
-auto GasTexConverterOneTapeDTM = GasTexConverter::RegistratorWrapper<void, automaton::OneTapeDTM>(GasTexConverter::convert);
+auto GasTexConverterOneTapeDTM = GasTexConverter::RegistratorWrapper<void, automaton::OneTapeDTM<>>(GasTexConverter::convert);
 
 std::string GasTexConverter::getStackSymbols(const std::vector<alphabet::Symbol>& stackSymbols) {
 	if (stackSymbols.size() == 0) {
@@ -1394,7 +1394,7 @@ void GasTexConverter::transitions(const automaton::SinglePopNPDA& pda, std::ostr
 	printTransitionMap(transitionMap, out);
 }
 
-void GasTexConverter::transitions(const automaton::OneTapeDTM& tm, std::ostream& out) {
+void GasTexConverter::transitions(const automaton::OneTapeDTM<>& tm, std::ostream& out) {
 	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
 
 	for (auto& transition : tm.getTransitions()) {
diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h
index c054794d03..eb896f4b9d 100644
--- a/aconvert2/src/GasTexConverter.h
+++ b/aconvert2/src/GasTexConverter.h
@@ -39,7 +39,7 @@ class GasTexConverter : public std::SingleDispatchFirstStaticParam<GasTexConvert
 	static void transitions(const automaton::RealTimeHeightDeterministicNPDA& tm, std::ostream& out);
 	static void transitions(const automaton::NPDA& pda, std::ostream& out);
 	static void transitions(const automaton::SinglePopNPDA& tm, std::ostream& out);
-	static void transitions(const automaton::OneTapeDTM& tm, std::ostream& out);
+	static void transitions(const automaton::OneTapeDTM<>& tm, std::ostream& out);
 public:
 	static void convert(std::ostream& out, const automaton::Automaton& a);
 
@@ -61,7 +61,7 @@ public:
 	static void convert(std::ostream& out, const automaton::RealTimeHeightDeterministicNPDA& a);
 	static void convert(std::ostream& out, const automaton::NPDA& a);
 	static void convert(std::ostream& out, const automaton::SinglePopNPDA& a);
-	static void convert(std::ostream& out, const automaton::OneTapeDTM& a);
+	static void convert(std::ostream& out, const automaton::OneTapeDTM<>& a);
 };
 
 #endif /* GAS_TEX_CONVERTER_H_ */
diff --git a/aconvert2/src/TikZConverter.cpp b/aconvert2/src/TikZConverter.cpp
index 1c7b0125ce..07eaefd2f5 100644
--- a/aconvert2/src/TikZConverter.cpp
+++ b/aconvert2/src/TikZConverter.cpp
@@ -567,7 +567,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::SinglePopNPDA
 
 auto TikZConverterSinglePopNPDA = TikZConverter::RegistratorWrapper < void, automaton::SinglePopNPDA > ( TikZConverter::convert );
 
-void TikZConverter::convert ( std::ostream & out, const automaton::OneTapeDTM & a ) {
+void TikZConverter::convert ( std::ostream & out, const automaton::OneTapeDTM < > & a ) {
 	out << "\\begin{tikzpicture}\n";
 	int cnt = 1;
 
@@ -594,7 +594,7 @@ void TikZConverter::convert ( std::ostream & out, const automaton::OneTapeDTM &
 	out << "\\end{tikzpicture}";
 }
 
-auto TikZConverterOneTapeDTM = TikZConverter::RegistratorWrapper < void, automaton::OneTapeDTM > ( TikZConverter::convert );
+auto TikZConverterOneTapeDTM = TikZConverter::RegistratorWrapper < void, automaton::OneTapeDTM < > > ( TikZConverter::convert );
 
 void TikZConverter::transitions ( const automaton::EpsilonNFA & fsm, const std::map < label::Label, int > & states, std::ostream & out ) {
 	std::map < std::pair < int, int >, std::string > transitions;
@@ -1919,7 +1919,7 @@ void TikZConverter::transitions ( const automaton::SinglePopNPDA & pda, const st
 	}
 }
 
-void TikZConverter::transitions ( const automaton::OneTapeDTM & tm, const std::map < label::Label, int > & states, std::ostream & out ) {
+void TikZConverter::transitions ( const automaton::OneTapeDTM < > & tm, const std::map < label::Label, int > & states, std::ostream & out ) {
 	std::map < std::pair < int, int >, std::string > transitions;
 
 	for ( const auto & transition : tm.getTransitions ( ) ) {
diff --git a/aconvert2/src/TikZConverter.h b/aconvert2/src/TikZConverter.h
index 2cf8187a65..8504ef8d45 100644
--- a/aconvert2/src/TikZConverter.h
+++ b/aconvert2/src/TikZConverter.h
@@ -38,7 +38,7 @@ class TikZConverter : public std::SingleDispatchFirstStaticParam < TikZConverter
 	static void transitions ( const automaton::RealTimeHeightDeterministicNPDA & tm, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::NPDA & pda, const std::map < label::Label, int > & states, std::ostream & out );
 	static void transitions ( const automaton::SinglePopNPDA & tm, const std::map < label::Label, int > & states, std::ostream & out );
-	static void transitions ( const automaton::OneTapeDTM & tm, const std::map < label::Label, int > & states, std::ostream & out );
+	static void transitions ( const automaton::OneTapeDTM < > & tm, const std::map < label::Label, int > & states, std::ostream & out );
 
 public:
 	static void convert ( std::ostream & out, const automaton::Automaton & a );
@@ -61,7 +61,7 @@ public:
 	static void convert ( std::ostream & out, const automaton::RealTimeHeightDeterministicNPDA & a );
 	static void convert ( std::ostream & out, const automaton::NPDA & a );
 	static void convert ( std::ostream & out, const automaton::SinglePopNPDA & a );
-	static void convert ( std::ostream & out, const automaton::OneTapeDTM & a );
+	static void convert ( std::ostream & out, const automaton::OneTapeDTM < > & a );
 
 };
 
diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp
index df8725eef9..6a46bd6835 100644
--- a/alib2algo/src/automaton/determinize/Determinize.cpp
+++ b/alib2algo/src/automaton/determinize/Determinize.cpp
@@ -73,11 +73,11 @@ DPDA Determinize::determinize(const automaton::NPDA& automaton) {
 
 auto DeterminizeNPDA = Determinize::RegistratorWrapper<automaton::DPDA, automaton::NPDA>(Determinize::determinize);
 
-OneTapeDTM Determinize::determinize(const automaton::OneTapeDTM& automaton) {
+OneTapeDTM<> Determinize::determinize(const automaton::OneTapeDTM<>& automaton) {
 	return automaton;
 }
 
-auto DeterminizeOneTapeDTM = Determinize::RegistratorWrapper<automaton::OneTapeDTM, automaton::OneTapeDTM>(Determinize::determinize);
+auto DeterminizeOneTapeDTM = Determinize::RegistratorWrapper<automaton::OneTapeDTM<>, automaton::OneTapeDTM<>>(Determinize::determinize);
 
 DFTA Determinize::determinize(const automaton::DFTA& automaton) {
 	return automaton;
diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h
index 383dc764b4..0bff365476 100644
--- a/alib2algo/src/automaton/determinize/Determinize.h
+++ b/alib2algo/src/automaton/determinize/Determinize.h
@@ -45,7 +45,8 @@ public:
 	static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicNPDA& nondeterministic);
 	static automaton::DFTA determinize(const automaton::DFTA& nfta);
 	static automaton::DFTA determinize(const automaton::NFTA& nfta);
-	static automaton::OneTapeDTM determinize(const automaton::OneTapeDTM& nfta);
+
+	static automaton::OneTapeDTM<> determinize(const automaton::OneTapeDTM<>& nfta);
 };
 
 } /* namespace determinize */
diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h
index f8264c73e9..6892a67bcc 100644
--- a/alib2data/src/automaton/AutomatonFeatures.h
+++ b/alib2data/src/automaton/AutomatonFeatures.h
@@ -8,6 +8,9 @@
 #ifndef AUTOMATON_FEATURES_H_
 #define AUTOMATON_FEATURES_H_
 
+#include <alphabet/Symbol.h>
+#include <label/Label.h>
+
 namespace automaton {
 
 enum class FEATURES {
@@ -53,6 +56,7 @@ class RealTimeHeightDeterministicNPDA;
 class NPDA;
 class NPDTA;
 class SinglePopNPDA;
+template<class SymbolType = typename alphabet::Symbol, class StateType = typename label::Label >
 class OneTapeDTM;
 class DFTA;
 class NFTA;
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.cpp b/alib2data/src/automaton/TM/OneTapeDTM.cpp
index 7cc4dd0e52..3bba04f249 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.cpp
+++ b/alib2data/src/automaton/TM/OneTapeDTM.cpp
@@ -2,183 +2,17 @@
  * OneTapeDTM.cpp
  *
  *  Created on: Apr 24, 2013
- *      Author: Martin Zak
+ *      Author: Jan Travnicek
  */
 
 #include "OneTapeDTM.h"
-#include <sstream>
-
-#include <sax/FromXMLParserHelper.h>
-#include "../common/AutomatonFromXMLParser.h"
-#include "../common/AutomatonToXMLComposer.h"
-#include "../Automaton.h"
+#include <automaton/Automaton.h>
 #include <object/Object.h>
 #include <XmlApi.hpp>
 
-namespace automaton {
-
-OneTapeDTM::OneTapeDTM ( std::set < label::Label > states, std::set < alphabet::Symbol > tapeAlphabet, alphabet::Symbol blankSymbol, std::set< alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates ) : std::Components < OneTapeDTM, alphabet::Symbol, std::tuple < TapeAlphabet, InputAlphabet >, std::tuple < BlankSymbol >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > ( std::make_tuple ( std::move ( tapeAlphabet), std::move ( inputAlphabet ) ), std::make_tuple ( blankSymbol ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::make_tuple ( std::move ( initialState ) ) ) {
-
-}
-
-OneTapeDTM::OneTapeDTM(label::Label initial, alphabet::Symbol blank) : OneTapeDTM(std::set<label::Label>{initial}, std::set<alphabet::Symbol> {blank}, blank, std::set<alphabet::Symbol>{}, initial, std::set<label::Label>{}) {
-
-}
-
-AutomatonBase* OneTapeDTM::clone() const {
-	return new OneTapeDTM(*this);
-}
-
-AutomatonBase* OneTapeDTM::plunder() && {
-	return new OneTapeDTM(std::move(*this));
-}
-
-bool OneTapeDTM::addTransition(label::Label from, alphabet::Symbol input, label::Label to, alphabet::Symbol output, Shift shift) {
-	if (!getStates().count(from)) {
-		throw AutomatonException("State \"" + (std::string) from + "\" doesn't exist.");
-	}
-
-	if (!getTapeAlphabet().count(input)) {
-		throw AutomatonException("Tape symbol \"" + (std::string) input + "\" doesn't exist.");
-	}
-
-	if (!getStates().count(to)) {
-		throw AutomatonException("State \"" + (std::string) to + "\" doesn't exist.");
-	}
-
-	if (!getTapeAlphabet().count(output)) {
-		throw AutomatonException("Tape symbol  \"" + (std::string) output + "\" doesn't exist.");
-	}
-
-	std::pair<label::Label, alphabet::Symbol> key = std::make_pair(std::move(from), std::move(input));
-
-	std::tuple<label::Label, alphabet::Symbol, Shift > value(std::move(to), std::move(output), shift);
-
-	if (transitions.find(key) != transitions.end()) {
-		if(transitions.find(key)->second == value)
-			return false;
-		else
-			throw AutomatonException("Transition (\"" + (std::string) key.first + "\", \"" + (std::string) key.second + "\") -> ? already exists.");
-	}
-
-	transitions.insert(std::make_pair(std::move(key), std::move(value)));
-	return true;
-}
-
-bool OneTapeDTM::removeTransition(const label::Label& from, const alphabet::Symbol& input, const label::Label& to, const alphabet::Symbol& output, const Shift& shift) {
-	std::pair<label::Label, alphabet::Symbol> key = std::make_pair(from, input);
-
-	if (transitions.find(key) == transitions.end())
-		return false;
-
-	std::tuple<label::Label, alphabet::Symbol, Shift > value(to, output, shift);
-	if(transitions.find(key)->second != value) 
-		throw AutomatonException("Transition (\"" + (std::string) from + "\", \"" + (std::string) input + "\") -> ? doesn't exists.");
-
-	transitions.erase(key);
-	return true;
-}
-
-const std::map<std::pair<label::Label, alphabet::Symbol>, std::tuple<label::Label, alphabet::Symbol, Shift> >& OneTapeDTM::getTransitions() const {
-	return transitions;
-}
-
-int OneTapeDTM::compare(const OneTapeDTM& other) const {
-	auto first = std::tie(getStates(), getInputAlphabet(), getInitialState(), getFinalStates(), getTapeAlphabet(), getBlankSymbol(), transitions);
-	auto second = std::tie(other.getStates(), other.getInputAlphabet(), other.getInitialState(), other.getFinalStates(), other.getTapeAlphabet(), other.getBlankSymbol(), other.transitions);
-
-	std::compare<decltype(first)> comp;
-	return comp(first, second);
-}
-
-void OneTapeDTM::operator>>(std::ostream& out) const {
-	out << "(OneTapeDTM "
-			<< "states = " << getStates()
-			<< "inputAlphabet = " << getInputAlphabet()
-			<< "initialState = " << getInitialState()
-			<< "finalStates = " << getFinalStates()
-			<< "tapeAlphabet = " << getTapeAlphabet()
-			<< "blankSymbol = " << getBlankSymbol()
-			<< "transitions = " << transitions
-			<< ")";
-}
-
-OneTapeDTM::operator std::string () const {
-	std::stringstream ss;
-	ss << *this;
-	return ss.str();
-}
-
-OneTapeDTM OneTapeDTM::parse(std::deque<sax::Token>::iterator& input) {
-	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, OneTapeDTM::getXmlTagName());
-
-	std::set<label::Label> states = AutomatonFromXMLParser::parseStates(input);
-	std::set<alphabet::Symbol> tapeSymbols = AutomatonFromXMLParser::parseTapeAlphabet(input);
-	std::set<alphabet::Symbol> inputSymbols = AutomatonFromXMLParser::parseInputAlphabet(input);
-	alphabet::Symbol blank = AutomatonFromXMLParser::parseBlankSymbol(input);
-	label::Label initialState = AutomatonFromXMLParser::parseInitialState(input);
-	std::set<label::Label> finalStates = AutomatonFromXMLParser::parseFinalStates(input);
-
-	OneTapeDTM automaton(std::move(initialState), std::move(blank));
-	automaton.setStates(std::move(states));
-	automaton.setTapeAlphabet(std::move(tapeSymbols));
-	automaton.setInputAlphabet(std::move(inputSymbols));
-	automaton.setFinalStates(std::move(finalStates));
-
-	AutomatonFromXMLParser::parseTransitions<OneTapeDTM>(input, automaton);
-
-	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, OneTapeDTM::getXmlTagName());
-	return automaton;
-}
-
-void OneTapeDTM::parseTransition(std::deque<sax::Token>::iterator& input, OneTapeDTM& 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);
-	alphabet::Symbol outputSymbol = AutomatonFromXMLParser::parseTransitionOutputSymbol(input);
-	Shift shift = AutomatonFromXMLParser::parseTransitionShift(input);
-	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, "transition");
-
-	automaton.addTransition(std::move(from), std::move(inputSymbol), std::move(to), std::move(outputSymbol), shift);
-}
-
-void OneTapeDTM::compose(std::deque<sax::Token>& out) const {
-	out.emplace_back(OneTapeDTM::getXmlTagName(), sax::Token::TokenType::START_ELEMENT);
-
-	AutomatonToXMLComposer::composeStates(out, this->getStates());
-	AutomatonToXMLComposer::composeTapeAlphabet(out, this->getTapeAlphabet());
-	AutomatonToXMLComposer::composeInputAlphabet(out, this->getInputAlphabet());
-	AutomatonToXMLComposer::composeBlankSymbol(out, this->getBlankSymbol());
-	AutomatonToXMLComposer::composeInitialState(out, this->getInitialState());
-	AutomatonToXMLComposer::composeFinalStates(out, this->getFinalStates());
-	composeTransitions(out);
-
-	out.emplace_back(OneTapeDTM::getXmlTagName(), sax::Token::TokenType::END_ELEMENT);
-}
-
-void OneTapeDTM::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, std::get<0>(transition.second));
-		AutomatonToXMLComposer::composeTransitionOutputSymbol(out, std::get<1>(transition.second));
-		AutomatonToXMLComposer::composeTransitionShift(out, std::get<2>(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 oneTapeDTMParserRegister = xmlApi<automaton::Automaton>::ParserRegister<automaton::OneTapeDTM>();
-auto oneTapeDTMParserRegister2 = xmlApi<alib::Object>::ParserRegister<automaton::OneTapeDTM>();
+auto oneTapeDTMParserRegister = xmlApi<automaton::Automaton>::ParserRegister<automaton::OneTapeDTM<>>();
+auto oneTapeDTMParserRegister2 = xmlApi<alib::Object>::ParserRegister<automaton::OneTapeDTM<>>();
 
 } /* namespace alib */
diff --git a/alib2data/src/automaton/TM/OneTapeDTM.h b/alib2data/src/automaton/TM/OneTapeDTM.h
index dd2f221b14..003eba8af1 100644
--- a/alib2data/src/automaton/TM/OneTapeDTM.h
+++ b/alib2data/src/automaton/TM/OneTapeDTM.h
@@ -3,6 +3,7 @@
  *
  *  Created on: Apr 24, 2013
  *      Author: Martin Zak
+ *      Author: Jan Travnicek
  */
 
 #ifndef ONE_TAPE_DTM_H_
@@ -11,13 +12,16 @@
 #include "../AutomatonException.h"
 #include "../AutomatonBase.h"
 #include <core/components.hpp>
-#include "../../alphabet/Symbol.h"
-#include "../../label/Label.h"
 #include "../common/Shift.h"
+#include "../AutomatonException.h"
+#include <sax/FromXMLParserHelper.h>
+#include "../common/AutomatonFromXMLParser.h"
+#include "../common/AutomatonToXMLComposer.h"
 
 #include <map>
 #include <set>
 #include <tuple>
+#include <sstream>
 
 namespace automaton {
 
@@ -31,105 +35,106 @@ class InitialState;
 /**
  * One tape turing machine
  */
-class OneTapeDTM : public AutomatonBase, public std::Components < OneTapeDTM, alphabet::Symbol, std::tuple < TapeAlphabet, InputAlphabet >, std::tuple < BlankSymbol >, label::Label, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
+template<class SymbolType, class StateType >
+class OneTapeDTM : public AutomatonBase, public std::Components < OneTapeDTM < SymbolType, StateType >, SymbolType, std::tuple < TapeAlphabet, InputAlphabet >, std::tuple < BlankSymbol >, StateType, std::tuple < States, FinalStates >, std::tuple < InitialState > > {
 protected:
-	std::map < std::pair < label::Label, alphabet::Symbol >, std::tuple < label::Label, alphabet::Symbol, Shift > > transitions;
+	std::map < std::pair < StateType, SymbolType >, std::tuple < StateType, SymbolType, Shift > > transitions;
 
 public:
-	explicit OneTapeDTM ( std::set < label::Label > states, std::set < alphabet::Symbol > tapeAlphabet, alphabet::Symbol blankSymbol, std::set< alphabet::Symbol > inputAlphabet, label::Label initialState, std::set < label::Label > finalStates );
+	explicit OneTapeDTM ( std::set < StateType > states, std::set < SymbolType > tapeAlphabet, SymbolType blankSymbol, std::set< SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates );
 
-	explicit OneTapeDTM ( label::Label initialState, alphabet::Symbol blank );
+	explicit OneTapeDTM ( StateType initialState, SymbolType blank );
 
 	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 );
 	}
 
-	const std::set < alphabet::Symbol > & getTapeAlphabet ( ) const {
-		return accessComponent < TapeAlphabet > ( ).get ( );
+	const std::set < SymbolType > & getTapeAlphabet ( ) const {
+		return this-> template accessComponent < TapeAlphabet > ( ).get ( );
 	}
 
-	bool addTapeSymbol ( alphabet::Symbol symbol ) {
-		return accessComponent < TapeAlphabet > ( ).add ( std::move ( symbol ) );
+	bool addTapeSymbol ( SymbolType symbol ) {
+		return this-> template accessComponent < TapeAlphabet > ( ).add ( std::move ( symbol ) );
 	}
 
-	void addTapeSymbols ( std::set < alphabet::Symbol > symbols ) {
-		accessComponent < TapeAlphabet > ( ).add ( std::move ( symbols ) );
+	void addTapeSymbols ( std::set < SymbolType > symbols ) {
+		this-> template accessComponent < TapeAlphabet > ( ).add ( std::move ( symbols ) );
 	}
 
-	void setTapeAlphabet ( std::set < alphabet::Symbol > symbols ) {
-		accessComponent < TapeAlphabet > ( ).set ( std::move ( symbols ) );
+	void setTapeAlphabet ( std::set < SymbolType > symbols ) {
+		this-> template accessComponent < TapeAlphabet > ( ).set ( std::move ( symbols ) );
 	}
 
-	void removeTapeSymbol ( const alphabet::Symbol & symbol ) {
-		accessComponent < TapeAlphabet > ( ).remove ( symbol );
+	void removeTapeSymbol ( const SymbolType & symbol ) {
+		this-> template accessComponent < TapeAlphabet > ( ).remove ( symbol );
 	}
 
-	const alphabet::Symbol & getBlankSymbol ( ) const {
-		return accessElement < BlankSymbol > ( ).get ( );
+	const SymbolType & getBlankSymbol ( ) const {
+		return this-> template accessElement < BlankSymbol > ( ).get ( );
 	}
 
-	bool setBlankSymbol ( alphabet::Symbol state ) {
-		return accessElement < BlankSymbol > ( ).set ( std::move ( state ) );
+	bool setBlankSymbol ( SymbolType state ) {
+		return this-> template accessElement < BlankSymbol > ( ).set ( std::move ( state ) );
 	}
 
 	/**
@@ -138,19 +143,19 @@ public:
 	 * @throws AutomatonException when some part of the transition is not present
 	 * in the TM (state, tape symbol) or when transition already exists
 	 */
-	bool addTransition ( label::Label from, alphabet::Symbol input, label::Label to, alphabet::Symbol output, Shift shift );
+	bool addTransition ( StateType from, SymbolType input, StateType to, SymbolType output, Shift shift );
 
 	/**
 	 * Removes the transition from the TM.
 	 * @param transition transition to remove
 	 * @throws AutomatonException when transition is not present in the TM
 	 */
-	bool removeTransition ( const label::Label & from, const alphabet::Symbol & input, const label::Label & to, const alphabet::Symbol & output, const Shift & shift );
+	bool removeTransition ( const StateType & from, const SymbolType & input, const StateType & to, const SymbolType & output, const Shift & shift );
 
 	/**
 	 * @return TM transitions
 	 */
-	const std::map < std::pair < label::Label, alphabet::Symbol >, std::tuple < label::Label, alphabet::Symbol, Shift > > & getTransitions ( ) const;
+	const std::map < std::pair < StateType, SymbolType >, std::tuple < StateType, SymbolType, Shift > > & getTransitions ( ) const;
 
 	virtual int compare ( const ObjectBase & other ) const {
 		if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other );
@@ -177,21 +182,192 @@ public:
 	void composeTransitions ( std::deque < sax::Token > & out ) const;
 };
 
+template<class SymbolType, class StateType >
+OneTapeDTM<SymbolType, StateType>::OneTapeDTM ( std::set < StateType > states, std::set < SymbolType > tapeAlphabet, SymbolType blankSymbol, std::set< SymbolType > inputAlphabet, StateType initialState, std::set < StateType > finalStates ) : std::Components < OneTapeDTM, SymbolType, std::tuple < TapeAlphabet, InputAlphabet >, std::tuple < BlankSymbol >, StateType, std::tuple < States, FinalStates >, std::tuple < InitialState > > ( std::make_tuple ( std::move ( tapeAlphabet), std::move ( inputAlphabet ) ), std::make_tuple ( blankSymbol ), std::make_tuple ( std::move ( states ), std::move ( finalStates ) ), std::make_tuple ( std::move ( initialState ) ) ) {
+
+}
+
+template<class SymbolType, class StateType >
+OneTapeDTM<SymbolType, StateType>::OneTapeDTM(StateType initial, SymbolType blank) : OneTapeDTM(std::set<StateType>{initial}, std::set<SymbolType> {blank}, blank, std::set<SymbolType>{}, initial, std::set<StateType>{}) {
+
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase* OneTapeDTM<SymbolType, StateType>::clone() const {
+	return new OneTapeDTM<SymbolType, StateType>(*this);
+}
+
+template<class SymbolType, class StateType >
+AutomatonBase* OneTapeDTM<SymbolType, StateType>::plunder() && {
+	return new OneTapeDTM<SymbolType, StateType>(std::move(*this));
+}
+
+template<class SymbolType, class StateType >
+bool OneTapeDTM<SymbolType, StateType>::addTransition(StateType from, SymbolType input, StateType to, SymbolType output, Shift shift) {
+	if (!getStates().count(from)) {
+		throw AutomatonException("State \"" + (std::string) from + "\" doesn't exist.");
+	}
+
+	if (!getTapeAlphabet().count(input)) {
+		throw AutomatonException("Tape symbol \"" + (std::string) input + "\" doesn't exist.");
+	}
+
+	if (!getStates().count(to)) {
+		throw AutomatonException("State \"" + (std::string) to + "\" doesn't exist.");
+	}
+
+	if (!getTapeAlphabet().count(output)) {
+		throw AutomatonException("Tape symbol  \"" + (std::string) output + "\" doesn't exist.");
+	}
+
+	std::pair<StateType, SymbolType> key = std::make_pair(std::move(from), std::move(input));
+
+	std::tuple<StateType, SymbolType, Shift > value(std::move(to), std::move(output), shift);
+
+	if (transitions.find(key) != transitions.end()) {
+		if(transitions.find(key)->second == value)
+			return false;
+		else
+			throw AutomatonException("Transition (\"" + (std::string) key.first + "\", \"" + (std::string) key.second + "\") -> ? already exists.");
+	}
+
+	transitions.insert(std::make_pair(std::move(key), std::move(value)));
+	return true;
+}
+
+template<class SymbolType, class StateType >
+bool OneTapeDTM<SymbolType, StateType>::removeTransition(const StateType& from, const SymbolType& input, const StateType& to, const SymbolType& output, const Shift& shift) {
+	std::pair<StateType, SymbolType> key = std::make_pair(from, input);
+
+	if (transitions.find(key) == transitions.end())
+		return false;
+
+	std::tuple<StateType, SymbolType, Shift > value(to, output, shift);
+	if(transitions.find(key)->second != value) 
+		throw AutomatonException("Transition (\"" + (std::string) from + "\", \"" + (std::string) input + "\") -> ? doesn't exists.");
+
+	transitions.erase(key);
+	return true;
+}
+
+template<class SymbolType, class StateType >
+const std::map<std::pair<StateType, SymbolType>, std::tuple<StateType, SymbolType, Shift> >& OneTapeDTM<SymbolType, StateType>::getTransitions() const {
+	return transitions;
+}
+
+template<class SymbolType, class StateType >
+int OneTapeDTM<SymbolType, StateType>::compare(const OneTapeDTM<SymbolType, StateType>& other) const {
+	auto first = std::tie(getStates(), getInputAlphabet(), getInitialState(), getFinalStates(), getTapeAlphabet(), getBlankSymbol(), transitions);
+	auto second = std::tie(other.getStates(), other.getInputAlphabet(), other.getInitialState(), other.getFinalStates(), other.getTapeAlphabet(), other.getBlankSymbol(), other.transitions);
+
+	std::compare<decltype(first)> comp;
+	return comp(first, second);
+}
+
+template<class SymbolType, class StateType >
+void OneTapeDTM<SymbolType, StateType>::operator>>(std::ostream& out) const {
+	out << "(OneTapeDTM "
+			<< "states = " << getStates()
+			<< "inputAlphabet = " << getInputAlphabet()
+			<< "initialState = " << getInitialState()
+			<< "finalStates = " << getFinalStates()
+			<< "tapeAlphabet = " << getTapeAlphabet()
+			<< "blankSymbol = " << getBlankSymbol()
+			<< "transitions = " << transitions
+			<< ")";
+}
+
+template<class SymbolType, class StateType >
+OneTapeDTM<SymbolType, StateType>::operator std::string () const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
+template<class SymbolType, class StateType >
+OneTapeDTM<SymbolType, StateType> OneTapeDTM<SymbolType, StateType>::parse(std::deque<sax::Token>::iterator& input) {
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::START_ELEMENT, OneTapeDTM::getXmlTagName());
+
+	std::set<StateType> states = AutomatonFromXMLParser::parseStates(input);
+	std::set<SymbolType> tapeSymbols = AutomatonFromXMLParser::parseTapeAlphabet(input);
+	std::set<SymbolType> inputSymbols = AutomatonFromXMLParser::parseInputAlphabet(input);
+	SymbolType blank = AutomatonFromXMLParser::parseBlankSymbol(input);
+	StateType initialState = AutomatonFromXMLParser::parseInitialState(input);
+	std::set<StateType> finalStates = AutomatonFromXMLParser::parseFinalStates(input);
+
+	OneTapeDTM automaton(std::move(initialState), std::move(blank));
+	automaton.setStates(std::move(states));
+	automaton.setTapeAlphabet(std::move(tapeSymbols));
+	automaton.setInputAlphabet(std::move(inputSymbols));
+	automaton.setFinalStates(std::move(finalStates));
+
+	AutomatonFromXMLParser::parseTransitions<OneTapeDTM>(input, automaton);
+
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, OneTapeDTM::getXmlTagName());
+	return automaton;
+}
+
+template<class SymbolType, class StateType >
+void OneTapeDTM<SymbolType, StateType>::parseTransition(std::deque<sax::Token>::iterator& input, OneTapeDTM<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);
+	SymbolType outputSymbol = AutomatonFromXMLParser::parseTransitionOutputSymbol(input);
+	Shift shift = AutomatonFromXMLParser::parseTransitionShift(input);
+	sax::FromXMLParserHelper::popToken(input, sax::Token::TokenType::END_ELEMENT, "transition");
+
+	automaton.addTransition(std::move(from), std::move(inputSymbol), std::move(to), std::move(outputSymbol), shift);
+}
+
+template<class SymbolType, class StateType >
+void OneTapeDTM<SymbolType, StateType>::compose(std::deque<sax::Token>& out) const {
+	out.emplace_back(OneTapeDTM::getXmlTagName(), sax::Token::TokenType::START_ELEMENT);
+
+	AutomatonToXMLComposer::composeStates(out, this->getStates());
+	AutomatonToXMLComposer::composeTapeAlphabet(out, this->getTapeAlphabet());
+	AutomatonToXMLComposer::composeInputAlphabet(out, this->getInputAlphabet());
+	AutomatonToXMLComposer::composeBlankSymbol(out, this->getBlankSymbol());
+	AutomatonToXMLComposer::composeInitialState(out, this->getInitialState());
+	AutomatonToXMLComposer::composeFinalStates(out, this->getFinalStates());
+	composeTransitions(out);
+
+	out.emplace_back(OneTapeDTM::getXmlTagName(), sax::Token::TokenType::END_ELEMENT);
+}
+
+template<class SymbolType, class StateType >
+void OneTapeDTM<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, std::get<0>(transition.second));
+		AutomatonToXMLComposer::composeTransitionOutputSymbol(out, std::get<1>(transition.second));
+		AutomatonToXMLComposer::composeTransitionShift(out, std::get<2>(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::OneTapeDTM, alphabet::Symbol, automaton::TapeAlphabet > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::OneTapeDTM<SymbolType, StateType>, SymbolType, automaton::TapeAlphabet > {
 public:
-	static bool used ( const automaton::OneTapeDTM & automaton, const alphabet::Symbol & symbol ) {
+	static bool used ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) {
 		if ( automaton.getBlankSymbol ( ) == symbol )
 			return true;
 
 		if ( automaton.getInputAlphabet().count(symbol))
 			return true;
 
-		for (const std::pair<const std::pair<label::Label, alphabet::Symbol>, std::tuple<label::Label, alphabet::Symbol, automaton::Shift> >& transition : automaton.getTransitions())
+		for (const std::pair<const std::pair<StateType, SymbolType>, std::tuple<StateType, SymbolType, automaton::Shift> >& transition : automaton.getTransitions())
 			if (symbol == transition.first.second || symbol == std::get<1>(transition.second))
 				return true;
 
@@ -199,92 +375,93 @@ public:
 
 	}
 
-	static bool available ( const automaton::OneTapeDTM &, const alphabet::Symbol & ) {
+	static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> &, const SymbolType &) {
 		return true;
 	}
 
-	static void valid ( const automaton::OneTapeDTM &, const alphabet::Symbol & ) {
+	static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> &, const SymbolType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::OneTapeDTM, alphabet::Symbol, automaton::InputAlphabet > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::OneTapeDTM<SymbolType, StateType>, SymbolType, automaton::InputAlphabet > {
 public:
-	static bool used ( const automaton::OneTapeDTM &, const alphabet::Symbol & ) {
+	static bool used ( const automaton::OneTapeDTM<SymbolType, StateType> &, const SymbolType & ) {
 		return false;
 	}
 
-	static bool available ( const automaton::OneTapeDTM & automaton, const alphabet::Symbol & symbol ) {
-		return automaton.accessComponent < automaton::TapeAlphabet > ( ).get ( ).count ( symbol );
+	static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) {
+		return automaton.getTapeAlphabet ( ).count ( symbol );
 	}
 
-	static void valid ( const automaton::OneTapeDTM & automaton, const alphabet::Symbol & symbol ) {
+	static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) {
 		if (symbol == automaton.getBlankSymbol())
 			throw automaton::AutomatonException("Input symbol \"" + (std::string) symbol + "\" cannot be blank symbol.");
 	}
 };
 
-template < >
-class ElementConstraint< automaton::OneTapeDTM, alphabet::Symbol, automaton::BlankSymbol > {
+template<class SymbolType, class StateType >
+class ElementConstraint< automaton::OneTapeDTM<SymbolType, StateType>, SymbolType, automaton::BlankSymbol > {
 public:
-	static bool available ( const automaton::OneTapeDTM & automaton, const alphabet::Symbol & symbol ) {
-		return automaton.accessComponent < automaton::TapeAlphabet > ( ).get ( ).count ( symbol );
+	static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) {
+		return automaton.getTapeAlphabet ( ).count ( symbol );
 	}
 
-	static void valid ( const automaton::OneTapeDTM & automaton, const alphabet::Symbol & symbol ) {
+	static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const SymbolType & symbol ) {
 		if (automaton.getInputAlphabet().count( symbol ))
 			throw automaton::AutomatonException("Blank symbol \"" + (std::string) symbol + "\" cannot be in input alphabet.");
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::OneTapeDTM, label::Label, automaton::States > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::OneTapeDTM<SymbolType, StateType>, StateType, automaton::States > {
 public:
-	static bool used ( const automaton::OneTapeDTM & automaton, const label::Label & state ) {
+	static bool used ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const StateType & state ) {
 		if ( automaton.getInitialState ( ) == state )
 			return true;
 
 		if ( automaton.getFinalStates ( ).count ( state ) )
 			return true;
 
-		for (const std::pair<const std::pair<label::Label, alphabet::Symbol>, std::tuple<label::Label, alphabet::Symbol, automaton::Shift> >& transition : automaton.getTransitions ( ) )
+		for (const std::pair<const std::pair<StateType, SymbolType>, std::tuple<StateType, SymbolType, automaton::Shift> >& transition : automaton.getTransitions ( ) )
 			if ( state == transition.first.first || state == std::get < 0 > ( transition.second ) )
 				return true;
 
 		return false;
 	}
 
-	static bool available ( const automaton::OneTapeDTM &, const label::Label & ) {
+	static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> &, const StateType & ) {
 		return true;
 	}
 
-	static void valid ( const automaton::OneTapeDTM &, const label::Label & ) {
+	static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> &, const StateType & ) {
 	}
 };
 
-template < >
-class ComponentConstraint< automaton::OneTapeDTM, label::Label, automaton::FinalStates > {
+template<class SymbolType, class StateType >
+class ComponentConstraint< automaton::OneTapeDTM<SymbolType, StateType>, StateType, automaton::FinalStates > {
 public:
-	static bool used ( const automaton::OneTapeDTM &, const label::Label & ) {
+	static bool used ( const automaton::OneTapeDTM<SymbolType, StateType> &, const StateType & ) {
 		return false;
 	}
 
-	static bool available ( const automaton::OneTapeDTM & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const StateType & state ) {
+		return automaton.getStates ( ).count ( state );
 	}
 
-	static void valid ( const automaton::OneTapeDTM &, const label::Label & ) {
+	static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> &, const StateType & ) {
+		//TODO final state and outgoing transitions
 	}
 };
 
-template < >
-class ElementConstraint< automaton::OneTapeDTM, label::Label, automaton::InitialState > {
+template<class SymbolType, class StateType >
+class ElementConstraint< automaton::OneTapeDTM<SymbolType, StateType>, StateType, automaton::InitialState > {
 public:
-	static bool available ( const automaton::OneTapeDTM & automaton, const label::Label & state ) {
-		return automaton.accessComponent < automaton::States > ( ).get ( ).count ( state );
+	static bool available ( const automaton::OneTapeDTM<SymbolType, StateType> & automaton, const StateType & state ) {
+		return automaton.getStates ( ).count ( state );
 	}
 
-	static void valid ( const automaton::OneTapeDTM &, const label::Label & ) {
+	static void valid ( const automaton::OneTapeDTM<SymbolType, StateType> &, const StateType & ) {
 	}
 };
 
-- 
GitLab