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/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;