From 79fe90c38fa4c51139c9d9313be2658a70cbb04d Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 11 Sep 2017 21:51:06 +0200
Subject: [PATCH] new registration grammar and regexp algos

---
 alib2algo/src/grammar/convert/ToRegExp.cpp    |  8 ++---
 alib2algo/src/grammar/convert/ToRegExp.h      | 21 +++++--------
 .../grammar/properties/IsLanguageEmpty.cpp    | 22 ++++++--------
 .../src/grammar/properties/IsLanguageEmpty.h  |  8 +----
 .../IsLanguageGeneratingEpsilon.cpp           | 22 ++++++--------
 .../properties/IsLanguageGeneratingEpsilon.h  |  8 +----
 .../properties/NonterminalUnitRuleCycle.cpp   | 22 ++++++--------
 .../properties/NonterminalUnitRuleCycle.h     |  8 +----
 .../properties/NullableNonterminals.cpp       | 22 ++++++--------
 .../grammar/properties/NullableNonterminals.h | 10 ++-----
 .../properties/ProductiveNonterminals.cpp     | 22 ++++++--------
 .../properties/ProductiveNonterminals.h       | 10 ++-----
 .../properties/RecursiveNonterminal.cpp       | 22 ++++++--------
 .../grammar/properties/RecursiveNonterminal.h |  8 +----
 .../grammar/properties/UnreachableSymbols.cpp | 22 ++++++--------
 .../grammar/properties/UnreachableSymbols.h   | 10 ++-----
 .../grammar/simplify/LeftRecursionRemover.cpp | 18 +++++------
 .../grammar/simplify/LeftRecursionRemover.h   | 10 ++-----
 .../grammar/simplify/SimpleRulesRemover.cpp   | 22 ++++++--------
 .../src/grammar/simplify/SimpleRulesRemover.h | 10 ++-----
 .../simplify/UnproductiveSymbolsRemover.h     |  7 +----
 alib2algo/src/regexp/convert/ToAutomaton.cpp  |  8 ++---
 alib2algo/src/regexp/convert/ToAutomaton.h    | 21 +++++--------
 alib2algo/src/regexp/convert/ToGrammar.cpp    |  8 ++---
 alib2algo/src/regexp/convert/ToGrammar.h      | 22 +++++---------
 .../src/regexp/properties/RegExpEmpty.cpp     |  8 ++---
 alib2algo/src/regexp/properties/RegExpEmpty.h |  7 +----
 .../src/regexp/properties/RegExpEpsilon.cpp   |  8 ++---
 .../src/regexp/properties/RegExpEpsilon.h     |  7 +----
 .../src/regexp/transform/RegExpAlternate.cpp  |  8 ++---
 .../src/regexp/transform/RegExpAlternate.h    |  7 +----
 .../regexp/transform/RegExpConcatenate.cpp    |  8 ++---
 .../src/regexp/transform/RegExpConcatenate.h  |  7 +----
 .../src/regexp/transform/RegExpIterate.cpp    |  8 ++---
 .../src/regexp/transform/RegExpIterate.h      |  7 +----
 .../regexp/properties/RegExpEmptyTest.cpp     |  4 +--
 .../regexp/properties/RegExpEpsilonTest.cpp   | 14 ++++-----
 .../transform/RegExpConcatenateTest.cpp       | 30 +++++++++----------
 .../regexp/transform/RegExpDerivationTest.cpp |  5 ++--
 .../regexp/transform/RegExpIntegralTest.cpp   |  3 +-
 40 files changed, 167 insertions(+), 335 deletions(-)

