diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
index 2cf3e291bfd7a7b938ea88677b6ab15c4de4de1b..b1d5e6b6cddcd857dec5af972cd90be8ddf98679 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
@@ -28,85 +28,20 @@ bool IsLanguageEmpty::isLanguageEmpty( const T & grammar ) {
 	return grammar::properties::ProductiveNonterminals::getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
 }
 
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CFG & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::EpsilonFreeCFG & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::GNF & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CNF & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LG & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftLG & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftRG & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightLG & grammar );
-template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightRG & grammar );
+auto IsLanguageEmptyCFG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CFG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyEpsilonFreeCFG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::EpsilonFreeCFG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyGNF = IsLanguageEmpty::RegistratorWrapper<bool, grammar::GNF>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyCNF = IsLanguageEmpty::RegistratorWrapper<bool, grammar::CNF>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyLeftLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LeftLG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyLeftRG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::LeftRG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyRightLG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::RightLG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
+auto IsLanguageEmptyRightRG = IsLanguageEmpty::RegistratorWrapper<bool, grammar::RightRG>(IsLanguageEmpty::getInstance(), IsLanguageEmpty::isLanguageEmpty);
 
 bool IsLanguageEmpty::isLanguageEmpty(const grammar::Grammar& grammar) {
-	bool out;
-	grammar.getData().Accept((void*) &out, IsLanguageEmpty::IS_LANGUAGE_EMPTY);
-	return out;
+	return getInstance().dispatch(grammar.getData());
 }
 
-void IsLanguageEmpty::Visit(void* data, const grammar::LeftLG& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::LeftRG& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::RightLG& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::RightRG& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::LG& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::CFG& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::CNF& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void* data, const grammar::GNF& grammar) const {
-	bool & out = *((bool*) data);
-	out = this->isLanguageEmpty(grammar);
-}
-
-void IsLanguageEmpty::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
-
-void IsLanguageEmpty::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
-}
-
-void IsLanguageEmpty::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
-
-void IsLanguageEmpty::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
-}
-
-const IsLanguageEmpty IsLanguageEmpty::IS_LANGUAGE_EMPTY;
-
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
index 0921e4f4ad39668fcbe82a52efa7d9c512910357..02d8837bae73b5e82899cd7c5885a968506c127b 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.h
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
@@ -8,6 +8,8 @@
 #ifndef IS_LANGUAGE_EMPTY_H_
 #define IS_LANGUAGE_EMPTY_H_
 
