diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp
index 3c8cf8f8c712958a522135bf9a4377c7f1875c3d..2baf53dc82a8e98287a078c6d89316368a4db80d 100644
--- a/aepsilon2/src/aepsilon.cpp
+++ b/aepsilon2/src/aepsilon.cpp
@@ -3,7 +3,6 @@
 // Author	: Tomas Pecka
 //============================================================================
 
-
 #include <iostream>
 
 #include <factory/DataFactory.hpp>
@@ -12,50 +11,26 @@
 #include "epsilon/fsm/FSMEpsilonRemover.h"
 
 int main(int argc, char** argv) {
-	int fileParameterIndex = -1;
 
 	try {
-		if( argc > 1 )
-		{
-			for( int i = 1; i < argc; i++ )
-			{
-				if( std::string( "-h" ).compare( argv[i] ) == 0 )
-				{
-					std::cout << "Removes eps transitions from NFA." << std::endl;
-					std::cout << "Usage: aepsilon [automaton.xml]" << std::endl;
-					return 1;
-				}
-				else
-				{
-					if(fileParameterIndex == -1)
-						fileParameterIndex = i;
-					else
-						throw exception::AlibException("Only one file can be passed as parameter - " + std::string(argv[i]) + " " + std::string(argv[fileParameterIndex]));
-				}
-			}
-		}
-
-		std::list<sax::Token> tokens;
-
-		if(fileParameterIndex != -1) {
-			sax::SaxParseInterface::parseFile(argv[fileParameterIndex], tokens);
+		if (argc == 2 && std::string("-h").compare(argv[1]) == 0) {
+			std::cout << "Remove epsilon transitions from automaton." << std::endl << "Usage: aepsilon [automaton.xml]" << std::endl;
+			return -1;
+		} else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) {
+			alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>()));
+		} else if (argc == 2) {
+			alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>()));
 		} else {
-			sax::SaxParseInterface::parseStdin(tokens);
+			std::cout << "Automaton minimize require deterministic finite automaton" << std::endl;
+			return 1;
 		}
 
-		if(alib::FromXMLParsers::automatonParser.first(tokens)) {
-			std::string xmlMark = tokens.front( ).getData( );
-			automaton::Automaton automaton = alib::DataFactory::fromTokens<automaton::Automaton>(tokens);
-			automaton::Automaton res = epsilon::FSMEpsilonRemover::remove( automaton );
-			alib::DataFactory::toStdout(res);
-		} else {
-			throw exception::AlibException("Invalid argument expected Epsilon NFA.");
-		}
+		return 0;
 
 	} catch (const exception::AlibException& exception) {
 		alib::DataFactory::toStdout(exception);
 		return 1;
-	} catch (...) {
+	} catch(...) {
 		return 127;
 	}
 }
diff --git a/alib2algo/src/conversions/fa2re/Algebraic.cpp b/alib2algo/src/conversions/fa2re/Algebraic.cpp
index 16f1492fb36c7a8c1a347eb2b9c649f6ff7ee834..44d14dc7c69e63e74fad45aa25770bf6bac580b0 100644
--- a/alib2algo/src/conversions/fa2re/Algebraic.cpp
+++ b/alib2algo/src/conversions/fa2re/Algebraic.cpp
@@ -6,16 +6,28 @@
  */
 
 #include "Algebraic.h"
-#include "alphabet/Symbol.h"
-#include "automaton/FSM/DFA.h"
-#include "automaton/FSM/NFA.h"
-#include "automaton/FSM/EpsilonNFA.h"
+
+#include <alphabet/Symbol.h>
+#include <automaton/FSM/DFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <exception/AlibException.h>
+
+#include "../../equations/RightRegularEquationSolver.h"
 
 namespace conversions
 {
 
 namespace fa2re {
 
+regexp::RegExp Algebraic::convert(const automaton::Automaton& automaton) {
+	regexp::RegExp* out = NULL;
+	automaton.getData().Accept((void*) &out, Algebraic::ALGEBRAIC);
+	regexp::RegExp res = std::move(*out);
+	delete out;
+	return res;
+}
+
 template<>
 regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automaton ) {
 	equations::RightRegularEquationSolver solver;
@@ -25,7 +37,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automa
 		solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) );
 
 	for( const auto & q : automaton.getStates( ) ) {
-		if( isInSet( q, automaton.getFinalStates( ) ) )
+		if( automaton.getFinalStates( ).count( q ) > 0 )
 			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } );
 	}
 
