diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index a3c7a957a7330689682f54624ce715b59e6ae477..f7f86ee440d826fe75905c5ff8ede06975f00bb3 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -143,7 +143,7 @@ void ConversionHandler::convertFSMtoRG( void )
 
 void ConversionHandler::convertFSMtoRRG( void )
 {
-	const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );
+	const automaton::Automaton fsm = alib::DataFactory::fromTokens<automaton::Automaton>( m_tokens );
 
 	switch( m_algorithm )
 	{
@@ -157,7 +157,7 @@ void ConversionHandler::convertFSMtoRRG( void )
 
 void ConversionHandler::convertFSMtoLRG( void )
 {
-	const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );
+	const automaton::Automaton fsm = alib::DataFactory::fromTokens<automaton::Automaton>( m_tokens );
 
 	switch( m_algorithm )
 	{
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
index aa02f307715808e587806dcc4c8b2026161a5e5a..18198fb05a4172ab3c9698b0910b9c8e8d3afec3 100644
--- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
+++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
@@ -4,55 +4,153 @@
 #include <label/StringLabel.h>
 #include <alphabet/LabeledSymbol.h>
 
+#include <exception/AlibException.h>
+
 namespace fa2rg
 {
 
 grammar::LeftRG FAtoLRGConverter::convert(const automaton::NFA& automaton)
 {
-    std::map<automaton::State, alphabet::Symbol> nonterminalMap;
-    // step 2
-    grammar::LeftRG grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+	// step 2
+	grammar::LeftRG grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+
+	// step 1
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& state : automaton.getStates())
+	{
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::pair<automaton::State, alphabet::Symbol>(state, nt));
+	}
+
+
+	// step 3 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+
+		for(const auto& to : transition.second)
+		{
+			// 3a
+			grammar.addRule(nonterminalMap.find(to)->second, std::make_pair(nonterminalMap.find(from)->second, input));
+
+			if(automaton.getFinalStates().count(to) > 0)
+				grammar.addRule(grammar.getInitialSymbol(), std::make_pair(nonterminalMap.find(from)->second, input));
+
+
+			if(automaton.getInitialStates().count(from) > 0)
+			{
+				grammar.addRule(nonterminalMap.find(to)->second, input);
+
+				if(automaton.getFinalStates().count(to) > 0)
+					grammar.addRule(grammar.getInitialSymbol(), input);
+			}
+		}
+	}
+
+	for(const auto & initial : automaton.getInitialStates()) {
+		if(automaton.getFinalStates().count(initial) > 0)
+			grammar.setGeneratesEpsilon(true);
+	}
+
+	return grammar;
+}
+
+grammar::LeftRG FAtoLRGConverter::convert(const automaton::DFA& automaton)
+{
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+	// step 2
+	grammar::LeftRG grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+
+	// step 1
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& state : automaton.getStates())
+	{
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::pair<automaton::State, alphabet::Symbol>(state, nt));
+	}
+
 
-    // step 1
-    grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+	// step 3 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+		const automaton::State& to = transition.second;
 
-    for(const auto& state : automaton.getStates())
-    {
-        alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
-        grammar.addNonterminalSymbol(nt);
-        nonterminalMap.insert(std::pair<automaton::State, alphabet::Symbol>(state, nt));
-    }
+		// 3a
+		grammar.addRule(nonterminalMap.find(to)->second, std::make_pair(nonterminalMap.find(from)->second, input));
 
+		if(automaton.getFinalStates().count(to) > 0)
+			grammar.addRule(grammar.getInitialSymbol(), std::make_pair(nonterminalMap.find(from)->second, input));
 
-    // step 3 - create set of P in G
-    for(const auto& transition : automaton.getTransitions())
-    {
-        const automaton::State& from = transition.first.first;
-        const alphabet::Symbol& input = transition.first.second;
 
-        for(const auto& to : transition.second)
-        {
-            // 3a
-            grammar.addRule(nonterminalMap.find(to)->second, std::make_pair(nonterminalMap.find(from)->second, input));
+		if(automaton.getInitialState() == from)
+		{
+			grammar.addRule(nonterminalMap.find(to)->second, input);
 
-            if(automaton.getFinalStates().count(to) > 0)
-                grammar.addRule(grammar.getInitialSymbol(), std::make_pair(nonterminalMap.find(from)->second, input));
+			if(automaton.getFinalStates().count(to) > 0)
+				grammar.addRule(grammar.getInitialSymbol(), input);
+		}
+	}
 
+	if(automaton.getFinalStates().count(automaton.getInitialState()) > 0)
+		grammar.setGeneratesEpsilon(true);
 
-            if(automaton.getInitialStates().count(from) > 0)
-            {
-                grammar.addRule(nonterminalMap.find(to)->second, input);
+	return grammar;
+}
+
+grammar::Grammar FAtoLRGConverter::convert(const automaton::Automaton& automaton) {
+	grammar::Grammar* out = NULL;
+	automaton.getData().Accept((void*) &out, FAtoLRGConverter::FA_TO_LRG_CONVERTER);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoLRGConverter::Visit(void* data, const automaton::NFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->convert(automaton));
+}
 
-                if(automaton.getFinalStates().count(to) > 0)
-                    grammar.addRule(grammar.getInitialSymbol(), input);
-            }
-        }
-    }
+void FAtoLRGConverter::Visit(void* data, const automaton::DFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->convert(automaton));
+}
 