diff --git a/alib2algo/src/grammar/convert/ToRegExp.cpp b/alib2algo/src/grammar/convert/ToRegExp.cpp
index 692ad5161a..f78e6bc305 100644
--- a/alib2algo/src/grammar/convert/ToRegExp.cpp
+++ b/alib2algo/src/grammar/convert/ToRegExp.cpp
@@ -12,12 +12,8 @@ namespace grammar {
 
 namespace convert {
 
-regexp::RegExp ToRegExp::convert(const grammar::Grammar& grammar) {
-	return dispatch(grammar.getData());
-}
-
-auto ToRegExpRightRG = registration::OverloadRegister < ToRegExp, regexp::RegExp, grammar::RightRG < > > ( ToRegExp::convert );
-auto ToRegExpLeftRG = registration::OverloadRegister < ToRegExp, regexp::RegExp, grammar::LeftRG < > > ( ToRegExp::convert );
+auto ToRegExpRightRG = registration::AbstractRegister < ToRegExp, regexp::UnboundedRegExp < >, const grammar::RightRG < > & > ( ToRegExp::convert );
+auto ToRegExpLeftRG = registration::AbstractRegister < ToRegExp, regexp::UnboundedRegExp < >, const grammar::LeftRG < > & > ( ToRegExp::convert );
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/grammar/convert/ToRegExp.h b/alib2algo/src/grammar/convert/ToRegExp.h
index c4f1492015..4fde2da923 100644
--- a/alib2algo/src/grammar/convert/ToRegExp.h
+++ b/alib2algo/src/grammar/convert/ToRegExp.h
@@ -8,42 +8,35 @@
 #ifndef GRAMMAR_TO_REG_EXP_H_
 #define GRAMMAR_TO_REG_EXP_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
 #include <grammar/Regular/RightRG.h>
 #include <grammar/Regular/LeftRG.h>
 
-#include <regexp/RegExp.h>
-
 #include "ToRegExpAlgebraic.h"
 
 namespace grammar {
 
 namespace convert {
 
-class ToRegExp : public alib::SingleDispatch<ToRegExp, regexp::RegExp, const grammar::GrammarBase &> {
+class ToRegExp {
 public:
 	/**
 	 * @return regexp equivalent to source right regular grammar.
 	 * @param grammar Grammar to convert
 	 */
-	static regexp::RegExp convert(const grammar::Grammar& grammar);
-
 	template < class SymbolType >
-	static regexp::RegExp convert(const grammar::RightRG < SymbolType > & grammar);
+	static regexp::UnboundedRegExp < > convert(const grammar::RightRG < SymbolType > & grammar);
 	template < class SymbolType >
-	static regexp::RegExp convert(const grammar::LeftRG < SymbolType > & grammar);
+	static regexp::UnboundedRegExp < > convert(const grammar::LeftRG < SymbolType > & grammar);
 };
 
 template < class SymbolType >
-regexp::RegExp ToRegExp::convert(const grammar::RightRG < SymbolType > & grammar) {
-	return regexp::RegExp(ToRegExpAlgebraic::convert(grammar));
+regexp::UnboundedRegExp < > ToRegExp::convert(const grammar::RightRG < SymbolType > & grammar) {
+	return ToRegExpAlgebraic::convert(grammar);
 }
 
 template < class SymbolType >
-regexp::RegExp ToRegExp::convert(const grammar::LeftRG < SymbolType > & grammar) {
-	return regexp::RegExp(ToRegExpAlgebraic::convert(grammar));
+regexp::UnboundedRegExp < > ToRegExp::convert(const grammar::LeftRG < SymbolType > & grammar) {
+	return ToRegExpAlgebraic::convert(grammar);
 }
 
 } /* namespace covert */
diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
index c510f9d62c..7f676f5cd9 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace properties {
 
-bool IsLanguageEmpty::isLanguageEmpty(const grammar::Grammar& grammar) {
-	return dispatch(grammar.getData());
-}
-
-auto IsLanguageEmptyCFG = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::CFG < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyEpsilonFreeCFG = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::EpsilonFreeCFG < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyGNF = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::GNF < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyCNF = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::CNF < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyLG = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::LG < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyLeftLG = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::LeftLG < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyLeftRG = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::LeftRG < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyRightLG = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::RightLG < > > ( IsLanguageEmpty::isLanguageEmpty );
-auto IsLanguageEmptyRightRG = registration::OverloadRegister < IsLanguageEmpty, bool, grammar::RightRG < > > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyCFG = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::CFG < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyEpsilonFreeCFG = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::EpsilonFreeCFG < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyGNF = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::GNF < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyCNF = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::CNF < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyLG = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::LG < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyLeftLG = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::LeftLG < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyLeftRG = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::LeftRG < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyRightLG = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::RightLG < > & > ( IsLanguageEmpty::isLanguageEmpty );
+auto IsLanguageEmptyRightRG = registration::AbstractRegister < IsLanguageEmpty, bool, const grammar::RightRG < > & > ( IsLanguageEmpty::isLanguageEmpty );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
index ba47d3d3e1..76b215c5b9 100644
--- a/alib2algo/src/grammar/properties/IsLanguageEmpty.h
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
@@ -8,10 +8,6 @@
 #ifndef IS_LANGUAGE_EMPTY_H_
 #define IS_LANGUAGE_EMPTY_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/GNF.h>
@@ -31,10 +27,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class IsLanguageEmpty : public alib::SingleDispatch<IsLanguageEmpty, bool, const grammar::GrammarBase &> {
+class IsLanguageEmpty {
 public:
-	static bool isLanguageEmpty( const grammar::Grammar & grammar );
-
 	/*
 	 * Melichar 3.6 - decides whether L( grammar ) = \0
 	 *
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
index 7c126e800c..5007aee362 100644
--- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace properties {
 
-bool IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon(const grammar::Grammar& grammar) {
-	return dispatch(grammar.getData());
-}
-
-auto IsLanguageGeneratingEpsilonCFG = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::CFG < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonEpsilonFreeCFG = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::EpsilonFreeCFG < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonGNF = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::GNF < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonCNF = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::CNF < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonLG = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::LG < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonLeftLG = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::LeftLG < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonLeftRG = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::LeftRG < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonRightLG = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::RightLG < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
-auto IsLanguageGeneratingEpsilonRightRG = registration::OverloadRegister < IsLanguageGeneratingEpsilon, bool, grammar::RightRG < > > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonCFG = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::CFG < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonEpsilonFreeCFG = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::EpsilonFreeCFG < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonGNF = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::GNF < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonCNF = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::CNF < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonLG = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::LG < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonLeftLG = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::LeftLG < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonLeftRG = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::LeftRG < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonRightLG = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::RightLG < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
+auto IsLanguageGeneratingEpsilonRightRG = registration::AbstractRegister < IsLanguageGeneratingEpsilon, bool, const grammar::RightRG < > & > ( IsLanguageGeneratingEpsilon::isLanguageGeneratingEpsilon );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
index c7f7d7055f..a59b7a9f31 100644
--- a/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
+++ b/alib2algo/src/grammar/properties/IsLanguageGeneratingEpsilon.h
@@ -8,10 +8,6 @@
 #ifndef IS_LANGUAGE_GENERATING_EPSILON_H_
 #define IS_LANGUAGE_GENERATING_EPSILON_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/GNF.h>
@@ -31,10 +27,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class IsLanguageGeneratingEpsilon : public alib::SingleDispatch<IsLanguageGeneratingEpsilon, bool, const grammar::GrammarBase &> {
+class IsLanguageGeneratingEpsilon {
 public:
-	static bool isLanguageGeneratingEpsilon( const grammar::Grammar & grammar );
-
 	/*
 	 * Melichar 3.6 - decides whether L( grammar ) = \0
 	 *
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
index 234554e9ed..d8c13e70c3 100644
--- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace properties {
 
-auto NonterminalUnitRuleCycleCFG = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::CFG < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleEpsilonFreeCFG = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::EpsilonFreeCFG < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleGNF = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::GNF < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleCNF = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::CNF < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleLG = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::LG < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleLeftLG = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::LeftLG < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleLeftRG = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::LeftRG < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleRightLG = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::RightLG < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-auto NonterminalUnitRuleCycleRightRG = registration::OverloadRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, grammar::RightRG < > > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
-
-ext::set<DefaultSymbolType> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::Grammar& grammar, const DefaultSymbolType& nonterminal) {
-	return dispatch(grammar.getData(), nonterminal);
-}
+auto NonterminalUnitRuleCycleCFG = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::CFG < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleEpsilonFreeCFG = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::EpsilonFreeCFG < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleGNF = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::GNF < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleCNF = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::CNF < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleLG = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::LG < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleLeftLG = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::LeftLG < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleLeftRG = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::LeftRG < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleRightLG = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::RightLG < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
+auto NonterminalUnitRuleCycleRightRG = registration::AbstractRegister < NonterminalUnitRuleCycle, ext::set < DefaultSymbolType >, const grammar::RightRG < > &, const DefaultSymbolType & > ( NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
index 16acdc9857..3d8a1bbcc9 100644
--- a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
@@ -8,10 +8,6 @@
 #ifndef NONTERMINAL_UNIT_RULE_CYCLE_H_
 #define NONTERMINAL_UNIT_RULE_CYCLE_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/GNF.h>
@@ -34,10 +30,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class NonterminalUnitRuleCycle : public alib::SingleDispatch < NonterminalUnitRuleCycle, ext::set<DefaultSymbolType>, const grammar::GrammarBase &, const DefaultSymbolType&> {
+class NonterminalUnitRuleCycle {
 public:
-	static ext::set<DefaultSymbolType> getNonterminalUnitRuleCycle( const grammar::Grammar & grammar, const DefaultSymbolType& nonterminal );
-
 	/**
 	 * Retrieves set N = {B : A->^* B} for given grammar and nonterminal
 	 *
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
index fda546689f..76bbf38968 100644
--- a/alib2algo/src/grammar/properties/NullableNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace properties {
 
-auto NullableNonterminalsCFG = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::CFG < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsEpsilonFreeCFG = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::EpsilonFreeCFG < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsGNF = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::GNF < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsCNF = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::CNF < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsLG = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::LG < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsLeftLG = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::LeftLG < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsLeftRG = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::LeftRG < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsRightLG = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::RightLG < > > ( NullableNonterminals::getNullableNonterminals );
-auto NullableNonterminalsRightRG = registration::OverloadRegister < NullableNonterminals, ext::set < DefaultSymbolType >, grammar::RightRG < > > ( NullableNonterminals::getNullableNonterminals );
-
-ext::set<DefaultSymbolType> NullableNonterminals::getNullableNonterminals(const grammar::Grammar& grammar ) {
-	return dispatch(grammar.getData());
-}
+auto NullableNonterminalsCFG = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::CFG < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsEpsilonFreeCFG = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::EpsilonFreeCFG < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsGNF = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::GNF < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsCNF = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::CNF < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsLG = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::LG < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsLeftLG = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::LeftLG < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsLeftRG = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::LeftRG < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsRightLG = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::RightLG < > & > ( NullableNonterminals::getNullableNonterminals );
+auto NullableNonterminalsRightRG = registration::AbstractRegister < NullableNonterminals, ext::set < DefaultSymbolType >, const grammar::RightRG < > & > ( NullableNonterminals::getNullableNonterminals );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.h b/alib2algo/src/grammar/properties/NullableNonterminals.h
index 35924c2aec..a5023edec6 100644
--- a/alib2algo/src/grammar/properties/NullableNonterminals.h
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.h
@@ -8,10 +8,6 @@
 #ifndef NULLABLE_NONTERMINALS_H_
 #define NULLABLE_NONTERMINALS_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/GNF.h>
@@ -26,6 +22,8 @@
 #include <deque>
 #include <algorithm>
 
+#include <grammar/Grammar.h>
+
 namespace grammar {
 
 namespace properties {
@@ -33,10 +31,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class NullableNonterminals : public alib::SingleDispatch<NullableNonterminals, ext::set<DefaultSymbolType>, const grammar::GrammarBase &> {
+class NullableNonterminals {
 public:
-	static ext::set<DefaultSymbolType> getNullableNonterminals( const grammar::Grammar & grammar );
-
 	/**
 	 * Retrieve all nullable nonterminals from grammar
 	 * Nullable nonterminal is such nonterminal A for which holds that A ->^* \eps
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
index 5e3df111a2..61fe4e39d6 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace properties {
 
-auto ProductiveNonterminalsCFG = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::CFG < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsEpsilonFreeCFG = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::EpsilonFreeCFG < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsGNF = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::GNF < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsCNF = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::CNF < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsLG = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::LG < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsLeftLG = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::LeftLG < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsLeftRG = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::LeftRG < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsRightLG = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::RightLG < > > ( ProductiveNonterminals::getProductiveNonterminals );
-auto ProductiveNonterminalsRightRG = registration::OverloadRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, grammar::RightRG < > > ( ProductiveNonterminals::getProductiveNonterminals );
-
-ext::set<DefaultSymbolType> ProductiveNonterminals::getProductiveNonterminals(const grammar::Grammar& grammar ) {
-	return dispatch(grammar.getData());
-}
+auto ProductiveNonterminalsCFG = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::CFG < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsEpsilonFreeCFG = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::EpsilonFreeCFG < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsGNF = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::GNF < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsCNF = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::CNF < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsLG = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::LG < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsLeftLG = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::LeftLG < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsLeftRG = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::LeftRG < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsRightLG = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::RightLG < > & > ( ProductiveNonterminals::getProductiveNonterminals );
+auto ProductiveNonterminalsRightRG = registration::AbstractRegister < ProductiveNonterminals, ext::set < DefaultSymbolType >, const grammar::RightRG < > & > ( ProductiveNonterminals::getProductiveNonterminals );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
index b03491a487..b1dfd24dc9 100644
--- a/alib2algo/src/grammar/properties/ProductiveNonterminals.h
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
@@ -8,10 +8,6 @@
 #ifndef PRODUCTIVE_NONTERMINALS_H_
 #define PRODUCTIVE_NONTERMINALS_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/GNF.h>
@@ -26,6 +22,8 @@
 #include <deque>
 #include <algorithm>
 
+#include <grammar/Grammar.h>
+
 namespace grammar {
 
 namespace properties {
@@ -33,10 +31,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class ProductiveNonterminals : public alib::SingleDispatch<ProductiveNonterminals, ext::set<DefaultSymbolType>, const grammar::GrammarBase &> {
+class ProductiveNonterminals {
 public:
-	static ext::set<DefaultSymbolType> getProductiveNonterminals( const grammar::Grammar & grammar );
-
 	/**
 	 * Implements steps 1 through 3 in Melichar 3.6
 	 */
diff --git a/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp b/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
index afc32c0001..454e9a8f6e 100644
--- a/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
+++ b/alib2algo/src/grammar/properties/RecursiveNonterminal.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace properties {
 
-auto RecursiveNonterminalCFG = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::CFG < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalEpsilonFreeCFG = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::EpsilonFreeCFG < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalGNF = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::GNF < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalCNF = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::CNF < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalLG = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::LG < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalLeftLG = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::LeftLG < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalLeftRG = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::LeftRG < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalRightLG = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::RightLG < > > ( RecursiveNonterminal::isNonterminalRecursive );
-auto RecursiveNonterminalRightRG = registration::OverloadRegister < RecursiveNonterminal, bool, grammar::RightRG < > > ( RecursiveNonterminal::isNonterminalRecursive );
-
-bool RecursiveNonterminal::isNonterminalRecursive ( const grammar::Grammar & grammar, const DefaultSymbolType & nonterminal ) {
-	return dispatch ( grammar.getData ( ), nonterminal );
-}
+auto RecursiveNonterminalCFG = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::CFG < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalEpsilonFreeCFG = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::EpsilonFreeCFG < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalGNF = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::GNF < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalCNF = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::CNF < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalLG = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::LG < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalLeftLG = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::LeftLG < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalLeftRG = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::LeftRG < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalRightLG = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::RightLG < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
+auto RecursiveNonterminalRightRG = registration::AbstractRegister < RecursiveNonterminal, bool, const grammar::RightRG < > &, const DefaultSymbolType & > ( RecursiveNonterminal::isNonterminalRecursive );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/grammar/properties/RecursiveNonterminal.h b/alib2algo/src/grammar/properties/RecursiveNonterminal.h
index 727191a542..d5bc7e2edb 100644
--- a/alib2algo/src/grammar/properties/RecursiveNonterminal.h
+++ b/alib2algo/src/grammar/properties/RecursiveNonterminal.h
@@ -8,10 +8,6 @@
 #ifndef RECURSIVE_NONTERMINAL_H_
 #define RECURSIVE_NONTERMINAL_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-
 #include "NullableNonterminals.h"
 
 #include <grammar/ContextFree/CFG.h>
@@ -36,10 +32,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class RecursiveNonterminal : public alib::SingleDispatch < RecursiveNonterminal, bool, const grammar::GrammarBase &, const DefaultSymbolType & > {
+class RecursiveNonterminal {
 public:
-	static bool isNonterminalRecursive ( const grammar::Grammar & grammar, const DefaultSymbolType & nonterminal );
-
 	/**
 	 * Retrieves A \in { B : A->^+ B \alpha, where \alpha \in (NuT)* } for given grammar and nonterminal
 	 *
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
index df74a02682..8f61cea3a4 100644
--- a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace properties {
 
-auto UnreachableSymbolsCFG = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::CFG < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsEpsilonFreeCFG = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::EpsilonFreeCFG < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsGNF = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::GNF < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsCNF = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::CNF < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsLG = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::LG < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsLeftLG = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::LeftLG < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsLeftRG = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::LeftRG < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsRightLG = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::RightLG < > > ( UnreachableSymbols::getUnreachableSymbols );
-auto UnreachableSymbolsRightRG = registration::OverloadRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, grammar::RightRG < > > ( UnreachableSymbols::getUnreachableSymbols );
-
-ext::set < DefaultSymbolType > UnreachableSymbols::getUnreachableSymbols ( const grammar::Grammar & grammar ) {
-	return dispatch ( grammar.getData ( ) );
-}
+auto UnreachableSymbolsCFG = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::CFG < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsEpsilonFreeCFG = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::EpsilonFreeCFG < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsGNF = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::GNF < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsCNF = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::CNF < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsLG = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::LG < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsLeftLG = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::LeftLG < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsLeftRG = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::LeftRG < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsRightLG = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::RightLG < > & > ( UnreachableSymbols::getUnreachableSymbols );
+auto UnreachableSymbolsRightRG = registration::AbstractRegister < UnreachableSymbols, ext::set < DefaultSymbolType >, const grammar::RightRG < > & > ( UnreachableSymbols::getUnreachableSymbols );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.h b/alib2algo/src/grammar/properties/UnreachableSymbols.h
index 94307fa7f9..84ef135c17 100644
--- a/alib2algo/src/grammar/properties/UnreachableSymbols.h
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.h
@@ -8,10 +8,6 @@
 #ifndef UNREACHABLE_SYMBOLS_H_
 #define UNREACHABLE_SYMBOLS_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/GNF.h>
@@ -26,6 +22,8 @@
 #include <deque>
 #include <set>
 
+#include <grammar/Grammar.h>
+
 namespace grammar {
 
 namespace properties {
@@ -33,10 +31,8 @@ namespace properties {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class UnreachableSymbols : public alib::SingleDispatch<UnreachableSymbols, ext::set<DefaultSymbolType>, const grammar::GrammarBase &> {
+class UnreachableSymbols {
 public:
-	static ext::set<DefaultSymbolType> getUnreachableSymbols( const grammar::Grammar & grammar );
-
 	/**
 	 * Implements
 	 */
diff --git a/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp b/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp
index 13f9b113ae..5349c991f5 100644
--- a/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp
+++ b/alib2algo/src/grammar/simplify/LeftRecursionRemover.cpp
@@ -12,17 +12,13 @@ namespace grammar {
 
 namespace simplify {
 
-auto LeftRecursionRemoverEpsilonFreeCFG = registration::OverloadRegister < LeftRecursionRemover, grammar::EpsilonFreeCFG < >, grammar::EpsilonFreeCFG < > > ( LeftRecursionRemover::remove );
-auto LeftRecursionRemoverCNF = registration::OverloadRegister < LeftRecursionRemover, grammar::EpsilonFreeCFG < >, grammar::CNF < > > ( LeftRecursionRemover::remove );
-auto LeftRecursionRemoverGNF = registration::OverloadRegister < LeftRecursionRemover, grammar::GNF < >, grammar::GNF < > > ( LeftRecursionRemover::remove );
-auto LeftRecursionRemoverRightRG = registration::OverloadRegister < LeftRecursionRemover, grammar::RightRG < >, grammar::RightRG < > > ( LeftRecursionRemover::remove );
-auto LeftRecursionRemoverRightLG = registration::OverloadRegister < LeftRecursionRemover, grammar::RightLG < >, grammar::RightLG < > > ( LeftRecursionRemover::remove );
-auto LeftRecursionRemoverLeftRG = registration::OverloadRegister < LeftRecursionRemover, grammar::RightRG < >, grammar::LeftRG < > > ( LeftRecursionRemover::remove );
-auto LeftRecursionRemoverLeftLG = registration::OverloadRegister < LeftRecursionRemover, grammar::RightLG < >, grammar::LeftLG < > > ( LeftRecursionRemover::remove );
-
-grammar::Grammar LeftRecursionRemover::remove(const grammar::Grammar& grammar) {
-	return dispatch(grammar.getData());
-}
+auto LeftRecursionRemoverEpsilonFreeCFG = registration::AbstractRegister < LeftRecursionRemover, grammar::EpsilonFreeCFG < >, const grammar::EpsilonFreeCFG < > & > ( LeftRecursionRemover::remove );
+auto LeftRecursionRemoverCNF = registration::AbstractRegister < LeftRecursionRemover, grammar::EpsilonFreeCFG < >, const grammar::CNF < > & > ( LeftRecursionRemover::remove );
+auto LeftRecursionRemoverGNF = registration::AbstractRegister < LeftRecursionRemover, grammar::GNF < >, const grammar::GNF < > & > ( LeftRecursionRemover::remove );
+auto LeftRecursionRemoverRightRG = registration::AbstractRegister < LeftRecursionRemover, grammar::RightRG < >, const grammar::RightRG < > & > ( LeftRecursionRemover::remove );
+auto LeftRecursionRemoverRightLG = registration::AbstractRegister < LeftRecursionRemover, grammar::RightLG < >, const grammar::RightLG < > & > ( LeftRecursionRemover::remove );
+auto LeftRecursionRemoverLeftRG = registration::AbstractRegister < LeftRecursionRemover, grammar::RightRG < >, const grammar::LeftRG < > & > ( LeftRecursionRemover::remove );
+auto LeftRecursionRemoverLeftLG = registration::AbstractRegister < LeftRecursionRemover, grammar::RightLG < >, const grammar::LeftLG < > & > ( LeftRecursionRemover::remove );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/grammar/simplify/LeftRecursionRemover.h b/alib2algo/src/grammar/simplify/LeftRecursionRemover.h
index b93496c53c..ebc324ede1 100644
--- a/alib2algo/src/grammar/simplify/LeftRecursionRemover.h
+++ b/alib2algo/src/grammar/simplify/LeftRecursionRemover.h
@@ -8,12 +8,8 @@
 #ifndef LEFT_RECURSION_REMOVER_H_
 #define LEFT_RECURSION_REMOVER_H_
 
-#include <core/multipleDispatch.hpp>
-#include <map>
 #include <algorithm>
 
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/CNF.h>
@@ -24,7 +20,7 @@
 #include <grammar/Regular/RightLG.h>
 #include <grammar/Regular/RightRG.h>
 
-#include "../convert/ToGrammarRightRG.h"
+#include <grammar/convert/ToGrammarRightRG.h>
 #include <exception/CommonException.h>
 
 #include <vector>
@@ -34,15 +30,13 @@ namespace grammar {
 
 namespace simplify {
 
-class LeftRecursionRemover : public alib::SingleDispatch<LeftRecursionRemover, grammar::Grammar, const grammar::GrammarBase &> {
+class LeftRecursionRemover {
 	template < class SymbolType >
 	static grammar::EpsilonFreeCFG < SymbolType > directLeftRecursionRemoveAsOrder ( const grammar::EpsilonFreeCFG < SymbolType > & origGrammar );
 
 	template < class SymbolType >
 	static grammar::EpsilonFreeCFG < SymbolType > assignAsOrder ( const grammar::EpsilonFreeCFG < SymbolType > & origGrammar, unsigned i, const ext::set< SymbolType >& origNonterminals );
 public:
-	static grammar::Grammar remove( const grammar::Grammar & grammar );
-
 	template < class SymbolType >
 	static grammar::EpsilonFreeCFG < SymbolType > remove( const grammar::EpsilonFreeCFG < SymbolType > & grammar );
 	template < class SymbolType >
diff --git a/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp b/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp
index 575ad4aafd..47f627ec95 100644
--- a/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp
+++ b/alib2algo/src/grammar/simplify/SimpleRulesRemover.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace simplify {
 
-grammar::Grammar SimpleRulesRemover::remove ( const grammar::Grammar & grammar ) {
-	return dispatch ( grammar.getData ( ) );
-}
-
-auto SimpleRulesRemoverCFG = registration::OverloadRegister < SimpleRulesRemover, grammar::CFG < >, grammar::CFG < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverEpsilonFreeCFG = registration::OverloadRegister < SimpleRulesRemover, grammar::EpsilonFreeCFG < >, grammar::EpsilonFreeCFG < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverCNF = registration::OverloadRegister < SimpleRulesRemover, grammar::CNF < >, grammar::CNF < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverGNF = registration::OverloadRegister < SimpleRulesRemover, grammar::GNF < >, grammar::GNF < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverLG = registration::OverloadRegister < SimpleRulesRemover, grammar::LG < >, grammar::LG < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverLeftLG = registration::OverloadRegister < SimpleRulesRemover, grammar::LeftLG < >, grammar::LeftLG < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverLeftRG = registration::OverloadRegister < SimpleRulesRemover, grammar::LeftRG < >, grammar::LeftRG < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverRightLG = registration::OverloadRegister < SimpleRulesRemover, grammar::RightLG < >, grammar::RightLG < > > ( SimpleRulesRemover::remove );
-auto SimpleRulesRemoverRightRG = registration::OverloadRegister < SimpleRulesRemover, grammar::RightRG < >, grammar::RightRG < > > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverCFG = registration::AbstractRegister < SimpleRulesRemover, grammar::CFG < >, const grammar::CFG < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverEpsilonFreeCFG = registration::AbstractRegister < SimpleRulesRemover, grammar::EpsilonFreeCFG < >, const grammar::EpsilonFreeCFG < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverCNF = registration::AbstractRegister < SimpleRulesRemover, grammar::CNF < >, const grammar::CNF < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverGNF = registration::AbstractRegister < SimpleRulesRemover, grammar::GNF < >, const grammar::GNF < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverLG = registration::AbstractRegister < SimpleRulesRemover, grammar::LG < >, const grammar::LG < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverLeftLG = registration::AbstractRegister < SimpleRulesRemover, grammar::LeftLG < >, const grammar::LeftLG < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverLeftRG = registration::AbstractRegister < SimpleRulesRemover, grammar::LeftRG < >, const grammar::LeftRG < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverRightLG = registration::AbstractRegister < SimpleRulesRemover, grammar::RightLG < >, const grammar::RightLG < > & > ( SimpleRulesRemover::remove );
+auto SimpleRulesRemoverRightRG = registration::AbstractRegister < SimpleRulesRemover, grammar::RightRG < >, const grammar::RightRG < > & > ( SimpleRulesRemover::remove );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/grammar/simplify/SimpleRulesRemover.h b/alib2algo/src/grammar/simplify/SimpleRulesRemover.h
index 9fcf688d74..b8ee25ebaa 100644
--- a/alib2algo/src/grammar/simplify/SimpleRulesRemover.h
+++ b/alib2algo/src/grammar/simplify/SimpleRulesRemover.h
@@ -8,12 +8,8 @@
 #ifndef SIMPLE_RULES_REMOVER_H_
 #define SIMPLE_RULES_REMOVER_H_
 
-#include <core/multipleDispatch.hpp>
-#include <map>
 #include <algorithm>
 
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/CNF.h>
@@ -26,11 +22,13 @@
 
 #include <grammar/properties/NonterminalUnitRuleCycle.h>
 
+#include <grammar/Grammar.h>
+
 namespace grammar {
 
 namespace simplify {
 
-class SimpleRulesRemover : public alib::SingleDispatch<SimpleRulesRemover, grammar::Grammar, const grammar::GrammarBase &> {
+class SimpleRulesRemover {
 	template<class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
 	static T removeEpsilonFree( const T & origGrammar );
 
@@ -38,8 +36,6 @@ class SimpleRulesRemover : public alib::SingleDispatch<SimpleRulesRemover, gramm
 	static T removeNonEpsilonFree( const T & origGrammar );
 
 public:
-	static grammar::Grammar remove( const grammar::Grammar & grammar );
-
 	template < class SymbolType >
 	static grammar::CFG < SymbolType > remove( const grammar::CFG < SymbolType > & grammar );
 	template < class SymbolType >
diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h
index f6e7ec88be..d118dba8b6 100644
--- a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h
+++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h
@@ -8,9 +8,6 @@
 #ifndef UNPRODUCTIVE_SYMBOLS_REMOVER_H_
 #define UNPRODUCTIVE_SYMBOLS_REMOVER_H_
 
-#include <core/multipleDispatch.hpp>
-#include <grammar/Grammar.h>
-
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
 #include <grammar/ContextFree/GNF.h>
@@ -34,10 +31,8 @@ namespace simplify {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class UnproductiveSymbolsRemover : public alib::SingleDispatch<UnproductiveSymbolsRemover, grammar::Grammar, const grammar::GrammarBase &> {
+class UnproductiveSymbolsRemover {
 public:
-	static grammar::Grammar remove( const grammar::Grammar & automaton );
-
 	/**
 	 * Removes unproductive (or useless - terminology) symbols - Melichar 3.12
 	 */
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.cpp b/alib2algo/src/regexp/convert/ToAutomaton.cpp
index b24803b209..9bb07eb141 100644
--- a/alib2algo/src/regexp/convert/ToAutomaton.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomaton.cpp
@@ -12,12 +12,8 @@ namespace regexp {
 
 namespace convert {
 
-automaton::Automaton ToAutomaton::convert(const regexp::RegExp& regexp) {
-	return dispatch(regexp.getData());
-}
-
-auto ToAutomatonFormalRegExp = registration::OverloadRegister < ToAutomaton, automaton::Automaton, regexp::FormalRegExp < > > ( ToAutomaton::convert );
-auto ToAutomatonUnboundedRegExp = registration::OverloadRegister < ToAutomaton, automaton::Automaton, regexp::UnboundedRegExp < > > ( ToAutomaton::convert );
+auto ToAutomatonFormalRegExp = registration::AbstractRegister < ToAutomaton, automaton::NFA < >, const regexp::FormalRegExp < > & > ( ToAutomaton::convert );
+auto ToAutomatonUnboundedRegExp = registration::AbstractRegister < ToAutomaton, automaton::NFA < >, const regexp::UnboundedRegExp < > & > ( ToAutomaton::convert );
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.h b/alib2algo/src/regexp/convert/ToAutomaton.h
index 4c0c70a044..5e226063be 100644
--- a/alib2algo/src/regexp/convert/ToAutomaton.h
+++ b/alib2algo/src/regexp/convert/ToAutomaton.h
@@ -8,43 +8,36 @@
 #ifndef REG_EXP_TO_AUTOMATON_H_
 #define REG_EXP_TO_AUTOMATON_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
 
-#include <automaton/Automaton.h>
-
 #include "ToAutomatonGlushkov.h"
 
 namespace regexp {
 
 namespace convert {
 
-class ToAutomaton : public alib::SingleDispatch<ToAutomaton, automaton::Automaton, const regexp::RegExpBase &> {
+class ToAutomaton {
 public:
 	/**
 	 * Performs conversion.
 	 * @return FSM equivalent to original regular expression.
 	 */
-	static automaton::Automaton convert(const regexp::RegExp& regexp);
-
 	template < class SymbolType >
-	static automaton::Automaton convert(const regexp::FormalRegExp < SymbolType > & regexp);
+	static automaton::NFA < > convert(const regexp::FormalRegExp < SymbolType > & regexp);
 	template < class SymbolType >
-	static automaton::Automaton convert(const regexp::UnboundedRegExp < SymbolType > & regexp);
+	static automaton::NFA < > convert(const regexp::UnboundedRegExp < SymbolType > & regexp);
 
 };
 
 template < class SymbolType >
-automaton::Automaton ToAutomaton::convert(const regexp::FormalRegExp < SymbolType > & regexp) {
-	return automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
+automaton::NFA < > ToAutomaton::convert(const regexp::FormalRegExp < SymbolType > & regexp) {
+	return ToAutomatonGlushkov::convert(regexp);
 }
 
 template < class SymbolType >
-automaton::Automaton ToAutomaton::convert(const regexp::UnboundedRegExp < SymbolType > & regexp) {
-	return automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
+automaton::NFA < > ToAutomaton::convert(const regexp::UnboundedRegExp < SymbolType > & regexp) {
+	return ToAutomatonGlushkov::convert(regexp);
 }
 
 } /* namespace convert */
diff --git a/alib2algo/src/regexp/convert/ToGrammar.cpp b/alib2algo/src/regexp/convert/ToGrammar.cpp
index 038582b6b5..c1aaa22a67 100644
--- a/alib2algo/src/regexp/convert/ToGrammar.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammar.cpp
@@ -12,12 +12,8 @@ namespace regexp {
 
 namespace convert {
 
-grammar::Grammar ToGrammar::convert(const regexp::RegExp& regexp) {
-	return dispatch(regexp.getData());
-}
-
-auto ToGrammarFormalRegExp = registration::OverloadRegister < ToGrammar, grammar::Grammar, regexp::FormalRegExp < > > ( ToGrammar::convert );
-auto ToGrammarUnboundedRegExp = registration::OverloadRegister < ToGrammar, grammar::Grammar, regexp::UnboundedRegExp < > > ( ToGrammar::convert );
+auto ToGrammarFormalRegExp = registration::AbstractRegister < ToGrammar, grammar::RightRG < >, const regexp::FormalRegExp < > & > ( ToGrammar::convert );
+auto ToGrammarUnboundedRegExp = registration::AbstractRegister < ToGrammar, grammar::RightRG < >, const regexp::UnboundedRegExp < > & > ( ToGrammar::convert );
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToGrammar.h b/alib2algo/src/regexp/convert/ToGrammar.h
index fbeb7fa648..5a09b62ad0 100644
--- a/alib2algo/src/regexp/convert/ToGrammar.h
+++ b/alib2algo/src/regexp/convert/ToGrammar.h
@@ -8,41 +8,33 @@
 #ifndef REG_EXP_TO_GRAMMAR_H_
 #define REG_EXP_TO_GRAMMAR_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <grammar/Grammar.h>
-#include <regexp/RegExp.h>
-#include <regexp/RegExpFeatures.h>
-
 #include "ToGrammarRightRGGlushkov.h"
 
 namespace regexp {
 
 namespace convert {
 
-class ToGrammar : public alib::SingleDispatch<ToGrammar, grammar::Grammar, const regexp::RegExpBase &> {
+class ToGrammar {
 public:
 	/**
 	 * Performs conversion.
 	 * @return right regular grammar equivalent to source regexp.
 	 */
-	static grammar::Grammar convert(const regexp::RegExp& regexp);
-
 	template < class SymbolType >
-	static grammar::Grammar convert(const regexp::FormalRegExp < SymbolType > & regexp);
+	static grammar::RightRG < > convert(const regexp::FormalRegExp < SymbolType > & regexp);
 	template < class SymbolType >
-	static grammar::Grammar convert(const regexp::UnboundedRegExp < SymbolType > & regexp);
+	static grammar::RightRG < > convert(const regexp::UnboundedRegExp < SymbolType > & regexp);
 
 };
 
 template < class SymbolType >
-grammar::Grammar ToGrammar::convert(const regexp::FormalRegExp < SymbolType > & regexp) {
-	return grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
+grammar::RightRG < > ToGrammar::convert(const regexp::FormalRegExp < SymbolType > & regexp) {
+	return grammar::RightRG < >(ToGrammarRightRGGlushkov::convert(regexp));
 }
 
 template < class SymbolType >
-grammar::Grammar ToGrammar::convert(const regexp::UnboundedRegExp < SymbolType > & regexp) {
-	return grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
+grammar::RightRG < > ToGrammar::convert(const regexp::UnboundedRegExp < SymbolType > & regexp) {
+	return grammar::RightRG < >(ToGrammarRightRGGlushkov::convert(regexp));
 }
 
 } /* namespace convert */
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.cpp b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
index 3d1f5d579f..b06c4eace9 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
@@ -14,12 +14,8 @@ namespace regexp {
 
 namespace properties {
 
-bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp) {
-	return dispatch(regexp.getData());
-}
-
-auto RegExpEmptyFormalRegExp = registration::OverloadRegister < RegExpEmpty, bool, regexp::FormalRegExp < > > ( RegExpEmpty::languageIsEmpty );
-auto RegExpEmptyUnboundedRegExp = registration::OverloadRegister < RegExpEmpty, bool, regexp::UnboundedRegExp < > > ( RegExpEmpty::languageIsEmpty );
+auto RegExpEmptyFormalRegExp = registration::AbstractRegister < RegExpEmpty, bool, const regexp::FormalRegExp < > & > ( RegExpEmpty::languageIsEmpty );
+auto RegExpEmptyUnboundedRegExp = registration::AbstractRegister < RegExpEmpty, bool, const regexp::UnboundedRegExp < > & > ( RegExpEmpty::languageIsEmpty );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.h b/alib2algo/src/regexp/properties/RegExpEmpty.h
index 9d0af01de3..3f6b745a71 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.h
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.h
@@ -8,9 +8,6 @@
 #ifndef REG_EXP_EMPTY_H_
 #define REG_EXP_EMPTY_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/formal/FormalRegExpElement.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
@@ -24,10 +21,8 @@ namespace properties {
  * Determines whether regular expression is empty (regexp == \0)
  *
  */
-class RegExpEmpty : public alib::SingleDispatch<RegExpEmpty, bool, const regexp::RegExpBase &> {
+class RegExpEmpty {
 public:
-	static bool languageIsEmpty(const regexp::RegExp& regexp);
-
 	template < class SymbolType >
 	static bool languageIsEmpty(const regexp::FormalRegExpElement < SymbolType > & regexp);
 	template < class SymbolType >
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
index f1521fc644..f51e8dc78d 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
@@ -14,12 +14,8 @@ namespace regexp {
 
 namespace properties {
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp) {
-	return dispatch(regexp.getData());
-}
-
-auto RegExpEpsilonFormalRegExp = registration::OverloadRegister < RegExpEpsilon, bool, regexp::FormalRegExp < > > ( RegExpEpsilon::languageContainsEpsilon );
-auto RegExpEpsilonUnboundedRegExp = registration::OverloadRegister < RegExpEpsilon, bool, regexp::UnboundedRegExp < > > ( RegExpEpsilon::languageContainsEpsilon );
+auto RegExpEpsilonFormalRegExp = registration::AbstractRegister < RegExpEpsilon, bool, const regexp::FormalRegExp < > & > ( RegExpEpsilon::languageContainsEpsilon );
+auto RegExpEpsilonUnboundedRegExp = registration::AbstractRegister < RegExpEpsilon, bool, const regexp::UnboundedRegExp < > & > ( RegExpEpsilon::languageContainsEpsilon );
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h
index 2ff33d4900..4c381f4782 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.h
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h
@@ -8,9 +8,6 @@
 #ifndef REG_EXP_EPSILON_H_
 #define REG_EXP_EPSILON_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/formal/FormalRegExpElement.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
@@ -24,10 +21,8 @@ namespace properties {
  * Checks, whether regexp (or its subtree) describes epsilon (empty string).
  *
  */
-class RegExpEpsilon : public alib::SingleDispatch<RegExpEpsilon, bool, const regexp::RegExpBase &> {
+class RegExpEpsilon {
 public:
-	static bool languageContainsEpsilon(const regexp::RegExp& regexp);
-
 	template < class SymbolType >
 	static bool languageContainsEpsilon(const regexp::FormalRegExpElement < SymbolType > & regexp);
 	template < class SymbolType >
diff --git a/alib2algo/src/regexp/transform/RegExpAlternate.cpp b/alib2algo/src/regexp/transform/RegExpAlternate.cpp
index 0f1897263a..6a0fa1f65b 100644
--- a/alib2algo/src/regexp/transform/RegExpAlternate.cpp
+++ b/alib2algo/src/regexp/transform/RegExpAlternate.cpp
@@ -10,11 +10,7 @@
 
 namespace regexp {
 
-regexp::RegExp RegExpAlternate::alternate(const regexp::RegExp& first, const regexp::RegExp& second) {
-	return dispatch(first.getData(), second.getData());
-}
-
-auto RegExpAlternateFormalRegExp = registration::OverloadRegister < RegExpAlternate, regexp::FormalRegExp < > , regexp::FormalRegExp < > > ( RegExpAlternate::alternate );
-auto RegExpAlternateUnboundedRegExp = registration::OverloadRegister < RegExpAlternate, regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > > ( RegExpAlternate::alternate );
+auto RegExpAlternateFormalRegExp = registration::AbstractRegister < RegExpAlternate, regexp::FormalRegExp < >, const regexp::FormalRegExp < > &, const regexp::FormalRegExp < > & > ( RegExpAlternate::alternate );
+auto RegExpAlternateUnboundedRegExp = registration::AbstractRegister < RegExpAlternate, regexp::UnboundedRegExp < >, const regexp::UnboundedRegExp < > &, const regexp::UnboundedRegExp < > & > ( RegExpAlternate::alternate );
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpAlternate.h b/alib2algo/src/regexp/transform/RegExpAlternate.h
index 02f488d4b6..9e8e2c7b14 100644
--- a/alib2algo/src/regexp/transform/RegExpAlternate.h
+++ b/alib2algo/src/regexp/transform/RegExpAlternate.h
@@ -8,9 +8,6 @@
 #ifndef REG_EXP_ALTERNATE_H_
 #define REG_EXP_ALTERNATE_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
 
@@ -23,10 +20,8 @@ namespace regexp {
  * Alternates two regexpses
  *
  */
-class RegExpAlternate : public alib::PromotingDoubleDispatch<RegExpAlternate, regexp::RegExp, const regexp::RegExpBase &> {
+class RegExpAlternate {
 public:
-	static regexp::RegExp alternate(const regexp::RegExp& first, const regexp::RegExp& second);
-
 	template < class SymbolType >
 	static regexp::FormalRegExp < SymbolType > alternate(const regexp::FormalRegExp < SymbolType > & first, const regexp::FormalRegExp < SymbolType > & second);
 	template < class SymbolType >
diff --git a/alib2algo/src/regexp/transform/RegExpConcatenate.cpp b/alib2algo/src/regexp/transform/RegExpConcatenate.cpp
index 1139d0c5f3..d0ef54d364 100644
--- a/alib2algo/src/regexp/transform/RegExpConcatenate.cpp
+++ b/alib2algo/src/regexp/transform/RegExpConcatenate.cpp
@@ -10,11 +10,7 @@
 
 namespace regexp {
 
-regexp::RegExp RegExpConcatenate::concatenate(const regexp::RegExp& first, const regexp::RegExp& second) {
-	return dispatch(first.getData(), second.getData());
-}
-
-auto RegExpConcatenateFormalRegExp = registration::OverloadRegister < RegExpConcatenate, regexp::FormalRegExp < >, regexp::FormalRegExp < > > ( RegExpConcatenate::concatenate );
-auto RegExpConcatenateUnboundedRegExp = registration::OverloadRegister < RegExpConcatenate, regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > > ( RegExpConcatenate::concatenate );
+auto RegExpConcatenateFormalRegExp = registration::AbstractRegister < RegExpConcatenate, regexp::FormalRegExp < >, const regexp::FormalRegExp < > &, const regexp::FormalRegExp < > & > ( RegExpConcatenate::concatenate );
+auto RegExpConcatenateUnboundedRegExp = registration::AbstractRegister < RegExpConcatenate, regexp::UnboundedRegExp < >, const regexp::UnboundedRegExp < > &, const regexp::UnboundedRegExp < > & > ( RegExpConcatenate::concatenate );
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpConcatenate.h b/alib2algo/src/regexp/transform/RegExpConcatenate.h
index d48c0572bd..9653cadc52 100644
--- a/alib2algo/src/regexp/transform/RegExpConcatenate.h
+++ b/alib2algo/src/regexp/transform/RegExpConcatenate.h
@@ -8,9 +8,6 @@
 #ifndef REG_EXP_CONCATENATE_H_
 #define REG_EXP_CONCATENATE_H_
 
-#include <core/multipleDispatch.hpp>
-
-#include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
 
@@ -23,10 +20,8 @@ namespace regexp {
  * Concatenates two regexpses
  *
  */
-class RegExpConcatenate : public alib::PromotingDoubleDispatch<RegExpConcatenate, regexp::RegExp, const regexp::RegExpBase &> {
+class RegExpConcatenate {
 public:
-	static regexp::RegExp concatenate(const regexp::RegExp& first, const regexp::RegExp& second);
-
 	template < class SymbolType >
 	static regexp::FormalRegExp < SymbolType > concatenate(const regexp::FormalRegExp < SymbolType > & first, const regexp::FormalRegExp < SymbolType > & second);
 	template < class SymbolType >
diff --git a/alib2algo/src/regexp/transform/RegExpIterate.cpp b/alib2algo/src/regexp/transform/RegExpIterate.cpp
index 4205a203f8..0e17d994fd 100644
--- a/alib2algo/src/regexp/transform/RegExpIterate.cpp
+++ b/alib2algo/src/regexp/transform/RegExpIterate.cpp
@@ -10,11 +10,7 @@
 
 namespace regexp {
 
-regexp::RegExp RegExpIterate::iterate(const regexp::RegExp& regexp) {
-	return dispatch(regexp.getData());
-}
-
-auto RegExpIterateFormalRegExpFormalRegExp = registration::OverloadRegister < RegExpIterate, regexp::FormalRegExp < >, regexp::FormalRegExp < > > ( RegExpIterate::iterate );
-auto RegExpIterateUnboundedRegExpUnboundedRegExp = registration::OverloadRegister < RegExpIterate, regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > > ( RegExpIterate::iterate );
+auto RegExpIterateFormalRegExpFormalRegExp = registration::AbstractRegister < RegExpIterate, regexp::FormalRegExp < >, const regexp::FormalRegExp < > & > ( RegExpIterate::iterate );
+auto RegExpIterateUnboundedRegExpUnboundedRegExp = registration::AbstractRegister < RegExpIterate, regexp::UnboundedRegExp < >, const regexp::UnboundedRegExp < > & > ( RegExpIterate::iterate );
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpIterate.h b/alib2algo/src/regexp/transform/RegExpIterate.h
index 90dc4d22b9..67bf2512fd 100644
--- a/alib2algo/src/regexp/transform/RegExpIterate.h
+++ b/alib2algo/src/regexp/transform/RegExpIterate.h
@@ -8,12 +8,9 @@
 #ifndef REG_EXP_ITERATE_H_
 #define REG_EXP_ITERATE_H_
 
-#include <core/multipleDispatch.hpp>
-
 #include "regexp/formal/FormalRegExpIteration.h"
 #include "regexp/unbounded/UnboundedRegExpIteration.h"
 
-#include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
 
@@ -23,10 +20,8 @@ namespace regexp {
  * Iterates two regexpses
  *
  */
-class RegExpIterate : public alib::SingleDispatch<RegExpIterate, regexp::RegExp, const regexp::RegExpBase &> {
+class RegExpIterate {
 public:
-	static regexp::RegExp iterate(const regexp::RegExp& regexp);
-
 	template < class SymbolType >
 	static regexp::FormalRegExp < SymbolType > iterate(const regexp::FormalRegExp < SymbolType > & regexp);
 	template < class SymbolType >
diff --git a/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp
index 763deaa642..0091e786d9 100644
--- a/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp
+++ b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp
@@ -18,13 +18,13 @@ void RegExpEmptyTest::tearDown() {
 void RegExpEmptyTest::testRegExpEmpty() {
 	{
 		std::string input = "(#E #0 ) + ( #0 a + (b ( #0 (a*) ) ) )";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(regexp::properties::RegExpEmpty::languageIsEmpty(re));
 	}
 	{
 		std::string input = "(#E + a ) + ( #0 a + (b ( #0 (a*) ) ) )";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(! regexp::properties::RegExpEmpty::languageIsEmpty(re));
 	}
diff --git a/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp
index 4026c0b89b..e3a0f4ee5f 100644
--- a/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp
+++ b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp
@@ -16,43 +16,43 @@ void RegExpEpsilonTest::tearDown() {
 void RegExpEpsilonTest::testRegExpEpsilon() {
 	{
 		std::string input = "#E + ( (a #E) + a*)";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
 	}
 	{
 		std::string input = "( a* )( a* )";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
 	}
 	{
 		std::string input = "a + #0";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
 	}
 	{
 		std::string input = "#E + a #E + a*";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
 	}
 	{
 		std::string input = "a* a*";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
 	}
 	{
 		std::string input = "a s d #E + #E #0";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
 	}
 	{
 		std::string input = "a + #0";
-		regexp::RegExp re = alib::StringDataFactory::fromString (input);
+		regexp::UnboundedRegExp < > re = alib::StringDataFactory::fromString (input);
 
 		CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
 	}
diff --git a/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
index 062aa592d2..223b62d1da 100644
--- a/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
+++ b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
@@ -19,45 +19,45 @@ void RegExpConcatenateTest::tearDown() {
 void RegExpConcatenateTest::testRegExpConcatenate() {
 	{
 		std::string input1 = "(#E a b)";
-		regexp::RegExp re1 = alib::StringDataFactory::fromString (input1);
+		regexp::UnboundedRegExp < > re1 = alib::StringDataFactory::fromString (input1);
 
 		std::string input2 = "(#E a c)";
-		regexp::RegExp re2 = alib::StringDataFactory::fromString (input2);
+		regexp::UnboundedRegExp < > re2 = alib::StringDataFactory::fromString (input2);
 
-		regexp::RegExp re = regexp::RegExpConcatenate::concatenate(re1, re2);
+		regexp::UnboundedRegExp < > re = regexp::RegExpConcatenate::concatenate(re1, re2);
 
 		std::string inputr = "(#E a b)(#E a c)";
-		regexp::RegExp rer = alib::StringDataFactory::fromString (inputr);
+		regexp::UnboundedRegExp < > rer = alib::StringDataFactory::fromString (inputr);
 
 		CPPUNIT_ASSERT(re == rer);
 	}
 	{
 		std::string input1 = "(#E a b)";
-		regexp::RegExp re1 = alib::StringDataFactory::fromString (input1);
+		regexp::UnboundedRegExp < > re1 = alib::StringDataFactory::fromString (input1);
 
-		regexp::RegExp re2(regexp::FormalRegExp < > (regexp::FormalRegExpStructure < DefaultSymbolType > (regexp::FormalRegExpConcatenation < DefaultSymbolType > (regexp::FormalRegExpEmpty < DefaultSymbolType > {}, regexp::FormalRegExpEpsilon < DefaultSymbolType >  {}))));
+		regexp::UnboundedRegExp < > re2(regexp::FormalRegExp < > (regexp::FormalRegExpStructure < DefaultSymbolType > (regexp::FormalRegExpConcatenation < DefaultSymbolType > (regexp::FormalRegExpEmpty < DefaultSymbolType > {}, regexp::FormalRegExpEpsilon < DefaultSymbolType > {}))));
 
-		regexp::RegExp re = regexp::RegExpConcatenate::concatenate(re1, re2);
+		regexp::UnboundedRegExp < > re = regexp::RegExpConcatenate::concatenate(re1, re2);
 
 		std::string inputr = "(#E a b)(#0 #E )";
-		regexp::RegExp rer = alib::StringDataFactory::fromString (inputr);
+		regexp::UnboundedRegExp < > rer = alib::StringDataFactory::fromString (inputr);
 
 		CPPUNIT_ASSERT(re == rer);
 	}
 	{
-		regexp::RegExp re1(regexp::FormalRegExp < > (regexp::FormalRegExpStructure < DefaultSymbolType > (regexp::FormalRegExpConcatenation < DefaultSymbolType > (regexp::FormalRegExpEmpty < DefaultSymbolType > {}, regexp::FormalRegExpEpsilon < DefaultSymbolType >  {}))));
+		regexp::FormalRegExp < > re1 (regexp::FormalRegExpStructure < DefaultSymbolType > (regexp::FormalRegExpConcatenation < DefaultSymbolType > (regexp::FormalRegExpEmpty < DefaultSymbolType > {}, regexp::FormalRegExpEpsilon < DefaultSymbolType > {})));
 
 		std::string input2 = "(#E a b)";
-		regexp::RegExp re2 = alib::StringDataFactory::fromString (input2);
+		regexp::UnboundedRegExp < > re2 = alib::StringDataFactory::fromString (input2);
 
-		regexp::RegExp re = regexp::RegExpConcatenate::concatenate(re1, re2);
+		regexp::FormalRegExp < > re = regexp::RegExpConcatenate::concatenate(re1, regexp::FormalRegExp < > ( re2 ) );
 
 		std::string inputr = "(#0 #E )(#E a b)";
-		regexp::RegExp tmp = alib::StringDataFactory::fromString (inputr);
-		regexp::RegExp rer(regexp::FormalRegExp < > (dynamic_cast<const regexp::UnboundedRegExp < > & >(tmp.getData())));
+		regexp::UnboundedRegExp < > tmp = alib::StringDataFactory::fromString (inputr);
+		regexp::FormalRegExp < > rer = regexp::FormalRegExp < > ( tmp );
 
-		std::cout << (dynamic_cast<const regexp::UnboundedRegExp < > & >(tmp.getData())).getAlphabet() << std::endl;
-		std::cout << (dynamic_cast<const regexp::FormalRegExp < > & >(rer.getData())).getAlphabet() << std::endl;
+		std::cout << tmp.getAlphabet() << std::endl;
+		std::cout << rer.getAlphabet() << std::endl;
 
 		std::cout << re << std::endl;
 		std::cout << rer << std::endl;
diff --git a/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp
index 31fd3192ea..0a2a6ebaf7 100644
--- a/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp
+++ b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp
@@ -32,15 +32,14 @@ void RegExpDerivationTest::testRegExpDerivation() {
 }
 
 void RegExpDerivationTest::ExecSingleTest(std::string regexp_str, std::string string_str, std::string result) {
-    regexp::RegExp regexp0 = alib::StringDataFactory::fromString (regexp_str);
+    regexp::UnboundedRegExp < > regexp0 = alib::StringDataFactory::fromString (regexp_str);
     ext::deque<sax::Token> tokens = alib::XmlDataFactory::toTokens(regexp0);
-    regexp::RegExp regexp1 = alib::XmlDataFactory::fromTokens (std::move(tokens));
+    regexp::UnboundedRegExp < > regexp = alib::XmlDataFactory::fromTokens (std::move(tokens));
 
     string::String string0 = alib::StringDataFactory::fromString ("\"" + string_str + "\"");
     ext::deque<sax::Token> tokens2 = alib::XmlDataFactory::toTokens(string0);
     string::String string1 = alib::XmlDataFactory::fromTokens (std::move(tokens2));
 
-    const regexp::UnboundedRegExp < > & regexp = static_cast < const regexp::UnboundedRegExp < > & > ( regexp1.getData ( ) );
     const string::LinearString < > & string = static_cast<const string::LinearString < >&>(string1.getData());
 
     std::cout << alib::StringDataFactory::toString(regexp::RegExpDerivation::derivation(regexp, string)) << " == " << std::endl << result << std::endl << std::endl;
diff --git a/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp
index 1cffa7694a..fc8d9faa27 100644
--- a/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp
+++ b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp
@@ -23,10 +23,9 @@ void RegExpIntegralTest::testRegExpIntegral() {
 }
 
 void RegExpIntegralTest::ExecSingleTest(std::string regexp_str, std::string string_str, std::string result) {
-    regexp::RegExp re = alib::StringDataFactory::fromString ( regexp_str );
+    regexp::UnboundedRegExp < > regexp = alib::StringDataFactory::fromString ( regexp_str );
     string::String str = alib::StringDataFactory::fromString ( "\"" + string_str + "\"" );
 
-    const regexp::UnboundedRegExp < > & regexp = static_cast < const regexp::UnboundedRegExp < > & > ( re.getData ( ) );
     const string::LinearString < > & string = static_cast < const string::LinearString < > & > ( str.getData ( ) );
 
     std::cout << alib::StringDataFactory::toString(regexp::RegExpIntegral::integral(regexp, string)) << " == " << result << std::endl;
-- 
GitLab