@@ -61,7 +73,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) {
 		solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) );
 
 	for( const auto & q : automaton.getStates( ) ) {
-		if( isInSet( q, automaton.getFinalStates( ) ) )
+		if( automaton.getFinalStates( ).count( q ) > 0 )
 			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } );
 	}
 
@@ -91,7 +103,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) {
 		solver.addSymbol( alphabet::Symbol( alphabet::LabeledSymbol( q.getName( ) ) ) );
 
 	for( const auto & q : automaton.getStates( ) ) {
-		if( isInSet( q, automaton.getFinalStates( ) ) )
+		if( automaton.getFinalStates( ).count( q ) > 0 )
 			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q.getName( ) ) ), regexp::UnboundedRegExpEpsilon { } );
 	}
 
@@ -102,6 +114,64 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) {
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState().getName() ) ) );
 }
 
+
+void Algebraic::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void Algebraic::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(this->convert(automaton));
+}
+
+void Algebraic::Visit(void* data, const automaton::NFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(this->convert(automaton));
+}
+
+void Algebraic::Visit(void* data, const automaton::DFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(this->convert(automaton));
+}
+
+void Algebraic::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
+}
+
+void Algebraic::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type CompactNFA");
+}
+
+void Algebraic::Visit(void*, const automaton::DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void Algebraic::Visit(void*, const automaton::SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void Algebraic::Visit(void*, const automaton::InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void Algebraic::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void Algebraic::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void Algebraic::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void Algebraic::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const Algebraic Algebraic::ALGEBRAIC;
+
 } /* namespace fa2re */
 
 } /* namespace conversions */
diff --git a/alib2algo/src/conversions/fa2re/Algebraic.h b/alib2algo/src/conversions/fa2re/Algebraic.h
index 55dbaca7def75373f427aad929e7552d0c72e7ac..a6fbc2471e778d656a4e266cb63ef641391a45bd 100644
--- a/alib2algo/src/conversions/fa2re/Algebraic.h
+++ b/alib2algo/src/conversions/fa2re/Algebraic.h
@@ -12,10 +12,9 @@
 #include <map>
 #include <queue>
 
+#include <regexp/RegExp.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
-
-#include "common/macros.h"
-#include "../../equations/RightRegularEquationSolver.h"
+#include <automaton/Automaton.h>
 
 namespace conversions
 {
@@ -30,15 +29,34 @@ namespace fa2re
  * Converts FA to RE using Brzozowski's algebraic method using right regular equations.
  * Source : Melichar 2.122
  */
-class Algebraic
+class Algebraic : public automaton::VisitableAutomatonBase::const_visitor_type
 {
 public:
 	/**
 	 * Performs conversion.
 	 * @return regular expression equivalent to input automaton.
 	 */
+	static regexp::RegExp convert(const automaton::Automaton& automaton);
+
 	template <class T>
-	static regexp::UnboundedRegExp convert( const T & automaton );
+	static regexp::UnboundedRegExp convert(const T& automaton);
+
+private:
+	void Visit(void*, const automaton::UnknownAutomaton&) const;
+	void Visit(void*, const automaton::EpsilonNFA&) const;
+	void Visit(void*, const automaton::NFA&) const;
+	void Visit(void*, const automaton::DFA&) const;
+	void Visit(void*, const automaton::ExtendedNFA&) const;
+	void Visit(void*, const automaton::CompactNFA&) const;
+	void Visit(void*, const automaton::InputDrivenNPDA&) const;
+	void Visit(void*, const automaton::VisiblyPushdownNPDA&) const;
+	void Visit(void*, const automaton::NPDA&) const;
+	void Visit(void*, const automaton::SinglePopNPDA&) const;
+	void Visit(void*, const automaton::DPDA&) const;
+	void Visit(void*, const automaton::SinglePopDPDA&) const;
+	void Visit(void*, const automaton::OneTapeDTM&) const;
+
+	static const Algebraic ALGEBRAIC;
 };
 
 } /* namespace fa2re */
diff --git a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp
index 12e09fae7de98de43b1a6db0ea9af252b2cb8480..b1d2316e4adea49b46b6ec4a95f3b52318d70e06 100644
--- a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp
+++ b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.cpp
@@ -19,11 +19,20 @@ namespace conversions
 namespace fa2re
 {
 
+regexp::RegExp StateEliminationFormal::convert(const automaton::Automaton& automaton)
+{
+    regexp::RegExp* out = NULL;
+    automaton.getData().Accept((void*) &out, StateEliminationFormal::STATE_ELIMINATION_FORMAL);
+    regexp::RegExp res = std::move(*out);
+    delete out;
+    return res;
+}
+
 template<class T>
-regexp::RegExp StateEliminationFormal::convert(const T& automaton)
+regexp::FormalRegExp StateEliminationFormal::convert(const T& automaton)
 {
     if(automaton.getFinalStates().size() == 0)
-        return regexp::RegExp{regexp::FormalRegExp(regexp::FormalRegExpEmpty())};
+        return regexp::FormalRegExp(regexp::FormalRegExpEmpty());
 
     // steps 1 + 2
     automaton::ExtendedNFA extendedAutomaton = constructExtendedNFA(automaton);
@@ -46,21 +55,10 @@ regexp::RegExp StateEliminationFormal::convert(const T& automaton)
         regexp::FormalRegExpIteration(std::move(*transition(extendedAutomaton, *extendedAutomaton.getFinalStates().begin(), *extendedAutomaton.getFinalStates().begin())))
         );
     //return regexp::RegExp{opt.optimize(regexp::FormalRegExp(concat))};
-    return regexp::RegExp{regexp::FormalRegExp(concat)};
-}
-
-template<>
-regexp::RegExp StateEliminationFormal::convert(const automaton::Automaton& automaton)
-{
-    regexp::RegExp* out = NULL;
-    automaton.getData().Accept((void*) &out, StateEliminationFormal::STATE_ELIMINATION_FORMAL);
-    regexp::RegExp res = std::move(*out);
-    delete out;
-    return res;
+    return regexp::FormalRegExp(concat);
 }
 
 
-
 void StateEliminationFormal::Visit(void*, const automaton::UnknownAutomaton&) const
 {
     throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
diff --git a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h
index d94d57d849658b452b691585402543842452e460..e71cce1a267ffecb9bac14dd45e23a2e6f60a35f 100644
--- a/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h
+++ b/alib2algo/src/conversions/fa2re/formal/StateEliminationFormal.h
@@ -34,8 +34,10 @@ public:
      * Performs conversion.
      * @return regular expression equivalent to source NFA.
      */
+    static regexp::RegExp convert(const automaton::Automaton& automaton);
+
     template<class T>
-    static regexp::RegExp convert(const T& automaton);
+    static regexp::FormalRegExp convert(const T& automaton);
 
 private:
     void Visit(void*, const automaton::UnknownAutomaton& automaton) const;
diff --git a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp
index dd4422ec1ec9934326fa87afdd5a11ac18ad65e1..b714edfa725e40c60fa53c3f9054e4db86ed5d10 100644
--- a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp
+++ b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.cpp
@@ -19,11 +19,20 @@ namespace conversions
 namespace fa2re
 {
 
+regexp::RegExp StateEliminationUnbounded::convert(const automaton::Automaton& automaton)
+{
+	regexp::RegExp* out = NULL;
+	automaton.getData().Accept((void*) &out, StateEliminationUnbounded::STATE_ELIMINATION_UNBOUNDED);
+	regexp::RegExp res = std::move(*out);
+	delete out;
+	return res;
+}
+
 template<class T>
-regexp::RegExp StateEliminationUnbounded::convert(const T& automaton)
+regexp::UnboundedRegExp StateEliminationUnbounded::convert(const T& automaton)
 {
     if(automaton.getFinalStates().size() == 0)
-        return regexp::RegExp{regexp::UnboundedRegExp(regexp::UnboundedRegExpEmpty())};
+        return regexp::UnboundedRegExp(regexp::UnboundedRegExpEmpty());
 
     // steps 1 + 2
     automaton::ExtendedNFA extendedAutomaton = constructExtendedNFA(automaton);
@@ -44,21 +53,10 @@ regexp::RegExp StateEliminationUnbounded::convert(const T& automaton)
     regexp::UnboundedRegExpConcatenation concat;
     concat.appendElement(std::move(*transition(extendedAutomaton, *extendedAutomaton.getInitialStates().begin(), *extendedAutomaton.getFinalStates().begin())));
     concat.appendElement(regexp::UnboundedRegExpIteration(std::move(*transition(extendedAutomaton, *extendedAutomaton.getFinalStates().begin(), *extendedAutomaton.getFinalStates().begin()))));
-    return regexp::RegExp{opt.optimize(regexp::UnboundedRegExp(concat))};
-}
-
-template<>
-regexp::RegExp StateEliminationUnbounded::convert(const automaton::Automaton& automaton)
-{
-    regexp::RegExp* out = NULL;
-    automaton.getData().Accept((void*) &out, StateEliminationUnbounded::STATE_ELIMINATION_UNBOUNDED);
-    regexp::RegExp res = std::move(*out);
-    delete out;
-    return res;
+    return opt.optimize(regexp::UnboundedRegExp(concat));
 }
 
 
-
 void StateEliminationUnbounded::Visit(void*, const automaton::UnknownAutomaton&) const
 {
     throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
diff --git a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h
index 5cbd9c8840bd2a983d2bb74dba101ccbd09e7035..fa6c114a17e970ac2c9f2346b81799536eeac9b8 100644
--- a/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h
+++ b/alib2algo/src/conversions/fa2re/unbounded/StateEliminationUnbounded.h
@@ -32,10 +32,13 @@ class StateEliminationUnbounded : public automaton::VisitableAutomatonBase::cons
 public:
     /**
      * Performs conversion.
+     * @param automaton automaton to convert
      * @return regular expression equivalent to source NFA.
      */
+    static regexp::RegExp convert(const automaton::Automaton& automaton);
+
     template<class T>
-    static regexp::RegExp convert(const T& automaton);
+    static regexp::UnboundedRegExp convert(const T& automaton);
 
 private:
     void Visit(void*, const automaton::UnknownAutomaton& automaton) const;
diff --git a/alib2algo/src/conversions/re2fa/Thompson.cpp b/alib2algo/src/conversions/re2fa/Thompson.cpp
index 092f08422bca7f81f5307295558d739aeb3f46b9..e61a87b637614a452c0a5effda3e9b5afcc6e943 100644
--- a/alib2algo/src/conversions/re2fa/Thompson.cpp
+++ b/alib2algo/src/conversions/re2fa/Thompson.cpp
@@ -13,11 +13,11 @@ namespace conversions
 namespace re2fa
 {
 
-automaton::EpsilonNFA Thompson::convert(const regexp::RegExp& regexp)
+automaton::Automaton Thompson::convert(const regexp::RegExp& regexp)
 {
-	automaton::EpsilonNFA* out = NULL;
+	automaton::Automaton* out = NULL;
 	regexp.getData().Accept((void*) &out, Thompson::THOMPSON);
-	automaton::EpsilonNFA res = std::move(*out);
+	automaton::Automaton res = std::move(*out);
 	delete out;
 	return res;
 }
@@ -42,14 +42,14 @@ automaton::EpsilonNFA Thompson::convert(const T& regexp)
 
 void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
-	automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData);
-	out = new automaton::EpsilonNFA(this->convert(regexp));
+	automaton::Automaton* & out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(regexp));
 }
 
 void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
 {
-	automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData);
-	out = new automaton::EpsilonNFA(this->convert(regexp));
+	automaton::Automaton* & out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(regexp));
 }
 
 // ----------------------------------------------------------------------------
