diff --git a/alangop2/makefile.conf b/alangop2/makefile.conf
index 144609c1426593c747228f3b72444248d0ac4970..abc88450c8edf2ba6488a16f6e542dac04bdc27d 100644
--- a/alangop2/makefile.conf
+++ b/alangop2/makefile.conf
@@ -1,4 +1,4 @@
 EXECUTABLE:=alangop2
-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/alangop2/src/alangop.cpp b/alangop2/src/alangop.cpp
index c7be76a61f9965c1e6bbcf3d0193a379e14bdbfe..1d4fb28510e2ad4148a626d9b718bfea35b8df3a 100644
--- a/alangop2/src/alangop.cpp
+++ b/alangop2/src/alangop.cpp
@@ -8,21 +8,10 @@
 #include <tclap/CmdLine.h>
 #include <global/GlobalData.h>
 #include <measure>
-#include <vector>
-#include <sax/FromXMLParserHelper.h>
 
-#include <factory/XmlDataFactory.hpp>
 #include <exception/CommonException.h>
-#include <automaton/Automaton.h>
-
-#include <automaton/transform/AutomataConcatenationEpsilonTransition.h>
-#include <automaton/transform/AutomataConcatenation.h>
-#include <automaton/transform/AutomataIntersectionCartesianProduct.h>
-#include <automaton/transform/AutomataUnionCartesianProduct.h>
-#include <automaton/transform/AutomataUnionEpsilonTransition.h>
-#include <automaton/transform/AutomatonIterationEpsilonTransition.h>
-#include <automaton/transform/AutomatonIteration.h>
-
+#include <lexer/Lexer.h>
+#include <parser/Parser.h>
 
 int main(int argc, char* argv[]) {
 	try {
@@ -44,10 +33,10 @@ int main(int argc, char* argv[]) {
 		TCLAP::ValueArg<std::string> algorithm(	"a",	"algorithm",	"Execute algorithm", true,	"",	&allowedVals);
 		cmd.add(algorithm);
 
-		TCLAP::ValueArg<std::string> a1(	"i",	"input1",	"First automaton",	false,	"-",	"file");
-		TCLAP::ValueArg<std::string> a2(	"j",	"input2",	"Second automaton",	false,	"-",	"file");
-		cmd.add( a1 );
-		cmd.add( a2 );
+		TCLAP::ValueArg<std::string> input1(	"i",	"input1",	"First automaton",	false,	"-",	"file");
+		TCLAP::ValueArg<std::string> input2(	"j",	"input2",	"Second automaton",	false,	"-",	"file");
+		cmd.add( input1 );
+		cmd.add( input2 );
 
 		TCLAP::SwitchArg measure(		"m",	"measure",	"Measure times",		false);
 		cmd.add( measure );
@@ -62,97 +51,49 @@ int main(int argc, char* argv[]) {
 		if(measure.isSet())
 			common::GlobalData::measure = true;
 
+		cli::Environment environment;
+		environment.setBinding ( "input1", input1.getValue ( ) );
+		environment.setBinding ( "input2", input2.getValue ( ) );
+		environment.setBinding ( "stdout", "-" );
+
 		measurements::start("Overal", measurements::Type::OVERALL);
 		measurements::start("Input read", measurements::Type::AUXILIARY);
 
-		automaton::Automaton automaton1 = alib::XmlDataFactory::fromTokens (sax::FromXMLParserHelper::parseInput(a1));
-
-		if( algorithm.getValue() == "unionEpsilon") {
-			automaton::Automaton automaton2 = alib::XmlDataFactory::fromTokens (sax::FromXMLParserHelper::parseInput(a1));
+		cli::Parser parser ( cli::Lexer ( "execute <#input1 > $language1" ) );
+		parser.parse ( )->run ( environment );
 
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			automaton::Automaton res = automaton::transform::AutomataUnionEpsilonTransition::unification(automaton1, automaton2);
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
+		if ( algorithm.getValue ( ) == "unionEpsilon" || algorithm.getValue ( ) == "unionCartesian" || algorithm.getValue ( ) == "concatenationEpsilon" || algorithm.getValue ( ) == "concatenation" || algorithm.getValue ( ) == "intersectionCartesian") {
+			parser = cli::Parser ( cli::Lexer ( "execute <#input2 > $language2" ) );
+			parser.parse ( )->run ( environment );
+		}
 
-			alib::XmlDataFactory::toStdout( res );
+		measurements::end();
+		measurements::start("Algorithm", measurements::Type::MAIN);
 
+		if( algorithm.getValue() == "unionEpsilon") {
+			parser = cli::Parser ( cli::Lexer ( "execute automaton::transform::AutomataUnionEpsilonTransition $language1 $language2 > $output" ) );
 		} else if( algorithm.getValue() == "unionCartesian") {
-			automaton::Automaton automaton2 = alib::XmlDataFactory::fromTokens (sax::FromXMLParserHelper::parseInput(a1));
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			automaton::Automaton res = automaton::transform::AutomataUnionCartesianProduct::unification(automaton1, automaton2);
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
+			parser = cli::Parser ( cli::Lexer ( "execute automaton::transform::AutomataUnionCartesianProduct $language1 $language2 > $output" ) );
 		} else if( algorithm.getValue() == "concatenationEpsilon") {
-			automaton::Automaton automaton2 = alib::XmlDataFactory::fromTokens (sax::FromXMLParserHelper::parseInput(a1));
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			automaton::Automaton res = automaton::transform::AutomataConcatenationEpsilonTransition::concatenation(automaton1, automaton2);
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
+			parser = cli::Parser ( cli::Lexer ( "execute automaton::transform::AutomataConcatenationEpsilonTransition $language1 $language2 > $output" ) );
 		} else if( algorithm.getValue() == "concatenation") {
-			automaton::Automaton automaton2 = alib::XmlDataFactory::fromTokens (sax::FromXMLParserHelper::parseInput(a1));
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			automaton::Automaton res = automaton::transform::AutomataConcatenation::concatenation(automaton1, automaton2);
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
+			parser = cli::Parser ( cli::Lexer ( "execute automaton::transform::AutomataConcatenation $language1 $language2 > $output" ) );
 		} else if( algorithm.getValue() == "intersectionCartesian") {
-			automaton::Automaton automaton2 = alib::XmlDataFactory::fromTokens (sax::FromXMLParserHelper::parseInput(a1));
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			automaton::Automaton res = automaton::transform::AutomataIntersectionCartesianProduct::intersection(automaton1, automaton2);
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
+			parser = cli::Parser ( cli::Lexer ( "execute automaton::transform::AutomataIntersectionCartesianProduct $language1 $language2 > $output" ) );
 		} else if( algorithm.getValue() == "iteration") {
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			automaton::Automaton res = automaton::transform::AutomatonIteration::iteration(automaton1);
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
+			parser = cli::Parser ( cli::Lexer ( "execute automaton::transform::AutomatonIteration $language1 > $output" ) );
 		} else if( algorithm.getValue() == "iterationEpsilon") {
-
-			measurements::end();
-			measurements::start("Algorithm", measurements::Type::MAIN);
-
-			automaton::Automaton res = automaton::transform::AutomatonIterationEpsilonTransition::iteration(automaton1);
-
-			measurements::end();
-			measurements::start("Output write", measurements::Type::AUXILIARY);
-
-			alib::XmlDataFactory::toStdout( res );
+			parser = cli::Parser ( cli::Lexer ( "execute automaton::transform::AutomatonIterationEpsilonTransition $language1 > $output" ) );
 		} else {
 			throw exception::CommonException( "Invalid algorithm" );
 		}
+		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();
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
index 717c049033d199c18d535ffe0c43829718aa4748..8adaade50cf44daafb3fe0a8f6af6e476e8b6452 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
+++ b/alib2algo/src/automaton/transform/AutomataConcatenation.cpp
@@ -12,15 +12,8 @@ namespace automaton {
 
 namespace transform {
 
-automaton::Automaton AutomataConcatenation::concatenation(const automaton::Automaton& first, const automaton::Automaton& second) {
-	return dispatch(first.getData(), second.getData());
-}
-
-auto AutomataConcatenationNFA = registration::OverloadRegister < AutomataConcatenation, automaton::NFA < >, automaton::NFA < > > ( AutomataConcatenation::concatenation );
-auto AutomataConcatenationDFA = registration::OverloadRegister < AutomataConcatenation, automaton::NFA < >, automaton::DFA < > > ( AutomataConcatenation::concatenation );
-
-auto AutomataConcatenationNFA2 = registration::AbstractRegister < AutomataConcatenation, automaton::NFA < >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataConcatenation::concatenation );
-auto AutomataConcatenationDFA2 = registration::AbstractRegister < AutomataConcatenation, automaton::NFA < >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataConcatenation::concatenation );
+auto AutomataConcatenationNFA = registration::AbstractRegister < AutomataConcatenation, automaton::NFA < >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataConcatenation::concatenation );
+auto AutomataConcatenationDFA = registration::AbstractRegister < AutomataConcatenation, automaton::NFA < >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataConcatenation::concatenation );
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenation.h b/alib2algo/src/automaton/transform/AutomataConcatenation.h
index 48214980cfce8a005e408b82d35c0cc58a7f2569..94ba4ac7d122d4489ce54e0fed9483cb8941ee93 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenation.h
+++ b/alib2algo/src/automaton/transform/AutomataConcatenation.h
@@ -8,8 +8,6 @@
 #ifndef AUTOMATA_CONCATENATION_H_
 #define AUTOMATA_CONCATENATION_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
 namespace automaton {
@@ -20,10 +18,8 @@ namespace transform {
  * Concatenates two automata.
  *  - For finite automata A1, A2, we create automaton L accepting L(A1).L(A2) (Melichar, 2.78)
  */
-class AutomataConcatenation : public alib::PromotingDoubleDispatch<AutomataConcatenation, automaton::Automaton, const automaton::AutomatonBase &> {
+class AutomataConcatenation {
 public:
-	static automaton::Automaton concatenation(const automaton::Automaton& first, const automaton::Automaton& second);
-
 	template < class SymbolType, class StateType >
 	static automaton::NFA < SymbolType, StateType > concatenation(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second);
 	template < class SymbolType, class StateType >
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
index 9db6deb0386b1b6fe76844aac7bc82c30bae6640..f22eb6cce8d19c4cb3b61d26a750713dc32080a7 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.cpp
@@ -13,17 +13,9 @@ namespace automaton {
 
 namespace transform {
 
-automaton::Automaton AutomataConcatenationEpsilonTransition::concatenation(const automaton::Automaton& first, const automaton::Automaton& second) {
-	return dispatch(first.getData(), second.getData());
-}
-
-auto AutomataConcatenationEpsilonTransitionDFA = registration::OverloadRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, automaton::DFA < > > ( AutomataConcatenationEpsilonTransition::concatenation );
-auto AutomataConcatenationEpsilonTransitionNFA = registration::OverloadRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, automaton::NFA < > > ( AutomataConcatenationEpsilonTransition::concatenation );
-auto AutomataConcatenationEpsilonTransitionEpsilonNFA = registration::OverloadRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < > , automaton::EpsilonNFA < > > ( AutomataConcatenationEpsilonTransition::concatenation );
-
-auto AutomataConcatenationEpsilonTransitionDFA2 = registration::AbstractRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataConcatenationEpsilonTransition::concatenation );
-auto AutomataConcatenationEpsilonTransitionNFA2 = registration::AbstractRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataConcatenationEpsilonTransition::concatenation );
-auto AutomataConcatenationEpsilonTransitionEpsilonNFA2 = registration::AbstractRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > &, const automaton::EpsilonNFA < > & > ( AutomataConcatenationEpsilonTransition::concatenation );
+auto AutomataConcatenationEpsilonTransitionDFA = registration::AbstractRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataConcatenationEpsilonTransition::concatenation );
+auto AutomataConcatenationEpsilonTransitionNFA = registration::AbstractRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataConcatenationEpsilonTransition::concatenation );
+auto AutomataConcatenationEpsilonTransitionEpsilonNFA = registration::AbstractRegister < AutomataConcatenationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > &, const automaton::EpsilonNFA < > & > ( AutomataConcatenationEpsilonTransition::concatenation );
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
index 064f1f1a6f0f18a77f0b96fe2be22cb1732ee728..021d08c654b0b5cc07e303d3d44a7cbbed75f146 100644
--- a/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
+++ b/alib2algo/src/automaton/transform/AutomataConcatenationEpsilonTransition.h
@@ -8,8 +8,6 @@
 #ifndef AUTOMATA_CONCATENATION_EPSILON_TRANSITION_H_
 #define AUTOMATA_CONCATENATION_EPSILON_TRANSITION_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
 namespace automaton {
@@ -20,10 +18,8 @@ namespace transform {
  * Concatenates two automata.
  *  - For finite automata A1, A2, we create automaton L accepting L(A1).L(A2)
  */
-class AutomataConcatenationEpsilonTransition : public alib::PromotingDoubleDispatch<AutomataConcatenationEpsilonTransition, automaton::Automaton, const automaton::AutomatonBase &> {
+class AutomataConcatenationEpsilonTransition {
 public:
-	static automaton::Automaton concatenation(const automaton::Automaton& first, const automaton::Automaton& second);
-
 	template < class SymbolType, class EpsilonType = DefaultEpsilonType, class StateType >
 	static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > concatenation(const automaton::DFA < SymbolType, StateType > & first, const automaton::DFA < SymbolType, StateType > & second);
 	template < class SymbolType, class EpsilonType = DefaultEpsilonType, class StateType >
diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
index 53f31ce891f7ac4adca96fb22f0496984cbdb445..ff3718482e31ce1d3886a278d06213832912eb34 100644
--- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
+++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.cpp
@@ -13,15 +13,6 @@ namespace automaton {
 
 namespace transform {
 
-automaton::Automaton AutomataIntersectionCartesianProduct::intersection(const automaton::Automaton& first, const automaton::Automaton& second) {
-	automaton::Automaton res = dispatch(first.getData(), second.getData());
-	res.normalize ( );
-	return res;
-}
-
-auto AutomataIntersectionCartesianProductDFA = registration::OverloadRegister < AutomataIntersectionCartesianProduct, automaton::DFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, automaton::DFA < > > ( AutomataIntersectionCartesianProduct::intersection );
-auto AutomataIntersectionCartesianProductNFA = registration::OverloadRegister < AutomataIntersectionCartesianProduct, automaton::NFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, automaton::NFA < > > ( AutomataIntersectionCartesianProduct::intersection );
-
 auto AutomataIntersectionCartesianProductNFA2 = registration::AbstractRegister < AutomataIntersectionCartesianProduct, automaton::NFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataIntersectionCartesianProduct::intersection );
 auto AutomataIntersectionCartesianProductDFA2 = registration::AbstractRegister < AutomataIntersectionCartesianProduct, automaton::DFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataIntersectionCartesianProduct::intersection );
 
diff --git a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
index b3b607811c39db1ca4cf1f71a437c7f94c4abd48..cfb284245c84573c61c338ecc7488fa48b612c27 100644
--- a/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
+++ b/alib2algo/src/automaton/transform/AutomataIntersectionCartesianProduct.h
@@ -8,8 +8,6 @@
 #ifndef AUTOMATA_INTERSECTION_CARTESIAN_H_
 #define AUTOMATA_INTERSECTION_CARTESIAN_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
 namespace automaton {
@@ -20,10 +18,8 @@ namespace transform {
  * Intersection of two automata.
  *  - For finite automata A1, A2, we create automaton L accepting L(A1) \cap L(A2) (Melichar, 2.75)
  */
-class AutomataIntersectionCartesianProduct : public alib::PromotingDoubleDispatch<AutomataIntersectionCartesianProduct, automaton::Automaton, const automaton::AutomatonBase &> {
+class AutomataIntersectionCartesianProduct {
 public:
-	static automaton::Automaton intersection(const automaton::Automaton& first, const automaton::Automaton& second);
-
 	template < class SymbolType, class StateType1, class StateType2 >
 	static automaton::NFA < SymbolType, ext::pair < StateType1, StateType2 > > intersection(const automaton::NFA < SymbolType, StateType1 > & first, const automaton::NFA < SymbolType, StateType2 > & second);
 	template < class SymbolType, class StateType1, class StateType2 >
diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
index 1fce47fa800c85a7a95166f45f9aa739c0a770b7..cb4867b515a83b62d8d99a374a78a3ea354caa63 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
+++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.cpp
@@ -14,17 +14,8 @@ namespace automaton {
 
 namespace transform {
 
-automaton::Automaton AutomataUnionCartesianProduct::unification(const automaton::Automaton& first, const automaton::Automaton& second) {
-	automaton::Automaton res = dispatch(first.getData(), second.getData());
-	res.normalize ( );
-	return res;
-}
-
-auto AutomataUnionCartesianProductDFA = registration::OverloadRegister < AutomataUnionCartesianProduct, automaton::DFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, automaton::DFA < > > ( AutomataUnionCartesianProduct::unification );
-auto AutomataUnionCartesianProductNFA = registration::OverloadRegister < AutomataUnionCartesianProduct, automaton::NFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, automaton::NFA < > > ( AutomataUnionCartesianProduct::unification );
-
-auto AutomataUnionCartesianProductDFA2 = registration::AbstractRegister < AutomataUnionCartesianProduct, automaton::DFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataUnionCartesianProduct::unification );
-auto AutomataUnionCartesianProductNFA2 = registration::AbstractRegister < AutomataUnionCartesianProduct, automaton::NFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataUnionCartesianProduct::unification );
+auto AutomataUnionCartesianProductDFA = registration::AbstractRegister < AutomataUnionCartesianProduct, automaton::DFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataUnionCartesianProduct::unification );
+auto AutomataUnionCartesianProductNFA = registration::AbstractRegister < AutomataUnionCartesianProduct, automaton::NFA < DefaultSymbolType, ext::pair < DefaultStateType, DefaultStateType > >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataUnionCartesianProduct::unification );
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
index a5d44f87d82e0a857b937adc719ad9d78d273587..58c3748c2f29f80db5918970f6a6472ed0ad2725 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
+++ b/alib2algo/src/automaton/transform/AutomataUnionCartesianProduct.h
@@ -8,8 +8,6 @@
 #ifndef AUTOMATA_UNION_CARTESIAN_H_
 #define AUTOMATA_UNION_CARTESIAN_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
 namespace automaton {
@@ -20,10 +18,8 @@ namespace transform {
  * Union two automata.
  *  - For finite automata A1, A2, we create automaton L accepting L(A1) \cup L(A2) (Melichar, 2.71)
  */
-class AutomataUnionCartesianProduct : public alib::PromotingDoubleDispatch<AutomataUnionCartesianProduct, automaton::Automaton, const automaton::AutomatonBase &> {
+class AutomataUnionCartesianProduct {
 public:
-	static automaton::Automaton unification(const automaton::Automaton& first, const automaton::Automaton& second);
-
 	template < class SymbolType, class StateType1, class StateType2 >
 	static automaton::NFA < SymbolType, ext::pair < StateType1, StateType2 > > unification(const automaton::NFA < SymbolType, StateType1 > & first, const automaton::NFA < SymbolType, StateType2 > & second);
 	template < class SymbolType, class StateType1, class StateType2 >
diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
index fd40de5ac4dfcc7b09b8c2ead3241ef4c73272f1..2949b9f3d45bc1b94bbb900da4ac63b2961cd69b 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.cpp
@@ -14,14 +14,6 @@ namespace automaton {
 
 namespace transform {
 
-automaton::Automaton AutomataUnionEpsilonTransition::unification(const automaton::Automaton& first, const automaton::Automaton& second) {
-	return dispatch(first.getData(), second.getData());
-}
-
-auto AutomataUnionEpsilonTransitionEpsilonNFA = registration::OverloadRegister < AutomataUnionEpsilonTransition, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( AutomataUnionEpsilonTransition::unification );
-auto AutomataUnionEpsilonTransitionNFA = registration::OverloadRegister < AutomataUnionEpsilonTransition, automaton::EpsilonNFA < >, automaton::NFA < > > ( AutomataUnionEpsilonTransition::unification );
-auto AutomataUnionEpsilonTransitionDFA = registration::OverloadRegister < AutomataUnionEpsilonTransition, automaton::EpsilonNFA < >, automaton::DFA < > > ( AutomataUnionEpsilonTransition::unification );
-
 auto AutomataUnionEpsilonTransitionEpsilonNFA2 = registration::AbstractRegister < AutomataUnionEpsilonTransition, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > &, const automaton::EpsilonNFA < > & > ( AutomataUnionEpsilonTransition::unification );
 auto AutomataUnionEpsilonTransitionNFA2 = registration::AbstractRegister < AutomataUnionEpsilonTransition, automaton::EpsilonNFA < >, const automaton::NFA < > &, const automaton::NFA < > & > ( AutomataUnionEpsilonTransition::unification );
 auto AutomataUnionEpsilonTransitionDFA2 = registration::AbstractRegister < AutomataUnionEpsilonTransition, automaton::EpsilonNFA < >, const automaton::DFA < > &, const automaton::DFA < > & > ( AutomataUnionEpsilonTransition::unification );
diff --git a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
index ab136e7d7ca5c2ff0df4ca68294952df9ac1df10..df6430f31b7df35b2ea3120ce020a4f337ca175a 100644
--- a/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
+++ b/alib2algo/src/automaton/transform/AutomataUnionEpsilonTransition.h
@@ -8,8 +8,6 @@
 #ifndef AUTOMATA_UNION_EPSILON_H_
 #define AUTOMATA_UNION_EPSILON_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
 namespace automaton {
@@ -20,10 +18,8 @@ namespace transform {
  * Union two automata.
  *  - For finite automata A1, A2, we create automaton L accepting L(A1) \cup L(A2)
  */
-class AutomataUnionEpsilonTransition : public alib::PromotingDoubleDispatch<AutomataUnionEpsilonTransition, automaton::Automaton, const automaton::AutomatonBase &> {
+class AutomataUnionEpsilonTransition {
 public:
-	static automaton::Automaton unification(const automaton::Automaton& first, const automaton::Automaton& second);
-
 	template < class SymbolType, class EpsilonType, class StateType >
 	static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > unification(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & first, const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & second);
 	template < class SymbolType, class EpsilonType = DefaultEpsilonType, class StateType >
diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.cpp b/alib2algo/src/automaton/transform/AutomatonIteration.cpp
index 9302a6ebeb9657a43df7f12f650d9282f669d260..e4aac4b0b4cf63c786bd148f0bf11416182b3c36 100644
--- a/alib2algo/src/automaton/transform/AutomatonIteration.cpp
+++ b/alib2algo/src/automaton/transform/AutomatonIteration.cpp
@@ -13,15 +13,8 @@ namespace automaton {
 
 namespace transform {
 
-automaton::Automaton AutomatonIteration::iteration(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
-
-auto AutomatonIterationDFA = registration::OverloadRegister < AutomatonIteration, automaton::NFA < >, automaton::DFA < > > ( AutomatonIteration::iteration );
-auto AutomatonIterationNFA = registration::OverloadRegister < AutomatonIteration, automaton::NFA < >, automaton::NFA < > > ( AutomatonIteration::iteration );
-
-auto AutomatonIterationDFA2 = registration::AbstractRegister < AutomatonIteration, automaton::NFA < >, const automaton::DFA < > & > ( AutomatonIteration::iteration );
-auto AutomatonIterationNFA2 = registration::AbstractRegister < AutomatonIteration, automaton::NFA < >, const automaton::NFA < > & > ( AutomatonIteration::iteration );
+auto AutomatonIterationDFA = registration::AbstractRegister < AutomatonIteration, automaton::NFA < >, const automaton::DFA < > & > ( AutomatonIteration::iteration );
+auto AutomatonIterationNFA = registration::AbstractRegister < AutomatonIteration, automaton::NFA < >, const automaton::NFA < > & > ( AutomatonIteration::iteration );
 
 } /* namespace transform */
 
diff --git a/alib2algo/src/automaton/transform/AutomatonIteration.h b/alib2algo/src/automaton/transform/AutomatonIteration.h
index a2cfae3f17db1f2a0eadbf15327e709625ba594e..a60ece9fc89e8e861d992d7e4154aa5f9b2615c4 100644
--- a/alib2algo/src/automaton/transform/AutomatonIteration.h
+++ b/alib2algo/src/automaton/transform/AutomatonIteration.h
@@ -8,8 +8,6 @@
 #ifndef AUTOMATON_ITERATION_H_
 #define AUTOMATON_ITERATION_H_
 
-#include <core/multipleDispatch.hpp>
-#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
 namespace automaton {
@@ -20,10 +18,8 @@ namespace transform {
  * Iterates language given by automaton
  *  - For finite automaton A1, we create automaton L accepting L(A1)*
  */
-class AutomatonIteration : public alib::SingleDispatch<AutomatonIteration, automaton::Automaton, const automaton::AutomatonBase &> {
+class AutomatonIteration {
 public:
-	static automaton::Automaton iteration(const automaton::Automaton& automaton);
-
 	template < class SymbolType, class StateType >
 	static automaton::NFA < SymbolType, StateType > iteration(const automaton::DFA < SymbolType, StateType > & automaton);
 	template < class SymbolType, class StateType >
diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
index e93114f260022087348c4efc7bc3fd151ce2eff2..f91ee52d028cb932bb5760c0dc783946decb533b 100644
--- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
+++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.cpp
@@ -13,14 +13,6 @@ namespace automaton {
 
 namespace transform {
 
-automaton::Automaton AutomatonIterationEpsilonTransition::iteration(const automaton::Automaton& automaton) {
-	return dispatch(automaton.getData());
-}
-
-auto AutomatonIterationEpsilonTransitionDFA = registration::OverloadRegister < AutomatonIterationEpsilonTransition, automaton::EpsilonNFA < >, automaton::DFA < > > ( AutomatonIterationEpsilonTransition::iteration );
-auto AutomatonIterationEpsilonTransitionNFA = registration::OverloadRegister < AutomatonIterationEpsilonTransition, automaton::EpsilonNFA < >, automaton::NFA < > > ( AutomatonIterationEpsilonTransition::iteration );
-auto AutomatonIterationEpsilonTransitionEpsilonNFA = registration::OverloadRegister < AutomatonIterationEpsilonTransition, automaton::EpsilonNFA < >, automaton::EpsilonNFA < > > ( AutomatonIterationEpsilonTransition::iteration );
-
 auto AutomatonIterationEpsilonTransitionDFA2 = registration::AbstractRegister < AutomatonIterationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::DFA < > & > ( AutomatonIterationEpsilonTransition::iteration );
 auto AutomatonIterationEpsilonTransitionNFA2 = registration::AbstractRegister < AutomatonIterationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::NFA < > & > ( AutomatonIterationEpsilonTransition::iteration );
 auto AutomatonIterationEpsilonTransitionEpsilonNFA2 = registration::AbstractRegister < AutomatonIterationEpsilonTransition, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( AutomatonIterationEpsilonTransition::iteration );
diff --git a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h
index 14ff2885592fd1b219ef1b5cdd3284be7f38b799..125ede00d4255c332d2e025dbea9f01b38436555 100644
--- a/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h
+++ b/alib2algo/src/automaton/transform/AutomatonIterationEpsilonTransition.h
@@ -8,7 +8,6 @@
 #ifndef AUTOMATON_ITERATION_EPSILON_TRANSITION_H_
 #define AUTOMATON_ITERATION_EPSILON_TRANSITION_H_
 
-#include <core/multipleDispatch.hpp>
 #include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
@@ -20,10 +19,8 @@ namespace transform {
  * Iterates language given by automaton
  *  - For finite automaton A1, we create automaton L accepting L(A1)*
  */
-class AutomatonIterationEpsilonTransition : public alib::SingleDispatch<AutomatonIterationEpsilonTransition, automaton::Automaton, const automaton::AutomatonBase &> {
+class AutomatonIterationEpsilonTransition {
 public:
-	static automaton::Automaton iteration(const automaton::Automaton& automaton);
-
 	template < class T, class SymbolType = typename automaton::SymbolTypeOfAutomaton < T >, class EpsilonType = DefaultEpsilonType, class StateType = typename automaton::StateTypeOfAutomaton < T > >
 	static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > iteration(const T& automaton);
 };
diff --git a/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp b/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
index 8e9b3e565c39d4af6958c39a6aec5688471d29de..dc9f9fe86f1770017cc33d2f71c4eea072e02d12 100644
--- a/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
+++ b/alib2algo/test-src/automaton/transform/AutomataUnionTest.cpp
@@ -10,6 +10,8 @@
 #include "automaton/simplify/Total.h"
 #include "automaton/determinize/Determinize.h"
 
+#include <container/ObjectsPair.h>
+
 #include <exception/CommonException.h>
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AutomataUnionTest, "automaton" );
@@ -69,8 +71,8 @@ void AutomataUnionTest::testAutomataUnion() {
 	m3.setFinalStates({q20, q02});
 
 	auto u1 = automaton::transform::AutomataUnionEpsilonTransition::unification(m1, m2);
-	CPPUNIT_ASSERT_THROW(automaton::transform::AutomataUnionCartesianProduct::unification(automaton::Automaton(m1), automaton::Automaton(m2)), exception::CommonException);
-	CPPUNIT_ASSERT_THROW(automaton::transform::AutomataUnionCartesianProduct::unification(automaton::Automaton(automaton::NFA < > (m1)), automaton::Automaton(m2)), exception::CommonException);
+	CPPUNIT_ASSERT_THROW(automaton::transform::AutomataUnionCartesianProduct::unification(m1, m2), exception::CommonException);
+	CPPUNIT_ASSERT_THROW(automaton::transform::AutomataUnionCartesianProduct::unification(automaton::NFA < > (m1), automaton::NFA < > ( m2 )), exception::CommonException);
 	auto u2 = automaton::transform::AutomataUnionEpsilonTransition::unification(automaton::simplify::Total::total(m1), automaton::simplify::Total::total(m2));
 
 	auto umdfa(automaton::simplify::Normalize::normalize(automaton::simplify::Trim::trim(automaton::simplify::MinimizeBrzozowski::minimize(automaton::simplify::EpsilonRemoverIncoming::remove(m3)))));