diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp
index a2966075f08862da078a81dcb868b565e72254c4..723a3deac39135404bbbc917f91c8c130c792721 100644
--- a/alib2algo/src/automaton/determinize/Determinize.cpp
+++ b/alib2algo/src/automaton/determinize/Determinize.cpp
@@ -16,107 +16,64 @@ namespace automaton {
 namespace determinize {
 
 automaton::Automaton Determinize::determinize(const automaton::Automaton& automaton) {
-	automaton::Automaton* out = NULL;
-	automaton.getData().Accept((void*) &out, Determinize::DETERMINIZE);
-	automaton::Automaton res = std::move(*out);
-	delete out;
-	return res;
+	return getInstance().dispatch(automaton.getData());
 }
 
-void Determinize::Visit(void*, const automaton::EpsilonNFA&) const {
-	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
+DFA Determinize::determinize(const automaton::DFA& automaton) {
+	return automaton;
 }
 
-void Determinize::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
-
-void Determinize::Visit(void* data, const automaton::NFA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
+auto DeterminizeDFA = Determinize::RegistratorWrapper<automaton::DFA, automaton::DFA>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::DFA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
+DPDA Determinize::determinize(const automaton::DPDA& automaton) {
+	return automaton;
 }
 
-void Determinize::Visit(void*, const automaton::ExtendedNFA& ) const {
-	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
-}
-
-void Determinize::Visit(void*, const automaton::CompactNFA& ) const {
-	throw exception::AlibException("Unsupported automaton type CompactNFA");
-}
+auto DeterminizeDPDA = Determinize::RegistratorWrapper<automaton::DPDA, automaton::DPDA>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::DPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
+SinglePopDPDA Determinize::determinize(const automaton::SinglePopDPDA& automaton) {
+	return automaton;
 }
 
-void Determinize::Visit(void* data, const automaton::SinglePopDPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
-}
+auto DeterminizeSinglePopDPDA = Determinize::RegistratorWrapper<automaton::SinglePopDPDA, automaton::SinglePopDPDA>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::InputDrivenDPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
+InputDrivenDPDA Determinize::determinize(const automaton::InputDrivenDPDA& automaton) {
+	return automaton;
 }
 
-void Determinize::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
+auto DeterminizeInputDrivenDPDA = Determinize::RegistratorWrapper<automaton::InputDrivenDPDA, automaton::InputDrivenDPDA>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::VisiblyPushdownDPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
+VisiblyPushdownDPDA Determinize::determinize(const automaton::VisiblyPushdownDPDA& automaton) {
+	return automaton;
 }
 
-void Determinize::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
+auto DeterminizeVisiblyPushdownDPDA = Determinize::RegistratorWrapper<automaton::VisiblyPushdownDPDA, automaton::VisiblyPushdownDPDA>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::RealTimeHeightDeterministicDPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
+RealTimeHeightDeterministicDPDA Determinize::determinize(const automaton::RealTimeHeightDeterministicDPDA& automaton) {
+	return automaton;
 }
 
-void Determinize::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
+auto DeterminizeRealTimeHeightDeterministicDPDA = Determinize::RegistratorWrapper<automaton::RealTimeHeightDeterministicDPDA, automaton::RealTimeHeightDeterministicDPDA>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::NPDA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
+DPDA Determinize::determinize(const automaton::NPDA& automaton) {
 	automaton::RealTimeHeightDeterministicNPDA rhpda = automaton::PDAToRHPDA::convert(automaton);
-	automaton::RealTimeHeightDeterministicDPDA dpda = this->determinize(rhpda);
-	out = new automaton::Automaton(automaton::RHPDAToPDA::convert(dpda));
+	automaton::RealTimeHeightDeterministicDPDA dpda = Determinize::determinize(rhpda);
+	return automaton::RHPDAToPDA::convert(dpda);
 }
 
-void Determinize::Visit(void*, const automaton::SinglePopNPDA&) const {
-	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
-}
+auto DeterminizeNPDA = Determinize::RegistratorWrapper<automaton::DPDA, automaton::NPDA>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::OneTapeDTM& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
+OneTapeDTM Determinize::determinize(const automaton::OneTapeDTM& automaton) {
+	return automaton;
 }
 
-void Determinize::Visit(void* data, const automaton::NFTA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
+auto DeterminizeOneTapeDTM = Determinize::RegistratorWrapper<automaton::OneTapeDTM, automaton::OneTapeDTM>(Determinize::getInstance(), Determinize::determinize);
 
-void Determinize::Visit(void* data, const automaton::DFTA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(automaton);
+DFTA Determinize::determinize(const automaton::DFTA& automaton) {
+	return automaton;
 }
 
-const Determinize Determinize::DETERMINIZE;
+auto DeterminizeDFTA = Determinize::RegistratorWrapper<automaton::DFTA, automaton::DFTA>(Determinize::getInstance(), Determinize::determinize);
 
 } /* namespace determinize */
 
diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h
index ef939cbe808461d8fc8eb3e1e8356f42e17fa8f1..54421ad1ae4a6d0ca304a9303d35fa54fc208b8b 100644
--- a/alib2algo/src/automaton/determinize/Determinize.h
+++ b/alib2algo/src/automaton/determinize/Determinize.h
@@ -8,6 +8,7 @@
 #ifndef DETERMINIZE_H_
 #define DETERMINIZE_H_
 
+#include <common/multipleDispatch.hpp>
 #include <set>
 
 #include <automaton/common/State.h>
@@ -30,33 +31,7 @@ namespace determinize {
 /**
  * Class for running determinization algorithm on fsm.
  */
-class Determinize : public automaton::VisitableAutomatonBase::const_visitor_type {
-public:
-	Determinize() {}
-
-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::DFTA& automaton) const;
-	void Visit(void*, const automaton::NFTA& automaton) const;
-
-	static const Determinize DETERMINIZE;
-
+class Determinize : public std::SingleDispatch<automaton::Automaton, automaton::AutomatonBase> {
 public:
 
 	/**
@@ -66,12 +41,26 @@ public:
 	 */
 	static automaton::Automaton determinize(const automaton::Automaton& nfa);
 
+	static automaton::DFA determinize(const automaton::DFA& nfa);
 	static automaton::DFA determinize(const automaton::NFA& nfa);
 	static automaton::DFA determinize(const automaton::MultiInitialStateNFA& nfa);
+	static automaton::DPDA determinize(const automaton::DPDA& dpda);
+	static automaton::DPDA determinize(const automaton::NPDA& dpda);
+	static automaton::SinglePopDPDA determinize(const automaton::SinglePopDPDA& dpda);
+	static automaton::VisiblyPushdownDPDA determinize(const automaton::VisiblyPushdownDPDA& nondeterministic);
 	static automaton::VisiblyPushdownDPDA determinize(const automaton::VisiblyPushdownNPDA& nondeterministic);
+	static automaton::InputDrivenDPDA determinize(const automaton::InputDrivenDPDA& nfa);
 	static automaton::InputDrivenDPDA determinize(const automaton::InputDrivenNPDA& nfa);
+	static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicDPDA& nondeterministic);
 	static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicNPDA& nondeterministic);
+	static automaton::DFTA determinize(const automaton::DFTA& nfta);
 	static automaton::DFTA determinize(const automaton::NFTA& nfta);
+	static automaton::OneTapeDTM determinize(const automaton::OneTapeDTM& nfta);
+
+	static Determinize& getInstance() {
+		static Determinize res;
+		return res;
+	}
 };
 
 } /* namespace determinize */
diff --git a/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx
index e172c74d25cd9de4dd98226838eedf9feb8c08aa..f0faa2fee529f5f82d28014a2409a6934bce03b2 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx
@@ -5,6 +5,8 @@
  *	  Author: Jan Vesely
  */
 
+#include <common/multipleDispatch.hpp>
+
 #include "common/NFACommon.h"
 
 #include <automaton/PDA/InputDrivenNPDA.h>
@@ -64,6 +66,8 @@ automaton::InputDrivenDPDA Determinize::determinize(const automaton::InputDriven
 	return res;
 }
 
+auto DeterminizeInputDrivenNPDA = Determinize::RegistratorWrapper<automaton::InputDrivenDPDA, automaton::InputDrivenNPDA>(Determinize::getInstance(), Determinize::determinize);
+
 } /* namespace determinize */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
index 15b93f17eb8df99fdfb9d2886eafa5d3aca7b7c4..d49aa10b63f0ff517ad386fc571b9da43f7abe48 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
@@ -63,6 +63,8 @@ automaton::DFA Determinize::determinize(const automaton::MultiInitialStateNFA& n
 	return res;
 }
 
+auto DeterminizeMultiInitialStateNFA = Determinize::RegistratorWrapper<automaton::DFA, automaton::MultiInitialStateNFA>(Determinize::getInstance(), Determinize::determinize);
+
 automaton::DFA Determinize::determinize(const automaton::NFA& nfa) {
 	// 1, 4
 	automaton::State initialState(createDFAState({nfa.getInitialState()}));
@@ -110,6 +112,8 @@ automaton::DFA Determinize::determinize(const automaton::NFA& nfa) {
 	return res;
 }
 
+auto DeterminizeNFA = Determinize::RegistratorWrapper<automaton::DFA, automaton::NFA>(Determinize::getInstance(), Determinize::determinize);
+
 } /* namespace determinize */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx
index 2569e8dc09e845d64b271359960680b2e5535fb2..02f19dbc1ae43bf63939b5b1e897872b896e11cd 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeNFTAPart.cxx
@@ -94,6 +94,8 @@ DFTA Determinize::determinize(const NFTA & nfta) {
 	return res;
 }
 
+auto DeterminizeNFTA = Determinize::RegistratorWrapper<automaton::DFTA, automaton::NFTA>(Determinize::getInstance(), Determinize::determinize);
+
 } /* namespace determinize */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx
index ce8be6bf664a658e90665862270544262a661fe2..1be3c7ed820b67535a9cad6a86cf622983588155 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx
@@ -246,6 +246,8 @@ automaton::RealTimeHeightDeterministicDPDA Determinize::determinize(const automa
 	return d;
 }
 
+auto DeterminizeRealTimeHeightDeterministicNPDA = Determinize::RegistratorWrapper<automaton::RealTimeHeightDeterministicDPDA, automaton::RealTimeHeightDeterministicNPDA>(Determinize::getInstance(), Determinize::determinize);
+
 } /* namespace determinize */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx
index fb77c6f1441d6e9edc87be9558b22d8170eb9399..dc904a13597f7a3685564e4774fd649f1ce9f9df 100644
--- a/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx
+++ b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx
@@ -204,6 +204,8 @@ automaton::VisiblyPushdownDPDA Determinize::determinize(const automaton::Visibly
 	return d;
 }
 
+auto DeterminizeVisiblyPushdownNPDA = Determinize::RegistratorWrapper<automaton::VisiblyPushdownDPDA, automaton::VisiblyPushdownNPDA>(Determinize::getInstance(), Determinize::determinize);
+
 } /* namespace determinize */
 
 } /* namespace automaton */