diff --git a/alib2algo/src/conversions/re2fa/Thompson.h b/alib2algo/src/conversions/re2fa/Thompson.h
index d3365ec0b9361485831ea03101ad96bc09f416d5..e127f07f54e53f48e9691986e9f04e6d0af0f312 100644
--- a/alib2algo/src/conversions/re2fa/Thompson.h
+++ b/alib2algo/src/conversions/re2fa/Thompson.h
@@ -11,6 +11,7 @@
 #include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExpElements.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
+#include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
 namespace conversions
@@ -35,7 +36,7 @@ public:
 	 * @param regexp regexp to convert
 	 * @return nondeterministic finite automaton with epsilon transitions accepting language described by the regexp
 	 */
-	static automaton::EpsilonNFA convert(const regexp::RegExp& regexp);
+	static automaton::Automaton convert(const regexp::RegExp& regexp);
 
 	template<class T>
 	static automaton::EpsilonNFA convert(const T& regexp);
diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp b/alib2algo/src/determinize/nfa/NFADeterminizer.cpp
index 9af97b5284203cb2908e7ac182fb58c2e93a72e9..c95aae328fe05a9880d462fdb8516bf9b9f31caa 100644
--- a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp
+++ b/alib2algo/src/determinize/nfa/NFADeterminizer.cpp
@@ -13,6 +13,13 @@
 
 namespace determinize {
 
+automaton::Automaton NFADeterminizer::determinize(const automaton::Automaton& automaton) {
+	automaton::Automaton* out = NULL;
+	automaton.getData().Accept((void*) &out, NFADeterminizer::NFA_DETERMINIZER);
+	automaton::Automaton res = std::move(*out);
+	delete out;
+	return res;
+}
 
 automaton::State NFADeterminizer::createDFAState(const std::set<automaton::State>& nfaStates) {
 	std::set<label::Label> labelSet;
@@ -77,4 +84,59 @@ automaton::DFA NFADeterminizer::determinize(const automaton::NFA& nfa) {
 	return res;
 }
 
+void NFADeterminizer::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::EpsilonNFA&) const {
+	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
+}
+
+void NFADeterminizer::Visit(void* data, const automaton::NFA& automaton) const {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->determinize(automaton));
+}
+
+void NFADeterminizer::Visit(void*, const automaton::DFA&) const {
+	throw exception::AlibException("Unsupported automaton type DFA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type CompactNFA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void NFADeterminizer::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const NFADeterminizer NFADeterminizer::NFA_DETERMINIZER;
+
 }
diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.h b/alib2algo/src/determinize/nfa/NFADeterminizer.h
index b0a7697fa009ed4d57911cc481aa8afabe286ddd..b5476588710876243a50e7708970eb9958124b9a 100644
--- a/alib2algo/src/determinize/nfa/NFADeterminizer.h
+++ b/alib2algo/src/determinize/nfa/NFADeterminizer.h
@@ -10,16 +10,19 @@
 
 #include <set>
 
-#include "automaton/common/State.h"
-#include "automaton/FSM/NFA.h"
-#include "automaton/FSM/DFA.h"
+#include <automaton/common/State.h>
+#include <automaton/Automaton.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <exception/AlibException.h>
 
 namespace determinize {
 
 /**
  * Class for running determinization algorithm on fsm.
  */
-class NFADeterminizer {
+class NFADeterminizer : public automaton::VisitableAutomatonBase::const_visitor_type {
 
 private:
 
@@ -41,14 +44,33 @@ private:
 	 * @return set of states from nondeterministic fsm
 	 */
 	static std::set<automaton::State> recreateNFAStates(const automaton::State& dfaState);
+
+	void Visit(void*, const automaton::UnknownAutomaton& automaton) const;
+	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
+	void Visit(void*, const automaton::NFA& automaton) const;
+	void Visit(void*, const automaton::DFA& automaton) const;
+	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
+	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
+	void Visit(void*, const automaton::InputDrivenNPDA& automaton) const;
+	void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const automaton::NPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
+	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
+
+	static const NFADeterminizer NFA_DETERMINIZER;
+
 public:
 
 	/**
 	 * @param nfsm nondeterministic final-state machine given for determinization
+	 * @return DFA
 	 * Runs determinization algorithm on nondeterministic fsm given in constructor.
 	 */
-	static automaton::DFA determinize(const automaton::NFA& nfa);
+	static automaton::Automaton determinize(const automaton::Automaton& nfa);
 
+	static automaton::DFA determinize(const automaton::NFA& nfa);
 };
 
 } /* namespace determinize */
diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp b/alib2algo/src/minimize/dfa/MinimizeDFA.cpp
index 9840a5e8c94fbd3e9ccb5ded0975c6fac726c17b..9eefeb1c975afa487773aa948c076aab0740fcfc 100644
--- a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp
+++ b/alib2algo/src/minimize/dfa/MinimizeDFA.cpp
@@ -12,13 +12,23 @@
 #include <sstream>
 #include <iostream>
 
-#include "alphabet/Symbol.h"
-#include "label/IntegerLabel.h"
+#include <alphabet/Symbol.h>
+#include <label/IntegerLabel.h>
 
-#include "automaton/Automaton.h"
+#include <exception/AlibException.h>
+
+#include <automaton/Automaton.h>
 
 namespace minimize {
 
+automaton::Automaton MinimizeDFA::minimize(const automaton::Automaton& automaton) {
+	automaton::Automaton* out = NULL;
+	automaton.getData().Accept((void*) &out, MinimizeDFA::MINIMIZE_DFA);
+	automaton::Automaton res = std::move(*out);
+	delete out;
+	return res;
+}
+
 automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) {
 	if(dfa.getFinalStates().size() == 0) {
 		automaton::DFA result(automaton::State(0));
@@ -131,4 +141,59 @@ automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) {
 	return result;
 }
 
+void MinimizeDFA::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::EpsilonNFA&) const {
+	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
+}
+
+void MinimizeDFA::Visit(void* data, const automaton::DFA& automaton) const {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->minimize(automaton));
+}
+
+void MinimizeDFA::Visit(void*, const automaton::NFA&) const {
+	throw exception::AlibException("Unsupported automaton type DFA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type CompactNFA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void MinimizeDFA::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const MinimizeDFA MinimizeDFA::MINIMIZE_DFA;
+
 } /* namespace minimize */
diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.h b/alib2algo/src/minimize/dfa/MinimizeDFA.h
index 056914756a99a3c9aa4cae6c487df17ed8a88128..ea20405e8ab17e34c91a20c6740e309f44cd2549 100644
--- a/alib2algo/src/minimize/dfa/MinimizeDFA.h
+++ b/alib2algo/src/minimize/dfa/MinimizeDFA.h
@@ -8,14 +8,36 @@
 #ifndef MINIMIZE_DFA_H_
 #define MINIMIZE_DFA_H_
 
-#include "automaton/FSM/DFA.h"
+#include <automaton/Automaton.h>
+#include <automaton/FSM/DFA.h>
 
 namespace minimize {
 
-class MinimizeDFA {
+class MinimizeDFA : public automaton::VisitableAutomatonBase::const_visitor_type {
 public:
+	/**
+	 * @param dfa automaton to minimize
+	 */
+	static automaton::Automaton minimize(const automaton::Automaton& dfa);
+
 	static automaton::DFA minimize(const automaton::DFA& dfa);
 
+protected:
+	void Visit(void*, const automaton::UnknownAutomaton& automaton) const;
+	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
+	void Visit(void*, const automaton::NFA& automaton) const;
+	void Visit(void*, const automaton::DFA& automaton) const;
+	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
+	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
+	void Visit(void*, const automaton::InputDrivenNPDA& automaton) const;
+	void Visit(void*, const automaton::VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const automaton::NPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
+	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
+
+	static const MinimizeDFA MINIMIZE_DFA;
 };
 
 }
diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
index 4806de5eb3591f0f92beeb2f5de3ff19ed3767c4..9adb79a4c57b375ed7e1360c009cec27ed8b8a02 100644
--- a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
+++ b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
@@ -31,22 +31,20 @@ void re2faTest::testThompson() {
 	regexp::RegExpFromStringParser parser(inputs);
 	regexp::RegExp regexp1( parser.parseValue() );
 
-    conversions::re2fa::Thompson thompson1;
-	automaton::EpsilonNFA enfa1 = thompson1.convert(regexp1);
+	automaton::Automaton enfa1 = conversions::re2fa::Thompson::convert(regexp1);
 
 	regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(enfa1) );
 
-    conversions::re2fa::Thompson thompson2;
-	automaton::EpsilonNFA enfa2 = thompson2.convert(regexp2);
+	automaton::Automaton enfa2 = conversions::re2fa::Thompson::convert(regexp2);
 
-	automaton::NFA nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1);
-	automaton::NFA nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2);
+	automaton::Automaton nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1);
+	automaton::Automaton nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2);
 
