diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp
index ece17ebb619b40cd596c66188f864984a955b4b1..11b55ba29cdb0be02a116012a1d2ddef198d3b49 100644
--- a/aconvert2/src/DotConverter.cpp
+++ b/aconvert2/src/DotConverter.cpp
@@ -14,6 +14,8 @@
 #include <automaton/FSM/DFA.h>
 #include <automaton/FSM/ExtendedNFA.h>
 #include <automaton/FSM/CompactNFA.h>
+#include <automaton/TA/NFTA.h>
+#include <automaton/TA/DFTA.h>
 #include <automaton/PDA/NPDA.h>
 #include <automaton/PDA/SinglePopNPDA.h>
 #include <automaton/PDA/InputDrivenDPDA.h>
@@ -45,12 +47,11 @@ auto replace = [](std::string& str, const std::string& what, const std::string&
 	}
 };
 
-void DotConverter::convert(const automaton::Automaton& a, std::ostream& out) {
-	a.getData().Accept((void*) &out, DotConverter::instance);
+void DotConverter::convert(std::ostream& out, const automaton::Automaton& a) {
+	getInstance().dispatch(out, a.getData());
 }
 
-void DotConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out) {
-
+void DotConverter::convert(std::ostream& out, const automaton::EpsilonNFA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -81,7 +82,9 @@ void DotConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out) {
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::MultiInitialStateNFA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::EpsilonNFA> DotConverterEpsilonNFA = DotConverter::RegistratorWrapper<void, automaton::EpsilonNFA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::MultiInitialStateNFA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -114,7 +117,9 @@ void DotConverter::convert(const automaton::MultiInitialStateNFA& a, std::ostrea
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::NFA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::MultiInitialStateNFA> DotConverterMultiInitialStateNFA = DotConverter::RegistratorWrapper<void, automaton::MultiInitialStateNFA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::NFA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -145,7 +150,9 @@ void DotConverter::convert(const automaton::NFA& a, std::ostream& out) {
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::DFA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::NFA> DotConverterNFA = DotConverter::RegistratorWrapper<void, automaton::NFA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::DFA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -176,7 +183,9 @@ void DotConverter::convert(const automaton::DFA& a, std::ostream& out) {
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::ExtendedNFA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::DFA> DotConverterDFA = DotConverter::RegistratorWrapper<void, automaton::DFA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -207,7 +216,9 @@ void DotConverter::convert(const automaton::ExtendedNFA& a, std::ostream& out) {
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::CompactNFA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::ExtendedNFA> DotConverterExtendedNFA = DotConverter::RegistratorWrapper<void, automaton::ExtendedNFA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::CompactNFA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -238,15 +249,21 @@ void DotConverter::convert(const automaton::CompactNFA& a, std::ostream& out) {
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::NFTA&, std::ostream&) {
+DotConverter::RegistratorWrapper<void, automaton::CompactNFA> DotConverterCompactNFA = DotConverter::RegistratorWrapper<void, automaton::CompactNFA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream&, const automaton::NFTA&) {
 	//TODO
 }
 
-void DotConverter::convert(const automaton::DFTA&, std::ostream&) {
+DotConverter::RegistratorWrapper<void, automaton::NFTA> DotConverterNFTA = DotConverter::RegistratorWrapper<void, automaton::NFTA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream&, const automaton::DFTA&) {
 	//TODO
 }
 
-void DotConverter::convert(const automaton::DPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::DFTA> DotConverterDFTA = DotConverter::RegistratorWrapper<void, automaton::DFTA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::DPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -277,7 +294,9 @@ void DotConverter::convert(const automaton::DPDA& a, std::ostream& out) {
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::DPDA> DotConverterDPDA = DotConverter::RegistratorWrapper<void, automaton::DPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::SinglePopDPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -308,7 +327,9 @@ void DotConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out)
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::InputDrivenDPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::SinglePopDPDA> DotConverterSinglePopDPDA = DotConverter::RegistratorWrapper<void, automaton::SinglePopDPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::InputDrivenDPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -339,7 +360,9 @@ void DotConverter::convert(const automaton::InputDrivenDPDA& a, std::ostream& ou
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::InputDrivenDPDA> DotConverterInputDrivenDPDA = DotConverter::RegistratorWrapper<void, automaton::InputDrivenDPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::InputDrivenNPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -370,7 +393,9 @@ void DotConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& ou
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::VisiblyPushdownDPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::InputDrivenNPDA> DotConverterInputDrivenNPDA = DotConverter::RegistratorWrapper<void, automaton::InputDrivenNPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::VisiblyPushdownDPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -401,7 +426,9 @@ void DotConverter::convert(const automaton::VisiblyPushdownDPDA& a, std::ostream
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::VisiblyPushdownDPDA> DotConverterVisiblyPushdownDPDA = DotConverter::RegistratorWrapper<void, automaton::VisiblyPushdownDPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::VisiblyPushdownNPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -434,7 +461,9 @@ void DotConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::RealTimeHeightDeterministicDPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::VisiblyPushdownNPDA> DotConverterVisiblyPushdownNPDA = DotConverter::RegistratorWrapper<void, automaton::VisiblyPushdownNPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::RealTimeHeightDeterministicDPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -465,7 +494,9 @@ void DotConverter::convert(const automaton::RealTimeHeightDeterministicDPDA& a,
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicDPDA> DotConverterRealTimeHeightDeterministicDPDA = DotConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicDPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::RealTimeHeightDeterministicNPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -498,7 +529,9 @@ void DotConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& a,
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::NPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicNPDA> DotConverterRealTimeHeightDeterministicNPDA = DotConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicNPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::NPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -529,7 +562,9 @@ void DotConverter::convert(const automaton::NPDA& a, std::ostream& out) {
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::SinglePopNPDA& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::NPDA> DotConverterNPDA = DotConverter::RegistratorWrapper<void, automaton::NPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::SinglePopNPDA& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -560,7 +595,9 @@ void DotConverter::convert(const automaton::SinglePopNPDA& a, std::ostream& out)
 	out << "}";
 }
 
-void DotConverter::convert(const automaton::OneTapeDTM& a, std::ostream& out) {
+DotConverter::RegistratorWrapper<void, automaton::SinglePopNPDA> DotConverterSinglePopNPDA = DotConverter::RegistratorWrapper<void, automaton::SinglePopNPDA>(DotConverter::getInstance(), DotConverter::convert);
+
+void DotConverter::convert(std::ostream& out, const automaton::OneTapeDTM& a) {
 	out << "digraph automaton {\n";
 	out << "rankdir=LR;\n";
 	int cnt = 1;
@@ -591,6 +628,8 @@ void DotConverter::convert(const automaton::OneTapeDTM& a, std::ostream& out) {
 	out << "}";
 }
 
+DotConverter::RegistratorWrapper<void, automaton::OneTapeDTM> DotConverterOneTapeDTM = DotConverter::RegistratorWrapper<void, automaton::OneTapeDTM>(DotConverter::getInstance(), DotConverter::convert);
+
 void DotConverter::transitions(const automaton::EpsilonNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out) {
 	std::map<std::pair<int, int>, std::string> transitions;
 
@@ -1704,81 +1743,3 @@ void DotConverter::transitions(const automaton::OneTapeDTM& tm, const std::map<a
 	}
 }
 
-const DotConverter DotConverter::instance;
-
-void DotConverter::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::NFA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::DFA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::ExtendedNFA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::CompactNFA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::DPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::SinglePopDPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::InputDrivenDPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::VisiblyPushdownDPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::NPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::SinglePopNPDA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::OneTapeDTM& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::NFTA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void DotConverter::Visit(void* data, const automaton::DFTA& automaton) const {
-	DotConverter::convert(automaton, *((std::ostream*) data));
-}
-
diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h
index 3c99fa76780c29c7507724890e583b4808a749d3..b9d4ed32b2ff08dec289d52e124b67ec3fb81378 100644
--- a/aconvert2/src/DotConverter.h
+++ b/aconvert2/src/DotConverter.h
@@ -9,37 +9,15 @@
 #define DOT_CONVERTER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 
 #include <automaton/Automaton.h>
+#include <automaton/AutomatonFeatures.h>
 
 #include <map>
 #include <utility>
 
-class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_type {
-public:
-	DotConverter() {}
-
-private:
-	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
-	void Visit(void*, const automaton::MultiInitialStateNFA& automaton) const;
-	void Visit(void*, const automaton::NFA& automaton) const;
-	void Visit(void*, const automaton::DFA& automaton) const;
-	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
-	void Visit(void*, const automaton::CompactNFA& automaton) const;
-	void Visit(void*, const automaton::DPDA& automaton) const;
-	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
-	void Visit(void*, const automaton::InputDrivenDPDA& automaton) const;
-	void Visit(void*, const automaton::InputDrivenNPDA& automaton) const;
-	void Visit(void*, const automaton::VisiblyPushdownDPDA& automaton) const;
-	void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const;
-	void Visit(void*, const automaton::RealTimeHeightDeterministicDPDA& automaton) const;
-	void Visit(void*, const automaton::RealTimeHeightDeterministicNPDA& automaton) const;
-	void Visit(void*, const automaton::NPDA& automaton) const;
-	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
-	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
-	void Visit(void*, const automaton::NFTA& automaton) const;
-	void Visit(void*, const automaton::DFTA& automaton) const;
-
+class DotConverter : public std::SingleDispatchFirstStaticParam<void, std::ostream, automaton::AutomatonBase> {
 	static void transitions(const automaton::EpsilonNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::MultiInitialStateNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::NFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out);
@@ -59,30 +37,33 @@ private:
 	static void transitions(const automaton::NPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::SinglePopNPDA& tm, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::OneTapeDTM& tm, const std::map<automaton::State, int>& states, std::ostream& out);
-
-	static const DotConverter instance;
 public:
-	static void convert(const automaton::Automaton& a, std::ostream& out);
+	static void convert(std::ostream& out, const automaton::Automaton& a);
+
+	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::ExtendedNFA& a);
+	static void convert(std::ostream& out, const automaton::CompactNFA& a);
+	static void convert(std::ostream& out, const automaton::NFTA& a);
+	static void convert(std::ostream& out, const automaton::DFTA& a);
+	static void convert(std::ostream& out, const automaton::DPDA& a);
+	static void convert(std::ostream& out, const automaton::SinglePopDPDA& a);
+	static void convert(std::ostream& out, const automaton::InputDrivenDPDA& a);
+	static void convert(std::ostream& out, const automaton::InputDrivenNPDA& a);
+	static void convert(std::ostream& out, const automaton::VisiblyPushdownDPDA& a);
+	static void convert(std::ostream& out, const automaton::VisiblyPushdownNPDA& a);
+	static void convert(std::ostream& out, const automaton::RealTimeHeightDeterministicDPDA& a);
+	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(const automaton::EpsilonNFA& a, std::ostream& out);
-	static void convert(const automaton::MultiInitialStateNFA& a, std::ostream& out);
-	static void convert(const automaton::NFA& a, std::ostream& out);
-	static void convert(const automaton::DFA& a, std::ostream& out);
-	static void convert(const automaton::ExtendedNFA& a, std::ostream& out);
-	static void convert(const automaton::CompactNFA& a, std::ostream& out);
-	static void convert(const automaton::NFTA& a, std::ostream& out);
-	static void convert(const automaton::DFTA& a, std::ostream& out);
-	static void convert(const automaton::DPDA& a, std::ostream& out);
-	static void convert(const automaton::SinglePopDPDA& a, std::ostream& out);
-	static void convert(const automaton::InputDrivenDPDA& a, std::ostream& out);
-	static void convert(const automaton::InputDrivenNPDA& a, std::ostream& out);
-	static void convert(const automaton::VisiblyPushdownDPDA& a, std::ostream& out);
-	static void convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out);
-	static void convert(const automaton::RealTimeHeightDeterministicDPDA& a, std::ostream& out);
-	static void convert(const automaton::RealTimeHeightDeterministicNPDA& a, std::ostream& out);
-	static void convert(const automaton::NPDA& a, std::ostream& out);
-	static void convert(const automaton::SinglePopNPDA& a, std::ostream& out);
-	static void convert(const automaton::OneTapeDTM& a, std::ostream& out);
+	static DotConverter& getInstance() {
+		static DotConverter res;
+		return res;
+	}
 };
 
 #endif /* DOT_CONVERTER_H_ */
diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp
index f03a4a0a77e8f77df947bf0ca41c0ac5f559eac1..2404c2a344c51244a27eaafa66cd26b0b197a03d 100644
--- a/aconvert2/src/GasTexConverter.cpp
+++ b/aconvert2/src/GasTexConverter.cpp
@@ -13,6 +13,8 @@
 #include <automaton/FSM/DFA.h>
 #include <automaton/FSM/ExtendedNFA.h>
 #include <automaton/FSM/CompactNFA.h>
+#include <automaton/TA/NFTA.h>
+#include <automaton/TA/DFTA.h>
 #include <automaton/PDA/DPDA.h>
 #include <automaton/PDA/SinglePopDPDA.h>
 #include <automaton/PDA/InputDrivenDPDA.h>
@@ -32,11 +34,11 @@
 #include <typeinfo>
 #include "exception/AlibException.h"
 
-void GasTexConverter::convert(const automaton::Automaton& a, std::ostream& out) {
-	a.getData().Accept((void*) &out, GasTexConverter::instance);
+void GasTexConverter::convert(std::ostream& out, const automaton::Automaton& a) {
+	getInstance().dispatch(out, a.getData());
 }
 
-void GasTexConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out) {
+void GasTexConverter::convert(std::ostream& out, const automaton::EpsilonNFA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -75,7 +77,9 @@ void GasTexConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out)
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::MultiInitialStateNFA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::EpsilonNFA> GasTexConverterEpsilonNFA = GasTexConverter::RegistratorWrapper<void, automaton::EpsilonNFA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::MultiInitialStateNFA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -114,7 +118,9 @@ void GasTexConverter::convert(const automaton::MultiInitialStateNFA& a, std::ost
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::NFA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::MultiInitialStateNFA> GasTexConverterMultiInitialStateNFA = GasTexConverter::RegistratorWrapper<void, automaton::MultiInitialStateNFA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::NFA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -153,7 +159,9 @@ void GasTexConverter::convert(const automaton::NFA& a, std::ostream& out) {
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::DFA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::NFA> GasTexConverterNFA = GasTexConverter::RegistratorWrapper<void, automaton::NFA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::DFA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -192,7 +200,9 @@ void GasTexConverter::convert(const automaton::DFA& a, std::ostream& out) {
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::ExtendedNFA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::DFA> GasTexConverterDFA = GasTexConverter::RegistratorWrapper<void, automaton::DFA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::ExtendedNFA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -231,7 +241,9 @@ void GasTexConverter::convert(const automaton::ExtendedNFA& a, std::ostream& out
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::CompactNFA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::ExtendedNFA> GasTexConverterExtendedNFA = GasTexConverter::RegistratorWrapper<void, automaton::ExtendedNFA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::CompactNFA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -270,15 +282,21 @@ void GasTexConverter::convert(const automaton::CompactNFA& a, std::ostream& out)
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::NFTA&, std::ostream&) {
+GasTexConverter::RegistratorWrapper<void, automaton::CompactNFA> GasTexConverterCompactNFA = GasTexConverter::RegistratorWrapper<void, automaton::CompactNFA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream&, const automaton::NFTA&) {
 	//TODO
 }
 
-void GasTexConverter::convert(const automaton::DFTA&, std::ostream&) {
+GasTexConverter::RegistratorWrapper<void, automaton::NFTA> GasTexConverterNFTA = GasTexConverter::RegistratorWrapper<void, automaton::NFTA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream&, const automaton::DFTA&) {
 	//TODO
 }
 
-void GasTexConverter::convert(const automaton::DPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::DFTA> GasTexConverterDFTA = GasTexConverter::RegistratorWrapper<void, automaton::DFTA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::DPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -317,7 +335,9 @@ void GasTexConverter::convert(const automaton::DPDA& a, std::ostream& out) {
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::DPDA> GasTexConverterDPDA = GasTexConverter::RegistratorWrapper<void, automaton::DPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::SinglePopDPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -356,7 +376,9 @@ void GasTexConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& o
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::InputDrivenDPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::SinglePopDPDA> GasTexConverterSinglePopDPDA = GasTexConverter::RegistratorWrapper<void, automaton::SinglePopDPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::InputDrivenDPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -395,7 +417,9 @@ void GasTexConverter::convert(const automaton::InputDrivenDPDA& a, std::ostream&
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::InputDrivenDPDA> GasTexConverterInputDrivenDPDA = GasTexConverter::RegistratorWrapper<void, automaton::InputDrivenDPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::InputDrivenNPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -434,7 +458,9 @@ void GasTexConverter::convert(const automaton::InputDrivenNPDA& a, std::ostream&
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::VisiblyPushdownDPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::InputDrivenNPDA> GasTexConverterInputDrivenNPDA = GasTexConverter::RegistratorWrapper<void, automaton::InputDrivenNPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::VisiblyPushdownDPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -473,7 +499,9 @@ void GasTexConverter::convert(const automaton::VisiblyPushdownDPDA& a, std::ostr
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::VisiblyPushdownDPDA> GasTexConverterVisiblyPushdownDPDA = GasTexConverter::RegistratorWrapper<void, automaton::VisiblyPushdownDPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::VisiblyPushdownNPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -512,7 +540,9 @@ void GasTexConverter::convert(const automaton::VisiblyPushdownNPDA& a, std::ostr
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::RealTimeHeightDeterministicDPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::VisiblyPushdownNPDA> GasTexConverterVisiblyPushdownNPDA = GasTexConverter::RegistratorWrapper<void, automaton::VisiblyPushdownNPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::RealTimeHeightDeterministicDPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -551,7 +581,9 @@ void GasTexConverter::convert(const automaton::RealTimeHeightDeterministicDPDA&
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::RealTimeHeightDeterministicNPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicDPDA> GasTexConverterRealTimeHeightDeterministicDPDA = GasTexConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicDPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::RealTimeHeightDeterministicNPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -590,7 +622,9 @@ void GasTexConverter::convert(const automaton::RealTimeHeightDeterministicNPDA&
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::NPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicNPDA> GasTexConverterRealTimeHeightDeterministicNPDA = GasTexConverter::RegistratorWrapper<void, automaton::RealTimeHeightDeterministicNPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::NPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -629,7 +663,9 @@ void GasTexConverter::convert(const automaton::NPDA& a, std::ostream& out) {
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::SinglePopNPDA& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::NPDA> GasTexConverterNPDA = GasTexConverter::RegistratorWrapper<void, automaton::NPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::SinglePopNPDA& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -668,7 +704,9 @@ void GasTexConverter::convert(const automaton::SinglePopNPDA& a, std::ostream& o
 	out << "\\end{picture}\n";
 }
 
-void GasTexConverter::convert(const automaton::OneTapeDTM& a, std::ostream& out) {
+GasTexConverter::RegistratorWrapper<void, automaton::SinglePopNPDA> GasTexConverterSinglePopNPDA = GasTexConverter::RegistratorWrapper<void, automaton::SinglePopNPDA>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
+void GasTexConverter::convert(std::ostream& out, const automaton::OneTapeDTM& a) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
 
@@ -707,6 +745,8 @@ void GasTexConverter::convert(const automaton::OneTapeDTM& a, std::ostream& out)
 	out << "\\end{picture}\n";
 }
 
+GasTexConverter::RegistratorWrapper<void, automaton::OneTapeDTM> GasTexConverterOneTapeDTM = GasTexConverter::RegistratorWrapper<void, automaton::OneTapeDTM>(GasTexConverter::getInstance(), GasTexConverter::convert);
+
 std::string GasTexConverter::getStackSymbols(const std::vector<alphabet::Symbol>& stackSymbols) {
 	if (stackSymbols.size() == 0) {
 		return "$\\varepsilon$";
@@ -1389,81 +1429,3 @@ void GasTexConverter::transitions(const automaton::OneTapeDTM& tm, std::ostream&
 	printTransitionMap(transitionMap, out);
 }
 
-const GasTexConverter GasTexConverter::instance;
-
-void GasTexConverter::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::NFA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::DFA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::ExtendedNFA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::CompactNFA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::DPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::SinglePopDPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::InputDrivenDPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::VisiblyPushdownDPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::NPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::SinglePopNPDA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::OneTapeDTM& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::NFTA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
-void GasTexConverter::Visit(void* data, const automaton::DFTA& automaton) const {
-	GasTexConverter::convert(automaton, *((std::ostream*) data));
-}
-
diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h
index 73dea5085eff0fa9320cc0786b904ce3e99e0d9b..9de2682c033996f1ffa9d4d26b58d4c886f9ce72 100644
--- a/aconvert2/src/GasTexConverter.h
+++ b/aconvert2/src/GasTexConverter.h
@@ -9,37 +9,14 @@
 #define GAS_TEX_CONVERTER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 #include <map>
 #include <utility>
 #include <vector>
 #include "automaton/Automaton.h"
 #include "alphabet/Symbol.h"
 
-class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_type {
-public:
-	GasTexConverter() {}
-
-private:
-	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
-	void Visit(void*, const automaton::MultiInitialStateNFA& automaton) const;
-	void Visit(void*, const automaton::NFA& automaton) const;
-	void Visit(void*, const automaton::DFA& automaton) const;
-	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
-	void Visit(void*, const automaton::CompactNFA& automaton) const;
-	void Visit(void*, const automaton::DPDA& automaton) const;
-	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
-	void Visit(void*, const automaton::InputDrivenDPDA& automaton) const;
-	void Visit(void*, const automaton::InputDrivenNPDA& automaton) const;
-	void Visit(void*, const automaton::VisiblyPushdownDPDA& automaton) const;
-	void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const;
-	void Visit(void*, const automaton::RealTimeHeightDeterministicDPDA& automaton) const;
-	void Visit(void*, const automaton::RealTimeHeightDeterministicNPDA& automaton) const;
-	void Visit(void*, const automaton::NPDA& automaton) const;
-	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
-	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
-	void Visit(void*, const automaton::NFTA& automaton) const;
-	void Visit(void*, const automaton::DFTA& automaton) const;
-
+class GasTexConverter : public std::SingleDispatchFirstStaticParam<void, std::ostream, automaton::AutomatonBase> {
 	static void printTransitionMap( const std::map<std::pair<std::string, std::string>, std::string> transitionMap, std::ostream& out);
 	static std::string getStackSymbols(const std::vector<alphabet::Symbol>& stackSymbols);
 
@@ -62,30 +39,33 @@ private:
 	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 const GasTexConverter instance;
 public:
-	static void convert(const automaton::Automaton& a, std::ostream& out);
+	static void convert(std::ostream& out, const automaton::Automaton& a);
+
+	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::ExtendedNFA& a);
+	static void convert(std::ostream& out, const automaton::CompactNFA& a);
+	static void convert(std::ostream& out, const automaton::NFTA& a);
+	static void convert(std::ostream& out, const automaton::DFTA& a);
+	static void convert(std::ostream& out, const automaton::DPDA& a);
+	static void convert(std::ostream& out, const automaton::SinglePopDPDA& a);
+	static void convert(std::ostream& out, const automaton::InputDrivenDPDA& a);
+	static void convert(std::ostream& out, const automaton::InputDrivenNPDA& a);
+	static void convert(std::ostream& out, const automaton::VisiblyPushdownDPDA& a);
+	static void convert(std::ostream& out, const automaton::VisiblyPushdownNPDA& a);
+	static void convert(std::ostream& out, const automaton::RealTimeHeightDeterministicDPDA& a);
+	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(const automaton::EpsilonNFA& a, std::ostream& out);
-	static void convert(const automaton::MultiInitialStateNFA& a, std::ostream& out);
-	static void convert(const automaton::NFA& a, std::ostream& out);
-	static void convert(const automaton::DFA& a, std::ostream& out);
-	static void convert(const automaton::ExtendedNFA& a, std::ostream& out);
-	static void convert(const automaton::CompactNFA& a, std::ostream& out);
-	static void convert(const automaton::NFTA& a, std::ostream& out);
-	static void convert(const automaton::DFTA& a, std::ostream& out);
-	static void convert(const automaton::DPDA& a, std::ostream& out);
-	static void convert(const automaton::SinglePopDPDA& a, std::ostream& out);
-	static void convert(const automaton::InputDrivenDPDA& a, std::ostream& out);
-	static void convert(const automaton::InputDrivenNPDA& a, std::ostream& out);
-	static void convert(const automaton::VisiblyPushdownDPDA& a, std::ostream& out);
-	static void convert(const automaton::VisiblyPushdownNPDA& a, std::ostream& out);
-	static void convert(const automaton::RealTimeHeightDeterministicDPDA& a, std::ostream& out);
-	static void convert(const automaton::RealTimeHeightDeterministicNPDA& a, std::ostream& out);
-	static void convert(const automaton::NPDA& a, std::ostream& out);
-	static void convert(const automaton::SinglePopNPDA& a, std::ostream& out);
-	static void convert(const automaton::OneTapeDTM& a, std::ostream& out);
+	static GasTexConverter& getInstance() {
+		static GasTexConverter res;
+		return res;
+	}
 };
 
 #endif /* GAS_TEX_CONVERTER_H_ */
diff --git a/aconvert2/src/aconvert.cpp b/aconvert2/src/aconvert.cpp
index eb03aa481cc0e7de99c53c06484539b808ecb44f..f1369ee304db47a395d453936d8086d49e39a523 100644
--- a/aconvert2/src/aconvert.cpp
+++ b/aconvert2/src/aconvert.cpp
@@ -94,7 +94,7 @@ void automatonToDot(std::istream& in, std::ostream& out) {
 	std::chrono::measurements::end();
 	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
 
-	DotConverter::convert(automaton, out);
+	DotConverter::convert(out, automaton);
 }
 
 void automatonToGasTex(std::istream& in, std::ostream& out) {
@@ -103,7 +103,7 @@ void automatonToGasTex(std::istream& in, std::ostream& out) {
 	std::chrono::measurements::end();
 	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
 
-	GasTexConverter::convert(automaton, out);
+	GasTexConverter::convert(out, automaton);
 }
 
 int main(int argc, char* argv[]) {
diff --git a/alib2str/src/StringApi.cpp b/alib2str/src/StringApi.cpp
index 48e958afd038416df161da0d30e7add4ad266a26..19b1af90c43489894fa03b607b7df5df039c0873 100644
--- a/alib2str/src/StringApi.cpp
+++ b/alib2str/src/StringApi.cpp
@@ -20,30 +20,20 @@ const grammar::GrammarFromStringParser FromStringParsers::grammarParser;
 const graph::GraphFromStringParser FromStringParsers::graphParser;
 const primitive::PrimitiveFromStringParser FromStringParsers::primitiveParser;
 
-const label::LabelToStringComposer ToStringComposers::labelComposer;
-const alphabet::SymbolToStringComposer ToStringComposers::symbolComposer;
-const regexp::RegExpToStringComposer ToStringComposers::regexpComposer;
-const string::StringToStringComposer ToStringComposers::stringComposer;
-const automaton::AutomatonToStringComposer ToStringComposers::automatonComposer;
-const grammar::GrammarToStringComposer ToStringComposers::grammarComposer;
-const graph::GraphToStringComposer ToStringComposers::graphComposer;
-const primitive::PrimitiveToStringComposer ToStringComposers::primitiveComposer;
-
 alphabet::Symbol stringApi<alphabet::Symbol>::parse(std::istream& input) {
 	return FromStringParsers::symbolParser.parseSymbol(input);
 }
 
 void stringApi<alphabet::Symbol>::compose(std::ostream& output, const alphabet::Symbol& data) {
-	return ToStringComposers::symbolComposer.compose(output, data);
+	return alphabet::SymbolToStringComposer::compose(output, data);
 }
 
-
 automaton::Automaton stringApi<automaton::Automaton>::parse(std::istream& input) {
 	return FromStringParsers::automatonParser.parseAutomaton(input);
 }
 
 void stringApi<automaton::Automaton>::compose(std::ostream& output, const automaton::Automaton& data) {
-	return ToStringComposers::automatonComposer.compose(output, data);
+	return automaton::AutomatonToStringComposer::compose(output, data);
 }
 
 grammar::Grammar stringApi<grammar::Grammar>::parse(std::istream& input) {
@@ -51,7 +41,7 @@ grammar::Grammar stringApi<grammar::Grammar>::parse(std::istream& input) {
 }
 
 void stringApi<grammar::Grammar>::compose(std::ostream& output, const grammar::Grammar& data) {
-	return ToStringComposers::grammarComposer.compose(output, data);
+	return grammar::GrammarToStringComposer::compose(output, data);
 }
 
 graph::Graph stringApi<graph::Graph>::parse(std::istream& input) {
@@ -59,7 +49,7 @@ graph::Graph stringApi<graph::Graph>::parse(std::istream& input) {
 }
 
 void stringApi<graph::Graph>::compose(std::ostream& output, const graph::Graph& data) {
-	return ToStringComposers::graphComposer.compose(output, data);
+	return graph::GraphToStringComposer::compose(output, data);
 }
 
 label::Label stringApi<label::Label>::parse(std::istream& input) {
@@ -67,7 +57,7 @@ label::Label stringApi<label::Label>::parse(std::istream& input) {
 }
 
 void stringApi<label::Label>::compose(std::ostream& output, const label::Label& data) {
-	return ToStringComposers::labelComposer.compose(output, data);
+	return label::LabelToStringComposer::compose(output, data);
 }
 
 regexp::RegExp stringApi<regexp::RegExp>::parse(std::istream& input) {
@@ -75,7 +65,7 @@ regexp::RegExp stringApi<regexp::RegExp>::parse(std::istream& input) {
 }
 
 void stringApi<regexp::RegExp>::compose(std::ostream& output, const regexp::RegExp& data) {
-	return ToStringComposers::regexpComposer.compose(output, data);
+	return regexp::RegExpToStringComposer::compose(output, data);
 }
 
 string::String stringApi<string::String>::parse(std::istream& input) {
@@ -83,16 +73,15 @@ string::String stringApi<string::String>::parse(std::istream& input) {
 }
 
 void stringApi<string::String>::compose(std::ostream& output, const string::String& data) {
-	return ToStringComposers::stringComposer.compose(output, data);
+	return string::StringToStringComposer::compose(output, data);
 }
 
-
 primitive::Primitive stringApi<primitive::Primitive>::parse(std::istream& input) {
 	return FromStringParsers::primitiveParser.parsePrimitive(input);
 }
 
 void stringApi<primitive::Primitive>::compose(std::ostream& output, const primitive::Primitive& data) {
-	return ToStringComposers::primitiveComposer.compose(output, data);
+	return primitive::PrimitiveToStringComposer::compose(output, data);
 }
 
 } /* namespace alib */
diff --git a/alib2str/src/StringApi.hpp b/alib2str/src/StringApi.hpp
index 752e3f1224776596a60de56f97d81f6b453d6067..6420ad1b8cbeacaabd327c12651256a0c22ab41f 100644
--- a/alib2str/src/StringApi.hpp
+++ b/alib2str/src/StringApi.hpp
@@ -98,18 +98,6 @@ public:
 
 };
 
-class ToStringComposers {
-public:
-	static const label::LabelToStringComposer labelComposer;
-	static const alphabet::SymbolToStringComposer symbolComposer;
-	static const regexp::RegExpToStringComposer regexpComposer;
-	static const string::StringToStringComposer stringComposer;
-	static const automaton::AutomatonToStringComposer automatonComposer;
-	static const grammar::GrammarToStringComposer grammarComposer;
-	static const graph::GraphToStringComposer graphComposer;
-	static const primitive::PrimitiveToStringComposer primitiveComposer;
-};
-
 } /* namespace alib */
 
 #endif /* STRING_API_HPP_ */
diff --git a/alib2str/src/alphabet/SymbolToStringComposer.cpp b/alib2str/src/alphabet/SymbolToStringComposer.cpp
index ad5d8a0452b54057182d1a823135ca3b28dd27ef..eb7b6bfcf486b289974d6738f3f4e7a62c8455ad 100644
--- a/alib2str/src/alphabet/SymbolToStringComposer.cpp
+++ b/alib2str/src/alphabet/SymbolToStringComposer.cpp
@@ -7,6 +7,13 @@
 
 #include "SymbolToStringComposer.h"
 #include "alphabet/LabeledSymbol.h"
+#include "alphabet/StartSymbol.h"
+#include "alphabet/EndSymbol.h"
+#include "alphabet/BottomOfTheStackSymbol.h"
+#include "alphabet/BlankSymbol.h"
+#include "alphabet/BarSymbol.h"
+#include "alphabet/VariablesBarSymbol.h"
+#include "alphabet/SubtreeWildcardSymbol.h"
 #include "alphabet/RankedSymbol.h"
 #include "alphabet/SymbolPairSymbol.h"
 #include "alphabet/SymbolSetSymbol.h"
@@ -16,64 +23,62 @@
 
 namespace alphabet {
 
-void SymbolToStringComposer::Visit(void* userData, const LabeledSymbol& symbol) const {
-	std::ostream &out = *((std::ostream*) userData);
-
+void SymbolToStringComposer::compose(std::ostream& out, const LabeledSymbol& symbol) {
 	alib::stringApi<label::Label>::compose(out, symbol.getLabel());
 }
 
-void SymbolToStringComposer::Visit(void* userData, const BlankSymbol&) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, LabeledSymbol> SymbolToStringComposerLabeledSymbol = SymbolToStringComposer::RegistratorWrapper<void, LabeledSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const BlankSymbol&) {
 	out << "#B";
 }
 
-void SymbolToStringComposer::Visit(void* userData, const BottomOfTheStackSymbol&) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, BlankSymbol> SymbolToStringComposerBlankSymbol = SymbolToStringComposer::RegistratorWrapper<void, BlankSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const BottomOfTheStackSymbol&) {
 	out << "#T";
 }
 
-void SymbolToStringComposer::Visit(void* userData, const EndSymbol&) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, BottomOfTheStackSymbol> SymbolToStringComposerBottomOfTheStackSymbol = SymbolToStringComposer::RegistratorWrapper<void, BottomOfTheStackSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const EndSymbol&) {
 	out << "#$";
 }
 
-void SymbolToStringComposer::Visit(void* userData, const StartSymbol&) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, EndSymbol> SymbolToStringComposerEndSymbol = SymbolToStringComposer::RegistratorWrapper<void, EndSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const StartSymbol&) {
 	out << "#^";
 }
 
-void SymbolToStringComposer::Visit(void* userData, const RankedSymbol& symbol) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, StartSymbol> SymbolToStringComposerStartSymbol = SymbolToStringComposer::RegistratorWrapper<void, StartSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const RankedSymbol& symbol) {
 	alib::stringApi<alphabet::Symbol>::compose(out, symbol.getSymbol());
 	alib::stringApi<primitive::Primitive>::compose(out, primitive::Primitive(symbol.getRank()));
 }
 
-void SymbolToStringComposer::Visit(void* userData, const BarSymbol&) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, RankedSymbol> SymbolToStringComposerRankedSymbol = SymbolToStringComposer::RegistratorWrapper<void, RankedSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const BarSymbol&) {
 	out << "#|";
 }
 
-void SymbolToStringComposer::Visit(void* userData, const VariablesBarSymbol&) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, BarSymbol> SymbolToStringComposerBarSymbol = SymbolToStringComposer::RegistratorWrapper<void, BarSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const VariablesBarSymbol&) {
 	out << "#/";
 }
 
-void SymbolToStringComposer::Visit(void* userData, const SubtreeWildcardSymbol&) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, VariablesBarSymbol> SymbolToStringComposerVariablesBarSymbol = SymbolToStringComposer::RegistratorWrapper<void, VariablesBarSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const SubtreeWildcardSymbol&) {
 	out << "#S";
 }
 
-void SymbolToStringComposer::Visit(void* userData, const SymbolSetSymbol& symbol) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, SubtreeWildcardSymbol> SymbolToStringComposerSubtreeWildcardSymbol = SymbolToStringComposer::RegistratorWrapper<void, SubtreeWildcardSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const SymbolSetSymbol& symbol) {
 	out << '[';
 	bool first = true;
 	for(const Symbol& innerSymbol : symbol.getData()) {
@@ -81,33 +86,35 @@ void SymbolToStringComposer::Visit(void* userData, const SymbolSetSymbol& symbol
 			out << ", ";
 		else
 			first = false;
-		innerSymbol.getData().Accept(userData, *this);
+		getInstance().dispatch(out, innerSymbol.getData());
 	}
 	out << ']';
 }
 
-void SymbolToStringComposer::Visit(void* userData, const SymbolPairSymbol& symbol) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, SymbolSetSymbol> SymbolToStringComposerSymbolSetSymbol = SymbolToStringComposer::RegistratorWrapper<void, SymbolSetSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const SymbolPairSymbol& symbol) {
 	out << '<';
-	symbol.getData().first.getData().Accept(userData, *this);
+	getInstance().dispatch(out, symbol.getData().first.getData());
 	out << ", ";
-	symbol.getData().second.getData().Accept(userData, *this);
+	getInstance().dispatch(out, symbol.getData().second.getData());
 	out << '>';
 }
 
-void SymbolToStringComposer::Visit(void* userData, const UniqueSymbol& symbol) const {
-	std::ostream &out = *((std::ostream*) userData);
+SymbolToStringComposer::RegistratorWrapper<void, SymbolPairSymbol> SymbolToStringComposerSymbolPairSymbol = SymbolToStringComposer::RegistratorWrapper<void, SymbolPairSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
 
+void SymbolToStringComposer::compose(std::ostream& out, const UniqueSymbol& symbol) {
 	out << '<';
-	symbol.getSymbol().getData().Accept(userData, *this);
+	getInstance().dispatch(out, symbol.getSymbol().getData());
 	out << ", ";
 	alib::stringApi<primitive::Primitive>::compose(out, primitive::Primitive(symbol.getId()));
 	out << '>';
 }
 
-void SymbolToStringComposer::compose(std::ostream& out, const Symbol& symbol) const {
-	symbol.getData().Accept((void*) &out, *this);
+SymbolToStringComposer::RegistratorWrapper<void, UniqueSymbol> SymbolToStringComposerUniqueSymbol = SymbolToStringComposer::RegistratorWrapper<void, UniqueSymbol>(SymbolToStringComposer::getInstance(), SymbolToStringComposer::compose);
+
+void SymbolToStringComposer::compose(std::ostream& out, const Symbol& symbol) {
+	getInstance().dispatch(out, symbol.getData());
 }
 
 } /* namespace alphabet */
diff --git a/alib2str/src/alphabet/SymbolToStringComposer.h b/alib2str/src/alphabet/SymbolToStringComposer.h
index ae04b582dbd7d2f6effd9019fef59aaa4de394dc..1c47edaefd56dea93ce0f50d69732069a2027a9f 100644
--- a/alib2str/src/alphabet/SymbolToStringComposer.h
+++ b/alib2str/src/alphabet/SymbolToStringComposer.h
@@ -9,38 +9,41 @@
 #define SYMBOL_TO_STRING_COMPOSER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 #include "alphabet/Symbol.h"
+#include "alphabet/SymbolFeatures.h"
 
 namespace alphabet {
 
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class SymbolToStringComposer : public VisitableSymbolBase::const_visitor_type {
+class SymbolToStringComposer : public std::SingleDispatchFirstStaticParam<void, std::ostream, SymbolBase> {
 public:
-	SymbolToStringComposer() {}
-
-private:
-	void Visit(void*, const LabeledSymbol& symbol) const;
-	void Visit(void*, const BlankSymbol& symbol) const;
-	void Visit(void*, const BottomOfTheStackSymbol& symbol) const;
-	void Visit(void*, const EndSymbol& symbol) const;
-	void Visit(void*, const StartSymbol& symbol) const;
-	void Visit(void*, const RankedSymbol& symbol) const;
-	void Visit(void*, const BarSymbol& symbol) const;
-	void Visit(void*, const VariablesBarSymbol& symbol) const;
-	void Visit(void*, const SubtreeWildcardSymbol& symbol) const;
-	void Visit(void*, const SymbolPairSymbol& symbol) const;
-	void Visit(void*, const SymbolSetSymbol& symbol) const;
-	void Visit(void*, const UniqueSymbol& symbol) const;
+	static void compose(std::ostream& output, const LabeledSymbol& symbol);
+	static void compose(std::ostream& output, const BlankSymbol& symbol);
+	static void compose(std::ostream& output, const BottomOfTheStackSymbol& symbol);
+	static void compose(std::ostream& output, const EndSymbol& symbol);
+	static void compose(std::ostream& output, const StartSymbol& symbol);
+	static void compose(std::ostream& output, const RankedSymbol& symbol);
+	static void compose(std::ostream& output, const BarSymbol& symbol);
+	static void compose(std::ostream& output, const VariablesBarSymbol& symbol);
+	static void compose(std::ostream& output, const SubtreeWildcardSymbol& symbol);
+	static void compose(std::ostream& output, const SymbolPairSymbol& symbol);
+	static void compose(std::ostream& output, const SymbolSetSymbol& symbol);
+	static void compose(std::ostream& output, const UniqueSymbol& symbol);
 
-public:
 	/**
 	 * Prints text representation of Symbol to the output stream.
 	 * @param string String to print
 	 * @param out output stream to which print the String
 	 */
-	void compose(std::ostream& output, const Symbol& string) const;
+	static void compose(std::ostream& output, const Symbol& string);
+
+	static SymbolToStringComposer& getInstance() {
+		static SymbolToStringComposer res;
+		return res;
+	}
 };
 
 } /* namespace alphabet */
diff --git a/alib2str/src/automaton/AutomatonToStringComposer.cpp b/alib2str/src/automaton/AutomatonToStringComposer.cpp
index 9e4acb611fb3b32881a68d26a11364793130a829..cce2cb00eff88f8c0910037b7cd74c8fbea38801 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 State& from) const {
+void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const DFA& automaton, const State& from) {
 	std::map<std::pair<State, alphabet::Symbol>, State> symbolTransitionsFromState = automaton.getTransitionsFromState(from);
 
 	for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) {
@@ -30,7 +30,7 @@ void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, c
 	}
 }
 
-void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const NFA& automaton, const State& from) const {
+void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const NFA& automaton, const State& from) {
 	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getTransitionsFromState(from);
 
 	for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) {
@@ -48,7 +48,7 @@ void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, c
 	}
 }
 
-void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const MultiInitialStateNFA& automaton, const State& from) const {
+void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const MultiInitialStateNFA& automaton, const State& from) {
 	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getTransitionsFromState(from);
 
 	for(const alphabet::Symbol& inputSymbol : automaton.getInputAlphabet()) {
@@ -66,7 +66,7 @@ void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, c
 	}
 }
 
-void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const EpsilonNFA& automaton, const State& from) const {
+void AutomatonToStringComposer::composeTransitionsFromState(std::ostream& out, const EpsilonNFA& automaton, const State& from) {
 	std::map<std::pair<State, alphabet::Symbol>, std::set<State> > symbolTransitionsFromState = automaton.getSymbolTransitionsFromState(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) const {
+void AutomatonToStringComposer::compose(std::ostream& out, const DFA& automaton) {
 	out << "DFA";
 	for(const auto& symbol : automaton.getInputAlphabet()) {
 		out << " ";
@@ -120,7 +120,9 @@ void AutomatonToStringComposer::compose(std::ostream& out, const DFA& automaton)
 	}
 }
 
-void AutomatonToStringComposer::compose(std::ostream& out, const NFA& automaton) const {
+AutomatonToStringComposer::RegistratorWrapper<void, DFA> AutomatonToStringComposerDFA = AutomatonToStringComposer::RegistratorWrapper<void, DFA>(AutomatonToStringComposer::getInstance(), AutomatonToStringComposer::compose);
+
+void AutomatonToStringComposer::compose(std::ostream& out, const NFA& automaton) {
 	out << "NFA";
 	for(const auto& symbol : automaton.getInputAlphabet()) {
 		out << " ";
@@ -144,7 +146,9 @@ void AutomatonToStringComposer::compose(std::ostream& out, const NFA& automaton)
 	}
 }
 
-void AutomatonToStringComposer::compose(std::ostream& out, const MultiInitialStateNFA& automaton) const {
+AutomatonToStringComposer::RegistratorWrapper<void, NFA> AutomatonToStringComposerNFA = AutomatonToStringComposer::RegistratorWrapper<void, NFA>(AutomatonToStringComposer::getInstance(), AutomatonToStringComposer::compose);
+
+void AutomatonToStringComposer::compose(std::ostream& out, const MultiInitialStateNFA& automaton) {
 	out << "MISNFA";
 	for(const auto& symbol : automaton.getInputAlphabet()) {
 		out << " ";
@@ -168,7 +172,9 @@ void AutomatonToStringComposer::compose(std::ostream& out, const MultiInitialSta
 	}
 }
 
-void AutomatonToStringComposer::compose(std::ostream& out, const EpsilonNFA& automaton) const {
+AutomatonToStringComposer::RegistratorWrapper<void, MultiInitialStateNFA> AutomatonToStringComposerMultiInitialStateNFA = AutomatonToStringComposer::RegistratorWrapper<void, MultiInitialStateNFA>(AutomatonToStringComposer::getInstance(), AutomatonToStringComposer::compose);
+
+void AutomatonToStringComposer::compose(std::ostream& out, const EpsilonNFA& automaton) {
 	out << "ENFA";
 	for(const auto& symbol : automaton.getInputAlphabet()) {
 		out << " ";
@@ -193,84 +199,10 @@ void AutomatonToStringComposer::compose(std::ostream& out, const EpsilonNFA& aut
 	}
 }
 
-void AutomatonToStringComposer::compose(std::ostream& output, const Automaton& automaton) const {
-	automaton.getData().Accept((void*) &output, *this);
-}
-
-void AutomatonToStringComposer::Visit(void* data, const EpsilonNFA& automaton) const {
-	this->compose(*((std::ostream*) data), automaton);
-}
-
-void AutomatonToStringComposer::Visit(void* data, const MultiInitialStateNFA& automaton) const {
-	this->compose(*((std::ostream*) data), automaton);
-}
-
-void AutomatonToStringComposer::Visit(void* data, const NFA& automaton) const {
-	this->compose(*((std::ostream*) data), automaton);
-}
-
-void AutomatonToStringComposer::Visit(void* data, const DFA& automaton) const {
-	this->compose(*((std::ostream*) data), automaton);
-}
-
-void AutomatonToStringComposer::Visit(void*, const ExtendedNFA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const CompactNFA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const DPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const SinglePopDPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const InputDrivenDPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const InputDrivenNPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const VisiblyPushdownDPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const VisiblyPushdownNPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const NPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const SinglePopNPDA&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const OneTapeDTM&) const {
-	throw exception::AlibException();
-}
-
-void AutomatonToStringComposer::Visit(void*, const DFTA&) const {
-	throw exception::AlibException();
-}
+AutomatonToStringComposer::RegistratorWrapper<void, EpsilonNFA> AutomatonToStringComposerEpsilonNFA = AutomatonToStringComposer::RegistratorWrapper<void, EpsilonNFA>(AutomatonToStringComposer::getInstance(), AutomatonToStringComposer::compose);
 
-void AutomatonToStringComposer::Visit(void*, const NFTA&) const {
-	throw exception::AlibException();
+void AutomatonToStringComposer::compose(std::ostream& output, const Automaton& automaton) {
+	getInstance().dispatch(output, automaton.getData());
 }
 
 } /* namespace automaton */
diff --git a/alib2str/src/automaton/AutomatonToStringComposer.h b/alib2str/src/automaton/AutomatonToStringComposer.h
index 186bd423dff9aeace74f8b4c5ac1775d23061f7f..700a6e8f6d149c34c2e008c2aed89c0f8eea4868 100644
--- a/alib2str/src/automaton/AutomatonToStringComposer.h
+++ b/alib2str/src/automaton/AutomatonToStringComposer.h
@@ -9,39 +9,17 @@
 #define AUTOMATON_TO_STRING_COMPOSER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 #include "automaton/Automaton.h"
+#include "automaton/AutomatonFeatures.h"
 
 namespace automaton {
 
-class AutomatonToStringComposer : public VisitableAutomatonBase::const_visitor_type {
-public:
-	AutomatonToStringComposer() {}
-
-private:
-	void Visit(void*, const EpsilonNFA& automaton) const;
-	void Visit(void*, const MultiInitialStateNFA& automaton) const;
-	void Visit(void*, const NFA& automaton) const;
-	void Visit(void*, const DFA& automaton) const;
-	void Visit(void*, const ExtendedNFA& automaton) const;
-	void Visit(void*, const CompactNFA& automaton) const;
-	void Visit(void*, const DPDA& automaton) const;
-	void Visit(void*, const SinglePopDPDA& automaton) const;
-	void Visit(void*, const InputDrivenDPDA& automaton) const;
-	void Visit(void*, const InputDrivenNPDA& automaton) const;
-	void Visit(void*, const VisiblyPushdownDPDA& automaton) const;
-	void Visit(void*, const VisiblyPushdownNPDA& automaton) const;
-	void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const;
-	void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const;
-	void Visit(void*, const NPDA& automaton) const;
-	void Visit(void*, const SinglePopNPDA& automaton) const;
-	void Visit(void*, const OneTapeDTM& automaton) const;
-	void Visit(void*, const DFTA& automaton) const;
-	void Visit(void*, const NFTA& automaton) const;
-
-	void composeTransitionsFromState(std::ostream& out, const DFA& automaton, const State& from) const;
-	void composeTransitionsFromState(std::ostream& out, const NFA& automaton, const State& from) const;
-	void composeTransitionsFromState(std::ostream& out, const MultiInitialStateNFA& automaton, const State& from) const;
-	void composeTransitionsFromState(std::ostream& out, const EpsilonNFA& automaton, const State& from) const;
+class AutomatonToStringComposer : public std::SingleDispatchFirstStaticParam<void, std::ostream, AutomatonBase> {
+	static void composeTransitionsFromState(std::ostream& out, const DFA& automaton, const State& from);
+	static void composeTransitionsFromState(std::ostream& out, const NFA& automaton, const State& from);
+	static void composeTransitionsFromState(std::ostream& out, const MultiInitialStateNFA& automaton, const State& from);
+	static void composeTransitionsFromState(std::ostream& out, const EpsilonNFA& automaton, const State& from);
 
 public:
 	/**
@@ -49,14 +27,17 @@ public:
 	 * @param automaton automaton to print
 	 * @return list of xml tokens representing the automaton
 	 */
-	void compose(std::ostream& output, const AutomatonBase& automaton) const;
+	static void compose(std::ostream& output, const Automaton& automaton);
 
-	void compose(std::ostream& output, const Automaton& automaton) const;
+	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);
 
-	void compose(std::ostream& output, const DFA& automaton) const;
-	void compose(std::ostream& output, const NFA& automaton) const;
-	void compose(std::ostream& output, const MultiInitialStateNFA& automaton) const;
-	void compose(std::ostream& output, const EpsilonNFA& automaton) const;
+	static AutomatonToStringComposer& getInstance() {
+		static AutomatonToStringComposer res;
+		return res;
+	}
 };
 
 } /* namespace automaton */
diff --git a/alib2str/src/grammar/GrammarToStringComposer.cpp b/alib2str/src/grammar/GrammarToStringComposer.cpp
index d3e60d6c8e46a5be0b25601b57af53d94b110ed1..23d6f2ae1bba475f91fb389cf9a8f003daea66be 100644
--- a/alib2str/src/grammar/GrammarToStringComposer.cpp
+++ b/alib2str/src/grammar/GrammarToStringComposer.cpp
@@ -12,7 +12,7 @@
 namespace grammar {
 
 template<class T>
-void GrammarToStringComposer::composeCFLikeGrammar(std::ostream& output, const T& grammar) const {
+void GrammarToStringComposer::composeCFLikeGrammar(std::ostream& output, const T& grammar) {
 	bool first;
 
 	output << " (" << std::endl;
@@ -64,7 +64,7 @@ void GrammarToStringComposer::composeCFLikeGrammar(std::ostream& output, const T
 }
 
 template<class T>
-void GrammarToStringComposer::composeCSLikeGrammar(std::ostream& output, const T& grammar) const {
+void GrammarToStringComposer::composeCSLikeGrammar(std::ostream& output, const T& grammar) {
 	bool first;
 
 	output << " (" << std::endl;
@@ -119,7 +119,7 @@ void GrammarToStringComposer::composeCSLikeGrammar(std::ostream& output, const T
 }
 
 template<class T>
-void GrammarToStringComposer::composePreservingCSLikeGrammar(std::ostream& output, const T& grammar) const {
+void GrammarToStringComposer::composePreservingCSLikeGrammar(std::ostream& output, const T& grammar) {
 	bool first;
 
 	output << " (" << std::endl;
@@ -180,125 +180,99 @@ void GrammarToStringComposer::composePreservingCSLikeGrammar(std::ostream& outpu
 	output << ")" << std::endl;
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const Grammar& grammar) const {
-	grammar.getData().Accept((void*) &output, *this);
+void GrammarToStringComposer::compose(std::ostream& output, const Grammar& grammar) {
+	getInstance().dispatch(output, grammar.getData());
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const LeftLG& grammar) const {
+void GrammarToStringComposer::compose(std::ostream& output, const LeftLG& grammar) {
 	output << "LEFT_LG";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const LeftRG& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, LeftLG> GrammarToStringComposerLeftLG = GrammarToStringComposer::RegistratorWrapper<void, LeftLG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const LeftRG& grammar) {
 	output << "LEFT_RG";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const RightLG& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, LeftRG> GrammarToStringComposerLeftRG = GrammarToStringComposer::RegistratorWrapper<void, LeftRG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const RightLG& grammar) {
 	output << "RIGHT_LG";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const RightRG& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, RightLG> GrammarToStringComposerRightLG = GrammarToStringComposer::RegistratorWrapper<void, RightLG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const RightRG& grammar) {
 	output << "RIGHT_RG";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const LG& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, RightRG> GrammarToStringComposerRightRG = GrammarToStringComposer::RegistratorWrapper<void, RightRG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const LG& grammar) {
 	output << "LG";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const CFG& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, LG> GrammarToStringComposerLG = GrammarToStringComposer::RegistratorWrapper<void, LG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const CFG& grammar) {
 	output << "CFG";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const EpsilonFreeCFG& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, CFG> GrammarToStringComposerCFG = GrammarToStringComposer::RegistratorWrapper<void, CFG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const EpsilonFreeCFG& grammar) {
 	output << "EPSILON_FREE_CFG";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, EpsilonFreeCFG> GrammarToStringComposerEpsilonFreeCFG = GrammarToStringComposer::RegistratorWrapper<void, EpsilonFreeCFG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const CNF& grammar) {
 	output << "CNF";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const GNF& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, CNF> GrammarToStringComposerCNF = GrammarToStringComposer::RegistratorWrapper<void, CNF>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const GNF& grammar) {
 	output << "GNF";
 	composeCFLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const CSG& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, GNF> GrammarToStringComposerGNF = GrammarToStringComposer::RegistratorWrapper<void, GNF>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const CSG& grammar) {
 	output << "CSG";
 	composePreservingCSLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const NonContractingGrammar& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, CSG> GrammarToStringComposerCSG = GrammarToStringComposer::RegistratorWrapper<void, CSG>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const NonContractingGrammar& grammar) {
 	output << "NON_CONTRACTING_GRAMMAR";
 	composeCSLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, NonContractingGrammar> GrammarToStringComposerNonContractingGrammar = GrammarToStringComposer::RegistratorWrapper<void, NonContractingGrammar>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar) {
 	output << "CONTEXT_PRESERVING_UNRESTRICTED_GRAMMAR";
 	composePreservingCSLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::compose(std::ostream& output, const UnrestrictedGrammar& grammar) const {
+GrammarToStringComposer::RegistratorWrapper<void, ContextPreservingUnrestrictedGrammar> GrammarToStringComposerContextPreservingUnrestructedGrammar = GrammarToStringComposer::RegistratorWrapper<void, ContextPreservingUnrestrictedGrammar>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
+
+void GrammarToStringComposer::compose(std::ostream& output, const UnrestrictedGrammar& grammar) {
 	output << "UNRESTRICTED_GRAMMAR";
 	composeCSLikeGrammar(output, grammar);
 }
 
-void GrammarToStringComposer::Visit(void* data, const LeftLG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const LeftRG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const RightLG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const RightRG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const LG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const CFG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const EpsilonFreeCFG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const CNF& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const GNF& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const CSG& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const NonContractingGrammar& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const ContextPreservingUnrestrictedGrammar& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
-
-void GrammarToStringComposer::Visit(void* data, const UnrestrictedGrammar& grammar) const {
-	this->compose(*((std::ostream*) data), grammar);
-}
+GrammarToStringComposer::RegistratorWrapper<void, UnrestrictedGrammar> GrammarToStringComposerUnrestructedGrammar = GrammarToStringComposer::RegistratorWrapper<void, UnrestrictedGrammar>(GrammarToStringComposer::getInstance(), GrammarToStringComposer::compose);
 
 }
diff --git a/alib2str/src/grammar/GrammarToStringComposer.h b/alib2str/src/grammar/GrammarToStringComposer.h
index 2f22b265a67814cb11dd71538678e861bd074948..495e9da2376a7a3e8aaaf82330f722d7aa4a8161 100644
--- a/alib2str/src/grammar/GrammarToStringComposer.h
+++ b/alib2str/src/grammar/GrammarToStringComposer.h
@@ -2,54 +2,46 @@
 #define GRAMMAR_TO_STRING_COMPOSER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 #include "grammar/Grammar.h"
+#include "grammar/GrammarFeatures.h"
 
 namespace grammar {
 
-class GrammarToStringComposer : public VisitableGrammarBase::const_visitor_type {
+class GrammarToStringComposer: public std::SingleDispatchFirstStaticParam<void, std::ostream, GrammarBase> {
 public:
-	GrammarToStringComposer() {}
-
-private:
-	void Visit(void*, const LeftLG& grammar) const;
-	void Visit(void*, const LeftRG& grammar) const;
-	void Visit(void*, const RightLG& grammar) const;
-	void Visit(void*, const RightRG& grammar) const;
-	void Visit(void*, const LG& grammar) const;
-	void Visit(void*, const CFG& grammar) const;
-	void Visit(void*, const EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const CNF& grammar) const;
-	void Visit(void*, const GNF& grammar) const;
-	void Visit(void*, const CSG& grammar) const;
-	void Visit(void*, const NonContractingGrammar& grammar) const;
-	void Visit(void*, const ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const UnrestrictedGrammar& grammar) const;
-
-	template<class T> void composeCFLikeGrammar(std::ostream& output, const T& grammar) const;
-	template<class T> void composeCSLikeGrammar(std::ostream& input, const T& grammar) const;
-	template<class T> void composePreservingCSLikeGrammar(std::ostream& input, const T& grammar) const;
+	template<class T>
+	static void composeCFLikeGrammar(std::ostream& output, const T& grammar);
+	template<class T>
+	static void composeCSLikeGrammar(std::ostream& output, const T& grammar);
+	template<class T>
+	static void composePreservingCSLikeGrammar(std::ostream& output, const T& grammar);
 
-public:
 	/**
 	 * Prints XML representation of Automaton to the output stream.
 	 * @param automaton automaton to print
 	 * @return list of xml tokens representing the automaton
 	 */
-	void compose(std::ostream& output, const Grammar& grammar) const;
-
-	void compose(std::ostream& output, const LeftLG& grammar) const;
-	void compose(std::ostream& output, const LeftRG& grammar) const;
-	void compose(std::ostream& output, const RightLG& grammar) const;
-	void compose(std::ostream& output, const RightRG& grammar) const;
-	void compose(std::ostream& output, const LG& grammar) const;
-	void compose(std::ostream& output, const CFG& grammar) const;
-	void compose(std::ostream& output, const EpsilonFreeCFG& grammar) const;
-	void compose(std::ostream& output, const CNF& grammar) const;
-	void compose(std::ostream& output, const GNF& grammar) const;
-	void compose(std::ostream& output, const CSG& grammar) const;
-	void compose(std::ostream& output, const NonContractingGrammar& grammar) const;
-	void compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar) const;
-	void compose(std::ostream& output, const UnrestrictedGrammar& grammar) const;
+	static void compose(std::ostream& output, const Grammar& grammar);
+
+	static void compose(std::ostream& output, const LeftLG& grammar);
+	static void compose(std::ostream& output, const LeftRG& grammar);
+	static void compose(std::ostream& output, const RightLG& grammar);
+	static void compose(std::ostream& output, const RightRG& grammar);
+	static void compose(std::ostream& output, const LG& grammar);
+	static void compose(std::ostream& output, const CFG& grammar);
+	static void compose(std::ostream& output, const EpsilonFreeCFG& grammar);
+	static void compose(std::ostream& output, const CNF& grammar);
+	static void compose(std::ostream& output, const GNF& grammar);
+	static void compose(std::ostream& output, const CSG& grammar);
+	static void compose(std::ostream& output, const NonContractingGrammar& grammar);
+	static void compose(std::ostream& output, const ContextPreservingUnrestrictedGrammar& grammar);
+	static void compose(std::ostream& output, const UnrestrictedGrammar& grammar);
+
+	static GrammarToStringComposer& getInstance() {
+		static GrammarToStringComposer res;
+		return res;
+	}
 };
 
 }
diff --git a/alib2str/src/graph/GraphToStringComposer.cpp b/alib2str/src/graph/GraphToStringComposer.cpp
index c945859967ce9985ef0cdde09c28fa48a68d19b1..6ceec6a28cf64d1aacec08ed7e51b8eb280aa0f0 100644
--- a/alib2str/src/graph/GraphToStringComposer.cpp
+++ b/alib2str/src/graph/GraphToStringComposer.cpp
@@ -12,17 +12,13 @@
 
 namespace graph {
 
-void GraphToStringComposer::compose(std::ostream &out, const Graph &graph) const
-{
+void GraphToStringComposer::compose(std::ostream &out, const Graph &graph) {
 	out << "(";
-	graph.getData().Accept(static_cast<void*>(&out), *this);
+	getInstance().dispatch(out, graph.getData());
 	out << ")";
 }
 
-void GraphToStringComposer::Visit(void *data, const DirectedGraph &graph) const
-{
-	std::ostream &out = *static_cast<std::ostream*>(data);
-
+void GraphToStringComposer::compose(std::ostream& out, const DirectedGraph &graph) {
 	out << "DirectedGraph:";
 	composeRepresentation(out, graph.getRepresentation());
 	out << ":";
@@ -35,10 +31,9 @@ void GraphToStringComposer::Visit(void *data, const DirectedGraph &graph) const
 	composeEdgeValues(out, graph);
 }
 
-void GraphToStringComposer::Visit(void *data, const UndirectedGraph &graph) const
-{
-	std::ostream &out = *static_cast<std::ostream*>(data);
+GraphToStringComposer::RegistratorWrapper<void, DirectedGraph> GraphToStringComposerDirectedGraph = GraphToStringComposer::RegistratorWrapper<void, DirectedGraph>(GraphToStringComposer::getInstance(), GraphToStringComposer::compose);
 
+void GraphToStringComposer::compose(std::ostream& out, const UndirectedGraph &graph) {
 	out << "UndirectedGraph:";
 	composeRepresentation(out, graph.getRepresentation());
 	out << ":";
@@ -51,32 +46,29 @@ void GraphToStringComposer::Visit(void *data, const UndirectedGraph &graph) cons
 	composeEdgeValues(out, graph);
 }
 
-void GraphToStringComposer::composeNode(std::ostream& out, const Node &node) const
-{
+GraphToStringComposer::RegistratorWrapper<void, UndirectedGraph> GraphToStringComposerUndirectedGraph = GraphToStringComposer::RegistratorWrapper<void, UndirectedGraph>(GraphToStringComposer::getInstance(), GraphToStringComposer::compose);
+
+void GraphToStringComposer::composeNode(std::ostream& out, const Node &node) {
 	alib::stringApi<label::Label>::compose(out, node.getName());
 }
 
-void GraphToStringComposer::composeEdge(std::ostream& out, const DirectedEdge &edge) const
-{
+void GraphToStringComposer::composeEdge(std::ostream& out, const DirectedEdge &edge) {
 	composeNode(out, edge.getFromNode());
 	alib::stringApi<label::Label>::compose(out, edge.getName());
 	composeNode(out, edge.getToNode());
 }
 
-void GraphToStringComposer::composeEdge(std::ostream& out, const UndirectedEdge &edge) const
-{
+void GraphToStringComposer::composeEdge(std::ostream& out, const UndirectedEdge &edge) {
 	composeNode(out, edge.getFirstNode());
 	alib::stringApi<label::Label>::compose(out, edge.getName());
 	composeNode(out, edge.getSecondNode());
 }
 
-void GraphToStringComposer::composeRepresentation(std::ostream &out, REPRESENTATION representation) const
-{
+void GraphToStringComposer::composeRepresentation(std::ostream &out, REPRESENTATION representation) {
 	out << representationToString(representation);
 }
 
-void GraphToStringComposer::composeNodes(std::ostream &out, const std::set<Node> &nodes) const
-{
+void GraphToStringComposer::composeNodes(std::ostream &out, const std::set<Node> &nodes) {
 	bool first = true;
 
 	for (const Node &node : nodes) {
@@ -89,8 +81,7 @@ void GraphToStringComposer::composeNodes(std::ostream &out, const std::set<Node>
 	}
 }
 
-void GraphToStringComposer::composeDirectedEdges(std::ostream &out, const std::set<DirectedEdge> &edges) const
-{
+void GraphToStringComposer::composeDirectedEdges(std::ostream &out, const std::set<DirectedEdge> &edges) {
 	bool first = true;
 
 	for (const DirectedEdge &edge : edges) {
@@ -103,8 +94,7 @@ void GraphToStringComposer::composeDirectedEdges(std::ostream &out, const std::s
 	}
 }
 
-void GraphToStringComposer::composeUndirectedEdges(std::ostream &out, const std::set<UndirectedEdge> &edges) const
-{
+void GraphToStringComposer::composeUndirectedEdges(std::ostream &out, const std::set<UndirectedEdge> &edges) {
 	bool first = true;
 
 	for (const UndirectedEdge &edge : edges) {
@@ -118,8 +108,7 @@ void GraphToStringComposer::composeUndirectedEdges(std::ostream &out, const std:
 }
 
 template<typename T>
-void GraphToStringComposer::composeNodeValues(std::ostream &out, const T &graph) const
-{
+void GraphToStringComposer::composeNodeValues(std::ostream &out, const T &graph) {
 	bool first = true;
 
 	for (auto i : graph.nodeValues) {
@@ -134,8 +123,7 @@ void GraphToStringComposer::composeNodeValues(std::ostream &out, const T &graph)
 }
 
 template<typename T>
-void GraphToStringComposer::composeEdgeValues(std::ostream &out, const T &graph) const
-{
+void GraphToStringComposer::composeEdgeValues(std::ostream &out, const T &graph) {
 	bool first = true;
 
 	for (auto i : graph.edgeValues) {
diff --git a/alib2str/src/graph/GraphToStringComposer.h b/alib2str/src/graph/GraphToStringComposer.h
index 617e0809cd8e73edb570ecd1b0e3ee85e68d1998..91405eec9237fca39493f96d563552f1c3cbdd19 100644
--- a/alib2str/src/graph/GraphToStringComposer.h
+++ b/alib2str/src/graph/GraphToStringComposer.h
@@ -9,8 +9,9 @@
 #define GRAPH_TO_STRING_COMPOSER_H_
 
 #include <set>
-
+#include <common/multipleDispatch.hpp>
 #include "graph/Graph.h"
+#include "graph/GraphFeatures.h"
 #include "graph/GraphRepresentation.h"
 #include "graph/common/Node.h"
 #include "graph/directed/DirectedEdge.h"
@@ -18,31 +19,32 @@
 
 namespace graph {
 
-class GraphToStringComposer : public VisitableGraphBase::const_visitor_type
-{
-public:
-	GraphToStringComposer() {}
-
-	void compose(std::ostream &out, const Graph &graph) const;
-
+class GraphToStringComposer : public std::SingleDispatchFirstStaticParam<void, std::ostream, GraphBase> {
 private:
-	void Visit(void *data, const DirectedGraph &graph) const;
-	void Visit(void *data, const UndirectedGraph &graph) const;
+	static void composeNode(std::ostream& out, const Node &node);
+	static void composeEdge(std::ostream& out, const DirectedEdge &edge);
+	static void composeEdge(std::ostream& out, const UndirectedEdge &edge);
 
-	void composeNode(std::ostream& out, const Node &node) const;
-	void composeEdge(std::ostream& out, const DirectedEdge &edge) const;
-	void composeEdge(std::ostream& out, const UndirectedEdge &edge) const;
-
-	void composeRepresentation(std::ostream &out, REPRESENTATION representation) const;
-	void composeNodes(std::ostream &out, const std::set<Node> &nodes) const;
-	void composeDirectedEdges(std::ostream &out, const std::set<DirectedEdge> &edges) const;
-	void composeUndirectedEdges(std::ostream &out, const std::set<UndirectedEdge> &edges) const;
+	static void composeRepresentation(std::ostream &out, REPRESENTATION representation);
+	static void composeNodes(std::ostream &out, const std::set<Node> &nodes);
+	static void composeDirectedEdges(std::ostream &out, const std::set<DirectedEdge> &edges);
+	static void composeUndirectedEdges(std::ostream &out, const std::set<UndirectedEdge> &edges);
 
 	template<typename T>
-	void composeNodeValues(std::ostream &out, const T &graph) const;
+	static void composeNodeValues(std::ostream &out, const T &graph);
 	template<typename T>
-	void composeEdgeValues(std::ostream &out, const T &graph) const;
+	static void composeEdgeValues(std::ostream &out, const T &graph);
+
+public:
+	static void compose(std::ostream& out, const Graph& graph);
+
+	static void compose(std::ostream& out, const DirectedGraph& graph);
+	static void compose(std::ostream& out, const UndirectedGraph& graph);
 
+	static GraphToStringComposer& getInstance() {
+		static GraphToStringComposer res;
+		return res;
+	}
 };
 
 } // namespace graph
diff --git a/alib2str/src/label/LabelToStringComposer.cpp b/alib2str/src/label/LabelToStringComposer.cpp
index df4d893fef6cdd7c73e91ce9a127471ee13ffdb2..434e4c7280fc9056359ffd41f8b615f7b14d370e 100644
--- a/alib2str/src/label/LabelToStringComposer.cpp
+++ b/alib2str/src/label/LabelToStringComposer.cpp
@@ -17,26 +17,25 @@
 
 namespace label {
 
-void LabelToStringComposer::Visit(void* userData, const PrimitiveLabel& label) const {
-	std::ostream &out = *((std::ostream*) userData);
-
+void LabelToStringComposer::compose(std::ostream& out, const PrimitiveLabel& label) {
 	alib::stringApi<primitive::Primitive>::compose(out, label.getData());
 }
 
-void LabelToStringComposer::Visit(void* userData, const HexavigesimalLabel& label) const {
-	std::ostream &out = *((std::ostream*) userData);
+LabelToStringComposer::RegistratorWrapper<void, PrimitiveLabel> LabelToStringComposerPrimitiveLabel = LabelToStringComposer::RegistratorWrapper<void, PrimitiveLabel>(LabelToStringComposer::getInstance(), LabelToStringComposer::compose);
 
+void LabelToStringComposer::compose(std::ostream& out, const HexavigesimalLabel& label) {
 	out << (std::string) label;
 }
 
-void LabelToStringComposer::Visit(void* userData, const ObjectLabel& label) const {
-	std::ostream &out = *((std::ostream*) userData);
+LabelToStringComposer::RegistratorWrapper<void, HexavigesimalLabel> LabelToStringComposerHexavigesimalLabel = LabelToStringComposer::RegistratorWrapper<void, HexavigesimalLabel>(LabelToStringComposer::getInstance(), LabelToStringComposer::compose);
+
+void LabelToStringComposer::compose(std::ostream& out, const ObjectLabel& label) {
 	out << (std::string) label;
 }
 
-void LabelToStringComposer::Visit(void* userData, const LabelSetLabel& label) const {
-	std::ostream &out = *((std::ostream*) userData);
+LabelToStringComposer::RegistratorWrapper<void, ObjectLabel> LabelToStringComposerObjectLabel = LabelToStringComposer::RegistratorWrapper<void, ObjectLabel>(LabelToStringComposer::getInstance(), LabelToStringComposer::compose);
 
+void LabelToStringComposer::compose(std::ostream& out, const LabelSetLabel& label) {
 	out << '[';
 	bool first = true;
 	for(const Label& innerLabel : label.getData()) {
@@ -44,34 +43,35 @@ void LabelToStringComposer::Visit(void* userData, const LabelSetLabel& label) co
 			out << ", ";
 		else
 			first = false;
-		innerLabel.getData().Accept(userData, *this);
+		getInstance().dispatch(out, innerLabel.getData());
 	}
 	out << ']';
 }
 
-void LabelToStringComposer::Visit(void* userData, const LabelPairLabel& label) const {
-	std::ostream &out = *((std::ostream*) userData);
+LabelToStringComposer::RegistratorWrapper<void, LabelSetLabel> LabelToStringComposerLabelSetLabel = LabelToStringComposer::RegistratorWrapper<void, LabelSetLabel>(LabelToStringComposer::getInstance(), LabelToStringComposer::compose);
 
+void LabelToStringComposer::compose(std::ostream& out, const LabelPairLabel& label) {
 	out << '<';
-	label.getData().first.getData().Accept(userData, *this);
+	getInstance().dispatch(out, label.getData().first.getData());
 	out << ", ";
-	label.getData().second.getData().Accept(userData, *this);
+	getInstance().dispatch(out, label.getData().second.getData());
 	out << '>';
 }
 
-void LabelToStringComposer::Visit(void* userData, const UniqueLabel& label) const {
-	std::ostream &out = *((std::ostream*) userData);
+LabelToStringComposer::RegistratorWrapper<void, LabelPairLabel> LabelToStringComposerLabelPairLabel = LabelToStringComposer::RegistratorWrapper<void, LabelPairLabel>(LabelToStringComposer::getInstance(), LabelToStringComposer::compose);
 
+void LabelToStringComposer::compose(std::ostream& out, const UniqueLabel& label) {
 	out << '<';
-	label.getLabel().getData().Accept(userData, *this);
+	getInstance().dispatch(out, label.getLabel().getData());
 	out << ", ";
-	primitive::PrimitiveToStringComposer composer;
-	label.getId().Accept(userData, composer);
+	alib::stringApi<primitive::Primitive>::compose(out, primitive::Primitive(label.getId()));
 	out << '>';
 }
 
-void LabelToStringComposer::compose(std::ostream& output, const Label& label) const {
-	label.getData().Accept((void*) &output, *this);
+LabelToStringComposer::RegistratorWrapper<void, UniqueLabel> LabelToStringComposerUniqueLabel = LabelToStringComposer::RegistratorWrapper<void, UniqueLabel>(LabelToStringComposer::getInstance(), LabelToStringComposer::compose);
+
+void LabelToStringComposer::compose(std::ostream& output, const Label& label) {
+	getInstance().dispatch(output, label.getData());
 }
 
 } /* namespace label */
diff --git a/alib2str/src/label/LabelToStringComposer.h b/alib2str/src/label/LabelToStringComposer.h
index 12f946d15a5aa93441ec64bbbfcb68eacca30346..8b88feb659fd1ab9c7ed9a5cad2ed5371cdfb38f 100644
--- a/alib2str/src/label/LabelToStringComposer.h
+++ b/alib2str/src/label/LabelToStringComposer.h
@@ -9,31 +9,35 @@
 #define LABEL_TO_STRING_COMPOSER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 #include "label/Label.h"
+#include "label/LabelFeatures.h"
 
 namespace label {
 
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class LabelToStringComposer : public VisitableLabelBase::const_visitor_type {
-public:
-	LabelToStringComposer() {}
-
-private:
-	void Visit(void*, const PrimitiveLabel& label) const;
-	void Visit(void*, const HexavigesimalLabel& label) const;
-	void Visit(void*, const ObjectLabel& label) const;
-	void Visit(void*, const LabelSetLabel& label) const;
-	void Visit(void*, const LabelPairLabel& label) const;
-	void Visit(void*, const UniqueLabel& label) const;
+class LabelToStringComposer : public std::SingleDispatchFirstStaticParam<void, std::ostream, LabelBase> {
 public:
+	static void compose(std::ostream&, const PrimitiveLabel& label);
+	static void compose(std::ostream&, const HexavigesimalLabel& label);
+	static void compose(std::ostream&, const ObjectLabel& label);
+	static void compose(std::ostream&, const LabelSetLabel& label);
+	static void compose(std::ostream&, const LabelPairLabel& label);
+	static void compose(std::ostream&, const UniqueLabel& label);
+
 	/**
 	 * Prints text representation of Label to the output stream.
 	 * @param string String to print
 	 * @param out output stream to which print the String
 	 */
-	void compose(std::ostream& output, const Label& string) const;
+	static void compose(std::ostream& output, const Label& string);
+
+	static LabelToStringComposer& getInstance() {
+		static LabelToStringComposer res;
+		return res;
+	}
 };
 
 } /* namespace label */
diff --git a/alib2str/src/primitive/PrimitiveToStringComposer.cpp b/alib2str/src/primitive/PrimitiveToStringComposer.cpp
index 1bc42296acbedf8e1482e1b164f115b05665fceb..c588f93ffcfe5c1a3e5bb9a605a7106645cf4a68 100644
--- a/alib2str/src/primitive/PrimitiveToStringComposer.cpp
+++ b/alib2str/src/primitive/PrimitiveToStringComposer.cpp
@@ -14,9 +14,7 @@
 
 namespace primitive {
 
-void PrimitiveToStringComposer::Visit(void* userData, const primitive::String& primitive) const {
-	std::ostream &out = *((std::ostream*) userData);
-
+void PrimitiveToStringComposer::compose(std::ostream& out, const String& primitive) {
 	auto replace = [](std::string& str, const std::string& what, const std::string& with) {
 		size_t index = 0;
 		while((index = str.find(what, index)) != std::string::npos) {
@@ -30,32 +28,34 @@ void PrimitiveToStringComposer::Visit(void* userData, const primitive::String& p
 	out << '\'' << tmp << '\'';
 }
 
-void PrimitiveToStringComposer::Visit(void* userData, const Character& primitive) const {
-	std::ostream &out = *((std::ostream*) userData);
+PrimitiveToStringComposer::RegistratorWrapper<void, String> PrimitiveToStringComposerString = PrimitiveToStringComposer::RegistratorWrapper<void, String>(PrimitiveToStringComposer::getInstance(), PrimitiveToStringComposer::compose);
 
+void PrimitiveToStringComposer::compose(std::ostream& out, const Character& primitive) {
 	out << primitive.getData();
 }
 
-void PrimitiveToStringComposer::Visit(void* userData, const Integer& primitive) const {
-	std::ostream &out = *((std::ostream*) userData);
+PrimitiveToStringComposer::RegistratorWrapper<void, Character> PrimitiveToStringComposerCharacter = PrimitiveToStringComposer::RegistratorWrapper<void, Character>(PrimitiveToStringComposer::getInstance(), PrimitiveToStringComposer::compose);
 
+void PrimitiveToStringComposer::compose(std::ostream& out, const Integer& primitive) {
 	out << primitive.getData();
 }
 
-void PrimitiveToStringComposer::Visit(void* userData, const Unsigned& primitive) const {
-	std::ostream &out = *((std::ostream*) userData);
+PrimitiveToStringComposer::RegistratorWrapper<void, Integer> PrimitiveToStringComposerInteger = PrimitiveToStringComposer::RegistratorWrapper<void, Integer>(PrimitiveToStringComposer::getInstance(), PrimitiveToStringComposer::compose);
 
+void PrimitiveToStringComposer::compose(std::ostream& out, const Unsigned& primitive) {
 	out << primitive.getData();
 }
 
-void PrimitiveToStringComposer::Visit(void* userData, const Bool& primitive) const {
-	std::ostream &out = *((std::ostream*) userData);
+PrimitiveToStringComposer::RegistratorWrapper<void, Unsigned> PrimitiveToStringComposerUnsigned = PrimitiveToStringComposer::RegistratorWrapper<void, Unsigned>(PrimitiveToStringComposer::getInstance(), PrimitiveToStringComposer::compose);
 
+void PrimitiveToStringComposer::compose(std::ostream& out, const Bool& primitive) {
 	out << (primitive.getData() ? "true" : "false");
 }
 
-void PrimitiveToStringComposer::compose(std::ostream& out, const Primitive& primitive) const {
-	primitive.getData().Accept((void*) &out, *this);
+PrimitiveToStringComposer::RegistratorWrapper<void, Bool> PrimitiveToStringComposerBool = PrimitiveToStringComposer::RegistratorWrapper<void, Bool>(PrimitiveToStringComposer::getInstance(), PrimitiveToStringComposer::compose);
+
+void PrimitiveToStringComposer::compose(std::ostream& out, const Primitive& primitive) {
+	getInstance().dispatch(out, primitive.getData());
 }
 
 } /* namespace primitive */
diff --git a/alib2str/src/primitive/PrimitiveToStringComposer.h b/alib2str/src/primitive/PrimitiveToStringComposer.h
index a416615c3d2f7bcede7ec616292273fb077aee22..da37f1db94e402ef69a888c8a1c200d92ec3a30e 100644
--- a/alib2str/src/primitive/PrimitiveToStringComposer.h
+++ b/alib2str/src/primitive/PrimitiveToStringComposer.h
@@ -9,30 +9,34 @@
 #define PRIMITIVE_TO_STRING_COMPOSER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 #include "primitive/Primitive.h"
+#include "primitive/PrimitiveFeatures.h"
 
 namespace primitive {
 
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class PrimitiveToStringComposer : public VisitablePrimitiveBase::const_visitor_type {
-public:
-	PrimitiveToStringComposer() {}
-
-private:
-	void Visit(void*, const Integer& primitive) const;
-	void Visit(void*, const String& primitive) const;
-	void Visit(void*, const Character& primitive) const;
-	void Visit(void*, const Unsigned& primitive) const;
-	void Visit(void*, const Bool& primitive) const;
+class PrimitiveToStringComposer : public std::SingleDispatchFirstStaticParam<void, std::ostream, PrimitiveBase> {
 public:
+	static void compose(std::ostream&, const Integer& primitive);
+	static void compose(std::ostream&, const String& primitive);
+	static void compose(std::ostream&, const Character& primitive);
+	static void compose(std::ostream&, const Unsigned& primitive);
+	static void compose(std::ostream&, const Bool& primitive);
+
 	/**
 	 * Prints text representation of Primitive to the output stream.
 	 * @param string String to print
 	 * @param out output stream to which print the String
 	 */
-	void compose(std::ostream& out, const Primitive& string) const;
+	static void compose(std::ostream& out, const Primitive& string);
+
+	static PrimitiveToStringComposer& getInstance() {
+		static PrimitiveToStringComposer res;
+		return res;
+	}
 };
 
 } /* namespace primitive */
diff --git a/alib2str/src/regexp/RegExpToStringComposer.cpp b/alib2str/src/regexp/RegExpToStringComposer.cpp
index 8b3bad35195ba5e6631b60e8d7213191eb89cd04..048338354ab55e2c8873016cc00401b5fbfc49ad 100644
--- a/alib2str/src/regexp/RegExpToStringComposer.cpp
+++ b/alib2str/src/regexp/RegExpToStringComposer.cpp
@@ -15,14 +15,24 @@
 
 namespace regexp {
 
-void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExp& regexp) const {
-	regexp.getRegExp().Accept(userData, *this);
+void RegExpToStringComposer::compose(std::ostream& output, const UnboundedRegExp& regexp) {
+	Priority tmp = Priority::ALTERNATION;
+	std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output);
+	RegExpToStringComposer composer;
+	regexp.getRegExp().Accept((void*) &out, composer);
 }
 
-void RegExpToStringComposer::Visit(void* userData, const FormalRegExp& regexp) const {
-	regexp.getRegExp().Accept(userData, *this);
+RegExpToStringComposer::RegistratorWrapper<void, UnboundedRegExp> RegExpToStringComposerUnboundedRegExp = RegExpToStringComposer::RegistratorWrapper<void, UnboundedRegExp>(RegExpToStringComposer::getInstance(), RegExpToStringComposer::compose);
+
+void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExp& regexp) {
+	Priority tmp = Priority::ALTERNATION;
+	std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output);
+	RegExpToStringComposer composer;
+	regexp.getRegExp().Accept((void*) &out, composer);
 }
 
+RegExpToStringComposer::RegistratorWrapper<void, FormalRegExp> RegExpToStringComposerFormalRegExp = RegExpToStringComposer::RegistratorWrapper<void, FormalRegExp>(RegExpToStringComposer::getInstance(), RegExpToStringComposer::compose);
+
 void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const {
 	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
 
@@ -147,10 +157,8 @@ void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEmpty&) con
 	std::get<1>(out) << "#0";
 }
 
-void RegExpToStringComposer::compose(std::ostream& output, const RegExp& regexp) const {
-	Priority tmp = Priority::ALTERNATION;
-	std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output);
-	regexp.getData().Accept((void*) &out, *this);
+void RegExpToStringComposer::compose(std::ostream& output, const RegExp& regexp) {
+	getInstance().dispatch(output, regexp.getData());
 }
 
 } /* namespace regexp */
diff --git a/alib2str/src/regexp/RegExpToStringComposer.h b/alib2str/src/regexp/RegExpToStringComposer.h
index 4e627b65a37352f4195108ec97e6f183e3fcd2ea..683d2ff6073c14ac402bdf74a6b84eae86ae2e32 100644
--- a/alib2str/src/regexp/RegExpToStringComposer.h
+++ b/alib2str/src/regexp/RegExpToStringComposer.h
@@ -9,16 +9,14 @@
 #define REX_EXP_TO_STRING_COMPOSER_H_
 
 #include <string>
+#include <common/multipleDispatch.hpp>
 #include "regexp/RegExp.h"
 #include "regexp/unbounded/UnboundedRegExpElement.h"
 #include "regexp/formal/FormalRegExpElement.h"
 
 namespace regexp {
 
-class RegExpToStringComposer : public VisitableRegExpBase::const_visitor_type, UnboundedRegExpElement::const_visitor_type, FormalRegExpElement::const_visitor_type {
-public:
-	RegExpToStringComposer() {}
-
+class RegExpToStringComposer : public std::SingleDispatchFirstStaticParam<void, std::ostream, RegExpBase>, UnboundedRegExpElement::const_visitor_type, FormalRegExpElement::const_visitor_type {
 private:
 	void Visit(void*, const UnboundedRegExpAlternation& alternation) const;
 	void Visit(void*, const UnboundedRegExpConcatenation& concatenation) const;
@@ -27,7 +25,6 @@ private:
 	void Visit(void*, const UnboundedRegExpEpsilon& epsilon) const;
 	void Visit(void*, const UnboundedRegExpEmpty& empty) const;
 
-
 	void Visit(void*, const FormalRegExpAlternation& alternation) const;
 	void Visit(void*, const FormalRegExpConcatenation& concatenation) const;
 	void Visit(void*, const FormalRegExpIteration& iteration) const;
@@ -35,23 +32,27 @@ private:
 	void Visit(void*, const FormalRegExpEpsilon& epsilon) const;
 	void Visit(void*, const FormalRegExpEmpty& empty) const;
 
-
-	void Visit(void*, const UnboundedRegExp& empty) const;
-	void Visit(void*, const FormalRegExp& empty) const;
-
-
 	enum class Priority {
 		ALTERNATION,
 		CONCATENATION,
 		FACTOR
 	};
+
 public:
 	/**
 	 * Composes string representation of RegExp.
 	 * @param regexp RegExp to print
 	 * @returns string representation of regexp
 	 */
-	void compose(std::ostream& out, const RegExp& regexp) const;
+	static void compose(std::ostream& out, const RegExp& regexp);
+
+	static void compose(std::ostream& out, const UnboundedRegExp& regexp);
+	static void compose(std::ostream& out, const FormalRegExp& regexp);
+
+	static RegExpToStringComposer& getInstance() {
+		static RegExpToStringComposer res;
+		return res;
+	}
 };
 
 } /* namespace regexp */
diff --git a/alib2str/src/string/StringToStringComposer.cpp b/alib2str/src/string/StringToStringComposer.cpp
index fa373d63b52e864db84e812d78af3283afd177ab..ef5f407f96319ae60a27cad4d3a9a9ab19793140 100644
--- a/alib2str/src/string/StringToStringComposer.cpp
+++ b/alib2str/src/string/StringToStringComposer.cpp
@@ -13,9 +13,7 @@
 
 namespace string {
 
-void StringToStringComposer::Visit(void* userData, const CyclicString& string) const {
-	std::ostream &out = *((std::ostream*) userData);
-
+void StringToStringComposer::compose(std::ostream& out, const CyclicString& string) {
 	out << "<";
 	for(const auto& symbol : string.getContent()) {
 		alib::stringApi<alphabet::Symbol>::compose(out, symbol);
@@ -23,9 +21,9 @@ void StringToStringComposer::Visit(void* userData, const CyclicString& string) c
 	out << ">";
 }
 
-void StringToStringComposer::Visit(void* userData, const LinearString& string) const {
-	std::ostream &out = *((std::ostream*) userData);
+StringToStringComposer::RegistratorWrapper<void, CyclicString> StringToStringComposerCyclicString = StringToStringComposer::RegistratorWrapper<void, CyclicString>(StringToStringComposer::getInstance(), StringToStringComposer::compose);
 
+void StringToStringComposer::compose(std::ostream& out, const LinearString& string) {
 	out << "\"";
 	for(const auto& symbol : string.getContent()) {
 		alib::stringApi<alphabet::Symbol>::compose(out, symbol);
@@ -33,14 +31,16 @@ void StringToStringComposer::Visit(void* userData, const LinearString& string) c
 	out << "\"";
 }
 
-void StringToStringComposer::Visit(void* userData, const Epsilon&) const {
-	std::ostream &out = *((std::ostream*) userData);
+StringToStringComposer::RegistratorWrapper<void, LinearString> StringToStringComposerLinearString = StringToStringComposer::RegistratorWrapper<void, LinearString>(StringToStringComposer::getInstance(), StringToStringComposer::compose);
 
+void StringToStringComposer::compose(std::ostream& out, const Epsilon&) {
 	out << "#E";
 }
 
-void StringToStringComposer::compose(std::ostream& out, const String& string) const {
-	string.getData().Accept((void*) &out, *this);
+StringToStringComposer::RegistratorWrapper<void, Epsilon> StringToStringComposerEpsilon = StringToStringComposer::RegistratorWrapper<void, Epsilon>(StringToStringComposer::getInstance(), StringToStringComposer::compose);
+
+void StringToStringComposer::compose(std::ostream& out, const String& string) {
+	getInstance().dispatch(out, string.getData());
 }
 
 } /* namespace string */
diff --git a/alib2str/src/string/StringToStringComposer.h b/alib2str/src/string/StringToStringComposer.h
index 7e4157d76a74542d7859a76c7e860ad368735a85..7119954e8e639f014ac803e648d74cb84013825e 100644
--- a/alib2str/src/string/StringToStringComposer.h
+++ b/alib2str/src/string/StringToStringComposer.h
@@ -9,28 +9,32 @@
 #define STRING_TO_STRING_COMPOSER_H_
 
 #include <ostream>
+#include <common/multipleDispatch.hpp>
 #include "string/String.h"
+#include "string/StringFeatures.h"
 
 namespace string {
 
 /**
  * This class contains methods to print XML representation of string to the output stream.
  */
-class StringToStringComposer : public VisitableStringBase::const_visitor_type {
+class StringToStringComposer: public std::SingleDispatchFirstStaticParam<void, std::ostream, StringBase> {
 public:
-	StringToStringComposer() {}
+	static void compose(std::ostream&, const LinearString& string);
+	static void compose(std::ostream&, const CyclicString& string);
+	static void compose(std::ostream&, const Epsilon& string);
 
-private:
-	void Visit(void*, const LinearString& string) const;
-	void Visit(void*, const CyclicString& string) const;
-	void Visit(void*, const Epsilon& string) const;
-public:
 	/**
 	 * Prints XML representation of String to the output stream.
 	 * @param string String to print
 	 * @param out output stream to which print the String
 	 */
-	void compose(std::ostream& output, const String& string) const;
+	static void compose(std::ostream& output, const String& string);
+
+	static StringToStringComposer& getInstance() {
+		static StringToStringComposer res;
+		return res;
+	}
 };
 
 } /* namespace string */