diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h
index 79147ee784144f3e16de2289a15e225fa9af069e..df34d7452db4bdf9eed13cdea67bb21b80e190ff 100644
--- a/alib2algo/src/automaton/convert/ToGrammar.h
+++ b/alib2algo/src/automaton/convert/ToGrammar.h
@@ -43,7 +43,7 @@ public:
 	/**
 	 * Performs the conversion (@sa ToGrammarRightRG::convert).
 	 * @tparam SymbolType Type for symbols.
-	 * @tparam StateType Type for states.
+	 * @tparam StateAndNonterminalType Type for states.
 	 * @param automaton the automaton to convert
 	 * @return right regular grammar equivalent to the input @p automaton
 	 */
diff --git a/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
index b4acef5b64717f1dce5a4f3b8e67a427f18b5e9b..58e84d9f6f585557660e50071f6ff2e518447f87 100644
--- a/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
@@ -6,95 +6,12 @@
  */
 
 #include "ToGrammarRightRG.h"
-#include <common/createUnique.hpp>
 #include <registration/AlgoRegistration.hpp>
 
 namespace automaton {
 
 namespace convert {
 
-grammar::RightRG < > ToGrammarRightRG::convert(const automaton::NFA < > & automaton) {
-	ext::map<DefaultStateType, DefaultSymbolType> nonterminalMap;
-
-	const DefaultStateType& initState = automaton.getInitialState();
-	DefaultSymbolType initSymbol { initState };
-
-	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;
-
-		DefaultSymbolType nt = common::createUnique(DefaultSymbolType(state), 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 DefaultStateType& from = transition.first.first;
-		const DefaultSymbolType& input = transition.first.second;
-		for(const auto& to : transition.second) {
-			grammar.addRule(nonterminalMap.find(from)->second, ext::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.getInitialState())->second);
-
-	// step 4
-	if(automaton.getFinalStates().count(automaton.getInitialState()))
-		grammar.setGeneratesEpsilon(true); // okay this feature breaks algorithm but simplifies the code actually :))
-
-	return grammar;
-}
-
-grammar::RightRG < > ToGrammarRightRG::convert(const automaton::DFA<>& automaton) {
-	ext::map<DefaultStateType, DefaultSymbolType> nonterminalMap;
-
-	const DefaultStateType& initState = automaton.getInitialState();
-	DefaultSymbolType initSymbol { initState };
-
-	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;
-
-		DefaultSymbolType nt = common::createUnique(DefaultSymbolType(state), 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 DefaultStateType& from = transition.first.first;
-		const DefaultSymbolType& input = transition.first.second;
-		const DefaultStateType& to = transition.second;
-
-		grammar.addRule(nonterminalMap.find(from)->second, ext::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.getInitialState())->second);
-
-	// step 4
-	if(automaton.getFinalStates().count(automaton.getInitialState()))
-		grammar.setGeneratesEpsilon(true); // okay this feature breaks algorithm but simplifies the code actually :))
-
-	return grammar;
-}
-
 auto ToGrammarRightRGNFA = registration::AbstractRegister < ToGrammarRightRG, grammar::RightRG < >, const automaton::NFA < > & > ( ToGrammarRightRG::convert );
 auto ToGrammarRightRGDFA = registration::AbstractRegister < ToGrammarRightRG, grammar::RightRG < >, const automaton::DFA < > & > ( ToGrammarRightRG::convert );
 
diff --git a/alib2algo/src/automaton/convert/ToGrammarRightRG.h b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
index d3d29ee7892a55afcc2d2c51009ea65c768cbc89..f72eab3bd5f5415710c8e174bb6389aa6bde5383 100644
--- a/alib2algo/src/automaton/convert/ToGrammarRightRG.h
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
@@ -25,9 +25,12 @@
 #define __TO_GRAMMAR_RIGHT_RG_H__
 
 #include <grammar/Regular/RightRG.h>
+
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
 
+#include <common/createUnique.hpp>
+
 namespace automaton {
 
 namespace convert {
@@ -39,17 +42,82 @@ class ToGrammarRightRG {
 public:
 	/**
 	 * Performs the conversion of the finite automaton to right regular grammar.
-	 * @param automaton a finite automaton to convert
-	 * @return right regular grammar equivalent to the source @p automaton.
+	 *
+	 * \tparam SymbolType the type of input/terminal symbols of automaton and the resulting grammar
+	 * \tparam StateNonterminalType the type of states of the automaton and nonterminal symbols of the resulting grammar
+	 *
+	 * \param automaton a finite automaton to convert
+	 *
+	 * \return right regular grammar equivalent to the source @p automaton.
 	 */
-	static grammar::RightRG < > convert(const automaton::NFA < > & automaton);
+	template < class SymbolType, class StateNonterminalType >
+	static grammar::RightRG < SymbolType, StateNonterminalType > convert ( const automaton::NFA < SymbolType, StateNonterminalType > & automaton );
 
 	/**
 	 * \overload
 	 */
-	static grammar::RightRG < > convert(const automaton::DFA < > & automaton);
+	template < class SymbolType, class StateNonterminalType >
+	static grammar::RightRG < SymbolType, StateNonterminalType > convert ( const automaton::DFA < SymbolType, StateNonterminalType > & automaton );
 };
 
+
+template < class SymbolType, class StateNonterminalType >
+grammar::RightRG < SymbolType, StateNonterminalType > ToGrammarRightRG::convert ( const automaton::NFA < SymbolType, StateNonterminalType > & automaton ) {
+	grammar::RightRG < SymbolType, StateNonterminalType > grammar ( automaton.getInitialState ( ) );
+
+	grammar.setTerminalAlphabet ( automaton.getInputAlphabet ( ) );
+	grammar.setNonterminalAlphabet ( automaton.getStates ( ) );
+
+	// step 2 - create set of P in G
+	for(const auto& transition : automaton.getTransitions()) {
+		const auto & from = transition.first.first;
+		const auto & input = transition.first.second;
+
+		for(const auto& to : transition.second) {
+			grammar.addRule ( from, ext::make_pair ( input, to ) ); // 2a
+			if(automaton.getFinalStates().count(to)) // 2b
+				grammar.addRule(transition.first.first, transition.first.second );
+		}
+	}
+
+	// step 3 - set start symbol of G
+	grammar.setInitialSymbol(automaton.getInitialState());
+
+	// step 4
+	if(automaton.getFinalStates().count(automaton.getInitialState()))
+		grammar.setGeneratesEpsilon(true); // okay this feature makes the algorithm a bit different but at the same time it simplifies the code :))
+
+	return grammar;
+}
+
+template < class SymbolType, class StateNonterminalType >
+grammar::RightRG < SymbolType, StateNonterminalType > ToGrammarRightRG::convert ( const automaton::DFA < SymbolType, StateNonterminalType > & automaton ) {
+	grammar::RightRG < SymbolType, StateNonterminalType > grammar ( automaton.getInitialState ( ) );
+
+	grammar.setTerminalAlphabet ( automaton.getInputAlphabet ( ) );
+	grammar.setNonterminalAlphabet ( automaton.getStates ( ) );
+
+	// step 2 - create set of P in G
+	for(const auto& transition : automaton.getTransitions()) {
+		const auto & from = transition.first.first;
+		const auto & input = transition.first.second;
+		const auto & to = transition.second;
+
+		grammar.addRule(from, ext::make_pair(input, to)); // 2a
+		if(automaton.getFinalStates().count(to)) // 2b
+			grammar.addRule(from, input);
+	}
+
+	// step 3 - set start symbol of G
+	grammar.setInitialSymbol ( automaton.getInitialState ( ) );
+
+	// step 4
+	if ( automaton.getFinalStates ( ).count ( automaton.getInitialState ( ) ) )
+		grammar.setGeneratesEpsilon(true); // okay this feature makes the algorithm a bit different but at the same time it simplifies the code :))
+
+	return grammar;
+}
+
 } /* namespace convert */
 
 } /* namespace automaton */