-	automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1);
-	automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2);
+	automaton::Automaton dfa1 = determinize::NFADeterminizer::determinize(nfa1);
+	automaton::Automaton dfa2 = determinize::NFADeterminizer::determinize(nfa2);
 
-	automaton::DFA mdfa1 = minimize::MinimizeDFA::minimize(dfa1);
-	automaton::DFA mdfa2 = minimize::MinimizeDFA::minimize(dfa2);
+	automaton::Automaton mdfa1 = minimize::MinimizeDFA::minimize(dfa1);
+	automaton::Automaton mdfa2 = minimize::MinimizeDFA::minimize(dfa2);
 
 	CPPUNIT_ASSERT( mdfa1 == mdfa2);
 }
diff --git a/aminimize2/src/aminimize.cpp b/aminimize2/src/aminimize.cpp
index d43b6430c060664998ef0b821d742cff16d2a7c2..b2c963e5e4ba9d0055b2da791c8ed2b4b87a1719 100644
--- a/aminimize2/src/aminimize.cpp
+++ b/aminimize2/src/aminimize.cpp
@@ -4,35 +4,26 @@
 //============================================================================
 
 #include <iostream>
-#include <string>
-#include <set>
 
-#include "exception/AlibException.h"
-#include "factory/DataFactory.hpp"
+#include <exception/AlibException.h>
+#include <factory/DataFactory.hpp>
+
 #include "minimize/dfa/MinimizeDFA.h"
 
 int main(int argc, char** argv) {
 
 	try {
-
-		automaton::DFA* automatonPointer = NULL;
-
 		if (argc == 2 && std::string("-h").compare(argv[1]) == 0) {
 			std::cout << "Automaton minimize." << std::endl << "Usage: aminimize automaton.xml" << std::endl;
 			return -1;
 		} else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) {
-			automatonPointer = static_cast<automaton::DFA*>(std::move(alib::DataFactory::fromStdin<automaton::DFA>()).plunder());
+			alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>()));
 		} else if (argc == 2) {
-			automatonPointer = static_cast<automaton::DFA*>(std::move(alib::DataFactory::fromFile<automaton::DFA>(argv[1])).plunder());
+			alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>()));
 		} else {
 			std::cout << "Automaton minimize require deterministic finite automaton" << std::endl;
 			return 1;
 		}
-		
-		automaton::DFA res = minimize::MinimizeDFA::minimize(*automatonPointer);
-		alib::DataFactory::toStdout(res);
-
-		delete automatonPointer;
 
 		return 0;