+#include <common/multipleDispatch.hpp>
+
 #include <grammar/Grammar.h>
 
 namespace grammar {
@@ -17,10 +19,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class IsLanguageEmpty : public grammar::VisitableGrammarBase::const_visitor_type {
+class IsLanguageEmpty : public std::SingleDispatch<bool, grammar::GrammarBase> {
 public:
-	IsLanguageEmpty() {}
-
 	static bool isLanguageEmpty( const grammar::Grammar & grammar );
 
 	/*
@@ -32,22 +32,10 @@ public:
 	template<class T>
 	static bool isLanguageEmpty( const T & grammar );
 
-private:
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const IsLanguageEmpty IS_LANGUAGE_EMPTY;
+	static IsLanguageEmpty& getInstance() {
+		static IsLanguageEmpty res;
+		return res;
+	}
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
index eedaab2b1c758cc67c58831d60aa604dd40bd01d..3046cfd9918ad119ee968a9687ffc1cb3e314bd2 100644
--- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
@@ -28,85 +28,20 @@ bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const T & grammar
 	return grammar::properties::NullableNonterminals::getNullableNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
 }
 
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::CFG & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::EpsilonFreeCFG & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::GNF & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::CNF & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LG & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LeftLG & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::LeftRG & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::RightLG & grammar );
-template bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon( const grammar::RightRG & grammar );
+auto IsLanguageGeneratingEpsilonCFG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CFG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonEpsilonFreeCFG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::EpsilonFreeCFG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonGNF = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::GNF>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonCNF = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::CNF>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonLeftLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LeftLG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonLeftRG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::LeftRG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonRightLG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::RightLG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
+auto IsLanguageGeneratingEpsilonRightRG = IsLanguageGeneratingEpsilon::RegistratorWrapper<bool, grammar::RightRG>(IsLanguageGeneratingEpsilon::getInstance(), IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon);
 
 bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon(const grammar::Grammar& grammar) {
-	bool out;
-	grammar.getData().Accept((void*) &out, IsLanguageGeneratingEpsilon::IS_LANGUAGE_GENERATING_EPSILON);
-	return out;
+	return getInstance().dispatch(grammar.getData());
 }
 
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LeftLG& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LeftRG& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::RightLG& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::RightRG& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::LG& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::CFG& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::CNF& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void* data, const grammar::GNF& grammar) const {
-	bool & out = *((bool*) data);
-	out = std::move(this->isLanguageGeneratingEpsilon(grammar));
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
-
-void IsLanguageGeneratingEpsilon::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
-}
-
-const IsLanguageGeneratingEpsilon IsLanguageGeneratingEpsilon::IS_LANGUAGE_GENERATING_EPSILON;
-
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
index ef87b98b7c62aed9cf78fba3fedd480d2fd9e3d9..9e082a97bedc20fb207f4fb6e89a95bf85c39958 100644
--- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
@@ -8,6 +8,8 @@
 #ifndef IS_LANGUAGE_GENERATING_EPSILON_H_
 #define IS_LANGUAGE_GENERATING_EPSILON_H_
 
+#include <common/multipleDispatch.hpp>
+
 #include <grammar/Grammar.h>
 
 namespace grammar {
@@ -17,10 +19,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class IsLanguageGeneratingEpsilon : public grammar::VisitableGrammarBase::const_visitor_type {
+class IsLanguageGeneratingEpsilon : public std::SingleDispatch<bool, grammar::GrammarBase> {
 public:
-	IsLanguageGeneratingEpsilon() {}
-
 	static bool isLanguageGeneratingEpsilon( const grammar::Grammar & grammar );
 
 	/*
@@ -32,22 +32,10 @@ public:
 	template<class T>
 	static bool isLanguageGeneratingEpsilon( const T & grammar );
 
-private:
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const IsLanguageGeneratingEpsilon IS_LANGUAGE_GENERATING_EPSILON;
+	static IsLanguageGeneratingEpsilon& getInstance() {
+		static IsLanguageGeneratingEpsilon res;
+		return res;
+	}
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
index 2534518e51fd46854e4d8d8b3e0eb0e078577fab..7f28661b296119985b50bfb8f626c737343a52f8 100644
--- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
@@ -55,85 +55,20 @@ std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle
 	return Ni.at(i);
 }
 
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CFG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::EpsilonFreeCFG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::GNF& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CNF& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftLG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftRG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightLG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightRG& grammar, const alphabet::Symbol& nonterminal);
+auto NonterminalUnitRuleCycleCFG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleEpsilonFreeCFG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleGNF = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleCNF = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleLeftLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleLeftRG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleRightLG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
+auto NonterminalUnitRuleCycleRightRG = NonterminalUnitRuleCycle::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(NonterminalUnitRuleCycle::getInstance(), NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle);
 
 std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::Grammar& grammar, const alphabet::Symbol& nonterminal) {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> out(nonterminal, {});
-	grammar.getData().Accept((void*) &out, NonterminalUnitRuleCycle::NONTERMINAL_UNIT_RULE_CYCLE);
-	return out.second;
+	return getInstance().dispatch(grammar.getData(), nonterminal);
 }
 
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::LeftLG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::LeftRG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::RightLG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::RightRG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::LG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::CFG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::CNF& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void* data, const grammar::GNF& grammar) const {
-	std::pair<alphabet::Symbol, std::set<alphabet::Symbol>> & out = *((std::pair<alphabet::Symbol, std::set<alphabet::Symbol>>*) data);
-	out.second = std::move(this->getNonterminalUnitRuleCycle(grammar, out.first));
-}
-
-void NonterminalUnitRuleCycle::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
-
-void NonterminalUnitRuleCycle::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
-}
-
-void NonterminalUnitRuleCycle::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
-
-void NonterminalUnitRuleCycle::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
-}
-
-const NonterminalUnitRuleCycle NonterminalUnitRuleCycle::NONTERMINAL_UNIT_RULE_CYCLE;
-
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
index c5802dc48d161c931ce41eb30249aeab7666d84b..62c9206b9467a92b3eef83a6b09a9a527c664886 100644
--- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
@@ -8,6 +8,8 @@
 #ifndef NONTERMINAL_UNIT_RULE_CYCLE_H_
 #define NONTERMINAL_UNIT_RULE_CYCLE_H_
 
+#include <common/multipleDispatch.hpp>
+
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.h>
 
@@ -18,10 +20,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class NonterminalUnitRuleCycle : public grammar::VisitableGrammarBase::const_visitor_type {
+class NonterminalUnitRuleCycle : public std::SingleDispatchLastStaticParam<std::set<alphabet::Symbol>, grammar::GrammarBase, const alphabet::Symbol> {
 public:
-	NonterminalUnitRuleCycle() {}
-
 	static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle( const grammar::Grammar & grammar, const alphabet::Symbol& nonterminal );
 
 	/**
@@ -36,22 +36,10 @@ public:
 	template<class T>
 	static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal);
 
-private:
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const NonterminalUnitRuleCycle NONTERMINAL_UNIT_RULE_CYCLE;
+	static NonterminalUnitRuleCycle& getInstance() {
+		static NonterminalUnitRuleCycle res;
+		return res;
+	}
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
index 01fcae4083386e46b28b9544531dd31cd2142115..3749bf0c4bfa00d13c4c5591f0b72a387e2f3bc2 100644
--- a/alib2algo/src/grammar/properties/NullableNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
@@ -51,85 +51,20 @@ std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const T
 	return Ni.at(i);
 }
 
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CFG& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::EpsilonFreeCFG& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::GNF& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CNF& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LG& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftLG& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftRG& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightLG& grammar );
-template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightRG& grammar );
+auto NullableNonterminalsCFG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsEpsilonFreeCFG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsGNF = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsCNF = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsLeftLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsLeftRG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsRightLG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
+auto NullableNonterminalsRightRG = NullableNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(NullableNonterminals::getInstance(), NullableNonterminals::getNullableNonterminals);
 
 std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const grammar::Grammar& grammar) {
-	std::set<alphabet::Symbol> out;
-	grammar.getData().Accept((void*) &out, NullableNonterminals::NULLABLE_NONTERMINALS);
-	return out;
+	return getInstance().dispatch(grammar.getData());
 }
 
-void NullableNonterminals::Visit(void* data, const grammar::LeftLG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::LeftRG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::RightLG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::RightRG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::LG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::CFG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::CNF& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void* data, const grammar::GNF& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getNullableNonterminals(grammar));
-}
-
-void NullableNonterminals::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
-
-void NullableNonterminals::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
-}
-
-void NullableNonterminals::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
-
-void NullableNonterminals::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
-}
-
-const NullableNonterminals NullableNonterminals::NULLABLE_NONTERMINALS;
-
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.h b/alib2algo/src/grammar/properties/NullableNonterminals.h
index 85e47beb5409b8815fa14f9b6309d9d0c47fbe66..dc67ac96b5ff5026ee948dd14c3445a12b9bf6e6 100644
--- a/alib2algo/src/grammar/properties/NullableNonterminals.h
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.h
@@ -8,6 +8,8 @@
 #ifndef NULLABLE_NONTERMINALS_H_
 #define NULLABLE_NONTERMINALS_H_
 
+#include <common/multipleDispatch.hpp>
+
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.h>
 
@@ -18,10 +20,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class NullableNonterminals : public grammar::VisitableGrammarBase::const_visitor_type {
+class NullableNonterminals : public std::SingleDispatch<std::set<alphabet::Symbol>, grammar::GrammarBase> {
 public:
-	NullableNonterminals() {}
-
 	static std::set<alphabet::Symbol> getNullableNonterminals( const grammar::Grammar & grammar );
 
 	/**
@@ -36,22 +36,10 @@ public:
 	template<class T>
 	static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar);
 
-private:
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const NullableNonterminals NULLABLE_NONTERMINALS;
+	static NullableNonterminals& getInstance() {
+		static NullableNonterminals res;
+		return res;
+	}
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
index 6b6757ce3a2f70e509ac9fc04809778e68259995..e32f023dc1b882b5deabcda7f85509c20e7f4b14 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
@@ -56,85 +56,20 @@ std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( co
 	return Ni.at( i );
 }
 
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CFG & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::EpsilonFreeCFG & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::GNF & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CNF & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LG & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftLG & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftRG & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightLG & grammar );
-template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightRG & grammar );
+auto ProductiveNonterminalsCFG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsEpsilonFreeCFG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsGNF = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsCNF = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsLeftLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsLeftRG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsRightLG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
+auto ProductiveNonterminalsRightRG = ProductiveNonterminals::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(ProductiveNonterminals::getInstance(), ProductiveNonterminals::getProductiveNonterminals);
 
 std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals(const grammar::Grammar& grammar) {
-	std::set<alphabet::Symbol> out;
-	grammar.getData().Accept((void*) &out, ProductiveNonterminals::PRODUCTIVE_NONTERMINALS);
-	return out;
+	return getInstance().dispatch(grammar.getData());
 }
 
-void ProductiveNonterminals::Visit(void* data, const grammar::LeftLG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::LeftRG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::RightLG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::RightRG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::LG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::CFG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::CNF& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void* data, const grammar::GNF& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getProductiveNonterminals(grammar));
-}
-
-void ProductiveNonterminals::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
-
-void ProductiveNonterminals::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
-}
-
-void ProductiveNonterminals::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
-
-void ProductiveNonterminals::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
-}
-
-const ProductiveNonterminals ProductiveNonterminals::PRODUCTIVE_NONTERMINALS;
-
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
index 688c011f06e17e8d57c2406081ce95ee50adb66b..0b88d4144d35a227811e986e4da356509bd4e8f0 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.h
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
@@ -8,6 +8,8 @@
 #ifndef PRODUCTIVE_NONTERMINALS_H_
 #define PRODUCTIVE_NONTERMINALS_H_
 
+#include <common/multipleDispatch.hpp>
+
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.h>
 
@@ -18,10 +20,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class ProductiveNonterminals : public grammar::VisitableGrammarBase::const_visitor_type {
+class ProductiveNonterminals : public std::SingleDispatch<std::set<alphabet::Symbol>, grammar::GrammarBase> {
 public:
-	ProductiveNonterminals() {}
-
 	static std::set<alphabet::Symbol> getProductiveNonterminals( const grammar::Grammar & grammar );
 
 	/**
@@ -30,22 +30,10 @@ public:
 	template<class T>
 	static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar );
 
-private:
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const ProductiveNonterminals PRODUCTIVE_NONTERMINALS;
+	static ProductiveNonterminals& getInstance() {
+		static ProductiveNonterminals res;
+		return res;
+	}
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
index 3c0d9bfd63326ce50e3e444b28be11bc8d57601a..3f83b5dd7fd5a15f1f928578e55583507814fcfe 100644
--- a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
@@ -57,85 +57,20 @@ std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const T &
 	return Vi.at( i );
 }
 
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CFG & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::GNF & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CNF & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LG & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftLG & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftRG & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightLG & grammar );
-template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightRG & grammar );
+auto UnreachableSymbolsCFG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CFG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsEpsilonFreeCFG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::EpsilonFreeCFG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsGNF = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::GNF>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsCNF = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::CNF>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsLeftLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftLG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsLeftRG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::LeftRG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsRightLG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightLG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
+auto UnreachableSymbolsRightRG = UnreachableSymbols::RegistratorWrapper<std::set<alphabet::Symbol>, grammar::RightRG>(UnreachableSymbols::getInstance(), UnreachableSymbols::getUnreachableSymbols);
 
 std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols(const grammar::Grammar& grammar) {
-	std::set<alphabet::Symbol> out;
-	grammar.getData().Accept((void*) &out, UnreachableSymbols::UNREACHABLE_NONTERMINALS);
-	return out;
+	return getInstance().dispatch(grammar.getData());
 }
 
-void UnreachableSymbols::Visit(void* data, const grammar::LeftLG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::LeftRG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::RightLG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::RightRG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::LG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::CFG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::CNF& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void* data, const grammar::GNF& grammar) const {
-	std::set<alphabet::Symbol> & out = *((std::set<alphabet::Symbol>*) data);
-	out = std::move(this->getUnreachableSymbols(grammar));
-}
-
-void UnreachableSymbols::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
-
-void UnreachableSymbols::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
-}
-
-void UnreachableSymbols::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
-
-void UnreachableSymbols::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
-}
-
-const UnreachableSymbols UnreachableSymbols::UNREACHABLE_NONTERMINALS;
-
 } /* namespace properties */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.h b/alib2algo/src/grammar/properties/UnreachableSymbols.h
index a77f3421e29c259b977002c11cbaf3631736b7c5..c25efea00914da8b6c03f7512dc20a5b7946a6d3 100644
--- a/alib2algo/src/grammar/properties/UnreachableSymbols.h
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.h
@@ -8,6 +8,8 @@
 #ifndef UNREACHABLE_SYMBOLS_H_
 #define UNREACHABLE_SYMBOLS_H_
 
+#include <common/multipleDispatch.hpp>
+
 #include <grammar/Grammar.h>
 #include <alphabet/Symbol.h>
 
@@ -18,10 +20,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class UnreachableSymbols : public grammar::VisitableGrammarBase::const_visitor_type {
+class UnreachableSymbols : public std::SingleDispatch<std::set<alphabet::Symbol>, grammar::GrammarBase> {
 public:
-	UnreachableSymbols() {}
-
 	static std::set<alphabet::Symbol> getUnreachableSymbols( const grammar::Grammar & grammar );
 
 	/**
@@ -30,22 +30,10 @@ public:
 	template<class T>
 	static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar );
 
-private:
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const UnreachableSymbols UNREACHABLE_NONTERMINALS;
+	static UnreachableSymbols& getInstance() {
+		static UnreachableSymbols res;
+		return res;
+	}
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h
index 887a42c16b7f61a457cd49f588b246def89e683b..f0cdaaf0945d3f08e9abd8f863e76e7548663357 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.h
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h
@@ -22,8 +22,7 @@ namespace properties {
  * Checks, whether regexp (or its subtree) describes epsilon (empty string).
  *
  */
-class RegExpEpsilon : public std::SingleDispatch<bool, regexp::RegExpBase>, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type
-{
+class RegExpEpsilon : public std::SingleDispatch<bool, regexp::RegExpBase>, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type {
 public:
 	RegExpEpsilon() {}