-    if(automaton.getFinalStates().count(*automaton.getInitialStates().begin()) > 0)
-        grammar.setGeneratesEpsilon(true);
+void FAtoLRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
 
-    return grammar;
+void FAtoLRGConverter::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
 }
 
+void FAtoLRGConverter::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+const FAtoLRGConverter FAtoLRGConverter::FA_TO_LRG_CONVERTER;
+
 } /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
index ef2f0a32ac70af252448548b085a74bb8c6d7fe9..c7e3bbbff8bae134ac8c1a8f38c6b3fdf15bf510 100644
--- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
+++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
@@ -1,10 +1,12 @@
 #ifndef __FATOLRGCONVERTER_H__
 #define __FATOLRGCONVERTER_H__
 
-#include <map>
-
 #include <grammar/Regular/LeftRG.h>
 #include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <grammar/Grammar.h>
+#include <automaton/Automaton.h>
 
 namespace fa2rg
 {
@@ -13,14 +15,30 @@ namespace fa2rg
  * Finite automaton to right regular grammar converter.
  * Source: My own :)
  */
-class FAtoLRGConverter
+class FAtoLRGConverter : public automaton::VisitableAutomatonBase::const_visitor_type
 {
 public:
-    /**
-     * Performs conversion.
-     * @return left regular grammar equivalent to source automaton.
-     */
-    grammar::LeftRG convert(const automaton::NFA& automaton);
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static grammar::Grammar convert(const automaton::Automaton& automaton);
+
+	static grammar::LeftRG convert(const automaton::NFA& automaton);
+	static grammar::LeftRG convert(const automaton::DFA& automaton);
+
+private:
+	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::NPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
+	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
+
+	static const FAtoLRGConverter FA_TO_LRG_CONVERTER;
 };
 
 } /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
index 4cf3d3cf79d2084d3a3d0e3a9f4719ee2bb8455f..6c3a83fba75bfb593277ecf6573f07ffba4f15b7 100644
--- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
+++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
@@ -1,53 +1,150 @@
 #include "FAtoRRGConverter.h"
 
+#include <label/StringLabel.h>
 #include <alphabet/LabeledSymbol.h>
 
+#include <exception/AlibException.h>
+
 namespace fa2rg
 {
 
 grammar::RightRG FAtoRRGConverter::convert(const automaton::NFA& automaton)
 {
-    std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+
+	const automaton::State& initState = *automaton.getInitialStates().begin(); //FIXME what about other initial states
+	const alphabet::Symbol initSymbol(alphabet::LabeledSymbol(initState.getName()));
+
+	grammar::RightRG grammar(initSymbol);
+	nonterminalMap.insert(std::make_pair(initState, initSymbol));
+
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& state : automaton.getStates())
+	{
+		if(state == initState)
+			continue;
+
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::make_pair(state, nt));
+	}
+
+	// step 2 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+		for(const auto& to : transition.second)
+		{
+			grammar.addRule(nonterminalMap.find(from)->second, std::make_pair(input, nonterminalMap.find(to)->second)); // 2a
+			if(automaton.getFinalStates().count(to)) // 2b
+				grammar.addRule(nonterminalMap.find(from)->second, input);
+		}
+	}
+
+	// step 3 - set start symbol of G
+	grammar.setInitialSymbol(nonterminalMap.find(*automaton.getInitialStates().begin())->second);
+
+	// step 4
+	for(const auto & initial : automaton.getInitialStates()) {
+		if(automaton.getFinalStates().count(initial) > 0)
+			grammar.setGeneratesEpsilon(true); // okay this feature makes algorithm mismatch mathematical but simplifies the code actually :))
+	}
+
+	return grammar;
+}
+
+grammar::RightRG FAtoRRGConverter::convert(const automaton::DFA& automaton)
+{
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+
+	const automaton::State& initState = automaton.getInitialState();
+	const alphabet::Symbol initSymbol(alphabet::LabeledSymbol(initState.getName()));
 
-    const automaton::State& initState = *automaton.getInitialStates().begin();
-    const alphabet::Symbol initSymbol(alphabet::LabeledSymbol(initState.getName()));
+	grammar::RightRG grammar(initSymbol);
+	nonterminalMap.insert(std::make_pair(initState, initSymbol));
 
-    grammar::RightRG grammar(initSymbol);
-    nonterminalMap.insert(std::make_pair(initState, initSymbol));
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
 
-    grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+	for(const auto& state : automaton.getStates())
+	{
+		if(state == initState)
+			continue;
 
-    for(const auto& state : automaton.getStates())
-    {
-        if(state == initState)
-            continue;
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::make_pair(state, nt));
+	}
 
-        alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
-        grammar.addNonterminalSymbol(nt);
-        nonterminalMap.insert(std::make_pair(state, nt));
-    }
+	// step 2 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+		const automaton::State& to = transition.second;
 
