From 0f4f1864c0d40f615a1321310f87b01eb7c4065d Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 3 Sep 2017 17:07:07 +0200
Subject: [PATCH] use cli internally in atrim binary

---
 aepsilon2/src/aepsilon.cpp                    |   8 +-
 alib2algo/src/automaton/simplify/Trim.cpp     |  26 ++--
 alib2algo/src/automaton/simplify/Trim.h       |   7 +-
 .../simplify/UnreachableStatesRemover.cpp     |  26 ++--
 .../simplify/UnreachableStatesRemover.h       |   7 +-
 .../simplify/UselessStatesRemover.cpp         |  18 ++-
 .../automaton/simplify/UselessStatesRemover.h |   7 +-
 alib2algo/src/grammar/simplify/Trim.cpp       |  22 ++--
 alib2algo/src/grammar/simplify/Trim.h         |   7 +-
 .../simplify/UnproductiveSymbolsRemover.cpp   |  22 ++--
 .../simplify/UnreachableSymbolsRemover.cpp    |  22 ++--
 .../simplify/UnreachableSymbolsRemover.h      |   7 +-
 .../src/regexp/simplify/RegExpOptimize.cpp    |   8 +-
 .../src/regexp/simplify/RegExpOptimize.h      |   9 +-
 .../regexp/simplify/RegExpOptimizeTest.cpp    |  18 +--
 .../src/automaton/simplify/efficient/Trim.cpp |  16 +--
 .../src/automaton/simplify/efficient/Trim.h   |   6 +-
 .../efficient/UnreachableStatesRemover.cpp    |  16 +--
 .../efficient/UnreachableStatesRemover.h      |   6 +-
 .../efficient/UselessStatesRemover.cpp        |  16 +--
 .../simplify/efficient/UselessStatesRemover.h |   7 +-
 atrim2/makefile.conf                          |   6 +-
 atrim2/src/atrim.cpp                          | 117 +++++++-----------
 23 files changed, 139 insertions(+), 265 deletions(-)

diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp
index ddb835e725..9cd9764ae9 100644
--- a/aepsilon2/src/aepsilon.cpp
+++ b/aepsilon2/src/aepsilon.cpp
@@ -54,13 +54,13 @@ int main(int argc, char** argv) {
 		cli::Parser parser ( cli::Lexer ( "execute <#stdin > $input" ) );
 		parser.parse ( )->run ( environment );
 
-		measurements::end();
-		measurements::start("Algorithm", measurements::Type::MAIN);
-
-		parser = cli::Parser ( cli::Lexer ( "export type = typename ( $input )" ) );
+//		parser = cli::Parser ( cli::Lexer ( "export type = typename ( $input )" ) );
 		std::string inputType = environment.getVariable ( "input" )->getReturnType ( );
 		bool isAutomaton = inputType.find ( "automaton::" ) == 0;
 
+		measurements::end();
+		measurements::start("Algorithm", measurements::Type::MAIN);
+
 		if(algorithm.getValue() == "outgoing") {
 			if(efficient.getValue())
 				parser = cli::Parser ( cli::Lexer ( "execute automaton::simplify::efficient::EpsilonRemoverOutgoing $input > $output" ) );
diff --git a/alib2algo/src/automaton/simplify/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp
index 8d0b165caa..70d43486e5 100644
--- a/alib2algo/src/automaton/simplify/Trim.cpp
+++ b/alib2algo/src/automaton/simplify/Trim.cpp
@@ -19,25 +19,13 @@ namespace automaton {
 
 namespace simplify {
 
-auto TrimDFA = registration::OverloadRegister < Trim, automaton::DFA < >, automaton::DFA < > > ( Trim::trim );
-auto TrimNFA = registration::OverloadRegister < Trim, automaton::NFA < > , automaton::NFA < > >( Trim::trim );
-auto TrimMultiInitialStateNFA = registration::OverloadRegister < Trim, automaton::MultiInitialStateNFA < > , automaton::MultiInitialStateNFA < > > ( Trim::trim );
-auto TrimEpsilonNFA = registration::OverloadRegister < Trim, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( Trim::trim );
-auto TrimCompactNFA = registration::OverloadRegister < Trim, automaton::CompactNFA < >, automaton::CompactNFA < > > ( Trim::trim );
-auto TrimExtendedNFA = registration::OverloadRegister < Trim, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > > ( Trim::trim );
-auto TrimDFTA = registration::OverloadRegister < Trim, automaton::DFTA < >, automaton::DFTA < > > ( Trim::trim );
-
-auto TrimDFA2 = registration::AbstractRegister < Trim, automaton::DFA < >, const automaton::DFA < > & > ( Trim::trim );
-auto TrimNFA2 = registration::AbstractRegister < Trim, automaton::NFA < >, const automaton::NFA < > & > ( Trim::trim );
-auto TrimMultiInitialStateNFA2 = registration::AbstractRegister < Trim, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( Trim::trim );
-auto TrimEpsilonNFA2 = registration::AbstractRegister < Trim, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( Trim::trim );
-auto TrimCompactNFA2 = registration::AbstractRegister < Trim, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( Trim::trim );
-auto TrimExtendedNFA2 = registration::AbstractRegister < Trim, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( Trim::trim );
-auto TrimDFTA2 = registration::AbstractRegister < Trim, automaton::DFTA < >, const automaton::DFTA < > & > ( Trim::trim );
-
-automaton::Automaton Trim::trim(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
+auto TrimDFA = registration::AbstractRegister < Trim, automaton::DFA < >, const automaton::DFA < > & > ( Trim::trim );
+auto TrimNFA = registration::AbstractRegister < Trim, automaton::NFA < >, const automaton::NFA < > & > ( Trim::trim );
+auto TrimMultiInitialStateNFA = registration::AbstractRegister < Trim, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( Trim::trim );
+auto TrimEpsilonNFA = registration::AbstractRegister < Trim, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( Trim::trim );
+auto TrimCompactNFA = registration::AbstractRegister < Trim, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( Trim::trim );
+auto TrimExtendedNFA = registration::AbstractRegister < Trim, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( Trim::trim );
+auto TrimDFTA = registration::AbstractRegister < Trim, automaton::DFTA < >, const automaton::DFTA < > & > ( Trim::trim );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/Trim.h b/alib2algo/src/automaton/simplify/Trim.h
index 2909d5132e..8c042a97c4 100644
--- a/alib2algo/src/automaton/simplify/Trim.h
+++ b/alib2algo/src/automaton/simplify/Trim.h
@@ -8,9 +8,6 @@
 #ifndef AUTOMATON_TRIM_H_
 #define AUTOMATON_TRIM_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
-
 #include "UselessStatesRemover.h"
 #include "UnreachableStatesRemover.h"
 
@@ -18,10 +15,8 @@ namespace automaton {
 
 namespace simplify {
 
-class Trim : public alib::SingleDispatch<Trim, automaton::Automaton, const automaton::AutomatonBase &> {
+class Trim {
 public:
-	static automaton::Automaton trim( const automaton::Automaton & automaton );
-
 	/**
 	 * Removes dead states from FSM. Melichar 2.29
 	 */
diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
index a23c8ec811..8054df7cb3 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
@@ -12,25 +12,13 @@ namespace automaton {
 
 namespace simplify {
 
-auto UnreachableStatesRemoverEpsilonNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::NFA < > , automaton::NFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverCompactNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::CompactNFA < >, automaton::CompactNFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverExtendedNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverDFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::DFA < >, automaton::DFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverMultiInitialStateNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::MultiInitialStateNFA < > , automaton::MultiInitialStateNFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverDFTA = registration::OverloadRegister < UnreachableStatesRemover, automaton::DFTA < >, automaton::DFTA < > > ( UnreachableStatesRemover::remove );
-
-auto UnreachableStatesRemoverEpsilonNFA2 = registration::AbstractRegister < UnreachableStatesRemover, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverNFA2 = registration::AbstractRegister < UnreachableStatesRemover, automaton::NFA < >, const automaton::NFA < > & > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverCompactNFA2 = registration::AbstractRegister < UnreachableStatesRemover, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverExtendedNFA2 = registration::AbstractRegister < UnreachableStatesRemover, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverDFA2 = registration::AbstractRegister < UnreachableStatesRemover, automaton::DFA < >, const automaton::DFA < > & > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverMultiInitialStateNFA2 = registration::AbstractRegister < UnreachableStatesRemover, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverDFTA2 = registration::AbstractRegister < UnreachableStatesRemover, automaton::DFTA < >, const automaton::DFTA < > & > ( UnreachableStatesRemover::remove );
-
-automaton::Automaton UnreachableStatesRemover::remove(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
+auto UnreachableStatesRemoverEpsilonNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::NFA < >, const automaton::NFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverCompactNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverExtendedNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverDFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::DFA < >, const automaton::DFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverMultiInitialStateNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverDFTA = registration::AbstractRegister < UnreachableStatesRemover, automaton::DFTA < >, const automaton::DFTA < > & > ( UnreachableStatesRemover::remove );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
index 482b0bdf85..b17ee57159 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
@@ -8,9 +8,6 @@
 #ifndef UNREACHABLE_STATES_REMOVER_H_
 #define UNREACHABLE_STATES_REMOVER_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
-
 #include <automaton/FSM/ExtendedNFA.h>
 #include <automaton/FSM/CompactNFA.h>
 #include <automaton/FSM/EpsilonNFA.h>
@@ -25,10 +22,8 @@ namespace automaton {
 
 namespace simplify {
 
-class UnreachableStatesRemover : public alib::SingleDispatch<UnreachableStatesRemover, automaton::Automaton, const automaton::AutomatonBase &> {
+class UnreachableStatesRemover {
 public:
-	static automaton::Automaton remove( const automaton::Automaton & automaton );
-
 	/**
 	 * Removes dead states from FSM. Melichar 2.29
 	 */
diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
index 190ec3c0c6..6b15e97599 100644
--- a/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
@@ -12,17 +12,13 @@ namespace automaton {
 
 namespace simplify {
 
-auto UselessStatesRemoverEpsilonNFA = registration::OverloadRegister < UselessStatesRemover, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverNFA = registration::OverloadRegister < UselessStatesRemover, automaton::NFA < > , automaton::NFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverCompactNFA = registration::OverloadRegister < UselessStatesRemover, automaton::CompactNFA < >, automaton::CompactNFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverExtendedNFA = registration::OverloadRegister < UselessStatesRemover, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverDFA = registration::OverloadRegister < UselessStatesRemover, automaton::DFA < >, automaton::DFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverMultiInitialStateNFA = registration::OverloadRegister < UselessStatesRemover, automaton::MultiInitialStateNFA < > , automaton::MultiInitialStateNFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverDFTA = registration::OverloadRegister < UselessStatesRemover, automaton::DFTA < >, automaton::DFTA < > > ( UselessStatesRemover::remove );
-
-automaton::Automaton UselessStatesRemover::remove(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
+auto UselessStatesRemoverEpsilonNFA = registration::AbstractRegister < UselessStatesRemover, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverNFA = registration::AbstractRegister < UselessStatesRemover, automaton::NFA < >, const automaton::NFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverCompactNFA = registration::AbstractRegister < UselessStatesRemover, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverExtendedNFA = registration::AbstractRegister < UselessStatesRemover, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverDFA = registration::AbstractRegister < UselessStatesRemover, automaton::DFA < >, const automaton::DFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverMultiInitialStateNFA = registration::AbstractRegister < UselessStatesRemover, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverDFTA = registration::AbstractRegister < UselessStatesRemover, automaton::DFTA < >, const automaton::DFTA < > & > ( UselessStatesRemover::remove );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/automaton/simplify/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h
index 2d99bee19e..ebe2669053 100644
--- a/alib2algo/src/automaton/simplify/UselessStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.h
@@ -8,9 +8,6 @@
 #ifndef USELESS_STATES_REMOVER_H_
 #define USELESS_STATES_REMOVER_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
-
 #include "../properties/UsefullStates.h"
 
 #include <automaton/FSM/ExtendedNFA.h>
@@ -25,10 +22,8 @@ namespace automaton {
 
 namespace simplify {
 
-class UselessStatesRemover : public alib::SingleDispatch<UselessStatesRemover, automaton::Automaton, const automaton::AutomatonBase &> {
+class UselessStatesRemover {
 public:
-	static automaton::Automaton remove( const automaton::Automaton & automaton );
-
 	/**
 	 * Removes dead states from FSM. Melichar 2.29
 	 */
diff --git a/alib2algo/src/grammar/simplify/Trim.cpp b/alib2algo/src/grammar/simplify/Trim.cpp
index 580585fc28..5a0897ee39 100644
--- a/alib2algo/src/grammar/simplify/Trim.cpp
+++ b/alib2algo/src/grammar/simplify/Trim.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace simplify {
 
-auto TrimCFG = registration::OverloadRegister < Trim, grammar::CFG < >, grammar::CFG < > > ( Trim::trim );
-auto TrimEpsilonFreeCFG = registration::OverloadRegister < Trim, grammar::EpsilonFreeCFG < >, grammar::EpsilonFreeCFG < > > ( Trim::trim );
-auto TrimGNF = registration::OverloadRegister < Trim, grammar::GNF < >, grammar::GNF < > > ( Trim::trim );
-auto TrimCNF = registration::OverloadRegister < Trim, grammar::CNF < >, grammar::CNF < > > ( Trim::trim );
-auto TrimLG = registration::OverloadRegister < Trim, grammar::LG < >, grammar::LG < > > ( Trim::trim );
-auto TrimLeftLG = registration::OverloadRegister < Trim, grammar::LeftLG < >, grammar::LeftLG < > > ( Trim::trim );
-auto TrimLeftRG = registration::OverloadRegister < Trim, grammar::LeftRG < >, grammar::LeftRG < > > ( Trim::trim );
-auto TrimRightLG = registration::OverloadRegister < Trim, grammar::RightLG < >, grammar::RightLG < > > ( Trim::trim );
-auto TrimRightRG = registration::OverloadRegister < Trim, grammar::RightRG < >, grammar::RightRG < > > ( Trim::trim );
-
-grammar::Grammar Trim::trim(const grammar::Grammar& grammar) {
-	return dispatch(grammar.getData());
-}
+auto TrimCFG = registration::AbstractRegister < Trim, grammar::CFG < >, const grammar::CFG < > & > ( Trim::trim );
+auto TrimEpsilonFreeCFG = registration::AbstractRegister < Trim, grammar::EpsilonFreeCFG < >, const grammar::EpsilonFreeCFG < > & > ( Trim::trim );
+auto TrimGNF = registration::AbstractRegister < Trim, grammar::GNF < >, const grammar::GNF < > & > ( Trim::trim );
+auto TrimCNF = registration::AbstractRegister < Trim, grammar::CNF < >, const grammar::CNF < > & > ( Trim::trim );
+auto TrimLG = registration::AbstractRegister < Trim, grammar::LG < >, const grammar::LG < > & > ( Trim::trim );
+auto TrimLeftLG = registration::AbstractRegister < Trim, grammar::LeftLG < >, const grammar::LeftLG < > & > ( Trim::trim );
+auto TrimLeftRG = registration::AbstractRegister < Trim, grammar::LeftRG < >, const grammar::LeftRG < > & > ( Trim::trim );
+auto TrimRightLG = registration::AbstractRegister < Trim, grammar::RightLG < >, const grammar::RightLG < > & > ( Trim::trim );
+auto TrimRightRG = registration::AbstractRegister < Trim, grammar::RightRG < >, const grammar::RightRG < > & > ( Trim::trim );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/grammar/simplify/Trim.h b/alib2algo/src/grammar/simplify/Trim.h
index a86b155a4d..f6dc6834ef 100644
--- a/alib2algo/src/grammar/simplify/Trim.h
+++ b/alib2algo/src/grammar/simplify/Trim.h
@@ -8,9 +8,6 @@
 #ifndef GRAMMAR_TRIM_H_
 #define GRAMMAR_TRIM_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 +28,8 @@ namespace simplify {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class Trim : public alib::SingleDispatch<Trim, grammar::Grammar, const grammar::GrammarBase &> {
+class Trim {
 public:
-	static grammar::Grammar trim( const grammar::Grammar & grammar );
-
 	/**
 	 * Removes unproductive and useless symbols - Melichar 3.12
 	 */
diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
index 13d2ffab63..21c1149715 100644
--- a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
+++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace simplify {
 
-auto UnproductiveSymbolsRemoverCFG = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::CFG < >, grammar::CFG < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverEpsilonFreeCFG = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::EpsilonFreeCFG < >, grammar::EpsilonFreeCFG < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverGNF = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::GNF < >, grammar::GNF < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverCNF = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::CNF < >, grammar::CNF < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverLG = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::LG < >, grammar::LG < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverLeftLG = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::LeftLG < >, grammar::LeftLG < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverLeftRG = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::LeftRG < >, grammar::LeftRG < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverRightLG = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::RightLG < >, grammar::RightLG < > > ( UnproductiveSymbolsRemover::remove );
-auto UnproductiveSymbolsRemoverRightRG = registration::OverloadRegister < UnproductiveSymbolsRemover, grammar::RightRG < >, grammar::RightRG < > > ( UnproductiveSymbolsRemover::remove );
-
-grammar::Grammar UnproductiveSymbolsRemover::remove(const grammar::Grammar& grammar) {
-	return dispatch(grammar.getData());
-}
+auto UnproductiveSymbolsRemoverCFG = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::CFG < >, const grammar::CFG < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverEpsilonFreeCFG = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::EpsilonFreeCFG < >, const grammar::EpsilonFreeCFG < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverGNF = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::GNF < >, const grammar::GNF < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverCNF = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::CNF < >, const grammar::CNF < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverLG = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::LG < >, const grammar::LG < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverLeftLG = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::LeftLG < >, const grammar::LeftLG < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverLeftRG = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::LeftRG < >, const grammar::LeftRG < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverRightLG = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::RightLG < >, const grammar::RightLG < > & > ( UnproductiveSymbolsRemover::remove );
+auto UnproductiveSymbolsRemoverRightRG = registration::AbstractRegister < UnproductiveSymbolsRemover, grammar::RightRG < >, const grammar::RightRG < > & > ( UnproductiveSymbolsRemover::remove );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
index 34f7382693..9f63058122 100644
--- a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
+++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
@@ -12,19 +12,15 @@ namespace grammar {
 
 namespace simplify {
 
-auto UnreachableSymbolsRemoverCFG = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::CFG < >, grammar::CFG < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverEpsilonFreeCFG = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::EpsilonFreeCFG < >, grammar::EpsilonFreeCFG < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverGNF = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::GNF < >, grammar::GNF < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverCNF = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::CNF < >, grammar::CNF < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverLG = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::LG < >, grammar::LG < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverLeftLG = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::LeftLG < >, grammar::LeftLG < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverLeftRG = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::LeftRG < >, grammar::LeftRG < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverRightLG = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::RightLG < >, grammar::RightLG < > > ( UnreachableSymbolsRemover::remove );
-auto UnreachableSymbolsRemoverRightRG = registration::OverloadRegister < UnreachableSymbolsRemover, grammar::RightRG < >, grammar::RightRG < > > ( UnreachableSymbolsRemover::remove );
-
-grammar::Grammar UnreachableSymbolsRemover::remove(const grammar::Grammar& grammar) {
-	return dispatch(grammar.getData());
-}
+auto UnreachableSymbolsRemoverCFG = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::CFG < >, const grammar::CFG < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverEpsilonFreeCFG = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::EpsilonFreeCFG < >, const grammar::EpsilonFreeCFG < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverGNF = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::GNF < >, const grammar::GNF < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverCNF = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::CNF < >, const grammar::CNF < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverLG = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::LG < >, const grammar::LG < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverLeftLG = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::LeftLG < >, const grammar::LeftLG < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverLeftRG = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::LeftRG < >, const grammar::LeftRG < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverRightLG = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::RightLG < >, const grammar::RightLG < > & > ( UnreachableSymbolsRemover::remove );
+auto UnreachableSymbolsRemoverRightRG = registration::AbstractRegister < UnreachableSymbolsRemover, grammar::RightRG < >, const grammar::RightRG < > & > ( UnreachableSymbolsRemover::remove );
 
 } /* namespace simplify */
 
diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
index f84329d7c2..84c2b63ca4 100644
--- a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
+++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
@@ -8,9 +8,6 @@
 #ifndef UNREACHABLE_SYMBOLS_REMOVER_H_
 #define UNREACHABLE_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>
@@ -33,10 +30,8 @@ namespace simplify {
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class UnreachableSymbolsRemover : public alib::SingleDispatch<UnreachableSymbolsRemover, grammar::Grammar, const grammar::GrammarBase &> {
+class UnreachableSymbolsRemover {
 public:
-	static grammar::Grammar remove( const grammar::Grammar & automaton );
-
 	/*
 	 * Removes unreachable symbols - Melichar 3.9
 	 */
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimize.cpp b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
index 3aeb040de1..05dc9167f2 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
@@ -12,12 +12,8 @@ namespace regexp {
 
 namespace simplify {
 
-regexp::RegExp RegExpOptimize::optimize(const regexp::RegExp& regexp) {
-	return dispatch(regexp.getData());
-}
-
-auto RegExpOptimizeFormalRegExp = registration::OverloadRegister < RegExpOptimize, FormalRegExp < >, FormalRegExp < > > ( RegExpOptimize::optimize );
-auto RegExpOptimizeUnboundedRegExp = registration::OverloadRegister < RegExpOptimize, UnboundedRegExp < >, UnboundedRegExp < > > ( RegExpOptimize::optimize );
+auto RegExpOptimizeFormalRegExp = registration::AbstractRegister < RegExpOptimize, FormalRegExp < >, const FormalRegExp < > & > ( RegExpOptimize::optimize );
+auto RegExpOptimizeUnboundedRegExp = registration::AbstractRegister < RegExpOptimize, UnboundedRegExp < >, const UnboundedRegExp < > & > ( RegExpOptimize::optimize );
 
 } /* namespace regexp */
 
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimize.h b/alib2algo/src/regexp/simplify/RegExpOptimize.h
index 69870e5f19..7853763602 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimize.h
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.h
@@ -11,11 +11,6 @@
 #include <algorithm>
 #include <functional>
 #include <iterator>
-#include <iostream>
-
-#include <core/multipleDispatch.hpp>
-
-#include <regexp/RegExp.h>
 
 #include <regexp/unbounded/UnboundedRegExp.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
@@ -65,10 +60,8 @@ namespace simplify {
  *
  *  - X1 : -> : a* + \e = a*
  */
-class RegExpOptimize : public alib::SingleDispatch<RegExpOptimize, regexp::RegExp, const regexp::RegExpBase &> {
+class RegExpOptimize {
 public:
-	static regexp::RegExp optimize( const regexp::RegExp & regexp );
-
 	template < class SymbolType >
 	static regexp::UnboundedRegExp < SymbolType > optimize( const regexp::UnboundedRegExp < SymbolType > & regexp );
 	template < class SymbolType >
diff --git a/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
index 9bdf068614..f3f71ec811 100644
--- a/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
+++ b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
@@ -21,12 +21,12 @@ void RegExpOptimizeTest::tearDown() {
 void RegExpOptimizeTest::testOptimize() {
 	{
 		std::string input = "a+a";
-		regexp::RegExp regexp = alib::StringDataFactory::fromString ( input );
+		regexp::UnboundedRegExp < > regexp = alib::StringDataFactory::fromString ( input );
 
-		regexp::RegExp res = regexp::simplify::RegExpOptimize::optimize ( regexp );
+		regexp::UnboundedRegExp < > res = regexp::simplify::RegExpOptimize::optimize ( regexp );
 
 		std::string inputRes = "a";
-		regexp::RegExp regexpRes = alib::StringDataFactory::fromString ( inputRes );
+		regexp::UnboundedRegExp < > regexpRes = alib::StringDataFactory::fromString ( inputRes );
 
 		std::cout << res << std::endl;
 		std::cout << regexpRes << std::endl;
@@ -35,12 +35,12 @@ void RegExpOptimizeTest::testOptimize() {
 	}
 	{
 		std::string input = "(a+a)b + (#0 b + (#0 a + (#0 b + a)))";
-		regexp::RegExp regexp = alib::StringDataFactory::fromString ( input );
+		regexp::UnboundedRegExp < > regexp = alib::StringDataFactory::fromString ( input );
 
-		regexp::RegExp res = regexp::simplify::RegExpOptimize::optimize ( regexp );
+		regexp::UnboundedRegExp < > res = regexp::simplify::RegExpOptimize::optimize ( regexp );
 
 		std::string inputRes = "a + a b";
-		regexp::RegExp regexpRes = alib::StringDataFactory::fromString ( inputRes );
+		regexp::UnboundedRegExp < > regexpRes = alib::StringDataFactory::fromString ( inputRes );
 
 		std::cout << res << std::endl;
 		std::cout << regexpRes << std::endl;
@@ -49,12 +49,12 @@ void RegExpOptimizeTest::testOptimize() {
 	}
 	{
 		std::string input = "a z + a b* b z";
-		regexp::RegExp regexp = alib::StringDataFactory::fromString ( input );
+		regexp::UnboundedRegExp < > regexp = alib::StringDataFactory::fromString ( input );
 
-		regexp::RegExp res = regexp::simplify::RegExpOptimize::optimize ( regexp );
+		regexp::UnboundedRegExp < > res = regexp::simplify::RegExpOptimize::optimize ( regexp );
 
 		std::string inputRes = "a b* z";
-		regexp::RegExp regexpRes = alib::StringDataFactory::fromString ( inputRes );
+		regexp::UnboundedRegExp < > regexpRes = alib::StringDataFactory::fromString ( inputRes );
 
 		std::cout << res << std::endl;
 		std::cout << regexpRes << std::endl;
diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
index 6e1b96135d..fa111b1029 100644
--- a/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/Trim.cpp
@@ -22,16 +22,12 @@ namespace simplify {
 
 namespace efficient {
 
-auto TrimDFA = registration::OverloadRegister < Trim, automaton::DFA < >, automaton::DFA < > > ( Trim::trim );
-auto TrimNFA = registration::OverloadRegister < Trim, automaton::NFA < > , automaton::NFA < > > ( Trim::trim );
-auto TrimMultiInitialStateNFA = registration::OverloadRegister < Trim, automaton::MultiInitialStateNFA < >, automaton::MultiInitialStateNFA < > > ( Trim::trim );
-auto TrimEpsilonNFA = registration::OverloadRegister < Trim, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( Trim::trim );
-auto TrimCompactNFA = registration::OverloadRegister < Trim, automaton::CompactNFA < >, automaton::CompactNFA < > > ( Trim::trim );
-auto TrimExtendedNFA = registration::OverloadRegister < Trim, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > > ( Trim::trim );
-
-automaton::Automaton Trim::trim(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
+auto TrimDFA = registration::AbstractRegister < Trim, automaton::DFA < >, const automaton::DFA < > & > ( Trim::trim );
+auto TrimNFA = registration::AbstractRegister < Trim, automaton::NFA < > , const automaton::NFA < > & > ( Trim::trim );
+auto TrimMultiInitialStateNFA = registration::AbstractRegister < Trim, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( Trim::trim );
+auto TrimEpsilonNFA = registration::AbstractRegister < Trim, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( Trim::trim );
+auto TrimCompactNFA = registration::AbstractRegister < Trim, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( Trim::trim );
+auto TrimExtendedNFA = registration::AbstractRegister < Trim, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( Trim::trim );
 
 } /* namespace efficient */
 
diff --git a/alib2elgo/src/automaton/simplify/efficient/Trim.h b/alib2elgo/src/automaton/simplify/efficient/Trim.h
index 052ef3fde7..005b7c0442 100644
--- a/alib2elgo/src/automaton/simplify/efficient/Trim.h
+++ b/alib2elgo/src/automaton/simplify/efficient/Trim.h
@@ -8,11 +8,9 @@
 #ifndef EFFICIENT_AUTOMATON_TRIM_H_
 #define EFFICIENT_AUTOMATON_TRIM_H_
 
-#include <core/multipleDispatch.hpp>
 #include <algorithm>
 #include <deque>
 #include <set>
-#include <automaton/Automaton.h>
 
 #include "UselessStatesRemover.h"
 #include "UnreachableStatesRemover.h"
@@ -23,10 +21,8 @@ namespace simplify {
 
 namespace efficient {
 
-class Trim : public alib::SingleDispatch<Trim, automaton::Automaton, const automaton::AutomatonBase &> {
+class Trim {
 public:
-	static automaton::Automaton trim( const automaton::Automaton & automaton );
-
 	/**
 	 * Removes dead states from FSM. Melichar 2.29
 	 */
diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
index 1bd3fdce8c..1d4f2abc18 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.cpp
@@ -14,16 +14,12 @@ namespace simplify {
 
 namespace efficient {
 
-auto UnreachableStatesRemoverEpsilonNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::NFA < > , automaton::NFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverCompactNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::CompactNFA < >, automaton::CompactNFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverExtendedNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverDFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::DFA < >, automaton::DFA < > > ( UnreachableStatesRemover::remove );
-auto UnreachableStatesRemoverMultiInitialStateNFA = registration::OverloadRegister < UnreachableStatesRemover, automaton::MultiInitialStateNFA < >, automaton::MultiInitialStateNFA < > > ( UnreachableStatesRemover::remove );
-
-automaton::Automaton UnreachableStatesRemover::remove(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
+auto UnreachableStatesRemoverEpsilonNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::NFA < > , const automaton::NFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverCompactNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverExtendedNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverDFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::DFA < >, const automaton::DFA < > & > ( UnreachableStatesRemover::remove );
+auto UnreachableStatesRemoverMultiInitialStateNFA = registration::AbstractRegister < UnreachableStatesRemover, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( UnreachableStatesRemover::remove );
 
 } /* namespace efficient */
 
diff --git a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h
index ae0ab845a2..c5f1f1749d 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h
+++ b/alib2elgo/src/automaton/simplify/efficient/UnreachableStatesRemover.h
@@ -8,11 +8,9 @@
 #ifndef EFFICIENT_UNREACHABLE_STATES_REMOVER_H_
 #define EFFICIENT_UNREACHABLE_STATES_REMOVER_H_
 
-#include <core/multipleDispatch.hpp>
 #include <algorithm>
 #include <deque>
 #include <set>
-#include <automaton/Automaton.h>
 
 #include <automaton/FSM/ExtendedNFA.h>
 #include <automaton/FSM/CompactNFA.h>
@@ -29,10 +27,8 @@ namespace simplify {
 
 namespace efficient {
 
-class UnreachableStatesRemover : public alib::SingleDispatch<UnreachableStatesRemover, automaton::Automaton, const automaton::AutomatonBase &> {
+class UnreachableStatesRemover {
 public:
-	static automaton::Automaton remove( const automaton::Automaton & automaton );
-
 	/**
 	 * Removes dead states from FSM. Melichar 2.29
 	 */
diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
index 628f64a9a6..c221f05cc9 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
+++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.cpp
@@ -14,16 +14,12 @@ namespace simplify {
 
 namespace efficient {
 
-auto UselessStatesRemoverEpsilonNFA = registration::OverloadRegister < UselessStatesRemover, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverNFA = registration::OverloadRegister < UselessStatesRemover, automaton::NFA < > , automaton::NFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverCompactNFA = registration::OverloadRegister < UselessStatesRemover, automaton::CompactNFA < >, automaton::CompactNFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverExtendedNFA = registration::OverloadRegister < UselessStatesRemover, automaton::ExtendedNFA < >, automaton::ExtendedNFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverDFA = registration::OverloadRegister < UselessStatesRemover, automaton::DFA < >, automaton::DFA < > > ( UselessStatesRemover::remove );
-auto UselessStatesRemoverMultiInitialStateNFA = registration::OverloadRegister < UselessStatesRemover, automaton::MultiInitialStateNFA < >, automaton::MultiInitialStateNFA < > > ( UselessStatesRemover::remove );
-
-automaton::Automaton UselessStatesRemover::remove(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
+auto UselessStatesRemoverEpsilonNFA = registration::AbstractRegister < UselessStatesRemover, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverNFA = registration::AbstractRegister < UselessStatesRemover, automaton::NFA < > , const automaton::NFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverCompactNFA = registration::AbstractRegister < UselessStatesRemover, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverExtendedNFA = registration::AbstractRegister < UselessStatesRemover, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverDFA = registration::AbstractRegister < UselessStatesRemover, automaton::DFA < >, const automaton::DFA < > & > ( UselessStatesRemover::remove );
+auto UselessStatesRemoverMultiInitialStateNFA = registration::AbstractRegister < UselessStatesRemover, automaton::MultiInitialStateNFA < >, const automaton::MultiInitialStateNFA < > & > ( UselessStatesRemover::remove );
 
 } /* namespace efficient */
 
diff --git a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h
index 28f1e36f3c..e8eb8b1aa0 100644
--- a/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h
+++ b/alib2elgo/src/automaton/simplify/efficient/UselessStatesRemover.h
@@ -8,7 +8,6 @@
 #ifndef EFFICIENT_USELESS_STATES_REMOVER_H_
 #define EFFICIENT_USELESS_STATES_REMOVER_H_
 
-#include <core/multipleDispatch.hpp>
 #include <algorithm>
 #include <deque>
 #include <set>
@@ -22,18 +21,14 @@
 
 #include "../../properties/efficient/UsefullStates.h"
 
-#include "automaton/Automaton.h"
-
 namespace automaton {
 
 namespace simplify {
 
 namespace efficient {
 
-class UselessStatesRemover : public alib::SingleDispatch<UselessStatesRemover, automaton::Automaton, const automaton::AutomatonBase &> {
+class UselessStatesRemover {
 public:
-	static automaton::Automaton remove( const automaton::Automaton & automaton );
-
 	/**
 	 * Removes dead states from FSM. Melichar 2.29
 	 */
diff --git a/atrim2/makefile.conf b/atrim2/makefile.conf
index f50d679ed7..6874155da5 100644
--- a/atrim2/makefile.conf
+++ b/atrim2/makefile.conf
@@ -1,4 +1,4 @@
 EXECUTABLE:=atrim2
-LINK_PATHS=../alib2elgo/ ../alib2algo/ ../alib2data/ ../alib2common/ ../alib2std/
-LINK_LIBRARIES=alib2elgo alib2algo alib2data alib2common alib2std xml2
-INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2elgo/src/ \$$(SOURCES_BASE_DIR)/../../alib2algo/src/ \$$(SOURCES_BASE_DIR)/../../alib2data/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/
+LINK_PATHS=../alib2cli/ ../alib2elgo/ ../alib2algo/ ../alib2data/ ../alib2common/ ../alib2std/
+LINK_LIBRARIES=alib2cli alib2elgo alib2algo alib2data alib2common alib2std xml2
+INCLUDE_PATHS=\$$(SOURCES_BASE_DIR)/../../alib2cli/src/ \$$(SOURCES_BASE_DIR)/../../alib2common/src/ \$$(SOURCES_BASE_DIR)/../../alib2std/src/ /usr/include/libxml2/
diff --git a/atrim2/src/atrim.cpp b/atrim2/src/atrim.cpp
index fa2f079669..b35527c1b0 100644
--- a/atrim2/src/atrim.cpp
+++ b/atrim2/src/atrim.cpp
@@ -8,54 +8,43 @@
 #include <tclap/CmdLine.h>
 #include <global/GlobalData.h>
 #include <measure>
-#include <sax/FromXMLParserHelper.h>
 
-#include <factory/XmlDataFactory.hpp>
 #include <exception/CommonException.h>
+#include <lexer/Lexer.h>
+#include <parser/Parser.h>
 
-#include "grammar/simplify/Trim.h"
-#include "grammar/simplify/UnproductiveSymbolsRemover.h"
-#include "grammar/simplify/UnreachableSymbolsRemover.h"
-#include "automaton/simplify/Trim.h"
-#include "automaton/simplify/efficient/Trim.h"
-#include "automaton/simplify/UselessStatesRemover.h"
-#include "automaton/simplify/efficient/UselessStatesRemover.h"
-#include "automaton/simplify/UnreachableStatesRemover.h"
-#include "automaton/simplify/efficient/UnreachableStatesRemover.h"
-#include "regexp/simplify/RegExpOptimize.h"
-
-grammar::Grammar trimGrammar(const grammar::Grammar& g, bool del_unreachable, bool del_unproductive) {
+std::string trimGrammar ( bool del_unreachable, bool del_unproductive ) {
 	if( del_unreachable && del_unproductive )
-		return grammar::simplify::Trim::trim( g );
+		return "execute grammar::simplify::Trim $input > $output";
 	if( del_unreachable )
-		return grammar::simplify::UnreachableSymbolsRemover::remove( g );
+		return "execute grammar::simplify::UnreachableSymbolsRemover $input > $output";
 	if( del_unproductive )
-		return grammar::simplify::UnproductiveSymbolsRemover::remove( g );
-	return grammar::simplify::Trim::trim( g );
+		return "execute grammar::simplify::UnproductiveSymbolsRemover $input > $output";
+	return "execute grammar::simplify::Trim $input > $output";
 }
 
-automaton::Automaton trimAutomaton(const automaton::Automaton& g, bool del_unreachable, bool del_useless) {
+std::string trimAutomaton ( bool del_unreachable, bool del_useless ) {
 	if( del_unreachable && del_useless )
-		return automaton::simplify::Trim::trim( g );
+		return "execute automaton::simplify::Trim $input > $output";
 	if( del_unreachable )
-		return automaton::simplify::UnreachableStatesRemover::remove( g );
+		return "execute automaton::simplify::UnreachableStatesRemover $input > $output";
 	if( del_useless )
-		return automaton::simplify::UselessStatesRemover::remove( g );
-	return automaton::simplify::Trim::trim( g );
+		return "execute automaton::simplify::UselessStatesRemover $input > $output";
+	return "execute automaton::simplify::Trim $input > $output";
 }
 
-automaton::Automaton efficientTrimAutomaton(const automaton::Automaton& g, bool del_unreachable, bool del_useless) {
+std::string efficientTrimAutomaton ( bool del_unreachable, bool del_useless ) {
 	if( del_unreachable && del_useless )
-		return automaton::simplify::efficient::Trim::trim( g );
+		return "execute automaton::simplify::efficient::Trim $input > $output";
 	if( del_unreachable )
-		return automaton::simplify::efficient::UnreachableStatesRemover::remove( g );
+		return "execute automaton::simplify::efficient::UnreachableStatesRemover $input > $output";
 	if( del_useless )
-		return automaton::simplify::efficient::UselessStatesRemover::remove( g );
-	return automaton::simplify::efficient::Trim::trim( g );
+		return "execute automaton::simplify::efficient::UselessStatesRemover $input > $output";
+	return "execute automaton::simplify::efficient::Trim $input > $output";
 }
 
-regexp::RegExp optimizeRegExp(const regexp::RegExp& r) {
-	return regexp::simplify::RegExpOptimize::optimize( r );
+std::string optimizeRegExp ( ) {
+	return "execute regexp::simplify::RegExpOptimize $input > $output";
 }
 
 int main(int argc, char* argv[]) {
@@ -93,59 +82,45 @@ int main(int argc, char* argv[]) {
 		if(measure.isSet())
 			common::GlobalData::measure = true;
 
+		cli::Environment environment;
+		environment.setBinding ( "stdin", input.getValue ( ) );
+		environment.setBinding ( "stdout", "-" );
+
 		measurements::start("Overal", measurements::Type::OVERALL);
 		measurements::start("Input read", measurements::Type::AUXILIARY);
 
-		ext::deque<sax::Token> tokens = sax::FromXMLParserHelper::parseInput(input);
+		cli::Parser parser ( cli::Lexer ( "execute <#stdin > $input" ) );
+		parser.parse ( )->run ( environment );
 
-		if( alib::XmlDataFactory::first<automaton::Automaton>(tokens)) {
-			automaton::Automaton automaton = alib::XmlDataFactory::fromTokens (std::move(tokens));
+//		parser = cli::Parser ( cli::Lexer ( "export type = typename ( $input )" ) );
+		std::string inputType = environment.getVariable ( "input" )->getReturnType ( );
+		bool isAutomaton = inputType.find ( "automaton::" ) == 0;
+		bool isGrammar = inputType.find ( "grammar::" ) == 0;
+		bool isRegExp = inputType.find ( "regexp::" ) == 0;
 
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
+		measurements::end();
+		measurements::start("Algorithm", measurements::Type::MAIN);
 
+		if( isAutomaton ) {
 			if(efficient.getValue()) {
-				automaton::Automaton res = efficientTrimAutomaton(automaton, unreachable.getValue(), useless.getValue() );
-
-				measurements::end();
-				measurements::start("Output write", measurements::Type::AUXILIARY);
-
-				alib::XmlDataFactory::toStdout( res );
+				parser = cli::Parser ( cli::Lexer ( efficientTrimAutomaton ( unreachable.getValue(), useless.getValue() ) ) );
 			} else {
-				automaton::Automaton res = trimAutomaton(automaton, unreachable.getValue(), useless.getValue() );
-
-				measurements::end();
-				measurements::start("Output write", measurements::Type::AUXILIARY);
-
-				alib::XmlDataFactory::toStdout( res );
+				parser = cli::Parser ( cli::Lexer ( trimAutomaton ( unreachable.getValue(), useless.getValue() ) ) );
 			}
-		} else if( alib::XmlDataFactory::first<grammar::Grammar>(tokens)) {
-			grammar::Grammar grammar = alib::XmlDataFactory::fromTokens (std::move(tokens));
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			grammar::Grammar res = trimGrammar(grammar, unreachable.getValue(), useless.getValue() );
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
-		} else if( alib::XmlDataFactory::first<regexp::RegExp>(tokens)) {
-			regexp::RegExp regexp = alib::XmlDataFactory::fromTokens (std::move(tokens));
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			regexp::RegExp res = optimizeRegExp( regexp );
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
+		} else if( isGrammar ) {
+			parser = cli::Parser ( cli::Lexer ( trimGrammar ( unreachable.getValue(), useless.getValue() ) ) );
+		} else if( isRegExp ) {
+			parser = cli::Parser ( cli::Lexer ( optimizeRegExp ( ) ) );
 		} else {
 			throw exception::CommonException( "Input not recognized." );
 		}
+		parser.parse ( )->run ( environment );
+
+		measurements::end();
+		measurements::start("Output write", measurements::Type::AUXILIARY);
+
+		parser = cli::Parser ( cli::Lexer ( "execute $output >#stdout" ) );
+		parser.parse ( )->run ( environment );
 
 		measurements::end();
 		measurements::end();
-- 
GitLab