-    // step 2 - create set of P in G
-    for(const auto& transition : automaton.getTransitions())
-    {
-        const automaton::State& from = transition.first.first;
-        const alphabet::Symbol& input = transition.first.second;
-        for(const auto& to : transition.second)
-        {
-            grammar.addRule(nonterminalMap.find(from)->second, std::make_pair(input, nonterminalMap.find(to)->second)); // 2a
-            if(automaton.getFinalStates().count(to)) // 2b
-                grammar.addRule(nonterminalMap.find(from)->second, input);
-        }
-    }
+		grammar.addRule(nonterminalMap.find(from)->second, std::make_pair(input, nonterminalMap.find(to)->second)); // 2a
+		if(automaton.getFinalStates().count(to)) // 2b
+			grammar.addRule(nonterminalMap.find(from)->second, input);
+	}
 
-    // step 3 - set start symbol of G
-    grammar.setInitialSymbol(nonterminalMap.find(*automaton.getInitialStates().begin())->second);
+	// step 3 - set start symbol of G
+	grammar.setInitialSymbol(nonterminalMap.find(automaton.getInitialState())->second);
 
-    // step 4
-    if(automaton.getFinalStates().count(*automaton.getInitialStates().begin()))
-        grammar.setGeneratesEpsilon(true); // okay this feature breaks algorithm but simplifies the code actually :))
+	// step 4
+	if(automaton.getFinalStates().count(automaton.getInitialState()))
+		grammar.setGeneratesEpsilon(true); // okay this feature breaks algorithm but simplifies the code actually :))
+
+	return grammar;
+}
+
+grammar::Grammar FAtoRRGConverter::convert(const automaton::Automaton& automaton) {
+	grammar::Grammar* out = NULL;
+	automaton.getData().Accept((void*) &out, FAtoRRGConverter::FA_TO_RRG_CONVERTER);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
 
-    return grammar;
+void FAtoRRGConverter::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
 }
 
+void FAtoRRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void* data, const automaton::NFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->convert(automaton));
+}
+
+void FAtoRRGConverter::Visit(void* data, const automaton::DFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->convert(automaton));
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+const FAtoRRGConverter FAtoRRGConverter::FA_TO_RRG_CONVERTER;
+
 } /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
index 79132db83956f40ff4c36bb88336d36ff7238121..bd6ee8fd14d5c642218531b8d3dea7a539f6a6d4 100644
--- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
+++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
@@ -3,6 +3,10 @@
 
 #include <grammar/Regular/RightRG.h>
 #include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <grammar/Grammar.h>
+#include <automaton/Automaton.h>
 
 namespace fa2rg
 {
@@ -11,17 +15,30 @@ namespace fa2rg
  * Finite automaton to right regular grammar converter.
  * Source: Melichar 2.104
  */
-class FAtoRRGConverter
+class FAtoRRGConverter : public automaton::VisitableAutomatonBase::const_visitor_type
 {
 public:
-    /**
-     * Performs conversion.
-     * @return left regular grammar equivalent to source automaton.
-     */
-    grammar::RightRG convert(const automaton::NFA& automaton);
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static grammar::Grammar convert(const automaton::Automaton& automaton);
+
+	static grammar::RightRG convert(const automaton::NFA& automaton);
+	static grammar::RightRG convert(const automaton::DFA& automaton);
 
 private:
-    bool isSymbolOnAnyRightHandSide(const alphabet::Symbol& symbol, const grammar::RightRG& grammar) const;
+	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::NPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
+	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
+
+	static const FAtoRRGConverter FA_TO_RRG_CONVERTER;
 };
 
 } /* namespace fa2rg */