From c4446c2e99d1c51ee87d41dfefea3648512e11ab Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Fri, 28 Oct 2016 19:00:26 +0200
Subject: [PATCH] template RegExp datatypes part II

---
 aaccess2/src/RegExpAccess.cpp                 |   8 +-
 aaccess2/src/RegExpAccess.h                   |   4 +-
 .../automaton/convert/ToRegExpAlgebraic.cpp   |  38 +-
 .../src/automaton/convert/ToRegExpAlgebraic.h |   8 +-
 .../convert/ToRegExpStateElimination.cpp      |  47 ++-
 .../convert/ToRegExpStateElimination.h        |   4 +-
 .../properties/AllEpsilonClosure.cpp          |   2 +-
 .../equations/LeftRegularEquationSolver.cpp   |  22 +-
 .../src/equations/LeftRegularEquationSolver.h |   2 +-
 .../src/equations/RegularEquationSolver.cpp   |  18 +-
 .../src/equations/RegularEquationSolver.h     |  12 +-
 .../equations/RightRegularEquationSolver.cpp  |  22 +-
 .../equations/RightRegularEquationSolver.h    |   2 +-
 .../src/grammar/convert/ToRegExpAlgebraic.cpp |  12 +-
 alib2algo/src/regexp/convert/ToAutomaton.cpp  |   8 +-
 alib2algo/src/regexp/convert/ToAutomaton.h    |   4 +-
 .../regexp/convert/ToAutomatonDerivation.cpp  |   4 +-
 .../regexp/convert/ToAutomatonGlushkov.cpp    |  16 +-
 .../src/regexp/convert/ToAutomatonGlushkov.h  |   4 +-
 .../regexp/convert/ToAutomatonThompson.cpp    |  32 +-
 .../src/regexp/convert/ToAutomatonThompson.h  |  28 +-
 alib2algo/src/regexp/convert/ToGrammar.cpp    |   8 +-
 alib2algo/src/regexp/convert/ToGrammar.h      |   4 +-
 .../convert/ToGrammarRightRGDerivation.cpp    |   4 +-
 .../convert/ToGrammarRightRGGlushkov.cpp      |  16 +-
 .../regexp/convert/ToGrammarRightRGGlushkov.h |   4 +-
 .../regexp/generate/RandomRegExpFactory.cpp   |  46 +--
 .../src/regexp/generate/RandomRegExpFactory.h |   8 +-
 .../src/regexp/glushkov/GlushkovTraversal.cpp | 184 +++++-----
 .../src/regexp/glushkov/GlushkovTraversal.h   |  78 ++---
 .../src/regexp/properties/RegExpEmpty.cpp     |  40 +--
 alib2algo/src/regexp/properties/RegExpEmpty.h |  36 +-
 .../src/regexp/properties/RegExpEpsilon.cpp   |  40 +--
 .../src/regexp/properties/RegExpEpsilon.h     |  36 +-
 .../src/regexp/simplify/RegExpOptimize.cpp    |  24 +-
 .../src/regexp/simplify/RegExpOptimize.h      | 130 +++----
 .../simplify/RegExpOptimizeFormalPart.cxx     | 262 +++++++-------
 .../simplify/RegExpOptimizeUnboundedPart.cxx  | 324 +++++++++---------
 .../src/regexp/transform/RegExpAlternate.cpp  |  22 +-
 .../src/regexp/transform/RegExpAlternate.h    |   8 +-
 .../regexp/transform/RegExpConcatenate.cpp    |  22 +-
 .../src/regexp/transform/RegExpConcatenate.h  |   8 +-
 .../src/regexp/transform/RegExpDerivation.cpp |  94 ++---
 .../src/regexp/transform/RegExpDerivation.h   |  28 +-
 .../src/regexp/transform/RegExpIntegral.cpp   |  88 ++---
 .../src/regexp/transform/RegExpIntegral.h     |  28 +-
 .../src/regexp/transform/RegExpIterate.cpp    |  20 +-
 .../src/regexp/transform/RegExpIterate.h      |   8 +-
 alib2algo/test-src/regexp/RegExpTest.cpp      |  48 +--
 .../regexp/simplify/RegExpOptimizeTest.cpp    |  18 +-
 .../test-src/regexp/toAutomaton/re2faTest.cpp |   4 +-
 .../transform/RegExpConcatenateTest.cpp       |  10 +-
 .../regexp/formal/FormalRegExpAlternation.h   |   4 +-
 .../regexp/formal/FormalRegExpConcatenation.h |   4 +-
 .../src/regexp/formal/FormalRegExpIteration.h |   2 +-
 .../unbounded/UnboundedRegExpIteration.h      |   2 +-
 .../efficient/AllEpsilonClosure.cpp           |   2 +-
 .../src/regexp/RegExpFromStringParser.cpp     |  46 +--
 alib2str/src/regexp/RegExpFromStringParser.h  |  18 +-
 alib2str/src/regexp/RegExpStringApi.cpp       |   4 +-
 alib2str/src/regexp/RegExpStringApi.hpp       |   6 +-
 .../src/regexp/RegExpToStringComposer.cpp     |  36 +-
 alib2str/src/regexp/RegExpToStringComposer.h  |  32 +-
 arand2/src/arand.cpp                          |   2 +-
 64 files changed, 1050 insertions(+), 1055 deletions(-)

diff --git a/aaccess2/src/RegExpAccess.cpp b/aaccess2/src/RegExpAccess.cpp
index 17998dba06..b2a8aa3113 100644
--- a/aaccess2/src/RegExpAccess.cpp
+++ b/aaccess2/src/RegExpAccess.cpp
@@ -29,7 +29,7 @@ void RegExpAccess::access ( regexp::RegExp & regexp, const RegExpSettings::Setti
 	dispatch ( regexp.getData ( ), settings, operation, argument );
 }
 
-void RegExpAccess::access ( regexp::FormalRegExp & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument ) {
+void RegExpAccess::access ( regexp::FormalRegExp < > & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument ) {
 	if ( settings == RegExpSettings::Settings::ALPHABET )
 		return handleComponent < regexp::GeneralAlphabet > ( regexp, operation, argument );
 
@@ -38,9 +38,9 @@ void RegExpAccess::access ( regexp::FormalRegExp & regexp, const RegExpSettings:
 	throw exception::CommonException ( "Component not available" );
 }
 
-auto RegExpAccessFormalRegExp = RegExpAccess::RegistratorWrapper < void, regexp::FormalRegExp > ( RegExpAccess::access );
+auto RegExpAccessFormalRegExp = RegExpAccess::RegistratorWrapper < void, regexp::FormalRegExp < > > ( RegExpAccess::access );
 
-void RegExpAccess::access ( regexp::UnboundedRegExp & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument ) {
+void RegExpAccess::access ( regexp::UnboundedRegExp < > & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument ) {
 	if ( settings == RegExpSettings::Settings::ALPHABET )
 		return handleComponent < regexp::GeneralAlphabet > ( regexp, operation, argument );
 
@@ -49,4 +49,4 @@ void RegExpAccess::access ( regexp::UnboundedRegExp & regexp, const RegExpSettin
 	throw exception::CommonException ( "Component not available" );
 }
 
-auto RegExpAccessUnboundedRegExp = RegExpAccess::RegistratorWrapper < void, regexp::UnboundedRegExp > ( RegExpAccess::access );
+auto RegExpAccessUnboundedRegExp = RegExpAccess::RegistratorWrapper < void, regexp::UnboundedRegExp < > > ( RegExpAccess::access );
diff --git a/aaccess2/src/RegExpAccess.h b/aaccess2/src/RegExpAccess.h
index ad0a268cc9..217279aa64 100644
--- a/aaccess2/src/RegExpAccess.h
+++ b/aaccess2/src/RegExpAccess.h
@@ -21,8 +21,8 @@ class RegExpAccess : public std::SingleDispatch < RegExpAccess, void, regexp::Re
 public:
 	static void access ( regexp::RegExp & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument );
 
-	static void access ( regexp::UnboundedRegExp & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument );
-	static void access ( regexp::FormalRegExp & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument );
+	static void access ( regexp::UnboundedRegExp < > & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument );
+	static void access ( regexp::FormalRegExp < > & regexp, const RegExpSettings::Settings & settings, const OperationSettings::Settings & operation, std::deque < sax::Token > & argument );
 };
 
 #endif /* REG_EXP_ACCESS_H_ */
diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
index 161e31e4b9..f1da7bc1aa 100644
--- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
@@ -26,7 +26,7 @@ regexp::RegExp ToRegExpAlgebraic::convert(const automaton::Automaton& automaton)
 	return dispatch(automaton.getData());
 }
 
-regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::EpsilonNFA < > & automaton ) {
+regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::EpsilonNFA < > & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -35,27 +35,27 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::EpsilonNFA
 
 	for( const auto & q : automaton.getStates( ) ) {
 		if( automaton.getFinalStates( ).count( q ) > 0 )
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon { } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon < alphabet::Symbol > { } );
 	}
 
 	for( const auto & p : automaton.getSymbolTransitions() ) {
 		for( const auto & q : p.second ) {
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpSymbol { p.first.second } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpSymbol < alphabet::Symbol > { p.first.second } );
 		}
 	}
 
 	for( const auto & p : automaton.getEpsilonTransitions() ) {
 		for( const auto & q : p.second ) {
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpEpsilon { } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpEpsilon < alphabet::Symbol > { } );
 		}
 	}
 
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState() ) ) );
 }
 
-auto ToRegExpAlgebraicEpsilonNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::EpsilonNFA < > >(ToRegExpAlgebraic::convert);
+auto ToRegExpAlgebraicEpsilonNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::EpsilonNFA < > >(ToRegExpAlgebraic::convert);
 
-regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::MultiInitialStateNFA < > & automaton ) {
+regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::MultiInitialStateNFA < > & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -64,16 +64,16 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::MultiInitia
 
 	for( const auto & q : automaton.getStates( ) ) {
 		if( automaton.getFinalStates( ).count( q ) > 0 )
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon { } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon < alphabet::Symbol > { } );
 	}
 
 	for( const auto & p : automaton.getTransitions() ) {
 		for( const auto & q : p.second ) {
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpSymbol { p.first.second } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpSymbol < alphabet::Symbol > { p.first.second } );
 		}
 	}
 
-	regexp::UnboundedRegExpAlternation alternation;
+	regexp::UnboundedRegExpAlternation < alphabet::Symbol > alternation;
 	for(const auto& initialSymbol : automaton.getInitialStates() ) {
 		// set symbol for which the solver will solve equation system
 		alphabet::Symbol tmp { alphabet::LabeledSymbol ( initialSymbol ) };
@@ -81,12 +81,12 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::MultiInitia
 		alternation.appendElement( solver.solve( tmp ).getRegExp().getStructure() );
 	}
 
-	return regexp::UnboundedRegExp { regexp::UnboundedRegExpStructure ( alternation ) };
+	return regexp::UnboundedRegExp < > { regexp::UnboundedRegExpStructure < alphabet::Symbol > ( alternation ) };
 }
 
-auto ToRegExpAlgebraicMultiInitialStateNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::MultiInitialStateNFA < > >(ToRegExpAlgebraic::convert);
+auto ToRegExpAlgebraicMultiInitialStateNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::MultiInitialStateNFA < > >(ToRegExpAlgebraic::convert);
 
-regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA < > & automaton ) {
+regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::NFA < > & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -95,21 +95,21 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA < > & a
 
 	for( const auto & q : automaton.getStates( ) ) {
 		if( automaton.getFinalStates( ).count( q ) > 0 )
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon { } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon < alphabet::Symbol > { } );
 	}
 
 	for( const auto & p : automaton.getTransitions() ) {
 		for( const auto & q : p.second ) {
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpSymbol { p.first.second } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( q ) ), regexp::UnboundedRegExpSymbol < alphabet::Symbol > { p.first.second } );
 		}
 	}
 
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState() ) ) );
 }
 
-auto ToRegExpAlgebraicNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::NFA < > >(ToRegExpAlgebraic::convert);
+auto ToRegExpAlgebraicNFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::NFA < > >(ToRegExpAlgebraic::convert);
 
-regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA<> & automaton ) {
+regexp::UnboundedRegExp < > ToRegExpAlgebraic::convert( const automaton::DFA < > & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -118,17 +118,17 @@ regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA<> & aut
 
 	for( const auto & q : automaton.getStates( ) ) {
 		if( automaton.getFinalStates( ).count( q ) > 0 )
-			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon { } );
+			solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( q ) ), regexp::UnboundedRegExpEpsilon < alphabet::Symbol > { } );
 	}
 
 	for( const auto & p : automaton.getTransitions() ) {
-		solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( p.second ) ), regexp::UnboundedRegExpSymbol { p.first.second } );
+		solver.addEquation( alphabet::Symbol( alphabet::LabeledSymbol ( p.first.first ) ), alphabet::Symbol( alphabet::LabeledSymbol( p.second ) ), regexp::UnboundedRegExpSymbol < alphabet::Symbol > { p.first.second } );
 	}
 
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState() ) ) );
 }
 
-auto ToRegExpAlgebraicDFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp, automaton::DFA<>>(ToRegExpAlgebraic::convert);
+auto ToRegExpAlgebraicDFA = ToRegExpAlgebraic::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::DFA < > >(ToRegExpAlgebraic::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
index 2de997c985..fcbc295a48 100644
--- a/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
@@ -38,10 +38,10 @@ public:
 	 */
 	static regexp::RegExp convert(const automaton::Automaton& automaton);
 
-	static regexp::UnboundedRegExp convert(const automaton::EpsilonNFA < > & automaton);
-	static regexp::UnboundedRegExp convert(const automaton::MultiInitialStateNFA < > & automaton);
-	static regexp::UnboundedRegExp convert(const automaton::NFA < > & automaton);
-	static regexp::UnboundedRegExp convert(const automaton::DFA<>& automaton);
+	static regexp::UnboundedRegExp < > convert(const automaton::EpsilonNFA < > & automaton);
+	static regexp::UnboundedRegExp < > convert(const automaton::MultiInitialStateNFA < > & automaton);
+	static regexp::UnboundedRegExp < > convert(const automaton::NFA < > & automaton);
+	static regexp::UnboundedRegExp < > convert(const automaton::DFA<>& automaton);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
index 8949dfb5b9..46b0d7fe9c 100644
--- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
@@ -21,9 +21,9 @@ regexp::RegExp ToRegExpStateElimination::convert(const automaton::Automaton& aut
 }
 
 template<class T>
-regexp::UnboundedRegExp ToRegExpStateElimination::convert(const T& automaton) {
+regexp::UnboundedRegExp < > ToRegExpStateElimination::convert(const T& automaton) {
 	if(automaton.getFinalStates().size() == 0)
-		return regexp::UnboundedRegExp(regexp::UnboundedRegExpStructure(regexp::UnboundedRegExpEmpty()));
+		return regexp::UnboundedRegExp < > (regexp::UnboundedRegExpStructure < alphabet::Symbol > (regexp::UnboundedRegExpEmpty < alphabet::Symbol > ()));
 
 	// steps 1 + 2
 	automaton::ExtendedNFA extendedAutomaton(automaton);
@@ -39,18 +39,17 @@ regexp::UnboundedRegExp ToRegExpStateElimination::convert(const T& automaton) {
 		extendedAutomaton = eliminateState(extendedAutomaton, state);
 
 	// step 4
-	regexp::UnboundedRegExpStructure finalStateLoop = regexp::RegExpIterate::iterate ( transition(extendedAutomaton, *extendedAutomaton.getFinalStates().begin(), *extendedAutomaton.getFinalStates().begin()));
-	regexp::UnboundedRegExpStructure initialToFinalState = regexp::RegExpConcatenate::concatenate ( transition(extendedAutomaton, extendedAutomaton.getInitialState(), *extendedAutomaton.getFinalStates().begin()),finalStateLoop );
-	return regexp::UnboundedRegExp(regexp::simplify::RegExpOptimize::optimize(initialToFinalState));
+	regexp::UnboundedRegExpStructure < alphabet::Symbol > finalStateLoop = regexp::RegExpIterate::iterate ( transition(extendedAutomaton, *extendedAutomaton.getFinalStates().begin(), *extendedAutomaton.getFinalStates().begin()));
+	regexp::UnboundedRegExpStructure < alphabet::Symbol > initialToFinalState = regexp::RegExpConcatenate::concatenate ( transition(extendedAutomaton, extendedAutomaton.getInitialState(), *extendedAutomaton.getFinalStates().begin()),finalStateLoop );
+	return regexp::UnboundedRegExp < > (regexp::simplify::RegExpOptimize::optimize(initialToFinalState));
 }
 
-auto ToRegExpStateEliminationEpsilonNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp, automaton::EpsilonNFA < > >(ToRegExpStateElimination::convert);
-auto ToRegExpStateEliminationMultiInitialStateNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp, automaton::MultiInitialStateNFA < > >(ToRegExpStateElimination::convert);
-auto ToRegExpStateEliminationNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp, automaton::NFA < > >(ToRegExpStateElimination::convert);
-auto ToRegExpStateEliminationDFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp, automaton::DFA<>>(ToRegExpStateElimination::convert);
-auto ToRegExpStateEliminationExtendedNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp, automaton::ExtendedNFA>(ToRegExpStateElimination::convert);
-auto ToRegExpStateEliminationCompactNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp, automaton::CompactNFA < > >(ToRegExpStateElimination::convert);
-
+auto ToRegExpStateEliminationEpsilonNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::EpsilonNFA < > >(ToRegExpStateElimination::convert);
+auto ToRegExpStateEliminationMultiInitialStateNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::MultiInitialStateNFA < > >(ToRegExpStateElimination::convert);
+auto ToRegExpStateEliminationNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::NFA < > >(ToRegExpStateElimination::convert);
+auto ToRegExpStateEliminationDFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::DFA<>>(ToRegExpStateElimination::convert);
+auto ToRegExpStateEliminationExtendedNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::ExtendedNFA>(ToRegExpStateElimination::convert);
+auto ToRegExpStateEliminationCompactNFA = ToRegExpStateElimination::RegistratorWrapper<regexp::UnboundedRegExp < >, automaton::CompactNFA < > >(ToRegExpStateElimination::convert);
 
 automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const label::Label& q) {
 	automaton::ExtendedNFA newAutomaton(extendedAutomaton.getInitialState()); // sure that q is neither initial nor final (follows from step 2 - extending ExtendedNFA)
@@ -59,15 +58,13 @@ automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton:
 	newAutomaton.setInputAlphabet(extendedAutomaton.getInputAlphabet());
 	newAutomaton.setFinalStates(extendedAutomaton.getFinalStates());
 
-	for(const auto& p: newAutomaton.getStates())
-	{
-		for(const auto& r : newAutomaton.getStates())
-		{
-			regexp::UnboundedRegExpStructure concat = transition(extendedAutomaton, p, q);
+	for(const auto& p: newAutomaton.getStates()) {
+		for(const auto& r : newAutomaton.getStates()) {
+			regexp::UnboundedRegExpStructure < alphabet::Symbol > concat = transition(extendedAutomaton, p, q);
 			concat = regexp::RegExpConcatenate::concatenate(concat, regexp::RegExpIterate::iterate(transition(extendedAutomaton, q, q)));
 			concat = regexp::RegExpConcatenate::concatenate(concat, transition(extendedAutomaton, q, r));
 
-			regexp::UnboundedRegExpStructure alt = regexp::RegExpAlternate::alternate(concat, transition(extendedAutomaton, p, r));
+			regexp::UnboundedRegExpStructure < alphabet::Symbol > alt = regexp::RegExpAlternate::alternate(concat, transition(extendedAutomaton, p, r));
 
 			newAutomaton.addTransition(p, regexp::simplify::RegExpOptimize::optimize(alt), r);
 		}
@@ -76,8 +73,8 @@ automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton:
 	return newAutomaton;
 }
 
-const regexp::UnboundedRegExpStructure ToRegExpStateElimination::transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to) {
-	regexp::UnboundedRegExpStructure ret(regexp::UnboundedRegExpEmpty { });
+const regexp::UnboundedRegExpStructure < alphabet::Symbol > ToRegExpStateElimination::transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to) {
+	regexp::UnboundedRegExpStructure < alphabet::Symbol > ret(regexp::UnboundedRegExpEmpty < alphabet::Symbol > { });
 
 	for(const auto& transition: automaton.getTransitionsFromState(from))
 		if(transition.second.count(to) > 0)
@@ -88,24 +85,22 @@ const regexp::UnboundedRegExpStructure ToRegExpStateElimination::transition(cons
 
 void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton) {
 	const label::Label& initState = automaton.getInitialState();
-	if(automaton.getFinalStates().count(initState) > 0 || automaton.getTransitionsToState(initState).size() > 0 )
-	{
+	if(automaton.getFinalStates().count(initState) > 0 || automaton.getTransitionsToState(initState).size() > 0 ) {
 		label::Label q0 = label::createUniqueLabel(initState, automaton.getStates());
 		automaton.addState(q0);
 
-		regexp::UnboundedRegExpStructure regexp { regexp::UnboundedRegExpEpsilon() };
+		regexp::UnboundedRegExpStructure < alphabet::Symbol > regexp { regexp::UnboundedRegExpEpsilon < alphabet::Symbol > () };
 		automaton.addTransition(q0, regexp, initState);
 
 		automaton.setInitialState(q0);
 	}
 
-	if(automaton.getFinalStates().size() > 1)
-	{
+	if(automaton.getFinalStates().size() > 1) {
 		label::Label f = label::createUniqueLabel(label::labelFrom("f"), automaton.getStates());
 		automaton.addState(f);
 
 		for(const auto &state : automaton.getFinalStates() ) {
-			regexp::UnboundedRegExpStructure regexp { regexp::UnboundedRegExpEpsilon() };
+			regexp::UnboundedRegExpStructure < alphabet::Symbol > regexp { regexp::UnboundedRegExpEpsilon < alphabet::Symbol > () };
 			automaton.addTransition(state, regexp, f);
 
 			automaton.removeFinalState(state);
diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.h b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
index 8f3593aae4..070566a241 100644
--- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
@@ -38,12 +38,12 @@ public:
 	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:
 	static void extendExtendedNFA(automaton::ExtendedNFA& automaton);
 
-	static const regexp::UnboundedRegExpStructure transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to);
+	static const regexp::UnboundedRegExpStructure < alphabet::Symbol > transition(const automaton::ExtendedNFA& automaton, const label::Label& from, const label::Label& to);
 
 	static automaton::ExtendedNFA eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const label::Label& state);
 };
diff --git a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
index cf2350b8d9..cff859cd7a 100644
--- a/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/AllEpsilonClosure.cpp
@@ -85,7 +85,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 	std::map<label::Label, std::set<label::Label>> res;
 	std::map<label::Label, std::set<label::Label>> step;
 
-	for(const std::pair<const std::pair<label::Label, regexp::UnboundedRegExpStructure>, std::set<label::Label> >& transition : fsm.getTransitions() )
+	for(const std::pair<const std::pair<label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set<label::Label> >& transition : fsm.getTransitions() )
 		if( regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
 			step[transition.first.first].insert(transition.second.begin(), transition.second.end());
 
diff --git a/alib2algo/src/equations/LeftRegularEquationSolver.cpp b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
index 9e335c9016..52b1dfe3c2 100644
--- a/alib2algo/src/equations/LeftRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
@@ -12,7 +12,7 @@
 
 namespace equations {
 
-regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
+regexp::UnboundedRegExp < > LeftRegularEquationSolver::eliminate(void) {
 	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); ++ itA) {
 		const alphabet::Symbol& a = * itA;
 
@@ -21,24 +21,24 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 		 * A = A0 + B1 + C2
 		 * => A = 10*B + 20*C
 		 */
-		regexp::UnboundedRegExpIteration loop(std::move(equationTransition.find(std::make_pair(a, a))->second));
+		regexp::UnboundedRegExpIteration < alphabet::Symbol > loop(std::move(equationTransition.find(std::make_pair(a, a))->second));
 		regexp::simplify::RegExpOptimize::optimize(loop);
 
 		// for all transitions from A apply Arden's Lemma
 		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); ++ itB) {
 			const alphabet::Symbol& b = * itB;
-			regexp::UnboundedRegExpConcatenation concat;
+			regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 			concat.appendElement(std::move(equationTransition.find(std::make_pair(a, b))->second));
 			concat.appendElement(loop);
-			regexp::UnboundedRegExpAlternation alt;
+			regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 			alt.appendElement(std::move(concat));
 			equationTransition.find(std::make_pair(a, b))->second = std::move(alt);
 			regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second);
 		}
-		regexp::UnboundedRegExpConcatenation concat;
+		regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 		concat.appendElement(std::move(equationFinal.find(a)->second));
 		concat.appendElement(std::move(loop));
-		regexp::UnboundedRegExpAlternation alt;
+		regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 		alt.appendElement(std::move(concat));
 		equationFinal.find(a)->second = std::move(alt);
 		regexp::simplify::RegExpOptimize::optimize(equationFinal.find(a)->second);
@@ -53,20 +53,20 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 			for(auto itC = std::next(itA); itC != nonterminalSymbolsByDepth.rend(); ++ itC) {
 				const alphabet::Symbol& c = * itC;
 
-				regexp::UnboundedRegExpConcatenation concat;
+				regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 				concat.appendElement(equationTransition.find(std::make_pair(a, c))->second);
 				concat.appendElement(equationTransition.find(std::make_pair(b, a))->second);
-				regexp::UnboundedRegExpAlternation alt;
+				regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 				alt.appendElement(std::move(equationTransition.find(std::make_pair(b, c))->second));
 				alt.appendElement(std::move(concat));
 				equationTransition.find(std::make_pair(b, c))->second = std::move(alt);
 				regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second);
 			}
 
-			regexp::UnboundedRegExpConcatenation concat;
+			regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 			concat.appendElement(equationFinal.find(a)->second);
 			concat.appendElement(std::move(equationTransition.find(std::make_pair(b, a))->second));
-			regexp::UnboundedRegExpAlternation alt;
+			regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 			alt.appendElement(std::move(equationFinal.find(b)->second));
 			alt.appendElement(std::move(concat));
 			equationFinal.find(b)->second = std::move(alt);
@@ -74,7 +74,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 		}
 	}
 
-	return regexp::UnboundedRegExp(regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExpStructure(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))));
+	return regexp::UnboundedRegExp < > (regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExpStructure < alphabet::Symbol > (std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))));
 }
 
 } /* namespace equations */
diff --git a/alib2algo/src/equations/LeftRegularEquationSolver.h b/alib2algo/src/equations/LeftRegularEquationSolver.h
index d5f93780eb..a4de207c74 100644
--- a/alib2algo/src/equations/LeftRegularEquationSolver.h
+++ b/alib2algo/src/equations/LeftRegularEquationSolver.h
@@ -16,7 +16,7 @@ class LeftRegularEquationSolver : public RegularEquationSolver {
 	/**
 	 * @copydoc RegularEquationSolver::eliminate(void)
 	 */
-	virtual regexp::UnboundedRegExp eliminate( void );
+	virtual regexp::UnboundedRegExp < > eliminate( void );
 
 };
 
diff --git a/alib2algo/src/equations/RegularEquationSolver.cpp b/alib2algo/src/equations/RegularEquationSolver.cpp
index bf467f2804..25bb443842 100644
--- a/alib2algo/src/equations/RegularEquationSolver.cpp
+++ b/alib2algo/src/equations/RegularEquationSolver.cpp
@@ -32,7 +32,7 @@ void RegularEquationSolver::removeSymbol(const alphabet::Symbol& symb) {
 	for(const auto& kv : equationTransition) {
 		const alphabet::Symbol& from = kv.first.first;
 		const alphabet::Symbol& to = kv.first.second;
-		const regexp::UnboundedRegExpAlternation& alt = kv.second;
+		const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alt = kv.second;
 
 		if((from == symb || to == symb) && alt.getElements().size() != 0) {
 			throw exception::CommonException("Symbol '" + (std::string) symb + "' is in use.");
@@ -41,7 +41,7 @@ void RegularEquationSolver::removeSymbol(const alphabet::Symbol& symb) {
 
 	for(const auto& kv : equationFinal) {
 		const alphabet::Symbol& from = kv.first;
-		const regexp::UnboundedRegExpAlternation& alt = kv.second;
+		const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alt = kv.second;
 
 		if(from == symb && alt.getElements().size() != 0) {
 			throw exception::CommonException("Symbol '" + (std::string) from + "' is in use.");
@@ -61,16 +61,16 @@ void RegularEquationSolver::removeSymbol(const alphabet::Symbol& symb) {
 
 void RegularEquationSolver::addSymbol(const alphabet::Symbol& symb) {
 	for(const auto& s : nonterminalSymbols) {
-		equationTransition.insert(std::make_pair(std::make_pair(symb, s), regexp::UnboundedRegExpAlternation { }));
-		equationTransition.insert(std::make_pair(std::make_pair(s, symb), regexp::UnboundedRegExpAlternation { }));
+		equationTransition.insert(std::make_pair(std::make_pair(symb, s), regexp::UnboundedRegExpAlternation < alphabet::Symbol >  { }));
+		equationTransition.insert(std::make_pair(std::make_pair(s, symb), regexp::UnboundedRegExpAlternation < alphabet::Symbol >  { }));
 	}
-	equationTransition.insert(std::make_pair(std::make_pair(symb, symb), regexp::UnboundedRegExpAlternation { }));
+	equationTransition.insert(std::make_pair(std::make_pair(symb, symb), regexp::UnboundedRegExpAlternation < alphabet::Symbol >  { }));
 
 	nonterminalSymbols.insert(symb);
-	equationFinal.insert(std::make_pair(symb, regexp::UnboundedRegExpAlternation { }));
+	equationFinal.insert(std::make_pair(symb, regexp::UnboundedRegExpAlternation < alphabet::Symbol >  { }));
 }
 
-void RegularEquationSolver::addEquation(const alphabet::Symbol& from, const alphabet::Symbol& to, const regexp::UnboundedRegExpElement& eq) {
+void RegularEquationSolver::addEquation(const alphabet::Symbol& from, const alphabet::Symbol& to, const regexp::UnboundedRegExpElement < alphabet::Symbol > & eq) {
 	if(nonterminalSymbols.count(from) == 0) {
 		throw exception::CommonException("Symbol from ('" + (std::string) from + "') is not in equation system.");
 	}
@@ -82,7 +82,7 @@ void RegularEquationSolver::addEquation(const alphabet::Symbol& from, const alph
 	equationTransition.find(std::make_pair(from, to))->second.appendElement(eq);
 }
 
-void RegularEquationSolver::addEquation(const alphabet::Symbol& from, const regexp::UnboundedRegExpElement& eq) {
+void RegularEquationSolver::addEquation(const alphabet::Symbol& from, const regexp::UnboundedRegExpElement < alphabet::Symbol > & eq) {
 	if(nonterminalSymbols.count(from) == 0) {
 		throw exception::CommonException("Symbol from ('" + (std::string) from + "') is not in equation system.");
 	}
@@ -117,7 +117,7 @@ void RegularEquationSolver::sortSymbolsByDepth(const alphabet::Symbol& solveFor)
 	}
 }
 
-regexp::UnboundedRegExp RegularEquationSolver::solve(const alphabet::Symbol& solveFor) {
+regexp::UnboundedRegExp < > RegularEquationSolver::solve(const alphabet::Symbol& solveFor) {
 	if(nonterminalSymbols.count(solveFor) == 0) {
 		throw exception::CommonException("Symbol solveFor ('" + (std::string) solveFor + "') is not in equation system.");
 	}
diff --git a/alib2algo/src/equations/RegularEquationSolver.h b/alib2algo/src/equations/RegularEquationSolver.h
index 5e6249fd9b..2efe44f826 100644
--- a/alib2algo/src/equations/RegularEquationSolver.h
+++ b/alib2algo/src/equations/RegularEquationSolver.h
@@ -53,7 +53,7 @@ public:
 	 * @param to symbol
 	 * @param eq equation
 	 */
-	void addEquation(const alphabet::Symbol& from, const alphabet::Symbol& to, const regexp::UnboundedRegExpElement& eq);
+	void addEquation(const alphabet::Symbol& from, const alphabet::Symbol& to, const regexp::UnboundedRegExpElement < alphabet::Symbol > & eq);
 
 	/**
 	 * Adds equation in form: FROM = eq
@@ -61,7 +61,7 @@ public:
 	 * @param from
 	 * @param eq
 	 */
-	void addEquation(const alphabet::Symbol& from, const regexp::UnboundedRegExpElement& eq);
+	void addEquation(const alphabet::Symbol& from, const regexp::UnboundedRegExpElement < alphabet::Symbol > & eq);
 
 	/**
 	 * Solve expression system
@@ -69,14 +69,14 @@ public:
 	 * @param solveFor will solve equation system for given symbol
 	 * @return regexp
 	 */
-	regexp::UnboundedRegExp solve(const alphabet::Symbol& solveFor);
+	regexp::UnboundedRegExp < > solve(const alphabet::Symbol& solveFor);
 
 protected:
 	/**
 	 * actual equations elimination
 	 * @return pointer to solutions RegExp tree root
 	 */
-	virtual regexp::UnboundedRegExp eliminate(void) = 0;
+	virtual regexp::UnboundedRegExp < > eliminate(void) = 0;
 
 	/**
 	 * Runs BFS to determine depth of symbols in equation system and stores it in nonterminalSymbolsByDepth;
@@ -92,12 +92,12 @@ protected:
 	/**
 	 * Stores transitions from nonterminal to nonterminal, eg A = 2A + 2B + 1C
 	 */
-	std::map<std::pair<alphabet::Symbol, alphabet::Symbol>, regexp::UnboundedRegExpAlternation> equationTransition;
+	std::map<std::pair<alphabet::Symbol, alphabet::Symbol>, regexp::UnboundedRegExpAlternation < alphabet::Symbol > > equationTransition;
 
 	/**
 	 * Stores equation not going to particular nonterminal, eg A = 01*
 	 */
-	std::map<alphabet::Symbol, regexp::UnboundedRegExpAlternation> equationFinal;
+	std::map<alphabet::Symbol, regexp::UnboundedRegExpAlternation < alphabet::Symbol > > equationFinal;
 
 	/**
 	 * Set of symbols
diff --git a/alib2algo/src/equations/RightRegularEquationSolver.cpp b/alib2algo/src/equations/RightRegularEquationSolver.cpp
index ba020d4c87..891caedf8b 100644
--- a/alib2algo/src/equations/RightRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/RightRegularEquationSolver.cpp
@@ -12,7 +12,7 @@
 
 namespace equations {
 
-regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
+regexp::UnboundedRegExp < > RightRegularEquationSolver::eliminate(void) {
 	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); ++ itA) {
 		const alphabet::Symbol& a = * itA;
 
@@ -21,24 +21,24 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 		 * A = 0A + 1B + 2C
 		 * => A = 0*1B + 0*2C
 		 */
-		regexp::UnboundedRegExpIteration loop(std::move(equationTransition.find(std::make_pair(a, a))->second));
+		regexp::UnboundedRegExpIteration < alphabet::Symbol > loop(std::move(equationTransition.find(std::make_pair(a, a))->second));
 		regexp::simplify::RegExpOptimize::optimize(loop);
 
 		// for all transitions from A apply Arden's Lemma
 		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); ++ itB) {
 			const alphabet::Symbol& b = * itB;
-			regexp::UnboundedRegExpConcatenation concat;
+			regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 			concat.appendElement(loop);
 			concat.appendElement(std::move(equationTransition.find(std::make_pair(a,b))->second));
-			regexp::UnboundedRegExpAlternation alt;
+			regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 			alt.appendElement(std::move(concat));
 			equationTransition.find(std::make_pair(a, b))->second = std::move(alt);
 			regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second);
 		}
-		regexp::UnboundedRegExpConcatenation concat;
+		regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 		concat.appendElement(std::move(loop));
 		concat.appendElement(std::move(equationFinal.find(a)->second));
-		regexp::UnboundedRegExpAlternation alt;
+		regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 		alt.appendElement(std::move(concat));
 		equationFinal.find(a)->second = std::move(alt);
 		regexp::simplify::RegExpOptimize::optimize(equationFinal.find(a)->second);
@@ -53,20 +53,20 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 			for(auto itC = std::next(itA); itC != nonterminalSymbolsByDepth.rend(); ++ itC) {
 				const alphabet::Symbol& c = * itC;
 
-				regexp::UnboundedRegExpConcatenation concat;
+				regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 				concat.appendElement(equationTransition.find(std::make_pair(b, a))->second);
 				concat.appendElement(equationTransition.find(std::make_pair(a, c))->second);
-				regexp::UnboundedRegExpAlternation alt;
+				regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 				alt.appendElement(std::move(equationTransition.find(std::make_pair(b, c))->second));
 				alt.appendElement(std::move(concat));
 				equationTransition.find(std::make_pair(b, c))->second = std::move(alt);
 				regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second);
 			}
 
-			regexp::UnboundedRegExpConcatenation concat;
+			regexp::UnboundedRegExpConcatenation < alphabet::Symbol > concat;
 			concat.appendElement(std::move(equationTransition.find(std::make_pair(b, a))->second));
 			concat.appendElement(equationFinal.find(a)->second);
-			regexp::UnboundedRegExpAlternation alt;
+			regexp::UnboundedRegExpAlternation < alphabet::Symbol >  alt;
 			alt.appendElement(std::move(equationFinal.find(b)->second));
 			alt.appendElement(std::move(concat));
 			equationFinal.find(b)->second = std::move(alt);
@@ -74,7 +74,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 		}
 	}
 
-	return regexp::UnboundedRegExp(regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExpStructure(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))));
+	return regexp::UnboundedRegExp < > (regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExpStructure < alphabet::Symbol > (std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second))));
 }
 
 } /* namespace equations */
diff --git a/alib2algo/src/equations/RightRegularEquationSolver.h b/alib2algo/src/equations/RightRegularEquationSolver.h
index dffbedfc4e..1a4cf23cb7 100644
--- a/alib2algo/src/equations/RightRegularEquationSolver.h
+++ b/alib2algo/src/equations/RightRegularEquationSolver.h
@@ -16,7 +16,7 @@ class RightRegularEquationSolver : public RegularEquationSolver {
 	/**
 	 * @copydoc RegularEquationSolver::eliminate(void)
 	 */
-	virtual regexp::UnboundedRegExp eliminate( void );
+	virtual regexp::UnboundedRegExp < > eliminate( void );
 
 };
 
diff --git a/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp
index 4b7d5cd642..a424fb484c 100644
--- a/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp
+++ b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp
@@ -33,15 +33,15 @@ regexp::RegExp ToRegExpAlgebraic::convert(const grammar::LeftRG < > & grammar) {
 		for(const auto& ruleRHS : rule.second) {
 			if(ruleRHS.is<alphabet::Symbol>()) {
 				const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
-				solver.addEquation(lhs, regexp::UnboundedRegExpSymbol(rhs));
+				solver.addEquation(lhs, regexp::UnboundedRegExpSymbol < alphabet::Symbol > (rhs));
 			} else {
 				const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
-				solver.addEquation(lhs, rhs.first, regexp::UnboundedRegExpSymbol(rhs.second));
+				solver.addEquation(lhs, rhs.first, regexp::UnboundedRegExpSymbol < alphabet::Symbol > (rhs.second));
 			}
 		}
 	}
 	if(grammar.getGeneratesEpsilon())
-		solver.addEquation(grammar.getInitialSymbol(), regexp::UnboundedRegExpEpsilon());
+		solver.addEquation(grammar.getInitialSymbol(), regexp::UnboundedRegExpEpsilon < alphabet::Symbol > ());
 
 	return regexp::RegExp{solver.solve(grammar.getInitialSymbol())};
 }
@@ -60,15 +60,15 @@ regexp::RegExp ToRegExpAlgebraic::convert(const grammar::RightRG < > & grammar)
 		for(const auto& ruleRHS : rule.second) {
 			if(ruleRHS.is<alphabet::Symbol>()) {
 				const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
-				solver.addEquation(lhs, regexp::UnboundedRegExpSymbol(rhs));
+				solver.addEquation(lhs, regexp::UnboundedRegExpSymbol < alphabet::Symbol > (rhs));
 			} else {
 				const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
-				solver.addEquation(lhs, rhs.second, regexp::UnboundedRegExpSymbol(rhs.first));
+				solver.addEquation(lhs, rhs.second, regexp::UnboundedRegExpSymbol < alphabet::Symbol > (rhs.first));
 			}
 		}
 	}
 	if(grammar.getGeneratesEpsilon())
-		solver.addEquation(grammar.getInitialSymbol(), regexp::UnboundedRegExpEpsilon());
+		solver.addEquation(grammar.getInitialSymbol(), regexp::UnboundedRegExpEpsilon < alphabet::Symbol > ());
 
 	return regexp::RegExp{solver.solve(grammar.getInitialSymbol())};
 }
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.cpp b/alib2algo/src/regexp/convert/ToAutomaton.cpp
index d8b58eefd2..3ae1558fe0 100644
--- a/alib2algo/src/regexp/convert/ToAutomaton.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomaton.cpp
@@ -16,17 +16,17 @@ automaton::Automaton ToAutomaton::convert(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
-automaton::Automaton ToAutomaton::convert(const regexp::FormalRegExp& regexp) {
+automaton::Automaton ToAutomaton::convert(const regexp::FormalRegExp < > & regexp) {
 	return automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
 }
 
-auto ToAutomatonFormalRegExp = ToAutomaton::RegistratorWrapper<automaton::Automaton, regexp::FormalRegExp>(ToAutomaton::convert);
+auto ToAutomatonFormalRegExp = ToAutomaton::RegistratorWrapper<automaton::Automaton, regexp::FormalRegExp < > >(ToAutomaton::convert);
 
-automaton::Automaton ToAutomaton::convert(const regexp::UnboundedRegExp& regexp) {
+automaton::Automaton ToAutomaton::convert(const regexp::UnboundedRegExp < > & regexp) {
 	return automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
 }
 
-auto ToAutomatonUnboundedRegExp = ToAutomaton::RegistratorWrapper<automaton::Automaton, regexp::UnboundedRegExp>( ToAutomaton::convert);
+auto ToAutomatonUnboundedRegExp = ToAutomaton::RegistratorWrapper<automaton::Automaton, regexp::UnboundedRegExp < > >( ToAutomaton::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.h b/alib2algo/src/regexp/convert/ToAutomaton.h
index 17858bddd8..bcbb8b9e9f 100644
--- a/alib2algo/src/regexp/convert/ToAutomaton.h
+++ b/alib2algo/src/regexp/convert/ToAutomaton.h
@@ -28,8 +28,8 @@ public:
 	 */
 	static automaton::Automaton convert(const regexp::RegExp& regexp);
 
-	static automaton::Automaton convert(const regexp::FormalRegExp& regexp);
-	static automaton::Automaton convert(const regexp::UnboundedRegExp& regexp);
+	static automaton::Automaton convert(const regexp::FormalRegExp < > & regexp);
+	static automaton::Automaton convert(const regexp::UnboundedRegExp < > & regexp);
 
 };
 
diff --git a/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
index a8a5b058c2..c3d212f3f0 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
@@ -99,8 +99,8 @@ automaton::DFA<> ToAutomatonDerivation::convert(const T& regexp) {
 	return automaton;
 }
 
-auto ToAutomatonDerivationFormalRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA<>, regexp::FormalRegExp>( ToAutomatonDerivation::convert);
-auto ToAutomatonDerivationUnboundedRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA<>, regexp::UnboundedRegExp>( ToAutomatonDerivation::convert);
+auto ToAutomatonDerivationFormalRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA<>, regexp::FormalRegExp < > >( ToAutomatonDerivation::convert);
+auto ToAutomatonDerivationUnboundedRegExp = ToAutomatonDerivation::RegistratorWrapper<automaton::DFA<>, regexp::UnboundedRegExp < > >( ToAutomatonDerivation::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
index ed6e500989..e8815fff6a 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
@@ -27,18 +27,18 @@ automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::RegExp & regexp
 	return dispatch ( regexp.getData ( ) );
 }
 
-automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp & regexp ) {
+automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp < > & regexp ) {
 	label::Label q0 ( label::LabelPairLabel ( std::make_pair ( label::labelFrom ( 'q' ), label::labelFrom ( 0 ) ) ) );
 	automaton::NFA < > automaton ( q0 );
 
 	 // step 1
 	automaton.setInputAlphabet ( regexp.getAlphabet ( ) );
 
-	regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+	regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
 	 // steps 2, 3, 4
-	const std::set < regexp::UnboundedRegExpSymbol > first = regexp::GlushkovTraversal::first ( indexedRegExp );
-	const std::set < regexp::UnboundedRegExpSymbol > last = regexp::GlushkovTraversal::last ( indexedRegExp );
+	const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp );
+	const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp );
 
 	// \e in q0 check is in step 7
 
@@ -51,7 +51,7 @@ automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp
 		automaton.addTransition ( q0, regexp::GlushkovTraversal::getSymbolFromGlushkovPair ( symbol.getSymbol ( ) ), label::Label ( label::ObjectLabel ( alib::Object ( symbol.getSymbol ( ).getData ( ) ) ) ) );
 
 	for ( const auto & x : indexedRegExp.getAlphabet ( ) )
-		for ( const auto & f : regexp::GlushkovTraversal::follow ( indexedRegExp, UnboundedRegExpSymbol ( x ) ) ) {
+		for ( const auto & f : regexp::GlushkovTraversal::follow ( indexedRegExp, UnboundedRegExpSymbol < alphabet::Symbol > ( x ) ) ) {
 			const alphabet::Symbol & p = x;
 			const alphabet::Symbol & q = f.getSymbol ( );
 
@@ -69,13 +69,13 @@ automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp
 	return automaton;
 }
 
-auto ToAutomatonGlushkovUnboundedRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA < > , regexp::UnboundedRegExp > ( ToAutomatonGlushkov::convert );
+auto ToAutomatonGlushkovUnboundedRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA < > , regexp::UnboundedRegExp < > > ( ToAutomatonGlushkov::convert );
 
-automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::FormalRegExp & /* regexp */ ) {
+automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::FormalRegExp < > & /* regexp */ ) {
 	throw exception::CommonException ( "Glushkov: Converting FormalRegExp NYI" ); // TODO
 }
 
-auto ToAutomatonGlushkovFormalRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA < > , regexp::FormalRegExp > ( ToAutomatonGlushkov::convert );
+auto ToAutomatonGlushkovFormalRegExp = ToAutomatonGlushkov::RegistratorWrapper < automaton::NFA < > , regexp::FormalRegExp < > > ( ToAutomatonGlushkov::convert );
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
index 9968e0f7ba..9b4efac21c 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
@@ -33,8 +33,8 @@ public:
 	 */
 	static automaton::NFA < > convert(const regexp::RegExp& re);
 
-	static automaton::NFA < > convert(const regexp::UnboundedRegExp& re);
-	static automaton::NFA < > convert(const regexp::FormalRegExp& re);
+	static automaton::NFA < > convert(const regexp::UnboundedRegExp < > & re);
+	static automaton::NFA < > convert(const regexp::FormalRegExp < > & re);
 
 };
 
diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
index d2af830fab..79b5c6c310 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
@@ -17,7 +17,7 @@ automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::RegExp& reg
 	return dispatch(regexp.getData());
 }
 
-automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::FormalRegExp & regexp) {
+automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::FormalRegExp < > & regexp) {
 	//FIXME use actual algorithms that implement product alternation and iteration of re over automata and remove terrible TERRIBLE hack with dummy initial state
 	int nextState = 1;
 	const label::Label * headArg = nullptr;
@@ -36,9 +36,9 @@ automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::FormalRegEx
 	return automaton;
 }
 
-auto ToAutomatonThompsonFormalRegExp = ToAutomatonThompson::RegistratorWrapper<automaton::EpsilonNFA < >, regexp::FormalRegExp>(ToAutomatonThompson::convert);
+auto ToAutomatonThompsonFormalRegExp = ToAutomatonThompson::RegistratorWrapper<automaton::EpsilonNFA < >, regexp::FormalRegExp < > >(ToAutomatonThompson::convert);
 
-automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::UnboundedRegExp & regexp) {
+automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::UnboundedRegExp < > & regexp) {
 	//FIXME use actual algorithms that implement product alternation and iteration of re over automata and remove terrible TERRIBLE hack with dummy initial state
 	int nextState = 1;
 	const label::Label * headArg = nullptr;
@@ -57,11 +57,11 @@ automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::UnboundedRe
 	return automaton;
 }
 
-auto ToAutomatonThompsonUnboundedRegExp = ToAutomatonThompson::RegistratorWrapper<automaton::EpsilonNFA < >, regexp::UnboundedRegExp>(ToAutomatonThompson::convert);
+auto ToAutomatonThompsonUnboundedRegExp = ToAutomatonThompson::RegistratorWrapper<automaton::EpsilonNFA < >, regexp::UnboundedRegExp < > >(ToAutomatonThompson::convert);
 
 // ----------------------------------------------------------------------------
 
-void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -79,7 +79,7 @@ void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpAlternation& a
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	concatenation.getLeftElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
 	const label::Label* leftHead = headArg;
 	const label::Label* leftTail = tailArg;
@@ -91,7 +91,7 @@ void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpConcatenation&
 	// tailArg = tailArg;
 }
 
-void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -107,7 +107,7 @@ void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpIteration& ite
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -118,7 +118,7 @@ void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpSymbol& symbol
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEpsilon&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > &, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -129,7 +129,7 @@ void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEpsilon&, auto
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEmpty&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > &, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -141,7 +141,7 @@ void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEmpty&, automa
 
 // ----------------------------------------------------------------------------
 
-void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -157,7 +157,7 @@ void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpAlternat
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	std::vector<std::pair<const label::Label*, const label::Label*>> tails;
 	for(const auto& element : concatenation.getElements()) {
 		element->accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
@@ -171,7 +171,7 @@ void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpConcaten
 	tailArg = tails[tails.size()-1].second;
 }
 
-void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -187,7 +187,7 @@ void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpIteratio
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -198,7 +198,7 @@ void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpSymbol&
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > &, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
@@ -209,7 +209,7 @@ void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&
 	tailArg = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > &, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) {
 	label::Label head = label::labelFrom(nextState++);
 	label::Label tail = label::labelFrom(nextState++);
 	automaton.addState(head);
diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.h b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
index c5797afa03..1772e3e5aa 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonThompson.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
@@ -38,27 +38,27 @@ public:
 	 */
 	static automaton::EpsilonNFA < > convert(const regexp::RegExp& regexp);
 
-	static automaton::EpsilonNFA < > convert(const regexp::FormalRegExp& regexp);
-	static automaton::EpsilonNFA < > convert(const regexp::UnboundedRegExp& regexp);
+	static automaton::EpsilonNFA < > convert(const regexp::FormalRegExp < > & regexp);
+	static automaton::EpsilonNFA < > convert(const regexp::UnboundedRegExp < > & regexp);
 
 	class Unbounded {
 	public:
-		static void visit(const regexp::UnboundedRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::UnboundedRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::UnboundedRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::UnboundedRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::UnboundedRegExpEpsilon& epsilon, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::UnboundedRegExpEmpty& empty, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & epsilon, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & empty, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
 	};
 
 	class Formal {
 	public:
-		static void visit(const regexp::FormalRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::FormalRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::FormalRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::FormalRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::FormalRegExpEpsilon& epsilon, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
-		static void visit(const regexp::FormalRegExpEmpty& empty, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > & epsilon, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
+		static void visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > & empty, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg);
 	};
 
 };
diff --git a/alib2algo/src/regexp/convert/ToGrammar.cpp b/alib2algo/src/regexp/convert/ToGrammar.cpp
index 58cd1d3711..d02b338ab0 100644
--- a/alib2algo/src/regexp/convert/ToGrammar.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammar.cpp
@@ -16,17 +16,17 @@ grammar::Grammar ToGrammar::convert(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
-grammar::Grammar ToGrammar::convert(const regexp::FormalRegExp& regexp) {
+grammar::Grammar ToGrammar::convert(const regexp::FormalRegExp < > & regexp) {
 	return grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
 }
 
-auto ToGrammarFormalRegExp = ToGrammar::RegistratorWrapper<grammar::Grammar, regexp::FormalRegExp>(ToGrammar::convert);
+auto ToGrammarFormalRegExp = ToGrammar::RegistratorWrapper<grammar::Grammar, regexp::FormalRegExp < > >(ToGrammar::convert);
 
-grammar::Grammar ToGrammar::convert(const regexp::UnboundedRegExp& regexp) {
+grammar::Grammar ToGrammar::convert(const regexp::UnboundedRegExp < > & regexp) {
 	return grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
 }
 
-auto ToGrammarUnboundedRegExp = ToGrammar::RegistratorWrapper<grammar::Grammar, regexp::UnboundedRegExp>(ToGrammar::convert);
+auto ToGrammarUnboundedRegExp = ToGrammar::RegistratorWrapper<grammar::Grammar, regexp::UnboundedRegExp < > >(ToGrammar::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToGrammar.h b/alib2algo/src/regexp/convert/ToGrammar.h
index 001682aec7..f302528b67 100644
--- a/alib2algo/src/regexp/convert/ToGrammar.h
+++ b/alib2algo/src/regexp/convert/ToGrammar.h
@@ -26,8 +26,8 @@ public:
 	 */
 	static grammar::Grammar convert(const regexp::RegExp& regexp);
 
-	static grammar::Grammar convert(const regexp::FormalRegExp& regexp);
-	static grammar::Grammar convert(const regexp::UnboundedRegExp& regexp);
+	static grammar::Grammar convert(const regexp::FormalRegExp < > & regexp);
+	static grammar::Grammar convert(const regexp::UnboundedRegExp < > & regexp);
 
 };
 
diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
index 4a2c6fccbd..02c716c4d6 100644
--- a/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
@@ -102,8 +102,8 @@ grammar::RightRG < > ToGrammarRightRGDerivation::convert(const T& regexp) {
 	return grammar;
 }
 
-auto ToGrammarRightRGDerivationUnboundedRegExp = ToGrammarRightRGDerivation::RegistratorWrapper<grammar::RightRG < >, regexp::UnboundedRegExp>(ToGrammarRightRGDerivation::convert);
-auto ToGrammarRightRGDerivationFormalRegExp = ToGrammarRightRGDerivation::RegistratorWrapper<grammar::RightRG < >, regexp::FormalRegExp>(ToGrammarRightRGDerivation::convert);
+auto ToGrammarRightRGDerivationUnboundedRegExp = ToGrammarRightRGDerivation::RegistratorWrapper<grammar::RightRG < >, regexp::UnboundedRegExp < > >(ToGrammarRightRGDerivation::convert);
+auto ToGrammarRightRGDerivationFormalRegExp = ToGrammarRightRGDerivation::RegistratorWrapper<grammar::RightRG < >, regexp::FormalRegExp < > >(ToGrammarRightRGDerivation::convert);
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
index 38f96d1323..c0d5c91f8a 100644
--- a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
@@ -29,18 +29,18 @@ grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::RegExp &
 	return dispatch ( regexp.getData ( ) );
 }
 
-grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::UnboundedRegExp & regexp ) {
+grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::UnboundedRegExp < > & regexp ) {
 	alphabet::Symbol S = alphabet::symbolFrom ( "S" );
 	grammar::RightRG < > grammar ( S );
 
 	 // step 1
 	grammar.setTerminalAlphabet ( regexp.getAlphabet ( ) );
 
-	regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+	regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
 	 // steps 2, 3, 4
-	const std::set < regexp::UnboundedRegExpSymbol > first = regexp::GlushkovTraversal::first ( indexedRegExp );
-	const std::set < regexp::UnboundedRegExpSymbol > last = regexp::GlushkovTraversal::last ( indexedRegExp );
+	const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp );
+	const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp );
 
 	// \e in q0 check is in step 7
 
@@ -53,7 +53,7 @@ grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::Unbounded
 		grammar.addRule ( S, std::make_pair ( regexp::GlushkovTraversal::getSymbolFromGlushkovPair ( symbol.getSymbol ( ) ), symbol.getSymbol ( ) ) );
 
 	for ( const auto & x : indexedRegExp.getAlphabet ( ) )
-		for ( const auto & f : regexp::GlushkovTraversal::follow ( indexedRegExp, UnboundedRegExpSymbol ( x ) ) ) {
+		for ( const auto & f : regexp::GlushkovTraversal::follow ( indexedRegExp, UnboundedRegExpSymbol < alphabet::Symbol > ( x ) ) ) {
 			const alphabet::Symbol & a = x;
 			const alphabet::Symbol & b = f.getSymbol ( );
 
@@ -85,13 +85,13 @@ grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::Unbounded
 	return grammar;
 }
 
-auto ToGrammarRightRGGlushkovUnboundedRegExp = ToGrammarRightRGGlushkov::RegistratorWrapper < grammar::RightRG < >, regexp::UnboundedRegExp > ( ToGrammarRightRGGlushkov::convert );
+auto ToGrammarRightRGGlushkovUnboundedRegExp = ToGrammarRightRGGlushkov::RegistratorWrapper < grammar::RightRG < >, regexp::UnboundedRegExp < > > ( ToGrammarRightRGGlushkov::convert );
 
-grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::FormalRegExp & /* regexp */ ) {
+grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::FormalRegExp < > & /* regexp */ ) {
 	throw exception::CommonException ( "Glushkov: Converting FormalRegExp NYI" ); // TODO
 }
 
-auto ToGrammarRightRGGlushkovFormalRegExp = ToGrammarRightRGGlushkov::RegistratorWrapper < grammar::RightRG < >, regexp::FormalRegExp > ( ToGrammarRightRGGlushkov::convert );
+auto ToGrammarRightRGGlushkovFormalRegExp = ToGrammarRightRGGlushkov::RegistratorWrapper < grammar::RightRG < >, regexp::FormalRegExp < > > ( ToGrammarRightRGGlushkov::convert );
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h
index 5dbc829e93..63456f6c2a 100644
--- a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h
@@ -33,8 +33,8 @@ public:
 	 */
 	static grammar::RightRG < > convert(const regexp::RegExp& regexp);
 
-	static grammar::RightRG < > convert(const regexp::FormalRegExp& regexp);
-	static grammar::RightRG < > convert(const regexp::UnboundedRegExp& regexp);
+	static grammar::RightRG < > convert(const regexp::FormalRegExp < > & regexp);
+	static grammar::RightRG < > convert(const regexp::UnboundedRegExp < > & regexp);
 };
 
 } /* namespace convert */
diff --git a/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
index cdb4b5776f..8721dfdbf9 100644
--- a/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
+++ b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
@@ -16,7 +16,7 @@ namespace regexp {
 
 namespace generate {
 
-regexp::UnboundedRegExp RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize, bool randomizedAlphabet ) {
+regexp::UnboundedRegExp < > RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize, bool randomizedAlphabet ) {
 	if(alphabetSize > 26)
 		throw exception::CommonException("Too big alphabet.");
 
@@ -31,7 +31,7 @@ regexp::UnboundedRegExp RandomRegExpFactory::generateUnboundedRegExp( size_t lea
 	return RandomRegExpFactory::generateUnboundedRegExp( leafNodes, height, alphabet );
 }
 
-regexp::UnboundedRegExp RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, std::set<alphabet::Symbol> alphabet) {
+regexp::UnboundedRegExp < > RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, std::set<alphabet::Symbol> alphabet) {
 
 	if( alphabet.size() > 26)
 		throw exception::CommonException("Too big alphabet.");
@@ -39,40 +39,40 @@ regexp::UnboundedRegExp RandomRegExpFactory::generateUnboundedRegExp( size_t lea
 	if( alphabet.size() <= 0 )
 		throw exception::CommonException( "Alphabet size must be greater than 0." );
 
-	std::vector<const regexp::UnboundedRegExpElement*> elems;
+	std::vector<const regexp::UnboundedRegExpElement < alphabet::Symbol >*> elems;
 
 	{
-		elems.push_back(new regexp::UnboundedRegExpEmpty());
-		elems.push_back(new regexp::UnboundedRegExpEpsilon());
+		elems.push_back(new regexp::UnboundedRegExpEmpty < alphabet::Symbol > ( ) );
+		elems.push_back(new regexp::UnboundedRegExpEpsilon < alphabet::Symbol > ( ) );
 	}
 	if(alphabet.size() > 6) {
-		elems.push_back(new regexp::UnboundedRegExpEmpty());
-		elems.push_back(new regexp::UnboundedRegExpEpsilon());
+		elems.push_back(new regexp::UnboundedRegExpEmpty < alphabet::Symbol > ( ) );
+		elems.push_back(new regexp::UnboundedRegExpEpsilon < alphabet::Symbol > ( ) );
 	}
 	if(alphabet.size() > 16) {
-		elems.push_back(new regexp::UnboundedRegExpEmpty());
-		elems.push_back(new regexp::UnboundedRegExpEpsilon());
+		elems.push_back(new regexp::UnboundedRegExpEmpty < alphabet::Symbol > ( ) );
+		elems.push_back(new regexp::UnboundedRegExpEpsilon < alphabet::Symbol > ( ) );
 	}
 
 	for(const alphabet::Symbol& symbol : alphabet) {
-		elems.push_back(new regexp::UnboundedRegExpSymbol(symbol));
+		elems.push_back(new regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( symbol ) );
 	}
 
-	regexp::UnboundedRegExp res = RandomRegExpFactory::SimpleUnboundedRegExp( leafNodes, height, elems );
+	regexp::UnboundedRegExp < > res = RandomRegExpFactory::SimpleUnboundedRegExp( leafNodes, height, elems );
 
-	for(const regexp::UnboundedRegExpElement* elem : elems ) {
+	for(const regexp::UnboundedRegExpElement < alphabet::Symbol > * elem : elems ) {
 		delete elem;
 	}
 	return res;
 }
 
-regexp::UnboundedRegExp RandomRegExpFactory::SimpleUnboundedRegExp( size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement*> & elems) {
-	return regexp::UnboundedRegExp (regexp::UnboundedRegExpStructure ( SimpleUnboundedRegExpElement(n, h, elems)));
+regexp::UnboundedRegExp < > RandomRegExpFactory::SimpleUnboundedRegExp( size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement < alphabet::Symbol > * > & elems) {
+	return regexp::UnboundedRegExp < > (regexp::UnboundedRegExpStructure < alphabet::Symbol > ( SimpleUnboundedRegExpElement (n, h, elems)));
 }
 
-std::rvalue_ref < regexp::UnboundedRegExpElement > RandomRegExpFactory::SimpleUnboundedRegExpElement(size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement*> & elems) {
+std::rvalue_ref < regexp::UnboundedRegExpElement < alphabet::Symbol > > RandomRegExpFactory::SimpleUnboundedRegExpElement (size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement < alphabet::Symbol >*> & elems) {
 	if(h == 0 || n == 0) {
-		return std::rvalue_ref < UnboundedRegExpElement > ( elems[ std::random_devices::semirandom() % elems.size( ) ]->clone() );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( elems[ std::random_devices::semirandom() % elems.size( ) ]->clone() );
 	} else {
 		unsigned childNodes = std::random_devices::semirandom() % 10;
 		if(childNodes <  4) childNodes = 1;
@@ -111,22 +111,22 @@ std::rvalue_ref < regexp::UnboundedRegExpElement > RandomRegExpFactory::SimpleUn
 			subSizes[0] = n - subSizes[1];
 		}
 		if(childNodes == 1) {
-			return std::rvalue_ref < regexp::UnboundedRegExpElement> (new regexp::UnboundedRegExpIteration (SimpleUnboundedRegExpElement(n, h - 1, elems)));
+			return std::rvalue_ref < regexp::UnboundedRegExpElement < alphabet::Symbol > > (new regexp::UnboundedRegExpIteration < alphabet::Symbol > (SimpleUnboundedRegExpElement (n, h - 1, elems)));
 		}
 
 		int nodeType = std::random_devices::semirandom() % 2;
 		if(nodeType == 0) {
-			regexp::UnboundedRegExpConcatenation* con = new regexp::UnboundedRegExpConcatenation();
+			regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * con = new regexp::UnboundedRegExpConcatenation < alphabet::Symbol > ( );
 			for(unsigned i = 0; i < childNodes; i++) {
-				con->appendElement(std::move(SimpleUnboundedRegExpElement(subSizes[i], h - 1, elems)));
+				con->appendElement(std::move(SimpleUnboundedRegExpElement (subSizes[i], h - 1, elems)));
 			}
-			return std::rvalue_ref < regexp::UnboundedRegExpElement > ( con );
+			return std::rvalue_ref < regexp::UnboundedRegExpElement < alphabet::Symbol > > ( con );
 		} else {
-			regexp::UnboundedRegExpAlternation* alt = new regexp::UnboundedRegExpAlternation();
+			regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alt = new regexp::UnboundedRegExpAlternation < alphabet::Symbol > ( );
 			for(unsigned i = 0; i < childNodes; i++) {
-				alt->appendElement(std::move(SimpleUnboundedRegExpElement(subSizes[i], h - 1, elems)));
+				alt->appendElement(std::move(SimpleUnboundedRegExpElement (subSizes[i], h - 1, elems)));
 			}
-			return std::rvalue_ref < regexp::UnboundedRegExpElement > (alt);
+			return std::rvalue_ref < regexp::UnboundedRegExpElement < alphabet::Symbol > > (alt);
 		}
 		
 	}
diff --git a/alib2algo/src/regexp/generate/RandomRegExpFactory.h b/alib2algo/src/regexp/generate/RandomRegExpFactory.h
index c56d5031d2..a9dcb03d19 100644
--- a/alib2algo/src/regexp/generate/RandomRegExpFactory.h
+++ b/alib2algo/src/regexp/generate/RandomRegExpFactory.h
@@ -19,12 +19,12 @@ namespace generate {
 
 class RandomRegExpFactory {
 public:
-	static regexp::UnboundedRegExp generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize, bool randomizedAlphabet );
-	static regexp::UnboundedRegExp generateUnboundedRegExp( size_t leafNodes, size_t height, std::set<alphabet::Symbol> alphabet);
+	static regexp::UnboundedRegExp < > generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize, bool randomizedAlphabet );
+	static regexp::UnboundedRegExp < > generateUnboundedRegExp( size_t leafNodes, size_t height, std::set < alphabet::Symbol > alphabet);
 
 private:
-	static regexp::UnboundedRegExp SimpleUnboundedRegExp( size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement*> & elems);
-	static std::rvalue_ref < regexp::UnboundedRegExpElement > SimpleUnboundedRegExpElement(size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement*> & elems);
+	static regexp::UnboundedRegExp < > SimpleUnboundedRegExp( size_t n, size_t h, const std::vector < const regexp::UnboundedRegExpElement < alphabet::Symbol > * > & elems);
+	static std::rvalue_ref < regexp::UnboundedRegExpElement < alphabet::Symbol > > SimpleUnboundedRegExpElement(size_t n, size_t h, const std::vector < const regexp::UnboundedRegExpElement < alphabet::Symbol > * > & elems);
 };
 
 } /* namespace generate */
diff --git a/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp b/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp
index 45a6fca314..34d71fc86d 100644
--- a/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp
+++ b/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp
@@ -23,31 +23,31 @@ alphabet::Symbol GlushkovTraversal::getSymbolFromGlushkovPair ( const alphabet::
 
 // -----------------------------------------------------------------------------
 
-bool GlushkovTraversal::pos ( const UnboundedRegExpSymbol & symbol, const regexp::UnboundedRegExp & node ) {
+bool GlushkovTraversal::pos ( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const regexp::UnboundedRegExp < > & node ) {
 	return pos ( node.getRegExp ( ).getStructure ( ), symbol );
 }
 
-std::set < UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExp & re ) {
+std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExp < > & re ) {
 	return first ( re.getRegExp ( ).getStructure ( ) );
 }
 
-std::set < UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExp & re ) {
+std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExp < > & re ) {
 	return last ( re.getRegExp ( ).getStructure ( ) );
 }
 
-std::set < UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExp & re, const UnboundedRegExpSymbol & symbol ) {
+std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExp < > & re, const UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) {
 	return follow ( re.getRegExp ( ).getStructure ( ), symbol );
 }
 
 // -----------------------------------------------------------------------------
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExpElement & node ) {
-	const regexp::UnboundedRegExpAlternation * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation * > ( & node );
-	const regexp::UnboundedRegExpConcatenation * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation * > ( & node );
-	const regexp::UnboundedRegExpIteration * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration * > ( & node );
-	const regexp::UnboundedRegExpSymbol * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol * > ( & node );
-	const regexp::UnboundedRegExpEmpty * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty * > ( & node );
-	const regexp::UnboundedRegExpEpsilon * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon * > ( & node );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node ) {
+	const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node );
 
 	if ( alternation )
 		return first ( * alternation );
@@ -65,8 +65,8 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const rege
 	throw exception::CommonException ( "GlushkovTraversal::first - invalid RegExpElement node" );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExpAlternation & node ) {
-	std::set < regexp::UnboundedRegExpSymbol > ret, tmp;
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
+	std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp;
 
 	for ( auto const & element : node.getElements ( ) ) {
 		tmp = first ( * element );
@@ -76,8 +76,8 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const rege
 	return ret;
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExpConcatenation & node ) {
-	std::set < regexp::UnboundedRegExpSymbol > ret, tmp;
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
+	std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp;
 
 	for ( auto const & element : node.getElements ( ) ) {
 		tmp = first ( * element );
@@ -90,31 +90,31 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const rege
 	return ret;
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExpIteration & node ) {
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ) {
 	return first ( node.getElement ( ) );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExpSymbol & node ) {
-	return std::set < regexp::UnboundedRegExpSymbol > { node };
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > { node };
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExpEpsilon & /* node */ ) {
-	return std::set < regexp::UnboundedRegExpSymbol > ( );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */ ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::first ( const regexp::UnboundedRegExpEmpty & /* node */ ) {
-	return std::set < regexp::UnboundedRegExpSymbol > ( );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */ ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( );
 }
 
 // ----------------------------------------------------------------------------
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpElement & node ) {
-	const regexp::UnboundedRegExpAlternation * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation * > ( & node );
-	const regexp::UnboundedRegExpConcatenation * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation * > ( & node );
-	const regexp::UnboundedRegExpIteration * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration * > ( & node );
-	const regexp::UnboundedRegExpSymbol * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol * > ( & node );
-	const regexp::UnboundedRegExpEmpty * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty * > ( & node );
-	const regexp::UnboundedRegExpEpsilon * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon * > ( & node );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node ) {
+	const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node );
 
 	if ( symbol )
 		return last ( * symbol );
@@ -132,22 +132,22 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regex
 	throw exception::CommonException ( "GlushkovTraversal::last - invalid RegExpElement node" );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpAlternation & node ) {
-	std::set < regexp::UnboundedRegExpSymbol > ret;
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
+	std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret;
 
 	for ( const auto & element : node.getElements ( ) ) {
-		std::set < regexp::UnboundedRegExpSymbol > tmp = last ( * element );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > tmp = last ( * element );
 		ret.insert ( tmp.begin ( ), tmp.end ( ) );
 	}
 
 	return ret;
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpConcatenation & node ) {
-	std::set < regexp::UnboundedRegExpSymbol > ret;
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
+	std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret;
 
 	for ( const auto & element : std::make_reverse ( node.getElements ( ) ) ) {
-		std::set < regexp::UnboundedRegExpSymbol > tmp = last ( * element );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > tmp = last ( * element );
 		ret.insert ( tmp.begin ( ), tmp.end ( ) );
 
 		if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * element ) )
@@ -157,31 +157,31 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regex
 	return ret;
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpIteration & node ) {
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ) {
 	return last ( node.getElement ( ) );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpSymbol & node ) {
-	return std::set < regexp::UnboundedRegExpSymbol > { node };
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > { node };
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpEpsilon & /* node */ ) {
-	return std::set < regexp::UnboundedRegExpSymbol > ( );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */ ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::last ( const regexp::UnboundedRegExpEmpty & /* node */ ) {
-	return std::set < regexp::UnboundedRegExpSymbol > ( );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */ ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( );
 }
 
 // ----------------------------------------------------------------------------
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExpElement & node, const regexp::UnboundedRegExpSymbol & symbolptr ) {
-	const regexp::UnboundedRegExpAlternation * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation * > ( & node );
-	const regexp::UnboundedRegExpConcatenation * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation * > ( & node );
-	const regexp::UnboundedRegExpIteration * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration * > ( & node );
-	const regexp::UnboundedRegExpSymbol * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol * > ( & node );
-	const regexp::UnboundedRegExpEmpty * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty * > ( & node );
-	const regexp::UnboundedRegExpEpsilon * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon * > ( & node );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) {
+	const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node );
 
 	if ( alternation )
 		return follow ( * alternation, symbolptr );
@@ -204,7 +204,7 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const reg
 	throw exception::CommonException ( "GlushkovTraversal::follow() - unknown RegExpElement node" );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExpAlternation & node, const regexp::UnboundedRegExpSymbol & symbolptr ) {
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) {
 	for ( auto const & element : node.getElements ( ) )
 		if ( pos ( * element, symbolptr ) )
 			return follow ( * element, symbolptr );
@@ -212,8 +212,8 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const reg
 	throw exception::CommonException ( "GlushkovTraversal::follow(Alt)" );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExpConcatenation & node, const regexp::UnboundedRegExpSymbol & symbolptr ) {
-	std::set < regexp::UnboundedRegExpSymbol > ret, tmp, lastSet;
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) {
+	std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp, lastSet;
 
 	for ( auto e = node.getElements ( ).begin ( ); e != node.getElements ( ).end ( ); e++ ) {
 		if ( !pos ( * * e, symbolptr ) )
@@ -238,39 +238,39 @@ std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const reg
 	return ret;
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExpIteration & node, const regexp::UnboundedRegExpSymbol & symbolptr ) {
-	std::set < regexp::UnboundedRegExpSymbol > ret = follow ( node.getElement ( ), symbolptr );
-	std::set < regexp::UnboundedRegExpSymbol > lastSet = last ( node.getElement ( ) );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) {
+	std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret = follow ( node.getElement ( ), symbolptr );
+	std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > lastSet = last ( node.getElement ( ) );
 
 	if ( lastSet.find ( symbolptr ) != lastSet.end ( ) ) {
-		std::set < regexp::UnboundedRegExpSymbol > firstSet = first ( node.getElement ( ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > firstSet = first ( node.getElement ( ) );
 		ret.insert ( firstSet.begin ( ), firstSet.end ( ) );
 	}
 
 	return ret;
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExpSymbol & /* node */, const regexp::UnboundedRegExpSymbol & /* symbolptr */ ) {
-	return std::set < regexp::UnboundedRegExpSymbol > ( );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExpEmpty & /* node */, const regexp::UnboundedRegExpSymbol & /* symbolptr */ ) {
-	return std::set < regexp::UnboundedRegExpSymbol > ( );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( );
 }
 
-std::set < regexp::UnboundedRegExpSymbol > GlushkovTraversal::follow ( const regexp::UnboundedRegExpEpsilon & /* node */, const regexp::UnboundedRegExpSymbol & /* symbolptr */ ) {
-	return std::set < regexp::UnboundedRegExpSymbol > ( );
+std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) {
+	return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( );
 }
 
 // ----------------------------------------------------------------------------
 
-bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpElement & node, const regexp::UnboundedRegExpSymbol & symbolptr ) {
-	const regexp::UnboundedRegExpAlternation * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation * > ( & node );
-	const regexp::UnboundedRegExpConcatenation * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation * > ( & node );
-	const regexp::UnboundedRegExpIteration * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration * > ( & node );
-	const regexp::UnboundedRegExpSymbol * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol * > ( & node );
-	const regexp::UnboundedRegExpEmpty * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty * > ( & node );
-	const regexp::UnboundedRegExpEpsilon * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon * > ( & node );
+bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) {
+	const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node );
 
 	if ( alternation )
 		return pos ( * alternation, symbolptr );
@@ -293,7 +293,7 @@ bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpElement & node, const
 	throw exception::CommonException ( "GlushkovTraversal::pos() - unknown RegExpElement node" );
 }
 
-bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpAlternation & node, const regexp::UnboundedRegExpSymbol & symbol ) {
+bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) {
 	for ( const auto & element : node.getElements ( ) )
 		if ( pos ( * element, symbol ) )
 			return true;
@@ -301,7 +301,7 @@ bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpAlternation & node, c
 	return false;
 }
 
-bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpConcatenation & node, const regexp::UnboundedRegExpSymbol & symbol ) {
+bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) {
 	for ( const auto & element : node.getElements ( ) )
 		if ( pos ( * element, symbol ) )
 			return true;
@@ -309,60 +309,60 @@ bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpConcatenation & node,
 	return false;
 }
 
-bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpIteration & node, const regexp::UnboundedRegExpSymbol & symbol ) {
+bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) {
 	return pos ( node.getElement ( ), symbol );
 }
 
-bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpSymbol & node, const regexp::UnboundedRegExpSymbol & symbol ) {
+bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) {
 	return symbol == node;
 }
 
-bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpEmpty & /* node */, const regexp::UnboundedRegExpSymbol & /* symbol */ ) {
+bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbol */ ) {
 	return false;
 }
 
-bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpEpsilon & /* node */, const regexp::UnboundedRegExpSymbol & /* symbol */ ) {
+bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbol */ ) {
 	return false;
 }
 
 // ----------------------------------------------------------------------------
 
-UnboundedRegExp GlushkovTraversal::index ( const regexp::UnboundedRegExp & re ) {
+UnboundedRegExp < > GlushkovTraversal::index ( const regexp::UnboundedRegExp < > & re ) {
 	int i = 1;
 
-	return UnboundedRegExp ( regexp::UnboundedRegExpStructure ( index ( re.getRegExp ( ).getStructure ( ), i ) ) );
+	return UnboundedRegExp < > ( regexp::UnboundedRegExpStructure < alphabet::Symbol > ( index ( re.getRegExp ( ).getStructure ( ), i ) ) );
 }
 
-std::rvalue_ref < UnboundedRegExpElement > GlushkovTraversal::index ( const regexp::UnboundedRegExpElement & node, int & i ) {
-	const regexp::UnboundedRegExpAlternation * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation * > ( & node );
-	const regexp::UnboundedRegExpConcatenation * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation * > ( & node );
-	const regexp::UnboundedRegExpIteration * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration * > ( & node );
-	const regexp::UnboundedRegExpSymbol * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol * > ( & node );
-	const regexp::UnboundedRegExpEmpty * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty * > ( & node );
-	const regexp::UnboundedRegExpEpsilon * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon * > ( & node );
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > GlushkovTraversal::index ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, int & i ) {
+	const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node );
+	const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node );
 
 	if ( symbol ) {
-		return std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpSymbol ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( symbol->getSymbol ( ), alphabet::symbolFrom ( i++ ) ) ) ) ) );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpSymbol < alphabet::Symbol > ( alphabet::Symbol ( alphabet::SymbolPairSymbol ( std::make_pair ( symbol->getSymbol ( ), alphabet::symbolFrom ( i++ ) ) ) ) ) );
 	} else if ( alternation ) {
-		UnboundedRegExpAlternation * alt = new UnboundedRegExpAlternation ( );
+		UnboundedRegExpAlternation < alphabet::Symbol > * alt = new UnboundedRegExpAlternation < alphabet::Symbol > ( );
 
 		for ( const auto & element : alternation->getElements ( ) )
 			alt->appendElement ( index ( * element, i ) );
 
-		return std::rvalue_ref < UnboundedRegExpElement > ( alt );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( alt );
 	} else if ( concatenation ) {
-		UnboundedRegExpConcatenation * con = new UnboundedRegExpConcatenation ( );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * con = new UnboundedRegExpConcatenation < alphabet::Symbol > ( );
 
 		for ( const auto & element : concatenation->getElements ( ) )
 			con->appendElement ( index ( * element, i ) );
 
-		return std::rvalue_ref < UnboundedRegExpElement > ( con );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( con );
 	} else if ( iteration ) {
-		return std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpIteration ( index ( iteration->getElement ( ), i ) ) );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpIteration < alphabet::Symbol > ( index ( iteration->getElement ( ), i ) ) );
 	} else if ( empty ) {
-		return std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpEmpty ( ) );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEmpty < alphabet::Symbol > ( ) );
 	} else if ( eps ) {
-		return std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpEpsilon ( ) );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEpsilon < alphabet::Symbol > ( ) );
 	} else {
 		throw exception::CommonException ( "GlushkovTraversal::index() - unknown RegExpElement node" );
 	}
diff --git a/alib2algo/src/regexp/glushkov/GlushkovTraversal.h b/alib2algo/src/regexp/glushkov/GlushkovTraversal.h
index d7682dc095..e649746e67 100644
--- a/alib2algo/src/regexp/glushkov/GlushkovTraversal.h
+++ b/alib2algo/src/regexp/glushkov/GlushkovTraversal.h
@@ -36,66 +36,66 @@ public:
 	 * @param re RegExp to probe
 	 * @return all RegExpSymbols whichcan start the word.
 	 */
-	static std::set < UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExp & re );
+	static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExp < > & re );
 
 	/**
 	 * @param re RegExp to probe
 	 * @return all RegExpSymbols that can terminate the word.
 	 */
-	static std::set < UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExp & re );
+	static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExp < > & re );
 
 	/**
 	 * @param re RegExp to probe
 	 * @param symbol GlushkovSymbol for which we need the follow()
 	 * @return all symbols that can follow specific symbol in word
 	 */
-	static std::set < UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExp & re, const UnboundedRegExpSymbol & symbol );
+	static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExp < > & re, const UnboundedRegExpSymbol < alphabet::Symbol > & symbol );
 
 	/**
 	 * @param re RegExp to index
 	 * @return UnboundedRegExp with indexed elements
 	 */
-	static regexp::UnboundedRegExp index ( const regexp::UnboundedRegExp & re );
+	static regexp::UnboundedRegExp < > index ( const regexp::UnboundedRegExp < > & re );
 
 private:
 	/**
 	 * @return bool true if symbol pointer is in this subtree
 	 */
-	static bool pos ( const UnboundedRegExpSymbol & symbol, const regexp::UnboundedRegExp & node );
-
-	static std::rvalue_ref < UnboundedRegExpElement > index ( const regexp::UnboundedRegExpElement & node, int & i );
-
-	static std::set < regexp::UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExpElement & node );
-	static std::set < regexp::UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExpAlternation & node );
-	static std::set < regexp::UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExpConcatenation & node );
-	static std::set < regexp::UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExpIteration & node );
-	static std::set < regexp::UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExpSymbol & node );
-	static std::set < regexp::UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExpEmpty & node );
-	static std::set < regexp::UnboundedRegExpSymbol > first ( const regexp::UnboundedRegExpEpsilon & node );
-
-	static std::set < regexp::UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExpElement & node );
-	static std::set < regexp::UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExpAlternation & node );
-	static std::set < regexp::UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExpConcatenation & node );
-	static std::set < regexp::UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExpIteration & node );
-	static std::set < regexp::UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExpSymbol & node );
-	static std::set < regexp::UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExpEmpty & node );
-	static std::set < regexp::UnboundedRegExpSymbol > last ( const regexp::UnboundedRegExpEpsilon & node );
-
-	static bool pos ( const regexp::UnboundedRegExpElement & node, const regexp::UnboundedRegExpSymbol & symbSearch );
-	static bool pos ( const regexp::UnboundedRegExpAlternation & node, const regexp::UnboundedRegExpSymbol & symbSearch );
-	static bool pos ( const regexp::UnboundedRegExpConcatenation & node, const regexp::UnboundedRegExpSymbol & symbSearch );
-	static bool pos ( const regexp::UnboundedRegExpIteration & node, const regexp::UnboundedRegExpSymbol & symbSearch );
-	static bool pos ( const regexp::UnboundedRegExpSymbol & node, const regexp::UnboundedRegExpSymbol & symbSearch );
-	static bool pos ( const regexp::UnboundedRegExpEmpty & node, const regexp::UnboundedRegExpSymbol & symbSearch );
-	static bool pos ( const regexp::UnboundedRegExpEpsilon & node, const regexp::UnboundedRegExpSymbol & symbSearch );
-
-	static std::set < regexp::UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExpElement & node, const regexp::UnboundedRegExpSymbol & symbFollow );
-	static std::set < regexp::UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExpAlternation & node, const regexp::UnboundedRegExpSymbol & symbFollow );
-	static std::set < regexp::UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExpConcatenation & node, const regexp::UnboundedRegExpSymbol & symbFollow );
-	static std::set < regexp::UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExpIteration & node, const regexp::UnboundedRegExpSymbol & symbFollow );
-	static std::set < regexp::UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExpSymbol & node, const regexp::UnboundedRegExpSymbol & symbFollow );
-	static std::set < regexp::UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExpEmpty & node, const regexp::UnboundedRegExpSymbol & symbFollow );
-	static std::set < regexp::UnboundedRegExpSymbol > follow ( const regexp::UnboundedRegExpEpsilon & node, const regexp::UnboundedRegExpSymbol & symbFollow );
+	static bool pos ( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const regexp::UnboundedRegExp < > & node );
+
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > index ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, int & i );
+
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node );
+
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node );
+
+	static bool pos ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch );
+	static bool pos ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch );
+	static bool pos ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch );
+	static bool pos ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch );
+	static bool pos ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch );
+	static bool pos ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch );
+	static bool pos ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch );
+
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow );
+	static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow );
 };
 
 } /* namespace conversions */
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.cpp b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
index ebd2075478..c15d9bf123 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
@@ -17,37 +17,37 @@ bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
-bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpElement& regexp) {
+bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpElement < alphabet::Symbol > & regexp) {
 	return regexp.accept < bool, RegExpEmpty::Formal > ( );
 }
 
-bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpStructure& regexp) {
+bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp) {
 	return languageIsEmpty(regexp.getStructure());
 }
 
-bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExp& regexp) {
+bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExp < > & regexp) {
 	return languageIsEmpty(regexp.getRegExp());
 }
 
-auto RegExpEmptyFormalRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::FormalRegExp>( RegExpEmpty::languageIsEmpty);
+auto RegExpEmptyFormalRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::FormalRegExp < > >( RegExpEmpty::languageIsEmpty);
 
-bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpElement& regexp) {
+bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpElement < alphabet::Symbol > & regexp) {
 	return regexp.accept < bool, RegExpEmpty::Unbounded > ( );
 }
 
-bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpStructure& regexp) {
+bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp) {
 	return languageIsEmpty(regexp.getStructure());
 }
 
-bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExp& regexp) {
+bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExp < > & regexp) {
 	return languageIsEmpty(regexp.getRegExp());
 }
 
-auto RegExpEmptyUnboundedRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::UnboundedRegExp>( RegExpEmpty::languageIsEmpty);
+auto RegExpEmptyUnboundedRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::UnboundedRegExp < > >( RegExpEmpty::languageIsEmpty);
 
 // ----------------------------------------------------------------------------
 
-bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation) {
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation) {
 	for(const auto& element : alternation.getElements()) {
 		if(! element->accept < bool, RegExpEmpty::Unbounded > ( ) ) {
 			return false;
@@ -56,7 +56,7 @@ bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alt
 	return true;
 }
 
-bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation) {
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation) {
 	for(const auto& element : concatenation.getElements()) {
 		if( element->accept < bool, RegExpEmpty::Unbounded > ( ) ) {
 			return true;
@@ -65,45 +65,45 @@ bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& c
 	return false;
 }
 
-bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpIteration&) {
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > &) {
 	return false;
 }
 
-bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpSymbol&) {
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > &) {
 	return false;
 }
 
-bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEmpty&) {
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > &) {
 	return true;
 }
 
-bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&) {
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > &) {
 	return false;
 }
 
 // ----------------------------------------------------------------------------
 
-bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpAlternation& alternation) {
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation) {
 	return alternation.getLeftElement().accept < bool, RegExpEmpty::Formal > ( ) && alternation.getRightElement().accept < bool, RegExpEmpty::Formal > ( );
 }
 
-bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation) {
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation) {
 	return concatenation.getLeftElement().accept < bool, RegExpEmpty::Formal > ( ) || concatenation.getRightElement().accept < bool, RegExpEmpty::Formal > ( );
 }
 
-bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpIteration&) {
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpIteration < alphabet::Symbol > &) {
 	return false;
 }
 
-bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpSymbol&) {
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > &) {
 	return false;
 }
 
-bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEmpty&) {
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > &) {
 	return true;
 }
 
-bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEpsilon&) {
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > &) {
 	return false;
 }
 
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.h b/alib2algo/src/regexp/properties/RegExpEmpty.h
index 6fb4455a71..30871d0b9f 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.h
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.h
@@ -28,32 +28,32 @@ class RegExpEmpty : public std::SingleDispatch<RegExpEmpty, bool, const regexp::
 public:
 	static bool languageIsEmpty(const regexp::RegExp& regexp);
 
-	static bool languageIsEmpty(const regexp::FormalRegExpElement& regexp);
-	static bool languageIsEmpty(const regexp::FormalRegExpStructure& regexp);
-	static bool languageIsEmpty(const regexp::FormalRegExp& regexp);
+	static bool languageIsEmpty(const regexp::FormalRegExpElement < alphabet::Symbol > & regexp);
+	static bool languageIsEmpty(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp);
+	static bool languageIsEmpty(const regexp::FormalRegExp < > & regexp);
 
-	static bool languageIsEmpty(const regexp::UnboundedRegExpElement& regexp);
-	static bool languageIsEmpty(const regexp::UnboundedRegExpStructure& regexp);
-	static bool languageIsEmpty(const regexp::UnboundedRegExp& regexp);
+	static bool languageIsEmpty(const regexp::UnboundedRegExpElement < alphabet::Symbol > & regexp);
+	static bool languageIsEmpty(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp);
+	static bool languageIsEmpty(const regexp::UnboundedRegExp < > & regexp);
 
 	class Unbounded {
 	public:
-		static bool visit(const regexp::UnboundedRegExpAlternation& alternation);
-		static bool visit(const regexp::UnboundedRegExpConcatenation& concatenation);
-		static bool visit(const regexp::UnboundedRegExpIteration& iteration);
-		static bool visit(const regexp::UnboundedRegExpSymbol& symbol);
-		static bool visit(const regexp::UnboundedRegExpEmpty& empty);
-		static bool visit(const regexp::UnboundedRegExpEpsilon& epsilon);
+		static bool visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation);
+		static bool visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation);
+		static bool visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration);
+		static bool visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol);
+		static bool visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & empty);
+		static bool visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & epsilon);
 	};
 
 	class Formal {
 	public:
-		static bool visit(const regexp::FormalRegExpAlternation& alternation);
-		static bool visit(const regexp::FormalRegExpConcatenation& concatenation);
-		static bool visit(const regexp::FormalRegExpIteration& iteration);
-		static bool visit(const regexp::FormalRegExpSymbol& symbol);
-		static bool visit(const regexp::FormalRegExpEmpty& empty);
-		static bool visit(const regexp::FormalRegExpEpsilon& epsilon);
+		static bool visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation);
+		static bool visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation);
+		static bool visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration);
+		static bool visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol);
+		static bool visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > & empty);
+		static bool visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > & epsilon);
 	};
 
 };
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
index a7e9910cd9..d94bb17c7c 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
@@ -17,37 +17,37 @@ bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpElement& regexp) {
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpElement < alphabet::Symbol > & regexp) {
 	return regexp.accept<bool, RegExpEpsilon::Formal>();
 }
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpStructure& regexp) {
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp) {
 	return languageContainsEpsilon(regexp.getStructure());
 }
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp& regexp) {
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp < > & regexp) {
 	return languageContainsEpsilon(regexp.getRegExp());
 }
 
-auto RegExpEpsilonFormalRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::FormalRegExp>( RegExpEpsilon::languageContainsEpsilon);
+auto RegExpEpsilonFormalRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::FormalRegExp < > >( RegExpEpsilon::languageContainsEpsilon);
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpElement& regexp) {
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpElement < alphabet::Symbol > & regexp) {
 	return regexp.accept<bool, RegExpEpsilon::Unbounded>();
 }
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpStructure& regexp) {
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp) {
 	return languageContainsEpsilon(regexp.getStructure());
 }
 
-bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExp& regexp) {
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExp < > & regexp) {
 	return languageContainsEpsilon(regexp.getRegExp());
 }
 
-auto RegExpEpsilonUnboundedRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::UnboundedRegExp>( RegExpEpsilon::languageContainsEpsilon);
+auto RegExpEpsilonUnboundedRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::UnboundedRegExp < > >( RegExpEpsilon::languageContainsEpsilon);
 
 // ---------------------------------------------------------------------------
 
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation) {
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation) {
 	for ( const auto & element : alternation.getElements ( ) )
 		if ( element->accept < bool, RegExpEpsilon::Unbounded > ( ) )
 			return true;
@@ -55,7 +55,7 @@ bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpAlternation& a
 	return false;
 }
 
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation) {
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation) {
 	for ( const auto & element : concatenation.getElements ( ) )
 		if ( ! element->accept < bool, RegExpEpsilon::Unbounded > ( ) )
 			return false;
@@ -63,45 +63,45 @@ bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpConcatenation&
 	return true;
 }
 
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpIteration&) {
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > &) {
 	return true;
 }
 
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpSymbol&) {
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > &) {
 	return false;
 }
 
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&) {
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > &) {
 	return true;
 }
 
-bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEmpty&) {
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > &) {
 	return false;
 }
 
 // ----------------------------------------------------------------------------
 
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpAlternation& alternation) {
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation) {
 	return alternation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() || alternation.getRightElement().accept<bool, RegExpEpsilon::Formal>();
 }
 
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation) {
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation) {
 	return concatenation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() && concatenation.getRightElement().accept<bool, RegExpEpsilon::Formal>();
 }
 
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpIteration&) {
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpIteration < alphabet::Symbol > &) {
 	return true;
 }
 
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpSymbol&) {
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > &) {
 	return false;
 }
 
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEmpty&) {
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > &) {
 	return false;
 }
 
-bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEpsilon&) {
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > &) {
 	return true;
 }
 
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h
index e6002f7b1d..1253ec033b 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.h
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h
@@ -28,32 +28,32 @@ class RegExpEpsilon : public std::SingleDispatch<RegExpEpsilon, bool, const rege
 public:
 	static bool languageContainsEpsilon(const regexp::RegExp& regexp);
 
-	static bool languageContainsEpsilon(const regexp::FormalRegExpElement& regexp);
-	static bool languageContainsEpsilon(const regexp::FormalRegExpStructure& regexp);
-	static bool languageContainsEpsilon(const regexp::FormalRegExp& regexp);
+	static bool languageContainsEpsilon(const regexp::FormalRegExpElement < alphabet::Symbol > & regexp);
+	static bool languageContainsEpsilon(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp);
+	static bool languageContainsEpsilon(const regexp::FormalRegExp < > & regexp);
 
-	static bool languageContainsEpsilon(const regexp::UnboundedRegExpElement& regexp);
-	static bool languageContainsEpsilon(const regexp::UnboundedRegExpStructure& regexp);
-	static bool languageContainsEpsilon(const regexp::UnboundedRegExp& regexp);
+	static bool languageContainsEpsilon(const regexp::UnboundedRegExpElement < alphabet::Symbol > & regexp);
+	static bool languageContainsEpsilon(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp);
+	static bool languageContainsEpsilon(const regexp::UnboundedRegExp < > & regexp);
 
 	class Unbounded {
 	public:
-		static bool visit(const regexp::UnboundedRegExpAlternation& alternation);
-		static bool visit(const regexp::UnboundedRegExpConcatenation& concatenation);
-		static bool visit(const regexp::UnboundedRegExpIteration& iteration);
-		static bool visit(const regexp::UnboundedRegExpSymbol& symbol);
-		static bool visit(const regexp::UnboundedRegExpEmpty& empty);
-		static bool visit(const regexp::UnboundedRegExpEpsilon& epsilon);
+		static bool visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation);
+		static bool visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation);
+		static bool visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration);
+		static bool visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol);
+		static bool visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & empty);
+		static bool visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & epsilon);
 	};
 
 	class Formal {
 	public:
-		static bool visit(const regexp::FormalRegExpAlternation& alternation);
-		static bool visit(const regexp::FormalRegExpConcatenation& concatenation);
-		static bool visit(const regexp::FormalRegExpIteration& iteration);
-		static bool visit(const regexp::FormalRegExpSymbol& symbol);
-		static bool visit(const regexp::FormalRegExpEmpty& empty);
-		static bool visit(const regexp::FormalRegExpEpsilon& epsilon);
+		static bool visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation);
+		static bool visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation);
+		static bool visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration);
+		static bool visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol);
+		static bool visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > & empty);
+		static bool visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > & epsilon);
 	};
 };
 
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimize.cpp b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
index 9c23d659fb..093c0806d8 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
@@ -22,28 +22,28 @@ regexp::RegExp RegExpOptimize::optimize(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
-FormalRegExp RegExpOptimize::optimize( const FormalRegExp & regexp ) {
-	return regexp::FormalRegExp ( RegExpOptimize::optimize ( regexp.getRegExp ( ) ) );
+FormalRegExp < > RegExpOptimize::optimize( const FormalRegExp < > & regexp ) {
+	return regexp::FormalRegExp < > ( RegExpOptimize::optimize ( regexp.getRegExp ( ) ) );
 }
 
-auto RegExpOptimizeFormalRegEpx = RegExpOptimize::RegistratorWrapper<FormalRegExp, FormalRegExp>(RegExpOptimize::optimize);
+auto RegExpOptimizeFormalRegExp = RegExpOptimize::RegistratorWrapper<FormalRegExp < >, FormalRegExp < > >(RegExpOptimize::optimize);
 
-FormalRegExpStructure RegExpOptimize::optimize( const FormalRegExpStructure & regexp ) {
-	FormalRegExpElement* optimized = optimizeInner( regexp.getStructure ( ) );
+FormalRegExpStructure < alphabet::Symbol > RegExpOptimize::optimize( const FormalRegExpStructure < alphabet::Symbol > & regexp ) {
+	FormalRegExpElement < alphabet::Symbol > * optimized = optimizeInner( regexp.getStructure ( ) );
 
-	return regexp::FormalRegExpStructure ( std::manage_move ( optimized ) );
+	return regexp::FormalRegExpStructure < alphabet::Symbol > ( std::manage_move ( optimized ) );
 }
 
-UnboundedRegExp RegExpOptimize::optimize( const UnboundedRegExp & regexp ) {
-	return regexp::UnboundedRegExp ( RegExpOptimize::optimize ( regexp.getRegExp ( ) ) );
+UnboundedRegExp < > RegExpOptimize::optimize( const UnboundedRegExp < > & regexp ) {
+	return regexp::UnboundedRegExp < > ( RegExpOptimize::optimize ( regexp.getRegExp ( ) ) );
 }
 
-auto RegExpOptimizeUnboundedRegEpx = RegExpOptimize::RegistratorWrapper<UnboundedRegExp, UnboundedRegExp>(RegExpOptimize::optimize);
+auto RegExpOptimizeUnboundedRegExp = RegExpOptimize::RegistratorWrapper<UnboundedRegExp < >, UnboundedRegExp < > >(RegExpOptimize::optimize);
 
-UnboundedRegExpStructure RegExpOptimize::optimize( const UnboundedRegExpStructure & regexp ) {
-	UnboundedRegExpElement* optimized = optimizeInner( regexp.getStructure( ) );
+UnboundedRegExpStructure < alphabet::Symbol > RegExpOptimize::optimize( const UnboundedRegExpStructure < alphabet::Symbol > & regexp ) {
+	UnboundedRegExpElement < alphabet::Symbol > * optimized = optimizeInner( regexp.getStructure( ) );
 
-	return regexp::UnboundedRegExpStructure ( std::manage_move ( optimized ) );
+	return regexp::UnboundedRegExpStructure < alphabet::Symbol > ( std::manage_move ( optimized ) );
 }
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimize.h b/alib2algo/src/regexp/simplify/RegExpOptimize.h
index af93db38e9..640f031f1d 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimize.h
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.h
@@ -65,72 +65,72 @@ class RegExpOptimize : public std::SingleDispatch<RegExpOptimize, regexp::RegExp
 public:
 	static regexp::RegExp optimize( const regexp::RegExp & regexp );
 
-	static regexp::UnboundedRegExp optimize( const regexp::UnboundedRegExp & regexp );
-	static regexp::UnboundedRegExpStructure optimize( const regexp::UnboundedRegExpStructure & regexp );
-	static void optimize( regexp::UnboundedRegExpAlternation & regexp );
-	static void optimize( regexp::UnboundedRegExpConcatenation & regexp );
-	static void optimize( regexp::UnboundedRegExpIteration & regexp );
-
-	static regexp::FormalRegExp optimize( const regexp::FormalRegExp & regexp );
-	static regexp::FormalRegExpStructure optimize( const regexp::FormalRegExpStructure & regexp );
-	static void optimize( regexp::FormalRegExpElement & regexp );
+	static regexp::UnboundedRegExp < > optimize( const regexp::UnboundedRegExp < > & regexp );
+	static regexp::UnboundedRegExpStructure < alphabet::Symbol > optimize( const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp );
+	static void optimize( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & regexp );
+	static void optimize( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & regexp );
+	static void optimize( regexp::UnboundedRegExpIteration < alphabet::Symbol > & regexp );
+
+	static regexp::FormalRegExp < > optimize( const regexp::FormalRegExp < > & regexp );
+	static regexp::FormalRegExpStructure < alphabet::Symbol > optimize( const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp );
+	static void optimize( regexp::FormalRegExpElement < alphabet::Symbol > & regexp );
 private:
-	static regexp::FormalRegExpElement * optimizeInner( const regexp::FormalRegExpElement & node );
-
-	static regexp::UnboundedRegExpElement * optimizeInner( const regexp::UnboundedRegExpElement & node );
-	static regexp::UnboundedRegExpElement * optimizeInner( const regexp::UnboundedRegExpAlternation & node );
-	static regexp::UnboundedRegExpElement * optimizeInner( const regexp::UnboundedRegExpConcatenation & node );
-	static regexp::UnboundedRegExpElement * optimizeInner( const regexp::UnboundedRegExpIteration & node );
-	static regexp::UnboundedRegExpElement * optimizeInner( const regexp::UnboundedRegExpSymbol & node );
-	static regexp::UnboundedRegExpElement * optimizeInner( const regexp::UnboundedRegExpEpsilon & node );
-	static regexp::UnboundedRegExpElement * optimizeInner( const regexp::UnboundedRegExpEmpty & node );
-
-	static bool A1( regexp::UnboundedRegExpAlternation & node );
-	static bool A2( regexp::UnboundedRegExpAlternation & node );
-	static bool A3( regexp::UnboundedRegExpAlternation & node );
-	static bool A4( regexp::UnboundedRegExpAlternation & node );
-	static bool A5( regexp::UnboundedRegExpConcatenation & node );
-	static bool A6( regexp::UnboundedRegExpConcatenation & node );
-	static bool A7( regexp::UnboundedRegExpConcatenation & node );
-	static bool A8( regexp::UnboundedRegExpConcatenation & node );
-	static bool A9( regexp::UnboundedRegExpConcatenation & node );
-	static bool A10( regexp::UnboundedRegExpAlternation & node );
-	static bool A11( regexp::UnboundedRegExpIteration & node );
-	static bool V1( regexp::UnboundedRegExpIteration & node );
-	static bool V2( regexp::UnboundedRegExpAlternation & node );
-	static bool V3( regexp::UnboundedRegExpIteration & node );
-	static bool V4( regexp::UnboundedRegExpIteration & node );
-	static bool V5( regexp::UnboundedRegExpAlternation & node );
-	static bool V6( regexp::UnboundedRegExpAlternation & node );
-	static bool V8( regexp::UnboundedRegExpConcatenation & node );
-	static bool V9( regexp::UnboundedRegExpConcatenation & node );
-	static bool V10( regexp::UnboundedRegExpIteration & node );
-
-	static bool X1( regexp::UnboundedRegExpAlternation & node );
-
-	static bool S( regexp::FormalRegExpElement * & node );
-	static bool A1( regexp::FormalRegExpElement * & node );
-	static bool A2( regexp::FormalRegExpElement * & node );
-	static bool A3( regexp::FormalRegExpElement * & node );
-	static bool A4( regexp::FormalRegExpElement * & node );
-	static bool A5( regexp::FormalRegExpElement * & node );
-	static bool A6( regexp::FormalRegExpElement * & node );
-	static bool A7( regexp::FormalRegExpElement * & node );
-	static bool A8( regexp::FormalRegExpElement * & node );
-	static bool A9( regexp::FormalRegExpElement * & node );
-	static bool A10( regexp::FormalRegExpElement * & node );
-	static bool A11( regexp::FormalRegExpElement * & node );
-	static bool V1( regexp::FormalRegExpElement * & node );
-	static bool V2( regexp::FormalRegExpElement * & node );
-	static bool V3( regexp::FormalRegExpElement * & node );
-	static bool V4( regexp::FormalRegExpElement * & node );
-	static bool V5( regexp::FormalRegExpElement * & node );
-	static bool V6( regexp::FormalRegExpElement * & node );
-	static bool V8( regexp::FormalRegExpElement * & node );
-	static bool V9( regexp::FormalRegExpElement * & node );
-	static bool V10( regexp::FormalRegExpElement * & node );
-
-	static bool X1( regexp::FormalRegExpElement * & node );
+	static regexp::FormalRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::FormalRegExpElement < alphabet::Symbol > & node );
+
+	static regexp::UnboundedRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node );
+	static regexp::UnboundedRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static regexp::UnboundedRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static regexp::UnboundedRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+	static regexp::UnboundedRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node );
+	static regexp::UnboundedRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node );
+	static regexp::UnboundedRegExpElement < alphabet::Symbol > * optimizeInner( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node );
+
+	static bool A1( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool A2( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool A3( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool A4( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool A5( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static bool A6( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static bool A7( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static bool A8( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static bool A9( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static bool A10( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool A11( regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+	static bool V1( regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+	static bool V2( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool V3( regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+	static bool V4( regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+	static bool V5( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool V6( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+	static bool V8( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static bool V9( regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node );
+	static bool V10( regexp::UnboundedRegExpIteration < alphabet::Symbol > & node );
+
+	static bool X1( regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node );
+
+	static bool S( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A1( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A2( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A3( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A4( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A5( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A6( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A7( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A8( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A9( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A10( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool A11( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V1( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V2( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V3( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V4( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V5( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V6( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V8( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V9( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+	static bool V10( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
+
+	static bool X1( regexp::FormalRegExpElement < alphabet::Symbol > * & node );
 };
 
 } /* namespace simplify */
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
index ca2005e2e6..88acbde88c 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
@@ -9,41 +9,41 @@ namespace regexp {
 
 namespace simplify {
 
-void RegExpOptimize::optimize( FormalRegExpElement & element ) {
-	FormalRegExpElement* optimized = optimizeInner( element );
+void RegExpOptimize::optimize( FormalRegExpElement < alphabet::Symbol > & element ) {
+	FormalRegExpElement < alphabet::Symbol >* optimized = optimizeInner( element );
 
-	FormalRegExpAlternation * alternation = dynamic_cast<FormalRegExpAlternation *>( & element );
+	FormalRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( & element );
 	if( alternation ) {
-		FormalRegExpAlternation * alternationOptimized = dynamic_cast<FormalRegExpAlternation *>( optimized );
+		FormalRegExpAlternation < alphabet::Symbol > * alternationOptimized = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( optimized );
 		if( alternationOptimized ) {
 			* alternation = std::move( * alternationOptimized );
 			delete alternationOptimized;
 		} else {
-			* alternation = FormalRegExpAlternation { std::manage_move ( optimized ), FormalRegExpEmpty { } };
+			* alternation = FormalRegExpAlternation < alphabet::Symbol > { std::manage_move ( optimized ), FormalRegExpEmpty < alphabet::Symbol > { } };
 		}
 		return;
 	}
 
-	FormalRegExpConcatenation * concatenation = dynamic_cast<FormalRegExpConcatenation *>( & element );
+	FormalRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( & element );
 	if( concatenation ) {
-		FormalRegExpConcatenation * concatenationOptimized = dynamic_cast<FormalRegExpConcatenation *>( optimized );
+		FormalRegExpConcatenation < alphabet::Symbol > * concatenationOptimized = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( optimized );
 		if( concatenationOptimized ) {
 			* concatenation = std::move( * concatenationOptimized );
 			delete concatenationOptimized;
 		} else {
-			* concatenation = FormalRegExpConcatenation { std::manage_move ( optimized ), FormalRegExpEpsilon { } };
+			* concatenation = FormalRegExpConcatenation < alphabet::Symbol > { std::manage_move ( optimized ), FormalRegExpEpsilon < alphabet::Symbol > { } };
 		}
 		return;
 	}
 
-	FormalRegExpIteration * iteration = dynamic_cast<FormalRegExpIteration *>( & element );
+	FormalRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( & element );
 	if( iteration ) {
-		FormalRegExpIteration * iterationOptimized = dynamic_cast<FormalRegExpIteration *>( optimized );
+		FormalRegExpIteration < alphabet::Symbol > * iterationOptimized = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( optimized );
 		if( iterationOptimized ) {
 			* iteration = std::move( * iterationOptimized );
 			delete iterationOptimized;
 		} else {
-			* iteration = FormalRegExpIteration { std::manage_move ( optimized ) };
+			* iteration = FormalRegExpIteration < alphabet::Symbol > { std::manage_move ( optimized ) };
 		}
 		return;
 	}
@@ -52,8 +52,8 @@ void RegExpOptimize::optimize( FormalRegExpElement & element ) {
 	return;
 }
 
-FormalRegExpElement* RegExpOptimize::optimizeInner( const FormalRegExpElement & node ) {
-	FormalRegExpElement* elem = node.clone();
+FormalRegExpElement < alphabet::Symbol >* RegExpOptimize::optimizeInner( const FormalRegExpElement < alphabet::Symbol > & node ) {
+	FormalRegExpElement < alphabet::Symbol >* elem = node.clone();
 
 	// optimize while you can
 	while(    A1( elem ) || A2( elem ) || A3( elem ) || A4( elem ) || A10( elem ) || V2( elem ) || V5( elem ) || V6( elem ) || X1( elem )
@@ -63,49 +63,49 @@ FormalRegExpElement* RegExpOptimize::optimizeInner( const FormalRegExpElement &
 	return elem;
 }
 
-bool RegExpOptimize::S( FormalRegExpElement * & node ) {
+bool RegExpOptimize::S( FormalRegExpElement < alphabet::Symbol > * & node ) {
 	bool optimized = false;
-	FormalRegExpAlternation * alternation = dynamic_cast<FormalRegExpAlternation*>( node );
+	FormalRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol >*>( node );
 	if( alternation ) {
-		FormalRegExpElement * tmp = optimizeInner ( alternation->getLeftElement ( ) );
+		FormalRegExpElement < alphabet::Symbol > * tmp = optimizeInner ( alternation->getLeftElement ( ) );
 		if(* tmp != alternation->getLeftElement ( ) ) {
 			optimized = true;
-			alternation->setLeftElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
+			alternation->setLeftElement ( * std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > ( tmp ) );
 		}
 
 		tmp = optimizeInner ( alternation->getRightElement ( ) );
 		if(* tmp != alternation->getRightElement ( ) ) {
 			optimized = true;
-			alternation->setRightElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
+			alternation->setRightElement ( * std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > ( tmp ) );
 		}
 
 		return optimized;
 	}
 
-	FormalRegExpConcatenation * concatenation = dynamic_cast<FormalRegExpConcatenation*>( node );
+	FormalRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol >*>( node );
 	if( concatenation ) {
-		FormalRegExpElement* tmp = optimizeInner ( concatenation->getLeftElement() );
+		FormalRegExpElement < alphabet::Symbol >* tmp = optimizeInner ( concatenation->getLeftElement() );
 		if(* tmp != concatenation->getLeftElement ( ) ) {
 			optimized = true;
-			concatenation->setLeftElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
+			concatenation->setLeftElement ( * std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > ( tmp ) );
 		}
 
 		tmp = optimizeInner ( concatenation->getRightElement ( ));
 		if(* tmp != concatenation->getRightElement ( )) {
 			optimized = true;
-			concatenation->setRightElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
+			concatenation->setRightElement ( * std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > ( tmp ) );
 		}
 
 		return optimized;
 	}
 
-	FormalRegExpIteration * iteration = dynamic_cast<FormalRegExpIteration*>( node );
+	FormalRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast<FormalRegExpIteration < alphabet::Symbol >*>( node );
 	if( iteration ) {
-		FormalRegExpElement* tmp = optimizeInner ( iteration->getElement() );
+		FormalRegExpElement < alphabet::Symbol >* tmp = optimizeInner ( iteration->getElement() );
 
 		if(* tmp != iteration->getElement ( ) ) {
 			optimized = true;
-			iteration->setElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
+			iteration->setElement ( * std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > ( tmp ) );
 		}
 		return optimized;
 	}
@@ -116,19 +116,19 @@ bool RegExpOptimize::S( FormalRegExpElement * & node ) {
 
 /**
   * optimization A1: ( x + y ) + z = x + ( y + z )
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A1( FormalRegExpElement * & n ) {
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+bool RegExpOptimize::A1( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpAlternation *>( node->getLeft().get() ) ) {
-		std::smart_ptr < FormalRegExpAlternation > leftAlt ( static_cast<FormalRegExpAlternation *>( node->getLeft().release() ) );
+	if( dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( node->getLeft().get() ) ) {
+		std::smart_ptr < FormalRegExpAlternation < alphabet::Symbol > > leftAlt ( static_cast<FormalRegExpAlternation < alphabet::Symbol > *>( node->getLeft().release() ) );
 
-		std::smart_ptr < FormalRegExpElement > x = std::move ( leftAlt->getLeft() );
-		std::smart_ptr < FormalRegExpElement > y = std::move ( leftAlt->getRight() );
-		std::smart_ptr < FormalRegExpElement > z = std::move ( node->getRight() );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > x = std::move ( leftAlt->getLeft() );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > y = std::move ( leftAlt->getRight() );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > z = std::move ( node->getRight() );
 
 		leftAlt->setLeft ( std::move ( y ) );
 		leftAlt->setRight ( std::move ( z ) );
@@ -143,18 +143,18 @@ bool RegExpOptimize::A1( FormalRegExpElement * & n ) {
 
 /**
   * optimization A2: x + y = y + x (sort)
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A2( FormalRegExpElement * & n ) {
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+bool RegExpOptimize::A2( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpAlternation *>( node->getRight().get() ) ) {
-		FormalRegExpAlternation * rightAlt = static_cast < FormalRegExpAlternation * > ( node->getRight ( ).get ( ) );
+	if( dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( node->getRight().get() ) ) {
+		FormalRegExpAlternation < alphabet::Symbol > * rightAlt = static_cast < FormalRegExpAlternation < alphabet::Symbol > * > ( node->getRight ( ).get ( ) );
 
-		std::smart_ptr < FormalRegExpElement > x = std::move ( node->getLeft ( ) );
-		std::smart_ptr < FormalRegExpElement > y = std::move ( rightAlt->getLeft ( ) );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > x = std::move ( node->getLeft ( ) );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > y = std::move ( rightAlt->getLeft ( ) );
 
 		if(*x > *y) {
 			node->setLeft ( std::move ( y ) );
@@ -172,22 +172,22 @@ bool RegExpOptimize::A2( FormalRegExpElement * & n ) {
 
 /**
   * optimization A3: x + \0 = x
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A3( FormalRegExpElement * & n ) {
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+bool RegExpOptimize::A3( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
 	// input can be \0 + \0, so at least one element must be preserved
 
-	if( dynamic_cast<FormalRegExpEmpty *>( node->getRight().get() ) ) {
+	if( dynamic_cast<FormalRegExpEmpty < alphabet::Symbol > *>( node->getRight().get() ) ) {
 		n = node->getLeft().release();
 		delete node;
 		return true;
 	}
 
-	if( dynamic_cast<FormalRegExpEmpty *>( node->getLeft().get() ) ) {
+	if( dynamic_cast<FormalRegExpEmpty < alphabet::Symbol > *>( node->getLeft().get() ) ) {
 		n = node->getRight().release();
 		delete node;
 		return true;
@@ -198,10 +198,10 @@ bool RegExpOptimize::A3( FormalRegExpElement * & n ) {
 
 /**
   * optimization A4: x + x = x
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A4( FormalRegExpElement * & n ) {
+bool RegExpOptimize::A4( FormalRegExpElement < alphabet::Symbol > * & n ) {
 	/*
 	 * two ways of implementing this opitimization:
 	 * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts...
@@ -210,7 +210,7 @@ bool RegExpOptimize::A4( FormalRegExpElement * & n ) {
 	 * As we always sort in optimization, we can use the first version, but A4 must be __always__ called __after__ A2
 	 */
 
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
 	if( node->getLeftElement() == node->getRightElement() ) {
@@ -224,19 +224,19 @@ bool RegExpOptimize::A4( FormalRegExpElement * & n ) {
 
 /**
   * optimization A5: x.(y.z) = (x.y).z = x.y.z
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A5( FormalRegExpElement * & n ) {
-	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
+bool RegExpOptimize::A5( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpConcatenation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpConcatenation *>( node->getLeft().get() ) ) {
-		std::smart_ptr < FormalRegExpConcatenation > leftCon ( static_cast<FormalRegExpConcatenation *>( node->getLeft().release() ) );
+	if( dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( node->getLeft().get() ) ) {
+		std::smart_ptr < FormalRegExpConcatenation < alphabet::Symbol > > leftCon ( static_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( node->getLeft().release() ) );
 
-		std::smart_ptr < FormalRegExpElement > x = std::move ( leftCon->getLeft() );
-		std::smart_ptr < FormalRegExpElement > y = std::move ( leftCon->getRight() );
-		std::smart_ptr < FormalRegExpElement > z = std::move ( node->getRight() );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > x = std::move ( leftCon->getLeft() );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > y = std::move ( leftCon->getRight() );
+		std::smart_ptr < FormalRegExpElement < alphabet::Symbol > > z = std::move ( node->getRight() );
 
 		leftCon->setLeft ( std::move ( y ) );
 		leftCon->setRight ( std::move ( z ) );
@@ -251,22 +251,22 @@ bool RegExpOptimize::A5( FormalRegExpElement * & n ) {
 
 /**
   * optimization A6: \e.x = x.\e = x
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A6( FormalRegExpElement * & n ) {
-	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
+bool RegExpOptimize::A6( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpConcatenation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
 	// input can be \e + \e, so at least one element must be preserved
 
-	if( dynamic_cast<FormalRegExpEpsilon *>( node->getRight().get() ) ) {
+	if( dynamic_cast<FormalRegExpEpsilon < alphabet::Symbol > *>( node->getRight().get() ) ) {
 		n = node->getLeft().release();
 		delete node;
 		return true;
 	}
 
-	if( dynamic_cast<FormalRegExpEpsilon *>( node->getLeft().get() ) ) {
+	if( dynamic_cast<FormalRegExpEpsilon < alphabet::Symbol > *>( node->getLeft().get() ) ) {
 		n = node->getRight().release();
 		delete node;
 		return true;
@@ -277,16 +277,16 @@ bool RegExpOptimize::A6( FormalRegExpElement * & n ) {
 
 /**
   * optimization A7: \0.x = x.\0 = \0
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A7( FormalRegExpElement * & n ) {
-	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
+bool RegExpOptimize::A7( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpConcatenation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpEmpty *>( node->getRight().get() ) || dynamic_cast<FormalRegExpEmpty *>( node->getLeft().get() ) ) {
+	if( dynamic_cast<FormalRegExpEmpty < alphabet::Symbol > *>( node->getRight().get() ) || dynamic_cast<FormalRegExpEmpty < alphabet::Symbol > *>( node->getLeft().get() ) ) {
 		delete node;
-		n = new FormalRegExpEmpty { };
+		n = new FormalRegExpEmpty < alphabet::Symbol > { };
 		return true;
 	}
 
@@ -295,42 +295,42 @@ bool RegExpOptimize::A7( FormalRegExpElement * & n ) {
 
 /**
   * optimization A8: x.(y+z) = x.y + x.z
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A8( FormalRegExpElement * & /* n */) {
+bool RegExpOptimize::A8( FormalRegExpElement < alphabet::Symbol > * & /* n */) {
 	return false; //TODO
 }
 
 /**
   * optimization A9: (x+y).z = x.z + y.z
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A9( FormalRegExpElement * & /* n */) {
+bool RegExpOptimize::A9( FormalRegExpElement < alphabet::Symbol > * & /* n */) {
 	return false; //TODO
 }
 
 /**
   * optimization A10: x* = \e + x*x
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A10( FormalRegExpElement * & n ) {
+bool RegExpOptimize::A10( FormalRegExpElement < alphabet::Symbol > * & n ) {
 	/*
 	 * problem:
 	 * - \e + x*x = x*
 	 * - but if we do not have the eps, but we do have iteration, then \e \in h(iter), therefore \e in h(node).
 	 */
 
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpEpsilon *>( node->getLeft().get() ) ) {
-		FormalRegExpConcatenation * rightCon = dynamic_cast<FormalRegExpConcatenation *>( node->getRight().get() );
+	if( dynamic_cast<FormalRegExpEpsilon < alphabet::Symbol > *>( node->getLeft().get() ) ) {
+		FormalRegExpConcatenation < alphabet::Symbol > * rightCon = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( node->getRight().get() );
 		if( ! rightCon ) return false;
 
-		FormalRegExpIteration * rightLeftIte = dynamic_cast<FormalRegExpIteration *>( rightCon->getLeft().get() );
+		FormalRegExpIteration < alphabet::Symbol > * rightLeftIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( rightCon->getLeft().get() );
 		if( rightLeftIte ) {
 			if(rightLeftIte->getElement() == rightCon->getRightElement()) {
 				n = rightCon->getLeft().release();
@@ -339,7 +339,7 @@ bool RegExpOptimize::A10( FormalRegExpElement * & n ) {
 			}
 		}
 
-		FormalRegExpIteration * rightRightIte = dynamic_cast<FormalRegExpIteration *>( rightCon->getRight().get() );
+		FormalRegExpIteration < alphabet::Symbol > * rightRightIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( rightCon->getRight().get() );
 		if( rightRightIte ) {
 			if(rightRightIte->getElement() == rightCon->getLeftElement()) {
 				n = rightCon->getRight().release();
@@ -349,11 +349,11 @@ bool RegExpOptimize::A10( FormalRegExpElement * & n ) {
 		}
 	}
 
-	if( dynamic_cast<FormalRegExpEpsilon *>( node->getRight().get() ) ) {
-		FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->getLeft().get() );
+	if( dynamic_cast<FormalRegExpEpsilon < alphabet::Symbol > *>( node->getRight().get() ) ) {
+		FormalRegExpConcatenation < alphabet::Symbol > * leftCon = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( node->getLeft().get() );
 		if( ! leftCon ) return false;
 
-		FormalRegExpIteration * leftLeftIte = dynamic_cast<FormalRegExpIteration *>( leftCon->getLeft().get() );
+		FormalRegExpIteration < alphabet::Symbol > * leftLeftIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( leftCon->getLeft().get() );
 		if( leftLeftIte ) {
 			if(leftLeftIte->getElement() == leftCon->getRightElement()) {
 				n = leftCon->getLeft().release();
@@ -362,7 +362,7 @@ bool RegExpOptimize::A10( FormalRegExpElement * & n ) {
 			}
 		}
 
-		FormalRegExpIteration * leftRightIte = dynamic_cast<FormalRegExpIteration *>( leftCon->getRight().get() );
+		FormalRegExpIteration < alphabet::Symbol > * leftRightIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( leftCon->getRight().get() );
 		if( leftRightIte ) {
 			if(leftRightIte->getElement() == leftCon->getLeftElement()) {
 				n = leftCon->getRight().release();
@@ -377,20 +377,20 @@ bool RegExpOptimize::A10( FormalRegExpElement * & n ) {
 
 /**
   * optimization A11: x* = (\e + x)*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A11( FormalRegExpElement * & n ) {
-	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
+bool RegExpOptimize::A11( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpIteration < alphabet::Symbol > * node = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpAlternation * childAlt = dynamic_cast<FormalRegExpAlternation *>( node->getChild().get() );
+	FormalRegExpAlternation < alphabet::Symbol > * childAlt = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( node->getChild().get() );
 	if( childAlt ) {
-		if( dynamic_cast < FormalRegExpEpsilon * > ( childAlt->getLeft ( ).get ( ) ) ) {
+		if( dynamic_cast < FormalRegExpEpsilon < alphabet::Symbol > * > ( childAlt->getLeft ( ).get ( ) ) ) {
 			node->setChild ( std::move ( childAlt->getRight ( ) ) );
 			return true;
 		}
-		if( dynamic_cast < FormalRegExpEpsilon * > ( childAlt->getRight ( ).get ( ) ) ) {
+		if( dynamic_cast < FormalRegExpEpsilon < alphabet::Symbol > * > ( childAlt->getRight ( ).get ( ) ) ) {
 			node->setChild ( std::move ( childAlt->getLeft ( ) ) );
 			return true;
 		}
@@ -402,21 +402,21 @@ bool RegExpOptimize::A11( FormalRegExpElement * & n ) {
 /**
   * optimization V1: \0* = \e
   * optimization T1: \e* = \e
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V1( FormalRegExpElement * & n ) {
-	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
+bool RegExpOptimize::V1( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpIteration < alphabet::Symbol > * node = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpEmpty*>( node->getChild ( ).get() ) ) {
+	if( dynamic_cast<FormalRegExpEmpty< alphabet::Symbol > *>( node->getChild ( ).get() ) ) {
 		delete node;
-		n = new FormalRegExpEpsilon( );
+		n = new FormalRegExpEpsilon < alphabet::Symbol > ( );
 		return true;
 	}
-	if( dynamic_cast<FormalRegExpEpsilon*>( node->getChild ( ).get() ) ) {
+	if( dynamic_cast<FormalRegExpEpsilon < alphabet::Symbol > *>( node->getChild ( ).get() ) ) {
 		delete node;
-		n = new FormalRegExpEpsilon( );
+		n = new FormalRegExpEpsilon < alphabet::Symbol > ( );
 		return true;
 	}
 	return false;
@@ -424,14 +424,14 @@ bool RegExpOptimize::V1( FormalRegExpElement * & n ) {
 
 /**
   * optimization V2: x* + x = x*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V2( FormalRegExpElement * & n ) {
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+bool RegExpOptimize::V2( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->getLeft().get() );
+	FormalRegExpIteration < alphabet::Symbol > * leftIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( node->getLeft().get() );
 	if( leftIte ) {
 		if(leftIte->getElement() == node->getRightElement()) {
 			n = node->getLeft().release();
@@ -440,7 +440,7 @@ bool RegExpOptimize::V2( FormalRegExpElement * & n ) {
 		}
 	}
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->getRight().get() );
+	FormalRegExpIteration < alphabet::Symbol > * rightIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( node->getRight().get() );
 	if( rightIte ) {
 		if(rightIte->getElement() == node->getLeftElement()) {
 			n = node->getRight().release();
@@ -454,14 +454,14 @@ bool RegExpOptimize::V2( FormalRegExpElement * & n ) {
 
 /**
   * optimization V3: x** = x*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V3( FormalRegExpElement * & n ) {
-	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
+bool RegExpOptimize::V3( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpIteration < alphabet::Symbol > * node = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration* childIter = dynamic_cast<FormalRegExpIteration*>( node->getChild().get() );
+	FormalRegExpIteration < alphabet::Symbol >* childIter = dynamic_cast<FormalRegExpIteration < alphabet::Symbol >*>( node->getChild().get() );
 	if( childIter ) {
 		node->setChild ( std::move ( childIter->getChild ( ) ) );
 		return true;
@@ -472,23 +472,23 @@ bool RegExpOptimize::V3( FormalRegExpElement * & n ) {
 
 /**
   * optimization V4: (x+y)* = (x*y*)*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V4( FormalRegExpElement * & n ) {
-	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
+bool RegExpOptimize::V4( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpIteration < alphabet::Symbol > * node = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpConcatenation * child = dynamic_cast<FormalRegExpConcatenation *>( node->getChild().get() );
+	FormalRegExpConcatenation < alphabet::Symbol > * child = dynamic_cast<FormalRegExpConcatenation < alphabet::Symbol > *>( node->getChild().get() );
 	if( ! child ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( child->getLeft().get() );
+	FormalRegExpIteration < alphabet::Symbol > * leftIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( child->getLeft().get() );
 	if( ! leftIte ) return false;
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( child->getRight().get() );
+	FormalRegExpIteration < alphabet::Symbol > * rightIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( child->getRight().get() );
 	if( ! rightIte ) return false;
 
-	n = new FormalRegExpIteration( FormalRegExpAlternation(std::move( leftIte->getElement ( ) ), std::move( rightIte->getElement ( ) ) ) );
+	n = new FormalRegExpIteration < alphabet::Symbol >( FormalRegExpAlternation < alphabet::Symbol >(std::move( leftIte->getElement ( ) ), std::move( rightIte->getElement ( ) ) ) );
 
 	delete node;
 	return true;
@@ -496,56 +496,56 @@ bool RegExpOptimize::V4( FormalRegExpElement * & n ) {
 
 /**
   * optimization V5: x*y = y + x*xy
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V5( FormalRegExpElement * & /* n */) {
+bool RegExpOptimize::V5( FormalRegExpElement < alphabet::Symbol > * & /* n */) {
 	return false; //TODO
 }
 
 /**
   * optimization V6: x*y = y + xx*y
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V6( FormalRegExpElement * & /* n */) {
+bool RegExpOptimize::V6( FormalRegExpElement < alphabet::Symbol > * & /* n */) {
 	return false; //TODO
 }
 
 /**
   * optimization V8: \e in h(x) => xx*=x*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V8( FormalRegExpElement * & /* n */) {
+bool RegExpOptimize::V8( FormalRegExpElement < alphabet::Symbol > * & /* n */) {
 	return false; //TODO
 }
 
 /**
   * optimization V9: (xy)*x = x(yx)*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V9( FormalRegExpElement * & /* n */) {
+bool RegExpOptimize::V9( FormalRegExpElement < alphabet::Symbol > * & /* n */) {
 	return false; //TODO
 }
 
 /**
   * optimization V10: (x+y)* = (x*+y*)*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V10( FormalRegExpElement * & n ) {
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+bool RegExpOptimize::V10( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->getLeft().get() );
+	FormalRegExpIteration < alphabet::Symbol > * leftIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( node->getLeft().get() );
 	if( ! leftIte ) return false;
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->getRight().get() );
+	FormalRegExpIteration < alphabet::Symbol > * rightIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( node->getRight().get() );
 	if( ! rightIte ) return false;
 
-	n = new FormalRegExpConcatenation(std::move( leftIte->getElement() ), std::move( rightIte->getElement() ) );
+	n = new FormalRegExpConcatenation < alphabet::Symbol >(std::move( leftIte->getElement() ), std::move( rightIte->getElement() ) );
 
 	delete node;
 	return true;
@@ -553,25 +553,25 @@ bool RegExpOptimize::V10( FormalRegExpElement * & n ) {
 
 /**
   * optimization X1: a* + \e = a*
-  * @param node FormalRegExpElement node
+  * @param node FormalRegExpElement < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::X1( FormalRegExpElement * & n ) {
-	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
+bool RegExpOptimize::X1( FormalRegExpElement < alphabet::Symbol > * & n ) {
+	FormalRegExpAlternation < alphabet::Symbol > * node = dynamic_cast<FormalRegExpAlternation < alphabet::Symbol > *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->getLeft().get() );
+	FormalRegExpIteration < alphabet::Symbol > * leftIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( node->getLeft().get() );
 	if( leftIte ) {
-		if(dynamic_cast<FormalRegExpEpsilon*>(node->getRight().get())) {
+		if(dynamic_cast<FormalRegExpEpsilon < alphabet::Symbol > *>(node->getRight().get())) {
 			n = node->getLeft().release();
 			delete node;
 			return true;
 		}
 	}
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->getRight().get() );
+	FormalRegExpIteration < alphabet::Symbol > * rightIte = dynamic_cast<FormalRegExpIteration < alphabet::Symbol > *>( node->getRight().get() );
 	if( rightIte ) {
-		if(dynamic_cast<FormalRegExpEpsilon*>(node->getLeft().get())) {
+		if(dynamic_cast<FormalRegExpEpsilon < alphabet::Symbol > *>(node->getLeft().get())) {
 			n = node->getRight().release();
 			delete node;
 			return true;
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
index 0ceb4ff5df..5f5ae08ec5 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
@@ -9,150 +9,150 @@ namespace regexp {
 
 namespace simplify {
 
-void RegExpOptimize::optimize( UnboundedRegExpAlternation & alt ) {
+void RegExpOptimize::optimize( UnboundedRegExpAlternation < alphabet::Symbol > & alt ) {
 	for( unsigned i = 0; i < alt.getChildren ( ).size ( ); i++ )
-		alt.setChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( * alt.getChildren ( ) [ i ] ) ), i );
+		alt.setChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( * alt.getChildren ( ) [ i ] ) ), i );
 
 	while( A1( alt ) || A2( alt ) || A3( alt ) || A4( alt ) || A10( alt ) || V2( alt ) || V5( alt ) || V6( alt ) || X1( alt ) );
 }
 
-void RegExpOptimize::optimize( UnboundedRegExpConcatenation & concat ) {
+void RegExpOptimize::optimize( UnboundedRegExpConcatenation < alphabet::Symbol > & concat ) {
 	for( unsigned i = 0; i < concat.getChildren ( ).size ( ); i++ )
-		concat.setChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( * concat.getChildren ( ) [ i ] ) ), i );
+		concat.setChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( * concat.getChildren ( ) [ i ] ) ), i );
 
 	while( A5( concat ) || A6( concat ) || A7( concat ) || A8( concat ) || A9( concat ) || V8( concat ) );//|| V9( concat ) );
 }
 
-void RegExpOptimize::optimize( UnboundedRegExpIteration & iter ) {
-	iter.setChild ( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner ( * iter.getChild ( ) ) ) );
+void RegExpOptimize::optimize( UnboundedRegExpIteration < alphabet::Symbol > & iter ) {
+	iter.setChild ( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner ( * iter.getChild ( ) ) ) );
 	do {
 		// V1 is implemented right here
-		if( dynamic_cast<UnboundedRegExpEmpty*>( iter.getChild ( ).get() ) ) {
+		if( dynamic_cast<UnboundedRegExpEmpty < alphabet::Symbol >*>( iter.getChild ( ).get() ) ) {
 			return;
 		}
 		// T1 is implemented right here \e* = \e
-		if( dynamic_cast<UnboundedRegExpEpsilon*>( iter.getChild ( ).get() ) ) {
+		if( dynamic_cast<UnboundedRegExpEpsilon < alphabet::Symbol >*>( iter.getChild ( ).get() ) ) {
 			return;
 		}
 	} while( A11( iter ) || V1( iter ) || V3( iter ) || V4( iter ) || V10( iter ) );
 }
 
-UnboundedRegExpElement* RegExpOptimize::optimizeInner( const UnboundedRegExpElement & node ) {
-	const UnboundedRegExpAlternation * alternation = dynamic_cast<const UnboundedRegExpAlternation*>( & node );
+UnboundedRegExpElement < alphabet::Symbol >* RegExpOptimize::optimizeInner( const UnboundedRegExpElement < alphabet::Symbol > & node ) {
+	const UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast<const UnboundedRegExpAlternation < alphabet::Symbol >*>( & node );
 	if( alternation )
 		return optimizeInner( * alternation );
 
-	const UnboundedRegExpConcatenation * concatenation = dynamic_cast<const UnboundedRegExpConcatenation*>( & node );
+	const UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast<const UnboundedRegExpConcatenation < alphabet::Symbol >*>( & node );
 	if( concatenation )
 		return optimizeInner( * concatenation );
 
-	const UnboundedRegExpIteration * iteration = dynamic_cast<const UnboundedRegExpIteration*>( & node );
+	const UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast<const UnboundedRegExpIteration < alphabet::Symbol >*>( & node );
 	if( iteration )
 		return optimizeInner( * iteration );
 
-	const UnboundedRegExpSymbol * symbol = dynamic_cast<const UnboundedRegExpSymbol*>( & node );
+	const UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast<const UnboundedRegExpSymbol < alphabet::Symbol >*>( & node );
 	if( symbol )
 		return optimizeInner( * symbol );
 
-	const UnboundedRegExpEmpty * empty = dynamic_cast<const UnboundedRegExpEmpty*>( & node );
+	const UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast<const UnboundedRegExpEmpty < alphabet::Symbol >*>( & node );
 	if( empty )
 		return optimizeInner( * empty );
 
-	const UnboundedRegExpEpsilon * eps = dynamic_cast<const UnboundedRegExpEpsilon*>( & node );
+	const UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast<const UnboundedRegExpEpsilon < alphabet::Symbol >*>( & node );
 	if( eps )
 		return optimizeInner( * eps );
 
-	throw exception::CommonException( "RegExpOptimize::optimize - unknown UnboundedRegExpElement node" );
+	throw exception::CommonException( "RegExpOptimize::optimize - unknown UnboundedRegExpElement < alphabet::Symbol > node" );
 }
 
-UnboundedRegExpElement * RegExpOptimize::optimizeInner( const UnboundedRegExpAlternation & node ) {
-	UnboundedRegExpAlternation* alt = new UnboundedRegExpAlternation( );
+UnboundedRegExpElement < alphabet::Symbol > * RegExpOptimize::optimizeInner( const UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
+	UnboundedRegExpAlternation < alphabet::Symbol >* alt = new UnboundedRegExpAlternation < alphabet::Symbol >( );
 
 	for( const auto & child : node.getElements ( ) )
-		alt->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( * child ) ) );
+		alt->pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( * child ) ) );
 
 	// optimize while you can
 	while( A1( * alt ) || A2( * alt ) || A3( * alt ) || A4( * alt ) || A10( * alt ) || V2( * alt ) || V5( * alt ) || V6( * alt ) || X1( * alt ) );
 
 	if( alt->getElements ( ).size( ) == 1 ) {
-		UnboundedRegExpElement* ret = alt->getChildren ( ).front ( ).release ( );
+		UnboundedRegExpElement < alphabet::Symbol >* ret = alt->getChildren ( ).front ( ).release ( );
 		delete alt;
 		return ret;
 	}
 
 	if( alt->getElements ( ).size( ) == 0 ) {
 		delete alt;
-		return new UnboundedRegExpEmpty( );
+		return new UnboundedRegExpEmpty < alphabet::Symbol >( );
 	}
 
 	return alt;
 }
 
-UnboundedRegExpElement * RegExpOptimize::optimizeInner( const UnboundedRegExpConcatenation & node ) {
-	UnboundedRegExpConcatenation* concat = new UnboundedRegExpConcatenation( );
+UnboundedRegExpElement < alphabet::Symbol > * RegExpOptimize::optimizeInner( const UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
+	UnboundedRegExpConcatenation < alphabet::Symbol >* concat = new UnboundedRegExpConcatenation < alphabet::Symbol >( );
 
 	for( const auto & child : node.getElements ( ) )
-		concat->pushBackChild ( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( * child ) ) );
+		concat->pushBackChild ( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( * child ) ) );
 
 	while( A5( * concat ) || A6( * concat ) || A7( * concat ) || A8( * concat ) || A9( * concat ) || V8( * concat ) );//|| V9( * concat ) );
 
 	if( concat->getElements ( ).size( ) == 1 ) {
-		UnboundedRegExpElement* ret = concat->getChildren ( ).front( ).release();
+		UnboundedRegExpElement < alphabet::Symbol >* ret = concat->getChildren ( ).front( ).release();
 		delete concat;
 		return ret;
 	}
 
 	if( concat->getElements ( ).size( ) == 0 ) {
 		delete concat;
-		return new UnboundedRegExpEpsilon( );
+		return new UnboundedRegExpEpsilon < alphabet::Symbol >( );
 	}
 
 	return concat;
 }
 
-UnboundedRegExpElement * RegExpOptimize::optimizeInner( const UnboundedRegExpIteration & node ) {
-	UnboundedRegExpIteration* iter = new UnboundedRegExpIteration( UnboundedRegExpEmpty {} );
-	iter->setChild ( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner ( * node.getChild ( ) ) ) );
+UnboundedRegExpElement < alphabet::Symbol > * RegExpOptimize::optimizeInner( const UnboundedRegExpIteration < alphabet::Symbol > & node ) {
+	UnboundedRegExpIteration < alphabet::Symbol >* iter = new UnboundedRegExpIteration < alphabet::Symbol >( UnboundedRegExpEmpty < alphabet::Symbol > {} );
+	iter->setChild ( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner ( * node.getChild ( ) ) ) );
 
 	do {
 		// V1 is implemented right here
-		if( dynamic_cast<UnboundedRegExpEmpty*>( iter->getChild ( ).get() ) ) {
+		if( dynamic_cast<UnboundedRegExpEmpty < alphabet::Symbol >*>( iter->getChild ( ).get() ) ) {
 			delete iter;
-			return new UnboundedRegExpEpsilon( );
+			return new UnboundedRegExpEpsilon < alphabet::Symbol >( );
 		}
 		// T1 is implemented right here \e* = \e
-		if( dynamic_cast<UnboundedRegExpEpsilon*>( iter->getChild ( ).get() ) ) {
+		if( dynamic_cast<UnboundedRegExpEpsilon < alphabet::Symbol >*>( iter->getChild ( ).get() ) ) {
 			delete iter;
-			return new UnboundedRegExpEpsilon( );
+			return new UnboundedRegExpEpsilon < alphabet::Symbol >( );
 		}
 	} while( A11( * iter ) || V1( * iter ) || V3( * iter ) || V4( * iter ) || V10( * iter ) );
 
 	return iter;
 }
 
-UnboundedRegExpElement * RegExpOptimize::optimizeInner( const UnboundedRegExpSymbol & node ) {
+UnboundedRegExpElement < alphabet::Symbol > * RegExpOptimize::optimizeInner( const UnboundedRegExpSymbol < alphabet::Symbol > & node ) {
 	return node.clone( );
 }
 
-UnboundedRegExpElement * RegExpOptimize::optimizeInner( const UnboundedRegExpEmpty & node ) {
+UnboundedRegExpElement < alphabet::Symbol > * RegExpOptimize::optimizeInner( const UnboundedRegExpEmpty < alphabet::Symbol > & node ) {
 	return node.clone( );
 }
 
-UnboundedRegExpElement * RegExpOptimize::optimizeInner( const UnboundedRegExpEpsilon & node ) {
+UnboundedRegExpElement < alphabet::Symbol > * RegExpOptimize::optimizeInner( const UnboundedRegExpEpsilon < alphabet::Symbol > & node ) {
 	return node.clone( );
 }
 
 /**
   * optimization A1: x + ( y + z ) = ( x + y ) + z = x + y + z
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A1( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::A1( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
-		if( dynamic_cast < UnboundedRegExpAlternation * > ( it->get ( ) ) ) {
-			std::smart_ptr < UnboundedRegExpAlternation > childAlt ( static_cast < UnboundedRegExpAlternation * >( it->release() ) );
+		if( dynamic_cast < UnboundedRegExpAlternation < alphabet::Symbol > * > ( it->get ( ) ) ) {
+			std::smart_ptr < UnboundedRegExpAlternation < alphabet::Symbol > > childAlt ( static_cast < UnboundedRegExpAlternation < alphabet::Symbol > * >( it->release() ) );
 			it = node.getChildren ( ).erase( it );
 
 			it = node.insert( it, std::make_move_iterator(childAlt->getChildren ( ).begin ( ) ), std::make_move_iterator(childAlt->getChildren ( ).end ( ) ) );
@@ -167,11 +167,11 @@ bool RegExpOptimize::A1( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization A2: x + y = y + x (sort)
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A2( UnboundedRegExpAlternation & node ) {
-	auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a < *b; };
+bool RegExpOptimize::A2( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
+	auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a, const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & b ) -> bool { return *a < *b; };
 
 	if( std::is_sorted( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), cmp ) )
 		return false;
@@ -182,16 +182,16 @@ bool RegExpOptimize::A2( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization A3: x + \0 = x
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A3( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::A3( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	// alternation with no children is efectively \0
 
 	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
-		if( dynamic_cast < UnboundedRegExpEmpty * >( it->get ( ) ) ) {
+		if( dynamic_cast < UnboundedRegExpEmpty < alphabet::Symbol > * >( it->get ( ) ) ) {
 			it = node.getChildren ( ).erase( it );
 
 			optimized = true;
@@ -204,10 +204,10 @@ bool RegExpOptimize::A3( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization A4: x + x = x
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A4( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::A4( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	/*
 	 * two ways of implementing this opitimization:
 	 * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts...
@@ -215,7 +215,7 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation & node ) {
 	 *
 	 * As we always sort in optimization, we can use the first version, but A4 must be __always__ called __after__ A2
 	 */
-	auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a == *b; };
+	auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a, const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & b ) -> bool { return *a == *b; };
 
 	size_t size = node.getChildren ( ).size ( );
 	node.getChildren ( ).erase ( std::unique ( node.getChildren ( ).begin ( ), node.getChildren ( ).end ( ), cmp), node.getChildren ( ).end( ) );
@@ -225,15 +225,15 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization A5: x.(y.z) = (x.y).z = x.y.z
-  * @param node UnboundedRegExpConcatenation node
+  * @param node UnboundedRegExpConcatenation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A5( UnboundedRegExpConcatenation & node ) {
+bool RegExpOptimize::A5( UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
-		if( dynamic_cast<UnboundedRegExpConcatenation *>( it->get() ) ) {
-			std::smart_ptr < UnboundedRegExpConcatenation > childConcat ( static_cast<UnboundedRegExpConcatenation *>( it->release() ) );
+		if( dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol > *>( it->get() ) ) {
+			std::smart_ptr < UnboundedRegExpConcatenation < alphabet::Symbol > > childConcat ( static_cast<UnboundedRegExpConcatenation < alphabet::Symbol > *>( it->release() ) );
 			it = node.getChildren ( ).erase( it );
 
 			it = node.insert( it, std::make_move_iterator(childConcat->getChildren ( ).begin( )), std::make_move_iterator(childConcat->getChildren ( ).end( ) ));
@@ -248,16 +248,16 @@ bool RegExpOptimize::A5( UnboundedRegExpConcatenation & node ) {
 
 /**
   * optimization A6: \e.x = x.\e = x
-  * @param node UnboundedRegExpConcatenation node
+  * @param node UnboundedRegExpConcatenation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A6( UnboundedRegExpConcatenation & node ) {
+bool RegExpOptimize::A6( UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	// concatenation with no children is efectively \e
 
 	for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) {
-		if( dynamic_cast < UnboundedRegExpEpsilon * >( it->get ( ) ) ) {
+		if( dynamic_cast < UnboundedRegExpEpsilon < alphabet::Symbol > * >( it->get ( ) ) ) {
 			it = node.getChildren ( ).erase( it );
 
 			optimized = true;
@@ -270,15 +270,15 @@ bool RegExpOptimize::A6( UnboundedRegExpConcatenation & node ) {
 
 /**
   * optimization A7: \0.x = x.\0 = \0
-  * @param node UnboundedRegExpConcatenation node
+  * @param node UnboundedRegExpConcatenation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A7( UnboundedRegExpConcatenation & node ) {
+bool RegExpOptimize::A7( UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
 	if(node.getChildren ( ).size() == 1) return false;
 
-	if( std::any_of( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), []( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast < UnboundedRegExpEmpty * >( a.get() ); } ) ) {
+	if( std::any_of( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), []( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool{ return dynamic_cast < UnboundedRegExpEmpty < alphabet::Symbol > * >( a.get() ); } ) ) {
 		node.getChildren ( ).clear( );
-		node.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEmpty( ) ) );
+		node.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEmpty < alphabet::Symbol >( ) ) );
 
 		return true;
 	}
@@ -288,16 +288,16 @@ bool RegExpOptimize::A7( UnboundedRegExpConcatenation & node ) {
 
 /**
   * optimization A8: x.(y+z) = x.y + x.z
-  * @param node UnboundedRegExpConcatenation node
+  * @param node UnboundedRegExpConcatenation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A8( UnboundedRegExpConcatenation & /* node */) {
+bool RegExpOptimize::A8( UnboundedRegExpConcatenation < alphabet::Symbol > & /* node */) {
 /*
 	bool optimized = false;
 
 	for( auto it = std::next( node->elements.begin( ) ); it != node->elements.end( ); )
 	{
-		UnboundedRegExpAlternation * alt = dynamic_cast<UnboundedRegExpAlternation*>( * it );
+		UnboundedRegExpAlternation < alphabet::Symbol > * alt = dynamic_cast<UnboundedRegExpAlternation < alphabet::Symbol >*>( * it );
 		if( ! alt )
 		{
 			it ++;
@@ -305,19 +305,19 @@ bool RegExpOptimize::A8( UnboundedRegExpConcatenation & /* node */) {
 		}
 
 		// take everything to the left and copy it as prefix of every element in alternation.
-		UnboundedRegExpConcatenation * leftPart = new UnboundedRegExpConcatenation( );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * leftPart = new UnboundedRegExpConcatenation < alphabet::Symbol >( );
 		leftPart->elements.insert( leftPart->elements.end( ), node->elements.begin( ), it );
 
 		for( auto altIt = alt->elements.begin( ); altIt != alt->elements.end( ); altIt ++ )
 		{
-			UnboundedRegExpConcatenation * altElem = new UnboundedRegExpConcatenation( );
+			UnboundedRegExpConcatenation < alphabet::Symbol > * altElem = new UnboundedRegExpConcatenation < alphabet::Symbol >( );
 			altElem->elements.push_back( leftPart->clone( ) );
 			altElem->elements.push_back( * altIt );
 
 			* altIt = altElem;
 		}
 
-		UnboundedRegExpElement * optIt = optimize( * it );
+		UnboundedRegExpElement < alphabet::Symbol > * optIt = optimize( * it );
 		delete *it;
 		*it = optIt;
 
@@ -335,16 +335,16 @@ bool RegExpOptimize::A8( UnboundedRegExpConcatenation & /* node */) {
 
 /**
   * optimization A9: (x+y).z = x.z + y.z
-  * @param node UnboundedRegExpConcatenation node
+  * @param node UnboundedRegExpConcatenation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A9( UnboundedRegExpConcatenation & /* node */) {
+bool RegExpOptimize::A9( UnboundedRegExpConcatenation < alphabet::Symbol > & /* node */) {
 /*
 	bool optimized = false;
 
 	for( auto it = node->elements.begin( ); it != std::prev( node->elements.end( ) ); )
 	{
-		UnboundedRegExpAlternation * alt = dynamic_cast<UnboundedRegExpAlternation*>( * it );
+		UnboundedRegExpAlternation < alphabet::Symbol > * alt = dynamic_cast<UnboundedRegExpAlternation < alphabet::Symbol >*>( * it );
 		if( ! alt )
 		{
 			it ++;
@@ -352,19 +352,19 @@ bool RegExpOptimize::A9( UnboundedRegExpConcatenation & /* node */) {
 		}
 
 		// take everything to the right and copy it as suffix of every element in alternation.
-		UnboundedRegExpConcatenation * rest = new UnboundedRegExpConcatenation( );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * rest = new UnboundedRegExpConcatenation < alphabet::Symbol >( );
 		rest->elements.insert( rest->elements.end( ), std::next( it ), node->elements.end( ) );
 
 		for( auto altIt = alt->elements.begin( ); altIt != alt->elements.end( ); altIt ++ )
 		{
-			UnboundedRegExpConcatenation * altElem = new UnboundedRegExpConcatenation( );
+			UnboundedRegExpConcatenation < alphabet::Symbol > * altElem = new UnboundedRegExpConcatenation < alphabet::Symbol >( );
 			altElem->elements.push_back( * altIt );
 			altElem->elements.push_back( rest->clone( ) );
 
 			* altIt = altElem;
 		}
 
-		UnboundedRegExpElement * optIt = optimize( * it );
+		UnboundedRegExpElement < alphabet::Symbol > * optIt = optimize( * it );
 		delete *it;
 		*it = optIt;
 
@@ -373,7 +373,7 @@ bool RegExpOptimize::A9( UnboundedRegExpConcatenation & /* node */) {
 		optimized = true;
 
 		// as we move (delete) the rest of this expression, it surely wont do another round. More optimizations to be performerd are in subtree now.
-		// we do not care about this here as method optimize(UnboundedRegExpAlternation) will take care of this in next iteration
+		// we do not care about this here as method optimize(UnboundedRegExpAlternation < alphabet::Symbol >) will take care of this in next iteration
 		// it ++;
 		break;
 	}
@@ -385,10 +385,10 @@ bool RegExpOptimize::A9( UnboundedRegExpConcatenation & /* node */) {
 
 /**
   * optimization A10: x* = \e + x*x
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A10( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::A10( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	/*
@@ -398,27 +398,27 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation & node ) {
 	 */
 
 	// check if we have some epsilon or iteration left, else nothing to do
-	auto eps = find_if( node.getElements().begin( ), node.getElements().end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
-		return dynamic_cast<UnboundedRegExpEpsilon const *>( a.get() ) || dynamic_cast<UnboundedRegExpIteration const*>( a.get() );
+	auto eps = find_if( node.getElements().begin( ), node.getElements().end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool {
+		return dynamic_cast<UnboundedRegExpEpsilon < alphabet::Symbol > const *>( a.get() ) || dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol > const*>( a.get() );
 	});
 
 	if( eps == node.getElements().end( ) )
 		return false;
 
 	for( unsigned i = 0; i < node.getChildren ( ).size ( ); i++ ) {
-		UnboundedRegExpConcatenation * childConcat = dynamic_cast<UnboundedRegExpConcatenation *>( node.getChildren ( ) [ i ].get ( ) );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * childConcat = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol > *>( node.getChildren ( ) [ i ].get ( ) );
 		if( ! childConcat )
 			continue;
 
 		// if iteration is first element of concatenation
-		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration *>( childConcat->getElements().front( ).get() );
+		UnboundedRegExpIteration < alphabet::Symbol > * iter = dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol > *>( childConcat->getElements().front( ).get() );
 		if( ! iter )
 			continue;
 
 		// concatenation without the iteration node
-		UnboundedRegExpConcatenation tmpConcat ( * childConcat );
+		UnboundedRegExpConcatenation < alphabet::Symbol > tmpConcat ( * childConcat );
 		tmpConcat.getChildren ( ).erase( tmpConcat.getChildren ( ).begin( ) );
-		UnboundedRegExpElement * tmpConcatOpt = optimizeInner ( tmpConcat );
+		UnboundedRegExpElement < alphabet::Symbol > * tmpConcatOpt = optimizeInner ( tmpConcat );
 
 		// check if the iteration element is the same as the rest of the concatenation
 		if( iter->getElement() == * tmpConcatOpt ) {
@@ -435,16 +435,16 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization A11: x* = (\e + x)*
-  * @param node UnboundedRegExpIteration node
+  * @param node UnboundedRegExpIteration < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A11( UnboundedRegExpIteration & node ) {
-	UnboundedRegExpAlternation * childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node.getChild ( ).get() );
+bool RegExpOptimize::A11( UnboundedRegExpIteration < alphabet::Symbol > & node ) {
+	UnboundedRegExpAlternation < alphabet::Symbol > * childAlt = dynamic_cast<UnboundedRegExpAlternation < alphabet::Symbol > *>( node.getChild ( ).get() );
 
 	if( childAlt ) {
 		// check if eps inside iteration's alternation
-		auto eps = find_if( childAlt->getChildren ( ).begin( ), childAlt->getChildren ( ).end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
-			return dynamic_cast<UnboundedRegExpEpsilon *>( a.get() );
+		auto eps = find_if( childAlt->getChildren ( ).begin( ), childAlt->getChildren ( ).end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool {
+			return dynamic_cast<UnboundedRegExpEpsilon < alphabet::Symbol > *>( a.get() );
 		});
 
 		// if no eps
@@ -461,21 +461,21 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration & node ) {
 
 /**
   * optimization V1: \0* = \e
-  * @param node UnboundedRegExpIteration node
+  * @param node UnboundedRegExpIteration < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V1( UnboundedRegExpIteration &) {
-	// implemented in optimize( UnboundedRegExpIteration )
+bool RegExpOptimize::V1( UnboundedRegExpIteration < alphabet::Symbol > &) {
+	// implemented in optimize( UnboundedRegExpIteration < alphabet::Symbol > )
 
 	return false;
 }
 
 /**
   * optimization V2: x* + x = x*
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V2( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::V2( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	/*
@@ -483,14 +483,14 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation & node ) {
 	 * We need also to cover the cases like ( a + b + d )* + ( e )* + a + b + c + e = ( a + b + d )* + ( e )* + c
 	 */
 
-	std::vector < UnboundedRegExpElement * > iterElements;
+	std::vector < UnboundedRegExpElement < alphabet::Symbol > * > iterElements;
 	// cache  iter elements because of operator invalidation after erase
-	for( const std::smart_ptr < UnboundedRegExpElement > & n : node.getElements ( ) ) {
-		UnboundedRegExpIteration * iter = dynamic_cast < UnboundedRegExpIteration * > ( n.get ( ) );
+	for( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & n : node.getElements ( ) ) {
+		UnboundedRegExpIteration < alphabet::Symbol > * iter = dynamic_cast < UnboundedRegExpIteration < alphabet::Symbol > * > ( n.get ( ) );
 		if( iter ) {
-			UnboundedRegExpAlternation * inner = dynamic_cast < UnboundedRegExpAlternation * > ( iter->getChild ( ).get ( ) );
+			UnboundedRegExpAlternation < alphabet::Symbol > * inner = dynamic_cast < UnboundedRegExpAlternation < alphabet::Symbol > * > ( iter->getChild ( ).get ( ) );
 			if ( inner )
-				for ( const std::smart_ptr < UnboundedRegExpElement > & innerElement : inner->getElements ( ) )
+				for ( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & innerElement : inner->getElements ( ) )
 					iterElements.push_back ( innerElement.get() );
 			else
 				iterElements.push_back ( iter->getChild ( ).get ( ) );
@@ -498,8 +498,8 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation & node ) {
 		}
 	}
 
-	for( UnboundedRegExpElement * n : iterElements ) {
-		auto it = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ n ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool {
+	for( UnboundedRegExpElement < alphabet::Symbol > * n : iterElements ) {
+		auto it = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ n ] ( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool {
 			return *a == *n;
 		});
 
@@ -516,11 +516,11 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization V3: x** = x*
-  * @param node UnboundedRegExpIteration node
+  * @param node UnboundedRegExpIteration < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V3( UnboundedRegExpIteration & node ) {
-	UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node.getChild ( ).get() );
+bool RegExpOptimize::V3( UnboundedRegExpIteration < alphabet::Symbol > & node ) {
+	UnboundedRegExpIteration < alphabet::Symbol >* childIter = dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol >*>( node.getChild ( ).get() );
 	if( childIter ) {
 		node.setChild ( std::move ( childIter->getChild ( ) ) );
 
@@ -532,31 +532,31 @@ bool RegExpOptimize::V3( UnboundedRegExpIteration & node ) {
 
 /**
   * optimization V4: (x+y)* = (x*y*)*
-  * @param node UnboundedRegExpIteration node
+  * @param node UnboundedRegExpIteration < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V4( UnboundedRegExpIteration & node ) {
+bool RegExpOptimize::V4( UnboundedRegExpIteration < alphabet::Symbol > & node ) {
 	// interpretation: if iteration's element is concat and every concat's element is iteration
-	UnboundedRegExpConcatenation* cont = dynamic_cast<UnboundedRegExpConcatenation*>( node.getChild ( ).get() );
-	if( ! cont || ! all_of( cont->getChildren ( ).begin( ), cont->getChildren ( ).end( ), [] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration * >( a.get() ); } ) )
+	UnboundedRegExpConcatenation < alphabet::Symbol >* cont = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( node.getChild ( ).get() );
+	if( ! cont || ! all_of( cont->getChildren ( ).begin( ), cont->getChildren ( ).end( ), [] ( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol > * >( a.get() ); } ) )
 		return false;
 
-	UnboundedRegExpAlternation newAlt;
+	UnboundedRegExpAlternation < alphabet::Symbol > newAlt;
 
 	for( const auto & n : cont->getChildren ( ) )
-		newAlt.pushBackChild ( std::move ( static_cast < UnboundedRegExpIteration * > ( n.get ( ) )->getChild ( ) ) );
+		newAlt.pushBackChild ( std::move ( static_cast < UnboundedRegExpIteration < alphabet::Symbol > * > ( n.get ( ) )->getChild ( ) ) );
 
-	node.setChild ( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner ( newAlt ) ) );
+	node.setChild ( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner ( newAlt ) ) );
 
 	return true;
 }
 
 /**
   * optimization V5: x*y = y + x*xy
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V5( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::V5( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	// reinterpretation: ax*y = ay+ax*xy
@@ -567,14 +567,14 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation & node ) {
 	// prefix.x*x.suffix + prefix.suffix = prefix.x*.suffix
 
 	for( auto itA = node.getChildren().begin( ); itA != node.getChildren().end( ); ) {
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( itA->get() );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * concat = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( itA->get() );
 		if( ! concat ) {
 			++ itA;
 			continue;
 		}
 
 		for( auto itC = concat->getChildren().begin( ); itC != std::prev( concat->getChildren().end( ) ); ) {
-			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( itC->get() );
+			UnboundedRegExpIteration < alphabet::Symbol > * iter = dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol >*>( itC->get() );
 			if( ! iter ) {
 				++ itC;
 				continue;
@@ -584,12 +584,12 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation & node ) {
 			auto itStartY = std::next( itC ); //itStartY points to y in expression x*xy
 
 			// if iter's element is concat
-			if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->getChild().get() ) ) {
-				UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->getChild().get() );
+			if( dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( iter->getChild().get() ) ) {
+				UnboundedRegExpConcatenation < alphabet::Symbol > * iterConcat = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( iter->getChild().get() );
 
 				if( iterConcat->getChildren().size( ) != ( unsigned ) distance( std::next( itC ), concat->getChildren().end( ) )
 					|| ! equal( iterConcat->getChildren().begin( ), iterConcat->getChildren().end( ), std::next( itC ),
-					[ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool{ return *a == *b; } ) ) {
+					[ ]( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a, const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & b ) -> bool{ return *a == *b; } ) ) {
 					++ itC;
 					continue;
 				}
@@ -604,28 +604,28 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation & node ) {
 			}
 
 			// store everything before iteration as "a"
-			UnboundedRegExpConcatenation tmpAY;
+			UnboundedRegExpConcatenation < alphabet::Symbol > tmpAY;
 			if( concat->getChildren().begin( ) == itC ) {
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEpsilon( ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEpsilon < alphabet::Symbol >( ) ) );
 			} else {
-				UnboundedRegExpConcatenation tmpA;
+				UnboundedRegExpConcatenation < alphabet::Symbol > tmpA;
 				tmpA.insert( tmpA.getChildren().end( ), concat->getChildren().begin( ), itC );
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( tmpA ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( tmpA ) ) );
 			}
 
 			// store everything behind iteration's followup element as "y"
 			if( itStartY == concat->getChildren().end( ) ) {
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEpsilon( ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEpsilon < alphabet::Symbol >( ) ) );
 			} else {
-				UnboundedRegExpConcatenation tmpY;
+				UnboundedRegExpConcatenation < alphabet::Symbol > tmpY;
 				tmpY.insert( tmpY.getChildren().end( ), itStartY, concat->getChildren().end( ) );
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( tmpY ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( tmpY ) ) );
 			}
 
 			// concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node.getChildren() )
-			UnboundedRegExpElement * regexpAY = optimizeInner( tmpAY );
+			UnboundedRegExpElement < alphabet::Symbol > * regexpAY = optimizeInner( tmpAY );
 
-			auto iterAY = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } );
+			auto iterAY = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool{ return *a == *regexpAY; } );
 			delete regexpAY;
 			if( iterAY == node.getChildren().end( ) ) {
 				++ itC;
@@ -635,7 +635,7 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation & node ) {
 
 			tmpAY.insert( tmpAY.getChildren ( ).begin ( ) + 1, * itC );
 
-			node.setChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( tmpAY ) ), itA );
+			node.setChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( tmpAY ) ), itA );
 
 			itA = node.getChildren().erase( iterAY );
 
@@ -651,10 +651,10 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization V6: x*y = y + xx*y
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::V6( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	// reinterpretation: ax*y = ay+axx*y
@@ -665,14 +665,14 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
 	// prefix.xx*.suffix + prefix.suffix = prefix.x*.suffix
 
 	for( auto itA = node.getChildren ( ).begin( ); itA != node.getChildren ( ).end( ); ) {
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( itA->get() );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * concat = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( itA->get() );
 		if( ! concat ) {
 			++ itA;
 			continue;
 		}
 
 		for( auto itC = std::next( concat->getChildren ( ).begin( ) ); itC != concat->getChildren ( ).end( ); ) {
-			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( itC->get() );
+			UnboundedRegExpIteration < alphabet::Symbol > * iter = dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol >*>( itC->get() );
 			if( ! iter ) {
 				++ itC;
 				continue;
@@ -682,7 +682,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
 			auto itStartX = itC; //itStartX points to first x in expression xx*, everything before is therefore prefix - regexp "a"
 
 			// if iter's element is concat
-			UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->getChild ( ).get() );
+			UnboundedRegExpConcatenation < alphabet::Symbol > * iterConcat = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( iter->getChild ( ).get() );
 			if( iterConcat ) {
 
 				if( distance( concat->getChildren ( ).begin( ), itC ) < (int) iterConcat->getChildren ( ).size( ) ) {
@@ -693,7 +693,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
 
 				if( iterConcat->getChildren ( ).size( ) != ( unsigned ) distance( itStartX, concat->getChildren ( ).end( ) )
 						|| ! equal( iterConcat->getChildren().begin( ), iterConcat->getChildren().end( ), itStartX,
-						[]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool{ return *a == *b; } ) ) {
+						[]( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a, const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & b ) -> bool{ return *a == *b; } ) ) {
 					++ itC;
 					continue;
 				}
@@ -707,26 +707,26 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
 			}
 
 			// concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node->getChildren() )
-			UnboundedRegExpConcatenation tmpAY;
+			UnboundedRegExpConcatenation < alphabet::Symbol > tmpAY;
 			if( concat->getChildren().begin( ) == itStartX ) {
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEpsilon( ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEpsilon < alphabet::Symbol >( ) ) );
 			} else {
-				UnboundedRegExpConcatenation tmpA;
+				UnboundedRegExpConcatenation < alphabet::Symbol > tmpA;
 				tmpA.insert( tmpA.getChildren().end( ), concat->getChildren().begin( ), itStartX );
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( tmpA ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( tmpA ) ) );
 			}
 
 			if( std::next( itC ) == concat->getChildren().end( ) ) {
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEpsilon( ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEpsilon < alphabet::Symbol >( ) ) );
 			} else {
-				UnboundedRegExpConcatenation tmpY;
+				UnboundedRegExpConcatenation < alphabet::Symbol > tmpY;
 				tmpY.insert( tmpY.getChildren().end( ), std::next( itC ), concat->getChildren ( ).end( ) );
-				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( tmpY ) ) );
+				tmpAY.pushBackChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( tmpY ) ) );
 			}
 
-			UnboundedRegExpElement * regexpAY = optimizeInner( tmpAY );
+			UnboundedRegExpElement < alphabet::Symbol > * regexpAY = optimizeInner( tmpAY );
 
-			auto iterAY = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } );
+			auto iterAY = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool{ return *a == *regexpAY; } );
 			delete regexpAY;
 			if( iterAY == node.getChildren().end( ) ) {
 				++ itC;
@@ -737,7 +737,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
 			// if so make a x* y and replace a x x* y
 			tmpAY.insert( tmpAY.getChildren ( ).begin ( ) + 1, * itC );
 
-			node.setChild( std::smart_ptr < UnboundedRegExpElement > ( optimizeInner( tmpAY ) ), itA );
+			node.setChild( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( optimizeInner( tmpAY ) ), itA );
 
 			// remove a y
 			itA = node.getChildren().erase( iterAY );
@@ -754,10 +754,10 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) {
 
 /**
   * optimization V8: \e in h(x) => xx*=x*
-  * @param node UnboundedRegExpConcatenation node
+  * @param node UnboundedRegExpConcatenation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V8( UnboundedRegExpConcatenation & node ) {
+bool RegExpOptimize::V8( UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	// interpretation: if there is iteration in concatenation node, and element of iteration contains eps and is straight before this iteration, then this element can be omitted
@@ -766,7 +766,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation & node ) {
 		return false;
 
 	for( auto it = next ( node.getChildren ( ).begin( ) ); it != node.getChildren ( ).end( ); ) {
-		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( it->get() );
+		UnboundedRegExpIteration < alphabet::Symbol >* iter = dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol >*>( it->get() );
 
 		if( ! iter ) {
 			++ it;
@@ -774,7 +774,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation & node ) {
 		}
 
 		// if element of iteration is concatenation, we need to check this specially
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->getChild ( ).get() );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * concat = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( iter->getChild ( ).get() );
 
 		if( concat ) {
 			// check if not out of bounds
@@ -789,7 +789,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation & node ) {
 
 			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*concat) &&
 				concat->getChildren().size ( ) == ( unsigned ) distance ( it2, node.getChildren ( ).end( ) ) &&
-				equal( concat->getChildren ( ).begin( ), concat->getChildren ( ).end( ), it2, [] ( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a == *b; } ) ) {
+				equal( concat->getChildren ( ).begin( ), concat->getChildren ( ).end( ), it2, [] ( const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a, const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & b ) -> bool { return *a == *b; } ) ) {
 				optimized = true;
 
 				it = node.getChildren().erase( it2, it );
@@ -815,22 +815,22 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation & node ) {
 
 /**
   * optimization V9: (xy)*x = x(yx)*
-  * @param node UnboundedRegExpConcatenation node
+  * @param node UnboundedRegExpConcatenation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V9( UnboundedRegExpConcatenation & node ) {
+bool RegExpOptimize::V9( UnboundedRegExpConcatenation < alphabet::Symbol > & node ) {
 	bool optimized = false;
 
 	// interpretation: if concat (C1) with iter && iteration's element is concat (C2), then:
 	//	  simultaneously iterate through C1 and C2. (axy)*axz=ax(yax)*z -> get ax that is same and relocate them...
 
 	for( auto it = node.getChildren().begin( ) ; it != node.getChildren().end( ) ; ) {
-		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( it->get() );
+		UnboundedRegExpIteration < alphabet::Symbol > * iter = dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol >*>( it->get() );
 		if ( ! iter ) {
 			++ it;
 			continue;
 		}
-		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->getChild().get() );
+		UnboundedRegExpConcatenation < alphabet::Symbol > * concat = dynamic_cast<UnboundedRegExpConcatenation < alphabet::Symbol >*>( iter->getChild().get() );
 		if( ! concat ) {
 			++it;
 			continue;
@@ -849,12 +849,12 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation & node ) {
 		}
 
 		// std::cout << "xy" << std::endl;
-		// UnboundedRegExpConcatenation* tmp = new UnboundedRegExpConcatenation( );
+		// UnboundedRegExpConcatenation < alphabet::Symbol >* tmp = new UnboundedRegExpConcatenation < alphabet::Symbol >( );
 		// tmp->insert( tmp->getChildren().end( ), std::next( it ), c1Iter );
 		// std::cout << RegExp( tmp ) << std::endl;
 
 		// copy the range <it;sth>, delete it and go back to the iter node
-		std::vector<std::smart_ptr < UnboundedRegExpElement > > copyRange;
+		std::vector<std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > > copyRange;
 		copyRange.insert( copyRange.end(), std::next( it ), c1Iter );
 		it = node.getChildren().erase( std::next( it ), c1Iter );
 		it = std::prev( it );
@@ -875,18 +875,18 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation & node ) {
 /**
   * optimization V10: (x+y)* = (x*+y*)*
   * generalized to (x+y)* = (x+y*)* = (x*+y)* = (x*+y*)*
-  * @param node UnboundedRegExpIteration node
+  * @param node UnboundedRegExpIteration < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V10( UnboundedRegExpIteration & node ) {
+bool RegExpOptimize::V10( UnboundedRegExpIteration < alphabet::Symbol > & node ) {
 	// interpretation: if iter's child is alternation where some of its children are iteration, then they do not have to be iterations
-	UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node.getChild ( ).get() );
-	if( ! alt || ! any_of( alt->getChildren ( ).begin( ), alt->getChildren ( ).end( ), [] ( std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration * >( a.get() ); } ) )
+	UnboundedRegExpAlternation < alphabet::Symbol >* alt = dynamic_cast<UnboundedRegExpAlternation < alphabet::Symbol >*>( node.getChild ( ).get() );
+	if( ! alt || ! any_of( alt->getChildren ( ).begin( ), alt->getChildren ( ).end( ), [] ( std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol > * >( a.get() ); } ) )
 		return false;
 
 	for( auto it = alt->getChildren ( ).begin( ); it != alt->getChildren ( ).end( ); ) {
-		if ( dynamic_cast < UnboundedRegExpIteration * > ( it->get ( ) ) )
-			alt->setChild ( std::move ( static_cast < UnboundedRegExpIteration * >( it->get ( ) )->getChild ( ) ), it );
+		if ( dynamic_cast < UnboundedRegExpIteration < alphabet::Symbol > * > ( it->get ( ) ) )
+			alt->setChild ( std::move ( static_cast < UnboundedRegExpIteration < alphabet::Symbol > * >( it->get ( ) )->getChild ( ) ), it );
 	}
 
 	return true;
@@ -894,15 +894,15 @@ bool RegExpOptimize::V10( UnboundedRegExpIteration & node ) {
 
 /**
   * optimization X1: a* + \e = a*
-  * @param node UnboundedRegExpAlternation node
+  * @param node UnboundedRegExpAlternation < alphabet::Symbol > node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::X1( UnboundedRegExpAlternation & node ) {
+bool RegExpOptimize::X1( UnboundedRegExpAlternation < alphabet::Symbol > & node ) {
 	// theorem: In regexp like a* + \e, \e is described twice, first in a*, second in \e.
 	//  therefore we can delete the \e as it is redundant
 
-	auto iter = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration * >( a.get() );} );
-	auto eps = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon * >( a.get() );} );
+	auto iter = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration < alphabet::Symbol > * >( a.get() );} );
+	auto eps = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement < alphabet::Symbol > > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon < alphabet::Symbol > * >( a.get() );} );
 
 	if( iter != node.getChildren ( ).end( ) && eps != node.getChildren ( ).end( ) ) {
 		node.getChildren ( ).erase( eps );
diff --git a/alib2algo/src/regexp/transform/RegExpAlternate.cpp b/alib2algo/src/regexp/transform/RegExpAlternate.cpp
index 2590e99c81..5b4c75857f 100644
--- a/alib2algo/src/regexp/transform/RegExpAlternate.cpp
+++ b/alib2algo/src/regexp/transform/RegExpAlternate.cpp
@@ -16,27 +16,27 @@ regexp::RegExp RegExpAlternate::alternate(const regexp::RegExp& first, const reg
 	return dispatch(first.getData(), second.getData());
 }
 
-regexp::FormalRegExp RegExpAlternate::alternate(const regexp::FormalRegExp& first, const regexp::FormalRegExp& second) {
-	return regexp::FormalRegExp(RegExpAlternate::alternate(first.getRegExp(), second.getRegExp()));
+regexp::FormalRegExp < > RegExpAlternate::alternate(const regexp::FormalRegExp < > & first, const regexp::FormalRegExp < > & second) {
+	return regexp::FormalRegExp < > (RegExpAlternate::alternate(first.getRegExp(), second.getRegExp()));
 }
 
-auto RegExpAlternateFormalRegExp = RegExpAlternate::RegistratorWrapper<regexp::FormalRegExp, regexp::FormalRegExp>(RegExpAlternate::alternate);
+auto RegExpAlternateFormalRegExp = RegExpAlternate::RegistratorWrapper<regexp::FormalRegExp < > , regexp::FormalRegExp < > >(RegExpAlternate::alternate);
 
-regexp::FormalRegExpStructure RegExpAlternate::alternate(const regexp::FormalRegExpStructure& first, const regexp::FormalRegExpStructure& second) {
-	return regexp::FormalRegExpStructure(regexp::FormalRegExpAlternation(first.getStructure(), second.getStructure()));
+regexp::FormalRegExpStructure < alphabet::Symbol > RegExpAlternate::alternate(const regexp::FormalRegExpStructure < alphabet::Symbol > & first, const regexp::FormalRegExpStructure < alphabet::Symbol > & second) {
+	return regexp::FormalRegExpStructure < alphabet::Symbol > (regexp::FormalRegExpAlternation < alphabet::Symbol > (first.getStructure(), second.getStructure()));
 }
 
-regexp::UnboundedRegExp RegExpAlternate::alternate(const regexp::UnboundedRegExp& first, const regexp::UnboundedRegExp& second) {
-	return regexp::UnboundedRegExp(RegExpAlternate::alternate(first.getRegExp(), second.getRegExp()));
+regexp::UnboundedRegExp < > RegExpAlternate::alternate(const regexp::UnboundedRegExp < > & first, const regexp::UnboundedRegExp < > & second) {
+	return regexp::UnboundedRegExp < > (RegExpAlternate::alternate(first.getRegExp(), second.getRegExp()));
 }
 
-auto RegExpAlternateUnboundedRegExp = RegExpAlternate::RegistratorWrapper<regexp::UnboundedRegExp, regexp::UnboundedRegExp>(RegExpAlternate::alternate);
+auto RegExpAlternateUnboundedRegExp = RegExpAlternate::RegistratorWrapper<regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > >(RegExpAlternate::alternate);
 
-regexp::UnboundedRegExpStructure RegExpAlternate::alternate(const regexp::UnboundedRegExpStructure& first, const regexp::UnboundedRegExpStructure& second) {
-	regexp::UnboundedRegExpAlternation con;
+regexp::UnboundedRegExpStructure < alphabet::Symbol > RegExpAlternate::alternate(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & first, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & second) {
+	regexp::UnboundedRegExpAlternation < alphabet::Symbol > con;
 	con.appendElement(first.getStructure());
 	con.appendElement(second.getStructure());
-	return regexp::UnboundedRegExpStructure(con);
+	return regexp::UnboundedRegExpStructure < alphabet::Symbol > (con);
 }
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpAlternate.h b/alib2algo/src/regexp/transform/RegExpAlternate.h
index 7a5ad2f978..72a1025120 100644
--- a/alib2algo/src/regexp/transform/RegExpAlternate.h
+++ b/alib2algo/src/regexp/transform/RegExpAlternate.h
@@ -24,10 +24,10 @@ class RegExpAlternate : public std::PromotingDoubleDispatch<RegExpAlternate, reg
 public:
 	static regexp::RegExp alternate(const regexp::RegExp& first, const regexp::RegExp& second);
 
-	static regexp::FormalRegExp alternate(const regexp::FormalRegExp& first, const regexp::FormalRegExp& second);
-	static regexp::FormalRegExpStructure alternate(const regexp::FormalRegExpStructure& first, const regexp::FormalRegExpStructure& second);
-	static regexp::UnboundedRegExp alternate(const regexp::UnboundedRegExp& first, const regexp::UnboundedRegExp& second);
-	static regexp::UnboundedRegExpStructure alternate(const regexp::UnboundedRegExpStructure& first, const regexp::UnboundedRegExpStructure& second);
+	static regexp::FormalRegExp < > alternate(const regexp::FormalRegExp < > & first, const regexp::FormalRegExp < > & second);
+	static regexp::FormalRegExpStructure < alphabet::Symbol > alternate(const regexp::FormalRegExpStructure < alphabet::Symbol > & first, const regexp::FormalRegExpStructure < alphabet::Symbol > & second);
+	static regexp::UnboundedRegExp < > alternate(const regexp::UnboundedRegExp < > & first, const regexp::UnboundedRegExp < > & second);
+	static regexp::UnboundedRegExpStructure < alphabet::Symbol > alternate(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & first, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & second);
 };
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpConcatenate.cpp b/alib2algo/src/regexp/transform/RegExpConcatenate.cpp
index a9e3a65906..eee3499afc 100644
--- a/alib2algo/src/regexp/transform/RegExpConcatenate.cpp
+++ b/alib2algo/src/regexp/transform/RegExpConcatenate.cpp
@@ -16,27 +16,27 @@ regexp::RegExp RegExpConcatenate::concatenate(const regexp::RegExp& first, const
 	return dispatch(first.getData(), second.getData());
 }
 
-regexp::FormalRegExp RegExpConcatenate::concatenate(const regexp::FormalRegExp& first, const regexp::FormalRegExp& second) {
-	return regexp::FormalRegExp(RegExpConcatenate::concatenate(first.getRegExp(), second.getRegExp()));
+regexp::FormalRegExp < > RegExpConcatenate::concatenate(const regexp::FormalRegExp < > & first, const regexp::FormalRegExp < > & second) {
+	return regexp::FormalRegExp < > (RegExpConcatenate::concatenate(first.getRegExp(), second.getRegExp()));
 }
 
-auto RegExpConcatenateFormalRegExp = RegExpConcatenate::RegistratorWrapper<regexp::FormalRegExp, regexp::FormalRegExp>(RegExpConcatenate::concatenate);
+auto RegExpConcatenateFormalRegExp = RegExpConcatenate::RegistratorWrapper<regexp::FormalRegExp < >, regexp::FormalRegExp < > > (RegExpConcatenate::concatenate);
 
-regexp::FormalRegExpStructure RegExpConcatenate::concatenate(const regexp::FormalRegExpStructure& first, const regexp::FormalRegExpStructure& second) {
-	return regexp::FormalRegExpStructure(regexp::FormalRegExpConcatenation(first.getStructure(), second.getStructure()));
+regexp::FormalRegExpStructure < alphabet::Symbol > RegExpConcatenate::concatenate(const regexp::FormalRegExpStructure < alphabet::Symbol > & first, const regexp::FormalRegExpStructure < alphabet::Symbol > & second) {
+	return regexp::FormalRegExpStructure < alphabet::Symbol > (regexp::FormalRegExpConcatenation < alphabet::Symbol > (first.getStructure(), second.getStructure()));
 }
 
-regexp::UnboundedRegExp RegExpConcatenate::concatenate(const regexp::UnboundedRegExp& first, const regexp::UnboundedRegExp& second) {
-	return regexp::UnboundedRegExp(RegExpConcatenate::concatenate(first.getRegExp(), second.getRegExp()));
+regexp::UnboundedRegExp < > RegExpConcatenate::concatenate(const regexp::UnboundedRegExp < > & first, const regexp::UnboundedRegExp < > & second) {
+	return regexp::UnboundedRegExp < >(RegExpConcatenate::concatenate(first.getRegExp(), second.getRegExp()));
 }
 
-auto RegExpConcatenateUnboundedRegExp = RegExpConcatenate::RegistratorWrapper<regexp::UnboundedRegExp, regexp::UnboundedRegExp>(RegExpConcatenate::concatenate);
+auto RegExpConcatenateUnboundedRegExp = RegExpConcatenate::RegistratorWrapper<regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > >(RegExpConcatenate::concatenate);
 
-regexp::UnboundedRegExpStructure RegExpConcatenate::concatenate(const regexp::UnboundedRegExpStructure& first, const regexp::UnboundedRegExpStructure& second) {
-	regexp::UnboundedRegExpConcatenation con;
+regexp::UnboundedRegExpStructure < alphabet::Symbol > RegExpConcatenate::concatenate(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & first, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & second) {
+	regexp::UnboundedRegExpConcatenation < alphabet::Symbol > con;
 	con.appendElement(first.getStructure());
 	con.appendElement(second.getStructure());
-	return regexp::UnboundedRegExpStructure(con);
+	return regexp::UnboundedRegExpStructure < alphabet::Symbol > (con);
 }
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpConcatenate.h b/alib2algo/src/regexp/transform/RegExpConcatenate.h
index f1b8c1ecee..9faa59cde1 100644
--- a/alib2algo/src/regexp/transform/RegExpConcatenate.h
+++ b/alib2algo/src/regexp/transform/RegExpConcatenate.h
@@ -24,10 +24,10 @@ class RegExpConcatenate : public std::PromotingDoubleDispatch<RegExpConcatenate,
 public:
 	static regexp::RegExp concatenate(const regexp::RegExp& first, const regexp::RegExp& second);
 
-	static regexp::FormalRegExp concatenate(const regexp::FormalRegExp& first, const regexp::FormalRegExp& second);
-	static regexp::FormalRegExpStructure concatenate(const regexp::FormalRegExpStructure& first, const regexp::FormalRegExpStructure& second);
-	static regexp::UnboundedRegExp concatenate(const regexp::UnboundedRegExp& first, const regexp::UnboundedRegExp& second);
-	static regexp::UnboundedRegExpStructure concatenate(const regexp::UnboundedRegExpStructure& first, const regexp::UnboundedRegExpStructure& second);
+	static regexp::FormalRegExp < > concatenate(const regexp::FormalRegExp < > & first, const regexp::FormalRegExp < > & second);
+	static regexp::FormalRegExpStructure < alphabet::Symbol > concatenate(const regexp::FormalRegExpStructure < alphabet::Symbol > & first, const regexp::FormalRegExpStructure < alphabet::Symbol > & second);
+	static regexp::UnboundedRegExp < > concatenate(const regexp::UnboundedRegExp < > & first, const regexp::UnboundedRegExp < > & second);
+	static regexp::UnboundedRegExpStructure < alphabet::Symbol > concatenate(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & first, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & second);
 };
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.cpp b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
index afd330d1e7..6028c36df7 100644
--- a/alib2algo/src/regexp/transform/RegExpDerivation.cpp
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
@@ -17,89 +17,89 @@ regexp::RegExp RegExpDerivation::derivation(const regexp::RegExp& regexp, const
 	return dispatch(regexp.getData(), string);
 }
 
-regexp::FormalRegExp RegExpDerivation::derivation(const regexp::FormalRegExp& regexp, const string::LinearString < >& string) {
-	std::unique_ptr < regexp::FormalRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
+regexp::FormalRegExp < > RegExpDerivation::derivation(const regexp::FormalRegExp < > & regexp, const string::LinearString < >& string) {
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
 	for(const auto& symbol : string.getContent())
-		newRegExp = newRegExp->accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(symbol);
+		newRegExp = newRegExp->accept<std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Formal>(symbol);
 
-	return regexp::FormalRegExp ( regexp::FormalRegExpStructure ( std::move ( * newRegExp ) ) );
+	return regexp::FormalRegExp < > ( regexp::FormalRegExpStructure < alphabet::Symbol > ( std::move ( * newRegExp ) ) );
 }
 
-auto RegExpDerivationFormalRegExp = RegExpDerivation::RegistratorWrapper<regexp::FormalRegExp, regexp::FormalRegExp>(RegExpDerivation::derivation);
+auto RegExpDerivationFormalRegExp = RegExpDerivation::RegistratorWrapper<regexp::FormalRegExp < >, regexp::FormalRegExp < > >(RegExpDerivation::derivation);
 
-regexp::UnboundedRegExp RegExpDerivation::derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string) {
-	std::unique_ptr < regexp::UnboundedRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
+regexp::UnboundedRegExp < > RegExpDerivation::derivation(const regexp::UnboundedRegExp < > & regexp, const string::LinearString < >& string) {
+	std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
 	for(const auto& symbol : string.getContent())
-		newRegExp = newRegExp->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( symbol );
+		newRegExp = newRegExp->accept<std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Unbounded > ( symbol );
 
-	return regexp::UnboundedRegExp ( regexp::UnboundedRegExpStructure ( std::move ( * newRegExp ) ) );
+	return regexp::UnboundedRegExp < > ( regexp::UnboundedRegExpStructure < alphabet::Symbol > ( std::move ( * newRegExp ) ) );
 }
 
-auto RegExpDerivationUnboundedRegExp = RegExpDerivation::RegistratorWrapper<regexp::UnboundedRegExp, regexp::UnboundedRegExp>(RegExpDerivation::derivation);
+auto RegExpDerivationUnboundedRegExp = RegExpDerivation::RegistratorWrapper<regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > >(RegExpDerivation::derivation);
 
 // ----------------------------------------------------------------------------
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument) {
-	std::unique_ptr < regexp::FormalRegExpElement > leftDerivative = alternation.getLeftElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument);
-	std::unique_ptr < regexp::FormalRegExpElement > rightDerivative = alternation.getRightElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument);
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpDerivation::Formal::visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument) {
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > leftDerivative = alternation.getLeftElement().accept<std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Formal>(argument);
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > rightDerivative = alternation.getRightElement().accept<std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Formal>(argument);
 
-	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftDerivative ), std::move ( * rightDerivative ) ) );
+	return std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpAlternation < alphabet::Symbol > ( std::move ( * leftDerivative ), std::move ( * rightDerivative ) ) );
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument) {
-	std::unique_ptr < regexp::FormalRegExpElement > leftDerivative = concatenation.getLeftElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument);
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpDerivation::Formal::visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument) {
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > leftDerivative = concatenation.getLeftElement().accept<std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Formal>(argument);
 
-	std::unique_ptr < regexp::FormalRegExpElement > res ( new regexp::FormalRegExpConcatenation( std::move ( * leftDerivative ), std::move_copy ( concatenation.getRightElement ( ) ) ) );
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > res ( new regexp::FormalRegExpConcatenation < alphabet::Symbol > ( std::move ( * leftDerivative ), std::move_copy ( concatenation.getRightElement ( ) ) ) );
 
 	if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(concatenation.getLeftElement())) {
-		std::unique_ptr < regexp::FormalRegExpElement > rightDerivative = concatenation.getRightElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument);
+		std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > rightDerivative = concatenation.getRightElement().accept<std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Formal>(argument);
 
-		res = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation ( std::move ( * res ), std::move( * rightDerivative ) ) );
+		res = std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpAlternation < alphabet::Symbol > ( std::move ( * res ), std::move( * rightDerivative ) ) );
 	}
 
 	return res;
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument) {
-	std::unique_ptr < regexp::FormalRegExpElement > elementDerivative = iteration.getElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal > ( argument );
-	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpConcatenation( * elementDerivative, iteration ) );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpDerivation::Formal::visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument) {
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > elementDerivative = iteration.getElement().accept<std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Formal > ( argument );
+	return std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpConcatenation < alphabet::Symbol > ( * elementDerivative, iteration ) );
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument) {
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpDerivation::Formal::visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument) {
 	if(argument == symbol.getSymbol())
-		return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEpsilon() );
+		return std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpEpsilon < alphabet::Symbol > () );
 	else
-		return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
+		return std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpEmpty < alphabet::Symbol > () );
 }
 
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEpsilon&, const alphabet::Symbol&) {
-	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > &, const alphabet::Symbol&) {
+	return std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpEmpty < alphabet::Symbol > () );
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEmpty&, const alphabet::Symbol&) {
-	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > &, const alphabet::Symbol&) {
+	return std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpEmpty < alphabet::Symbol > () );
 }
 
 // ----------------------------------------------------------------------------
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument) {
-	std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument) {
+	std::unique_ptr < regexp::UnboundedRegExpAlternation < alphabet::Symbol > > ret ( new regexp::UnboundedRegExpAlternation < alphabet::Symbol > () );
 
 	for(const auto& child : alternation.getElements())
-		ret->appendElement( * ( child->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
+		ret->appendElement( * ( child->accept<std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
 
 	return ret;
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument) {
-	std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument) {
+	std::unique_ptr < regexp::UnboundedRegExpAlternation < alphabet::Symbol > > ret ( new regexp::UnboundedRegExpAlternation < alphabet::Symbol > () );
 
 	for(auto child = concatenation.getElements().begin(); child != concatenation.getElements().end(); ++ child) {
-		std::unique_ptr < regexp::UnboundedRegExpConcatenation > concat ( new regexp::UnboundedRegExpConcatenation() );
-		concat->appendElement( * ( (*child)->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
+		std::unique_ptr < regexp::UnboundedRegExpConcatenation < alphabet::Symbol > > concat ( new regexp::UnboundedRegExpConcatenation < alphabet::Symbol > () );
+		concat->appendElement( * ( (*child)->accept<std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
 
 		auto succeedingElement = child;
 		while(++succeedingElement != concatenation.getElements().end())
@@ -114,26 +114,26 @@ std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::
 	return ret;
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument) {
-	UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
-	con->appendElement ( * ( iteration.getElement().accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument) {
+	UnboundedRegExpConcatenation < alphabet::Symbol > * con = new regexp::UnboundedRegExpConcatenation < alphabet::Symbol > ( );
+	con->appendElement ( * ( iteration.getElement().accept<std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
 	con->appendElement ( iteration );
-	return std::unique_ptr < UnboundedRegExpElement > ( con );
+	return std::unique_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( con );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument) {
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument) {
 	if(argument == symbol.getSymbol())
-		return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEpsilon() );
+		return std::unique_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new regexp::UnboundedRegExpEpsilon < alphabet::Symbol > () );
 	else
-		return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
+		return std::unique_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new regexp::UnboundedRegExpEmpty < alphabet::Symbol > () );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, const alphabet::Symbol&) {
-	return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > &, const alphabet::Symbol&) {
+	return std::unique_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new regexp::UnboundedRegExpEmpty < alphabet::Symbol > () );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, const alphabet::Symbol&) {
-	return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > &, const alphabet::Symbol&) {
+	return std::unique_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( new regexp::UnboundedRegExpEmpty < alphabet::Symbol > () );
 }
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.h b/alib2algo/src/regexp/transform/RegExpDerivation.h
index e145ebfbff..c182a16d97 100644
--- a/alib2algo/src/regexp/transform/RegExpDerivation.h
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.h
@@ -36,28 +36,28 @@ public:
 	 */
 	static regexp::RegExp derivation(const regexp::RegExp& regexp, const string::LinearString < >& string);
 
-	static regexp::FormalRegExp derivation(const regexp::FormalRegExp& regexp, const string::LinearString < >& string);
-	static regexp::UnboundedRegExp derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string);
+	static regexp::FormalRegExp < > derivation(const regexp::FormalRegExp < > & regexp, const string::LinearString < > & string);
+	static regexp::UnboundedRegExp < > derivation(const regexp::UnboundedRegExp < > & regexp, const string::LinearString < > & string);
 
 private:
 	class Formal {
 	public:
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEpsilon& epsilon, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEmpty& empty, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > & epsilon, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > & empty, const alphabet::Symbol& argument);
 	};
 
 	class Unbounded {
 	public:
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEpsilon& epsilon, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEmpty& empty, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & epsilon, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & empty, const alphabet::Symbol& argument);
 	};
 };
 
diff --git a/alib2algo/src/regexp/transform/RegExpIntegral.cpp b/alib2algo/src/regexp/transform/RegExpIntegral.cpp
index f3f598ef49..2ae438ca98 100644
--- a/alib2algo/src/regexp/transform/RegExpIntegral.cpp
+++ b/alib2algo/src/regexp/transform/RegExpIntegral.cpp
@@ -15,101 +15,101 @@ regexp::RegExp RegExpIntegral::integral(const regexp::RegExp& regexp, const stri
 	return dispatch(regexp.getData(), string);
 }
 
-regexp::FormalRegExp RegExpIntegral::integral(const regexp::FormalRegExp& regexp, const string::LinearString < >& string) {
-	std::unique_ptr < regexp::FormalRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
+regexp::FormalRegExp < > RegExpIntegral::integral(const regexp::FormalRegExp < > & regexp, const string::LinearString < >& string) {
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
 	for(const auto& symbol : string.getContent())
-		newRegExp = newRegExp->accept < std::unique_ptr < regexp::FormalRegExpElement >, RegExpIntegral::Formal > ( symbol );
+		newRegExp = newRegExp->accept < std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, RegExpIntegral::Formal > ( symbol );
 
-	return regexp::FormalRegExp ( regexp::FormalRegExpStructure ( * newRegExp ) );
+	return regexp::FormalRegExp < > ( regexp::FormalRegExpStructure < alphabet::Symbol > ( * newRegExp ) );
 }
 
-auto RegExpIntegralFormalRegExp = RegExpIntegral::RegistratorWrapper<regexp::FormalRegExp, regexp::FormalRegExp>(RegExpIntegral::integral);
+auto RegExpIntegralFormalRegExp = RegExpIntegral::RegistratorWrapper<regexp::FormalRegExp < >, regexp::FormalRegExp < > > ( RegExpIntegral::integral );
 
-regexp::UnboundedRegExp RegExpIntegral::integral(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string) {
-	std::unique_ptr < regexp::UnboundedRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
+regexp::UnboundedRegExp < > RegExpIntegral::integral(const regexp::UnboundedRegExp < > & regexp, const string::LinearString < >& string) {
+	std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
 	for(const auto& symbol : string.getContent())
-		newRegExp = newRegExp->accept < std::unique_ptr < regexp::UnboundedRegExpElement >, RegExpIntegral::Unbounded > ( symbol );
+		newRegExp = newRegExp->accept < std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > >, RegExpIntegral::Unbounded > ( symbol );
 
-	return regexp::UnboundedRegExp ( regexp::UnboundedRegExpStructure( * newRegExp ) );
+	return regexp::UnboundedRegExp < > ( regexp::UnboundedRegExpStructure < alphabet::Symbol > ( * newRegExp ) );
 }
 
-auto RegExpIntegralUnboundedRegExp = RegExpIntegral::RegistratorWrapper<regexp::UnboundedRegExp, regexp::UnboundedRegExp>(RegExpIntegral::integral);
+auto RegExpIntegralUnboundedRegExp = RegExpIntegral::RegistratorWrapper<regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > > ( RegExpIntegral::integral );
 
 // ----------------------------------------------------------------------------
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument) {
-	std::unique_ptr < regexp::FormalRegExpElement > leftIntegral = alternation.getLeftElement().accept < std::unique_ptr < regexp::FormalRegExpElement >, RegExpIntegral::Formal > ( argument );
-	std::unique_ptr < regexp::FormalRegExpElement > rightIntegral = alternation.getRightElement().accept < std::unique_ptr < regexp::FormalRegExpElement >, RegExpIntegral::Formal > ( argument );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpIntegral::Formal::visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument) {
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > leftIntegral = alternation.getLeftElement().accept < std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, RegExpIntegral::Formal > ( argument );
+	std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > rightIntegral = alternation.getRightElement().accept < std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > >, RegExpIntegral::Formal > ( argument );
 
-	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftIntegral ), std::move ( * rightIntegral ) ) );
+	return std::unique_ptr < FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpAlternation < alphabet::Symbol > ( std::move ( * leftIntegral ), std::move ( * rightIntegral ) ) );
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument) {
-	return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( argument ), concatenation ) );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpIntegral::Formal::visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument) {
+	return std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpConcatenation < alphabet::Symbol > ( regexp::FormalRegExpSymbol < alphabet::Symbol > ( argument ), concatenation ) );
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument) {
-	return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( argument ), iteration ) );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpIntegral::Formal::visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument) {
+	return std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpConcatenation < alphabet::Symbol > ( regexp::FormalRegExpSymbol < alphabet::Symbol > ( argument ), iteration ) );
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument) {
-	return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( argument ), symbol ) );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpIntegral::Formal::visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument) {
+	return std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpConcatenation < alphabet::Symbol > ( regexp::FormalRegExpSymbol < alphabet::Symbol > ( argument ), symbol ) );
 }
 
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpEpsilon&, const alphabet::Symbol& argument) {
-	return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpSymbol( argument ) );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpIntegral::Formal::visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > &, const alphabet::Symbol& argument) {
+	return std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpSymbol < alphabet::Symbol > ( argument ) );
 }
 
-std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpEmpty&, const alphabet::Symbol&) {
-	return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpEmpty( ) );
+std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > RegExpIntegral::Formal::visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > &, const alphabet::Symbol&) {
+	return std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > ( new regexp::FormalRegExpEmpty < alphabet::Symbol > ( ) );
 }
 
 // ----------------------------------------------------------------------------
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument) {
-	regexp::UnboundedRegExpAlternation* alt = new regexp::UnboundedRegExpAlternation();
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument) {
+	regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alt = new regexp::UnboundedRegExpAlternation < alphabet::Symbol > ();
 
 	for(const auto& child : alternation.getElements())
-		alt->appendElement(* ( child->accept < std::unique_ptr < regexp::UnboundedRegExpElement >, RegExpIntegral::Unbounded > (argument) ) );
+		alt->appendElement(* ( child->accept < std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > >, RegExpIntegral::Unbounded > (argument) ) );
 
-	return std::unique_ptr < UnboundedRegExpElement > ( alt );
+	return std::unique_ptr < UnboundedRegExpElement < alphabet::Symbol > > ( alt );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument) {
-	regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument) {
+	regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * con = new regexp::UnboundedRegExpConcatenation < alphabet::Symbol > ( );
 
-	con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) );
+	con->appendElement ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( argument ) );
 	for ( const auto & element : concatenation.getElements() )
 		con->appendElement ( * element );
 
-	return std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
+	return std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > ( con );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument) {
-	regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
-	con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument) {
+	regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * con = new regexp::UnboundedRegExpConcatenation < alphabet::Symbol > ( );
+	con->appendElement ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( argument ) );
 	con->appendElement ( iteration );
 
-	return std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
+	return std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > ( con );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument) {
-	regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
-	con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument) {
+	regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * con = new regexp::UnboundedRegExpConcatenation < alphabet::Symbol > ( );
+	con->appendElement ( regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( argument ) );
 	con->appendElement ( symbol );
 
-	return std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
+	return std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > ( con );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, const alphabet::Symbol& argument) {
-	return std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpSymbol( argument ) );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > &, const alphabet::Symbol& argument) {
+	return std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > ( new regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( argument ) );
 }
 
-std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, const alphabet::Symbol&) {
-	return std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty( ) );
+std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > &, const alphabet::Symbol&) {
+	return std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > ( new regexp::UnboundedRegExpEmpty < alphabet::Symbol > ( ) );
 }
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpIntegral.h b/alib2algo/src/regexp/transform/RegExpIntegral.h
index ab84ebd42f..4d1440b10e 100644
--- a/alib2algo/src/regexp/transform/RegExpIntegral.h
+++ b/alib2algo/src/regexp/transform/RegExpIntegral.h
@@ -33,28 +33,28 @@ public:
 	 */
 	static regexp::RegExp integral(const regexp::RegExp& regexp, const string::LinearString < >& string);
 
-	static regexp::FormalRegExp integral(const regexp::FormalRegExp& regexp, const string::LinearString < >& string);
-	static regexp::UnboundedRegExp integral(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string);
+	static regexp::FormalRegExp < > integral(const regexp::FormalRegExp < > & regexp, const string::LinearString < >& string);
+	static regexp::UnboundedRegExp < > integral(const regexp::UnboundedRegExp < > & regexp, const string::LinearString < >& string);
 
 private:
 	class Formal {
 	public:
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEpsilon& epsilon, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEmpty& empty, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpEpsilon < alphabet::Symbol > & epsilon, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::FormalRegExpElement < alphabet::Symbol > > visit(const regexp::FormalRegExpEmpty < alphabet::Symbol > & empty, const alphabet::Symbol& argument);
 	};
 
 	class Unbounded {
 	public:
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEpsilon& epsilon, const alphabet::Symbol& argument);
-		static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEmpty& empty, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpIteration < alphabet::Symbol > & iteration, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & epsilon, const alphabet::Symbol& argument);
+		static std::unique_ptr < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & empty, const alphabet::Symbol& argument);
 	};
 };
 
diff --git a/alib2algo/src/regexp/transform/RegExpIterate.cpp b/alib2algo/src/regexp/transform/RegExpIterate.cpp
index 4a41497054..20f01e543f 100644
--- a/alib2algo/src/regexp/transform/RegExpIterate.cpp
+++ b/alib2algo/src/regexp/transform/RegExpIterate.cpp
@@ -15,24 +15,24 @@ regexp::RegExp RegExpIterate::iterate(const regexp::RegExp& regexp) {
 	return dispatch(regexp.getData());
 }
 
-regexp::FormalRegExp RegExpIterate::iterate(const regexp::FormalRegExp& regexp) {
-	return regexp::FormalRegExp(RegExpIterate::iterate(regexp.getRegExp()));
+regexp::FormalRegExp < > RegExpIterate::iterate(const regexp::FormalRegExp < > & regexp) {
+	return regexp::FormalRegExp < >(RegExpIterate::iterate(regexp.getRegExp()));
 }
 
-auto RegExpIterateFormalRegExpFormalRegExp = RegExpIterate::RegistratorWrapper<regexp::FormalRegExp, regexp::FormalRegExp>(RegExpIterate::iterate);
+auto RegExpIterateFormalRegExpFormalRegExp = RegExpIterate::RegistratorWrapper<regexp::FormalRegExp < >, regexp::FormalRegExp < > >(RegExpIterate::iterate);
 
-regexp::FormalRegExpStructure RegExpIterate::iterate(const regexp::FormalRegExpStructure& regexp) {
-	return regexp::FormalRegExpStructure(regexp::FormalRegExpIteration(regexp.getStructure()));
+regexp::FormalRegExpStructure < alphabet::Symbol > RegExpIterate::iterate(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp) {
+	return regexp::FormalRegExpStructure < alphabet::Symbol >(regexp::FormalRegExpIteration < alphabet::Symbol > (regexp.getStructure()));
 }
 
-regexp::UnboundedRegExp RegExpIterate::iterate(const regexp::UnboundedRegExp& regexp) {
-	return regexp::UnboundedRegExp(RegExpIterate::iterate(regexp.getRegExp()));
+regexp::UnboundedRegExp < > RegExpIterate::iterate(const regexp::UnboundedRegExp < > & regexp) {
+	return regexp::UnboundedRegExp < >(RegExpIterate::iterate(regexp.getRegExp()));
 }
 
-auto RegExpIterateUnboundedRegExpUnboundedRegExp = RegExpIterate::RegistratorWrapper<regexp::UnboundedRegExp, regexp::UnboundedRegExp>(RegExpIterate::iterate);
+auto RegExpIterateUnboundedRegExpUnboundedRegExp = RegExpIterate::RegistratorWrapper<regexp::UnboundedRegExp < >, regexp::UnboundedRegExp < > >(RegExpIterate::iterate);
 
-regexp::UnboundedRegExpStructure RegExpIterate::iterate(const regexp::UnboundedRegExpStructure& regexp) {
-	return regexp::UnboundedRegExpStructure(regexp::UnboundedRegExpIteration(regexp.getStructure()));
+regexp::UnboundedRegExpStructure < alphabet::Symbol > RegExpIterate::iterate(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp) {
+	return regexp::UnboundedRegExpStructure < alphabet::Symbol >(regexp::UnboundedRegExpIteration < alphabet::Symbol > (regexp.getStructure()));
 }
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpIterate.h b/alib2algo/src/regexp/transform/RegExpIterate.h
index 8ffd9fc242..27589fe092 100644
--- a/alib2algo/src/regexp/transform/RegExpIterate.h
+++ b/alib2algo/src/regexp/transform/RegExpIterate.h
@@ -24,10 +24,10 @@ class RegExpIterate : public std::SingleDispatch<RegExpIterate, regexp::RegExp,
 public:
 	static regexp::RegExp iterate(const regexp::RegExp& regexp);
 
-	static regexp::FormalRegExp iterate(const regexp::FormalRegExp& regexp);
-	static regexp::FormalRegExpStructure iterate(const regexp::FormalRegExpStructure& regexp);
-	static regexp::UnboundedRegExp iterate(const regexp::UnboundedRegExp& regexp);
-	static regexp::UnboundedRegExpStructure iterate(const regexp::UnboundedRegExpStructure& regexp);
+	static regexp::FormalRegExp < > iterate(const regexp::FormalRegExp < > & regexp);
+	static regexp::FormalRegExpStructure < alphabet::Symbol > iterate(const regexp::FormalRegExpStructure < alphabet::Symbol > & regexp);
+	static regexp::UnboundedRegExp < > iterate(const regexp::UnboundedRegExp < > & regexp);
+	static regexp::UnboundedRegExpStructure < alphabet::Symbol > iterate(const regexp::UnboundedRegExpStructure < alphabet::Symbol > & regexp);
 };
 
 } /* namespace regexp */
diff --git a/alib2algo/test-src/regexp/RegExpTest.cpp b/alib2algo/test-src/regexp/RegExpTest.cpp
index 81c1ae1db8..01410cebcc 100644
--- a/alib2algo/test-src/regexp/RegExpTest.cpp
+++ b/alib2algo/test-src/regexp/RegExpTest.cpp
@@ -27,19 +27,19 @@ void RegExpTest::tearDown ( ) {
 void RegExpTest::testFirst ( ) {
 	{
 		std::string input = "#E* #0*";
-		regexp::UnboundedRegExp regexp ( static_cast < const regexp::UnboundedRegExp & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
-		regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+		regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
+		regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
-		std::set < regexp::UnboundedRegExpSymbol > first = regexp::GlushkovTraversal::first ( indexedRegExp );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp );
 
 		CPPUNIT_ASSERT ( first.size ( ) == 0 );
 	}
 	{
 		std::string input = "#E* a";
-		regexp::UnboundedRegExp regexp ( static_cast < const regexp::UnboundedRegExp & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
-		regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+		regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
+		regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
-		std::set < regexp::UnboundedRegExpSymbol > first = regexp::GlushkovTraversal::first ( indexedRegExp );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp );
 
 		CPPUNIT_ASSERT ( first.size ( ) == 1 );
 	}
@@ -48,19 +48,19 @@ void RegExpTest::testFirst ( ) {
 void RegExpTest::testLast ( ) {
 	{
 		std::string input = "a+a";
-		regexp::UnboundedRegExp regexp ( static_cast < const regexp::UnboundedRegExp & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
-		regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+		regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
+		regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
-		std::set < regexp::UnboundedRegExpSymbol > last = regexp::GlushkovTraversal::last ( indexedRegExp );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp );
 
 		CPPUNIT_ASSERT ( last.size ( ) == 2 );
 	}
 	{
 		std::string input = "(a+a)b";
-		regexp::UnboundedRegExp regexp ( static_cast < const regexp::UnboundedRegExp & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
-		regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+		regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
+		regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
-		std::set < regexp::UnboundedRegExpSymbol > last = regexp::GlushkovTraversal::last ( indexedRegExp );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp );
 
 		std::cout << last << std::endl;
 		CPPUNIT_ASSERT ( last.size ( ) == 1 );
@@ -70,53 +70,53 @@ void RegExpTest::testLast ( ) {
 void RegExpTest::testFollow ( ) {
 	{
 		std::string input = "(a+a)b";
-		regexp::UnboundedRegExp regexp ( static_cast < const regexp::UnboundedRegExp & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
-		regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+		regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
+		regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
 		auto symbolsIter = indexedRegExp.getAlphabet ( ).begin ( );
 
-		std::set < regexp::UnboundedRegExpSymbol > follow1 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow1 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow1.size ( ) == 1 );
 
 		symbolsIter++;
-		std::set < regexp::UnboundedRegExpSymbol > follow2 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow2 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow2.size ( ) == 1 );
 
 		symbolsIter++;
-		std::set < regexp::UnboundedRegExpSymbol > follow3 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow3 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow3.size ( ) == 0 );
 	}
 	{
 		std::string input = "a+a* (b+a)* c";
-		regexp::UnboundedRegExp regexp ( static_cast < const regexp::UnboundedRegExp & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
-		regexp::UnboundedRegExp indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
+		regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) );
+		regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovTraversal::index ( regexp );
 
 		auto symbolsIter = indexedRegExp.getAlphabet ( ).begin ( );
 
-		std::set < regexp::UnboundedRegExpSymbol > follow1 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow1 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow1.size ( ) == 0 );
 
 		symbolsIter++;
-		std::set < regexp::UnboundedRegExpSymbol > follow2 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow2 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow2.size ( ) == 4 );
 
 		symbolsIter++;
-		std::set < regexp::UnboundedRegExpSymbol > follow3 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow3 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow3.size ( ) == 3 );
 
 		symbolsIter++;
-		std::set < regexp::UnboundedRegExpSymbol > follow4 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow4 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow4.size ( ) == 3 );
 
 		symbolsIter++;
-		std::set < regexp::UnboundedRegExpSymbol > follow5 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol ( * symbolsIter ) );
+		std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow5 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) );
 
 		CPPUNIT_ASSERT ( follow5.size ( ) == 0 );
 	}
diff --git a/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
index c5f4a38916..a71c93872c 100644
--- a/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
+++ b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
@@ -22,12 +22,12 @@ void RegExpOptimizeTest::tearDown() {
 void RegExpOptimizeTest::testOptimize() {
 	{
 		std::string input = "a+a";
-		regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
+		regexp::UnboundedRegExp < > regexp( static_cast<const regexp::UnboundedRegExp < > &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
 
-		regexp::UnboundedRegExp res = regexp::simplify::RegExpOptimize::optimize(regexp);
+		regexp::UnboundedRegExp < > res = regexp::simplify::RegExpOptimize::optimize(regexp);
 
 		std::string inputRes = "a";
-		regexp::UnboundedRegExp regexpRes( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(inputRes).getData() ) );
+		regexp::UnboundedRegExp < > regexpRes( static_cast<const regexp::UnboundedRegExp < > &>( alib::StringDataFactory::fromString<regexp::RegExp>(inputRes).getData() ) );
 
 		std::cout << res << std::endl;
 		std::cout << regexpRes << std::endl;
@@ -36,12 +36,12 @@ void RegExpOptimizeTest::testOptimize() {
 	}
 	{
 		std::string input = "(a+a)b + (#0 b + (#0 a + (#0 b + a)))";
-		regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
+		regexp::UnboundedRegExp < > regexp( static_cast<const regexp::UnboundedRegExp < > &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
 
-		regexp::UnboundedRegExp res = regexp::simplify::RegExpOptimize::optimize(regexp);
+		regexp::UnboundedRegExp < > res = regexp::simplify::RegExpOptimize::optimize(regexp);
 
 		std::string inputRes = "a + ab";
-		regexp::UnboundedRegExp regexpRes( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(inputRes).getData() ) );
+		regexp::UnboundedRegExp < > regexpRes( static_cast<const regexp::UnboundedRegExp < > &>( alib::StringDataFactory::fromString<regexp::RegExp>(inputRes).getData() ) );
 
 		std::cout << res << std::endl;
 		std::cout << regexpRes << std::endl;
@@ -50,12 +50,12 @@ void RegExpOptimizeTest::testOptimize() {
 	}
 	{
 		std::string input = "a z + a b* b z";
-		regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
+		regexp::UnboundedRegExp < > regexp( static_cast<const regexp::UnboundedRegExp < > &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
 
-		regexp::UnboundedRegExp res = regexp::simplify::RegExpOptimize::optimize(regexp);
+		regexp::UnboundedRegExp < > res = regexp::simplify::RegExpOptimize::optimize(regexp);
 
 		std::string inputRes = "a b* z";
-		regexp::UnboundedRegExp regexpRes( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(inputRes).getData() ) );
+		regexp::UnboundedRegExp < > regexpRes( static_cast<const regexp::UnboundedRegExp < > &>( alib::StringDataFactory::fromString<regexp::RegExp>(inputRes).getData() ) );
 
 		std::cout << res << std::endl;
 		std::cout << regexpRes << std::endl;
diff --git a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
index 4e78dcd2db..02f55dbc72 100644
--- a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
+++ b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
@@ -48,11 +48,11 @@ void re2faTest::testThompson() {
 
 void re2faTest::testGlushkov() {
 	std::string input = "a+a*b*";
-	regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
+	regexp::UnboundedRegExp < > regexp1( static_cast<const regexp::UnboundedRegExp < > &>( alib::StringDataFactory::fromString<regexp::RegExp>(input).getData() ) );
 
 	automaton::NFA < >  nfa1 = regexp::convert::ToAutomatonGlushkov::convert(regexp1);
 
-	regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( automaton::convert::ToRegExpAlgebraic::convert(nfa1) ) );
+	regexp::UnboundedRegExp < > regexp2( static_cast<const regexp::UnboundedRegExp < > &>( automaton::convert::ToRegExpAlgebraic::convert(nfa1) ) );
 
 	std::cout << regexp1 << std::endl;
 	std::cout << regexp2 << std::endl;
diff --git a/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
index 3292c4d671..6c5cf4ab83 100644
--- a/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
+++ b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
@@ -35,7 +35,7 @@ void RegExpConcatenateTest::testRegExpConcatenate() {
 		std::string input1 = "(#E a b)";
 		regexp::RegExp re1 = alib::StringDataFactory::fromString<regexp::RegExp>(input1);
 
-		regexp::RegExp re2(regexp::FormalRegExp(regexp::FormalRegExpStructure(regexp::FormalRegExpConcatenation(regexp::FormalRegExpEmpty {}, regexp::FormalRegExpEpsilon {}))));
+		regexp::RegExp re2(regexp::FormalRegExp < > (regexp::FormalRegExpStructure < alphabet::Symbol > (regexp::FormalRegExpConcatenation < alphabet::Symbol > (regexp::FormalRegExpEmpty < alphabet::Symbol > {}, regexp::FormalRegExpEpsilon < alphabet::Symbol >  {}))));
 
 		regexp::RegExp re = regexp::RegExpConcatenate::concatenate(re1, re2);
 
@@ -45,7 +45,7 @@ void RegExpConcatenateTest::testRegExpConcatenate() {
 		CPPUNIT_ASSERT(re == rer);
 	}
 	{
-		regexp::RegExp re1(regexp::FormalRegExp(regexp::FormalRegExpStructure(regexp::FormalRegExpConcatenation(regexp::FormalRegExpEmpty {}, regexp::FormalRegExpEpsilon {}))));
+		regexp::RegExp re1(regexp::FormalRegExp < > (regexp::FormalRegExpStructure < alphabet::Symbol > (regexp::FormalRegExpConcatenation < alphabet::Symbol > (regexp::FormalRegExpEmpty < alphabet::Symbol > {}, regexp::FormalRegExpEpsilon < alphabet::Symbol >  {}))));
 
 		std::string input2 = "(#E a b)";
 		regexp::RegExp re2 = alib::StringDataFactory::fromString<regexp::RegExp>(input2);
@@ -54,10 +54,10 @@ void RegExpConcatenateTest::testRegExpConcatenate() {
 
 		std::string inputr = "(#0 #E )(#E a b)";
 		regexp::RegExp tmp = alib::StringDataFactory::fromString<regexp::RegExp>(inputr);
-		regexp::RegExp rer(regexp::FormalRegExp(dynamic_cast<const regexp::UnboundedRegExp&>(tmp.getData())));
+		regexp::RegExp rer(regexp::FormalRegExp < > (dynamic_cast<const regexp::UnboundedRegExp < > & >(tmp.getData())));
 
-		std::cout << (dynamic_cast<const regexp::UnboundedRegExp&>(tmp.getData())).getAlphabet() << std::endl;
-		std::cout << (dynamic_cast<const regexp::FormalRegExp&>(rer.getData())).getAlphabet() << std::endl;
+		std::cout << (dynamic_cast<const regexp::UnboundedRegExp < > & >(tmp.getData())).getAlphabet() << std::endl;
+		std::cout << (dynamic_cast<const regexp::FormalRegExp < > & >(rer.getData())).getAlphabet() << std::endl;
 
 		std::cout << re << std::endl;
 		std::cout << rer << std::endl;
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
index d8308e33fa..3bbb48af99 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
@@ -138,7 +138,7 @@ FormalRegExpElement < SymbolType > & FormalRegExpAlternation < SymbolType >::get
 
 template < class SymbolType >
 void FormalRegExpAlternation < SymbolType >::setLeftElement ( FormalRegExpElement < SymbolType > && element ) {
-	setLeft ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
+	this->setLeft ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
 }
 
 template < class SymbolType >
@@ -148,7 +148,7 @@ void FormalRegExpAlternation < SymbolType >::setLeftElement ( const FormalRegExp
 
 template < class SymbolType >
 void FormalRegExpAlternation < SymbolType >::setRightElement ( FormalRegExpElement < SymbolType > && element ) {
-	setRight ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
+	this->setRight ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
index 8a06856cb6..06b17b62b1 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
@@ -134,7 +134,7 @@ FormalRegExpElement < SymbolType > & FormalRegExpConcatenation < SymbolType >::g
 
 template < class SymbolType >
 void FormalRegExpConcatenation < SymbolType >::setLeftElement ( FormalRegExpElement < SymbolType > && element ) {
-	setLeft( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
+	this->setLeft( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
 }
 
 template < class SymbolType >
@@ -144,7 +144,7 @@ void FormalRegExpConcatenation < SymbolType >::setLeftElement ( const FormalRegE
 
 template < class SymbolType >
 void FormalRegExpConcatenation < SymbolType >::setRightElement ( FormalRegExpElement < SymbolType > && element ) {
-	setRight ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
+	this->setRight ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( element ).plunder ( ) ) );
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h
index ea2e677d8c..8566166aac 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.h
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h
@@ -119,7 +119,7 @@ FormalRegExpElement < SymbolType > & FormalRegExpIteration < SymbolType >::getEl
 
 template < class SymbolType >
 void FormalRegExpIteration < SymbolType >::setElement ( FormalRegExpElement < SymbolType > && elementParam ) {
-	setChild ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( elementParam ).plunder ( ) ) );
+	this->setChild ( std::smart_ptr < FormalRegExpElement < SymbolType > > ( std::move ( elementParam ).plunder ( ) ) );
 }
 
 template < class SymbolType >
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
index b8d82a2524..1d7455f6ef 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
@@ -119,7 +119,7 @@ UnboundedRegExpElement < SymbolType > & UnboundedRegExpIteration < SymbolType >:
 
 template < class SymbolType >
 void UnboundedRegExpIteration < SymbolType >::setElement ( UnboundedRegExpElement < SymbolType > && elementParam ) {
-	setChild ( std::smart_ptr < UnboundedRegExpElement < SymbolType > > ( std::move ( elementParam ).plunder ( ) ) );
+	this->setChild ( std::smart_ptr < UnboundedRegExpElement < SymbolType > > ( std::move ( elementParam ).plunder ( ) ) );
 }
 
 template < class SymbolType >
diff --git a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
index 0f3e53bfac..1f2b3181ba 100644
--- a/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
+++ b/alib2elgo/src/automaton/properties/efficient/AllEpsilonClosure.cpp
@@ -104,7 +104,7 @@ std::map<label::Label, std::set<label::Label>> AllEpsilonClosure::allEpsilonClos
 	std::set<label::Label> nonvisited = fsm.getStates();
 
 	std::map<label::Label, std::set<label::Label>> epsilonTransitions;
-	for(const std::pair<const std::pair<label::Label, regexp::UnboundedRegExpStructure>, std::set<label::Label> >& transition : fsm.getTransitions() )
+	for(const std::pair<const std::pair<label::Label, regexp::UnboundedRegExpStructure < alphabet::Symbol > >, std::set<label::Label> >& transition : fsm.getTransitions() )
 		if( regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
 			epsilonTransitions[transition.first.first].insert(transition.second.begin(), transition.second.end());
 
diff --git a/alib2str/src/regexp/RegExpFromStringParser.cpp b/alib2str/src/regexp/RegExpFromStringParser.cpp
index 9bd787e0d8..e18387b9f2 100644
--- a/alib2str/src/regexp/RegExpFromStringParser.cpp
+++ b/alib2str/src/regexp/RegExpFromStringParser.cpp
@@ -21,29 +21,29 @@ RegExp RegExpFromStringParser::parseRegExp(std::istream& input) {
 	return parseRegExp(input, std::set<FEATURES>({FEATURES::FORMAL, FEATURES::UNBOUNDED}));
 }
 
-UnboundedRegExpStructure RegExpFromStringParser::parseUnboundedRegExpStructure(std::istream& input) {
-	std::rvalue_ref < UnboundedRegExpElement > element = alternation(input);
-	return regexp::UnboundedRegExpStructure(std::move(element));
+UnboundedRegExpStructure < alphabet::Symbol > RegExpFromStringParser::parseUnboundedRegExpStructure(std::istream& input) {
+	std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > element = alternation(input);
+	return regexp::UnboundedRegExpStructure < alphabet::Symbol >(std::move(element));
 }
 
 RegExp RegExpFromStringParser::parseRegExp(std::istream& input, const std::set<FEATURES>& features) {
-	UnboundedRegExp regexp { RegExpFromStringParser::parseUnboundedRegExpStructure ( input ) };
+	UnboundedRegExp < > regexp { RegExpFromStringParser::parseUnboundedRegExpStructure ( input ) };
 
 	if(features.count(FEATURES::UNBOUNDED)) return RegExp { std::move ( regexp ) };
 
-	if(features.count(FEATURES::FORMAL)) return RegExp { FormalRegExp { std::move ( regexp ) } };
+	if(features.count(FEATURES::FORMAL)) return RegExp { FormalRegExp < > { std::move ( regexp ) } };
 
 	throw exception::CommonException("Invalid input");
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternation(std::istream& input) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::alternation(std::istream& input) {
 	return alternationCont(input, concatenation(input));
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::alternationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > left) {
 	RegExpFromStringLexer::Token token = RegExpFromStringLexer::next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::PLUS) {
-		UnboundedRegExpAlternation res;
+		UnboundedRegExpAlternation < alphabet::Symbol > res;
 		res.appendElement(std::move(left));
 		res.appendElement(concatenation(input));
 
@@ -54,7 +54,7 @@ std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternationCo
 	}
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternationContCont(std::istream& input, UnboundedRegExpAlternation res) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::alternationContCont(std::istream& input, UnboundedRegExpAlternation < alphabet::Symbol > res) {
 	RegExpFromStringLexer::Token token = RegExpFromStringLexer::next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::PLUS) {
 		res.appendElement(concatenation(input));
@@ -62,19 +62,19 @@ std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternationCo
 		return alternationContCont(input, std::move ( res ) );
 	} else {
 		RegExpFromStringLexer::putback(input, token);
-		return std::rvalue_ref < UnboundedRegExpElement > ( std::move ( res ).plunder() );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( std::move ( res ).plunder() );
 	}
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenation(std::istream& input) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::concatenation(std::istream& input) {
 	return concatenationCont(input, factor(input));
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::concatenationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > left) {
 	RegExpFromStringLexer::Token token = RegExpFromStringLexer::next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) {
 		RegExpFromStringLexer::putback(input, token);
-		UnboundedRegExpConcatenation res;
+		UnboundedRegExpConcatenation < alphabet::Symbol > res;
 		res.appendElement(std::move(left));
 		res.appendElement(factor(input));
 
@@ -85,7 +85,7 @@ std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenation
 	}
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenationContCont(std::istream& input, UnboundedRegExpConcatenation res) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::concatenationContCont(std::istream& input, UnboundedRegExpConcatenation < alphabet::Symbol > res) {
 	RegExpFromStringLexer::Token token = RegExpFromStringLexer::next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) {
 		RegExpFromStringLexer::putback(input, token);
@@ -94,37 +94,37 @@ std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenation
 		return concatenationContCont(input, std::move ( res ) );
 	} else {
 		RegExpFromStringLexer::putback(input, token);
-		return std::rvalue_ref < UnboundedRegExpElement > ( std::move ( res ).plunder() );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( std::move ( res ).plunder() );
 	}
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::factor(std::istream& input) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::factor(std::istream& input) {
 	RegExpFromStringLexer::Token token = RegExpFromStringLexer::next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::LPAR) {
-		std::rvalue_ref < UnboundedRegExpElement > base = alternation(input);
+		std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > base = alternation(input);
 		token = RegExpFromStringLexer::next(input);
 		if(token.type != RegExpFromStringLexer::TokenType::RPAR) throw exception::CommonException("Expected RPAR");
 		return star(input, std::move ( base ) );
 	} else if(token.type == RegExpFromStringLexer::TokenType::EPS) {
-		return star(input, std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpEpsilon ( ) ) );
+		return star(input, std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEpsilon < alphabet::Symbol > ( ) ) );
 	} else if(token.type == RegExpFromStringLexer::TokenType::EMPTY) {
-		return star(input, std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpEmpty ( ) ) );
+		return star(input, std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEmpty < alphabet::Symbol > ( ) ) );
 	} else if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-		UnboundedRegExpSymbol res(alib::stringApi<alphabet::Symbol>::parse(input));
+		UnboundedRegExpSymbol < alphabet::Symbol > res(alib::stringApi<alphabet::Symbol>::parse(input));
 		return star(input, std::move ( res ) );
 	} else {
 		throw exception::CommonException("Unrecognised token at factor rule");
 	}
 }
 
-std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::star(std::istream& input, UnboundedRegExpElement && elem) {
+std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > RegExpFromStringParser::star(std::istream& input, UnboundedRegExpElement < alphabet::Symbol > && elem) {
 	RegExpFromStringLexer::Token token = RegExpFromStringLexer::next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::STAR) {
-		UnboundedRegExpIteration iter ( std::move ( elem ) );
+		UnboundedRegExpIteration < alphabet::Symbol > iter ( std::move ( elem ) );
 		return star(input, std::move ( iter ) );
 	} else {
 		RegExpFromStringLexer::putback(input, token);
-		return std::rvalue_ref < UnboundedRegExpElement > ( std::move ( elem ).plunder() );
+		return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( std::move ( elem ).plunder() );
 	}
 }
 
diff --git a/alib2str/src/regexp/RegExpFromStringParser.h b/alib2str/src/regexp/RegExpFromStringParser.h
index 4a2a0b67a9..985fbec340 100644
--- a/alib2str/src/regexp/RegExpFromStringParser.h
+++ b/alib2str/src/regexp/RegExpFromStringParser.h
@@ -17,19 +17,19 @@
 namespace regexp {
 
 class RegExpFromStringParser {
-	static std::rvalue_ref < UnboundedRegExpElement > alternation(std::istream& input);
-	static std::rvalue_ref < UnboundedRegExpElement > alternationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left);
-	static std::rvalue_ref < UnboundedRegExpElement > alternationContCont(std::istream& input, UnboundedRegExpAlternation left);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > alternation(std::istream& input);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > alternationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > left);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > alternationContCont(std::istream& input, UnboundedRegExpAlternation < alphabet::Symbol > left);
 
-	static std::rvalue_ref < UnboundedRegExpElement > concatenation(std::istream& input);
-	static std::rvalue_ref < UnboundedRegExpElement > concatenationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left);
-	static std::rvalue_ref < UnboundedRegExpElement > concatenationContCont(std::istream& input, UnboundedRegExpConcatenation left);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > concatenation(std::istream& input);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > concatenationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > left);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > concatenationContCont(std::istream& input, UnboundedRegExpConcatenation < alphabet::Symbol > left);
 
-	static std::rvalue_ref < UnboundedRegExpElement > factor(std::istream& input);
-	static std::rvalue_ref < UnboundedRegExpElement > star(std::istream& input, UnboundedRegExpElement && elem);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > factor(std::istream& input);
+	static std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > star(std::istream& input, UnboundedRegExpElement < alphabet::Symbol > && elem);
 
 public:
-	static UnboundedRegExpStructure parseUnboundedRegExpStructure(std::istream& input);
+	static UnboundedRegExpStructure < alphabet::Symbol > parseUnboundedRegExpStructure(std::istream& input);
 	static RegExp parseRegExp(std::istream& input);
 	static RegExp parseRegExp(std::istream& input, const std::set<FEATURES>& features);
 };
diff --git a/alib2str/src/regexp/RegExpStringApi.cpp b/alib2str/src/regexp/RegExpStringApi.cpp
index d53bdc3d51..e2f7abf94c 100644
--- a/alib2str/src/regexp/RegExpStringApi.cpp
+++ b/alib2str/src/regexp/RegExpStringApi.cpp
@@ -19,11 +19,11 @@ void stringApi < regexp::RegExp >::compose ( std::ostream & output, const regexp
 	return regexp::RegExpToStringComposer::compose ( output, data );
 }
 
-regexp::UnboundedRegExpStructure stringApi < regexp::UnboundedRegExpStructure >::parse ( std::istream & input ) {
+regexp::UnboundedRegExpStructure < alphabet::Symbol > stringApi < regexp::UnboundedRegExpStructure < alphabet::Symbol > >::parse ( std::istream & input ) {
 	return regexp::RegExpFromStringParser::parseUnboundedRegExpStructure ( input );
 }
 
-void stringApi < regexp::UnboundedRegExpStructure >::compose ( std::ostream & output, const regexp::UnboundedRegExpStructure & data ) {
+void stringApi < regexp::UnboundedRegExpStructure < alphabet::Symbol > >::compose ( std::ostream & output, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & data ) {
 	return regexp::RegExpToStringComposer::compose ( output, data );
 }
 
diff --git a/alib2str/src/regexp/RegExpStringApi.hpp b/alib2str/src/regexp/RegExpStringApi.hpp
index 807e3a90ca..0c655614b0 100644
--- a/alib2str/src/regexp/RegExpStringApi.hpp
+++ b/alib2str/src/regexp/RegExpStringApi.hpp
@@ -21,9 +21,9 @@ struct stringApi < regexp::RegExp > {
 };
 
 template < >
-struct stringApi < regexp::UnboundedRegExpStructure > {
-	static regexp::UnboundedRegExpStructure parse ( std::istream & input );
-	static void compose ( std::ostream & output, const regexp::UnboundedRegExpStructure & data );
+struct stringApi < regexp::UnboundedRegExpStructure < alphabet::Symbol > > {
+	static regexp::UnboundedRegExpStructure < alphabet::Symbol > parse ( std::istream & input );
+	static void compose ( std::ostream & output, const regexp::UnboundedRegExpStructure < alphabet::Symbol > & data );
 };
 
 } /* namespace alib */
diff --git a/alib2str/src/regexp/RegExpToStringComposer.cpp b/alib2str/src/regexp/RegExpToStringComposer.cpp
index 2e5aa43494..89141ee9b9 100644
--- a/alib2str/src/regexp/RegExpToStringComposer.cpp
+++ b/alib2str/src/regexp/RegExpToStringComposer.cpp
@@ -15,31 +15,31 @@
 
 namespace regexp {
 
-void RegExpToStringComposer::compose(std::ostream& output, const UnboundedRegExp& regexp) {
+void RegExpToStringComposer::compose(std::ostream& output, const UnboundedRegExp < > & regexp) {
 	RegExpToStringComposer::compose ( output, regexp.getRegExp ( ) );
 }
 
-RegExpToStringComposer::RegistratorWrapper<void, UnboundedRegExp> RegExpToStringComposerUnboundedRegExp = RegExpToStringComposer::RegistratorWrapper<void, UnboundedRegExp>(RegExpToStringComposer::compose);
+auto RegExpToStringComposerUnboundedRegExp = RegExpToStringComposer::RegistratorWrapper<void, UnboundedRegExp < > >(RegExpToStringComposer::compose);
 
-void RegExpToStringComposer::compose(std::ostream& output, const UnboundedRegExpStructure& regexp) {
+void RegExpToStringComposer::compose(std::ostream& output, const UnboundedRegExpStructure < alphabet::Symbol > & regexp) {
 	Priority tmp = Priority::ALTERNATION;
 	std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output);
 	regexp.getStructure().accept<void, RegExpToStringComposer::Unbounded > (out);
 }
 
-void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExp& regexp) {
+void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExp < > & regexp) {
 	RegExpToStringComposer::compose ( output, regexp.getRegExp ( ) );
 }
 
-RegExpToStringComposer::RegistratorWrapper<void, FormalRegExp> RegExpToStringComposerFormalRegExp = RegExpToStringComposer::RegistratorWrapper<void, FormalRegExp>(RegExpToStringComposer::compose);
+auto RegExpToStringComposerFormalRegExp = RegExpToStringComposer::RegistratorWrapper<void, FormalRegExp < > >(RegExpToStringComposer::compose);
 
-void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExpStructure& regexp) {
+void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExpStructure < alphabet::Symbol > & regexp) {
 	Priority tmp = Priority::ALTERNATION;
 	std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output);
 	regexp.getStructure().accept<void, RegExpToStringComposer::Formal > (out);
 }
 
-void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpAlternation < alphabet::Symbol > & alternation, std::tuple<Priority&, std::ostream &> & out ) {
 	if(alternation.getElements().size() == 0) {
 		std::get<1>(out) << "#0";
 	} else if(alternation.getElements().size() == 1) {
@@ -61,7 +61,7 @@ void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpAlternation&
 	}
 }
 
-void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, std::tuple<Priority&, std::ostream &> & out ) {
 	Priority outerPriorityMinimum = std::get<0>(out);
 	if(concatenation.getElements().size() == 0) {
 		std::get<1>(out) << "#E";
@@ -83,25 +83,25 @@ void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpConcatenatio
 	}
 }
 
-void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpIteration < alphabet::Symbol > & iteration, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<0>(out) = Priority::FACTOR;
 	iteration.getElement().accept<void, RegExpToStringComposer::Unbounded > (out);
 	std::get<1>(out) << "*";
 }
 
-void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, std::tuple<Priority&, std::ostream &> & out ) {
 	alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol());
 }
 
-void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEpsilon&, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEpsilon < alphabet::Symbol > &, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<1>(out) << "#E";
 }
 
-void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEmpty&, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEmpty < alphabet::Symbol > &, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<1>(out) << "#0";
 }
 
-void RegExpToStringComposer::Formal::visit( const FormalRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Formal::visit( const FormalRegExpAlternation < alphabet::Symbol > & alternation, std::tuple<Priority&, std::ostream &> & out ) {
 	Priority outerPriorityMinimum = std::get<0>(out);
 	if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '(';
 
@@ -113,7 +113,7 @@ void RegExpToStringComposer::Formal::visit( const FormalRegExpAlternation& alter
 	if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')';
 }
 
-void RegExpToStringComposer::Formal::visit( const FormalRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Formal::visit( const FormalRegExpConcatenation < alphabet::Symbol > & concatenation, std::tuple<Priority&, std::ostream &> & out ) {
 	Priority outerPriorityMinimum = std::get<0>(out);
 	if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '(';
 
@@ -125,21 +125,21 @@ void RegExpToStringComposer::Formal::visit( const FormalRegExpConcatenation& con
 	if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')';
 }
 
-void RegExpToStringComposer::Formal::visit( const FormalRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Formal::visit( const FormalRegExpIteration < alphabet::Symbol > & iteration, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<0>(out) = Priority::FACTOR;
 	iteration.getElement().accept<void, RegExpToStringComposer::Formal > (out);
 	std::get<1>(out) << "*";
 }
 
-void RegExpToStringComposer::Formal::visit( const FormalRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Formal::visit( const FormalRegExpSymbol < alphabet::Symbol > & symbol, std::tuple<Priority&, std::ostream &> & out ) {
 	alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol());
 }
 
-void RegExpToStringComposer::Formal::visit( const FormalRegExpEpsilon&, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Formal::visit( const FormalRegExpEpsilon < alphabet::Symbol > &, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<1>(out) << "#E";
 }
 
-void RegExpToStringComposer::Formal::visit( const FormalRegExpEmpty&, std::tuple<Priority&, std::ostream &> & out ) {
+void RegExpToStringComposer::Formal::visit( const FormalRegExpEmpty < alphabet::Symbol > &, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<1>(out) << "#0";
 }
 
diff --git a/alib2str/src/regexp/RegExpToStringComposer.h b/alib2str/src/regexp/RegExpToStringComposer.h
index 6323c8dc2f..ef5daff8b7 100644
--- a/alib2str/src/regexp/RegExpToStringComposer.h
+++ b/alib2str/src/regexp/RegExpToStringComposer.h
@@ -34,29 +34,29 @@ public:
 	 */
 	static void compose(std::ostream& out, const RegExp& regexp);
 
-	static void compose(std::ostream& out, const UnboundedRegExp& regexp);
-	static void compose(std::ostream& out, const UnboundedRegExpStructure& regexp);
-	static void compose(std::ostream& out, const FormalRegExp& regexp);
-	static void compose(std::ostream& out, const FormalRegExpStructure& regexp);
+	static void compose(std::ostream& out, const UnboundedRegExp < > & regexp);
+	static void compose(std::ostream& out, const UnboundedRegExpStructure < alphabet::Symbol > & regexp);
+	static void compose(std::ostream& out, const FormalRegExp < > & regexp);
+	static void compose(std::ostream& out, const FormalRegExpStructure < alphabet::Symbol > & regexp);
 
 	class Unbounded {
 	public:
-		static void visit( const UnboundedRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out );
-		static void visit( const UnboundedRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const UnboundedRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const UnboundedRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const UnboundedRegExpEpsilon& epsilon, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const UnboundedRegExpEmpty& empty, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const UnboundedRegExpAlternation < alphabet::Symbol > & alternation, std::tuple<Priority&, std::ostream &> & out );
+		static void visit( const UnboundedRegExpConcatenation < alphabet::Symbol > & concatenation, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const UnboundedRegExpIteration < alphabet::Symbol > & iteration, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const UnboundedRegExpEpsilon < alphabet::Symbol > & epsilon, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const UnboundedRegExpEmpty < alphabet::Symbol > & empty, std::tuple<Priority&, std::ostream &> & output);
 	};
 
 	class Formal {
 	public:
-		static void visit( const FormalRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const FormalRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const FormalRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const FormalRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const FormalRegExpEpsilon& epsilon, std::tuple<Priority&, std::ostream &> & output);
-		static void visit( const FormalRegExpEmpty& empty, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const FormalRegExpAlternation < alphabet::Symbol > & alternation, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const FormalRegExpConcatenation < alphabet::Symbol > & concatenation, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const FormalRegExpIteration < alphabet::Symbol > & iteration, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const FormalRegExpSymbol < alphabet::Symbol > & symbol, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const FormalRegExpEpsilon < alphabet::Symbol > & epsilon, std::tuple<Priority&, std::ostream &> & output);
+		static void visit( const FormalRegExpEmpty < alphabet::Symbol > & empty, std::tuple<Priority&, std::ostream &> & output);
 	};
 };
 
diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp
index d245927b86..480198738a 100644
--- a/arand2/src/arand.cpp
+++ b/arand2/src/arand.cpp
@@ -128,7 +128,7 @@ int main ( int argc, char * argv[] ) {
 		} else if ( type.getValue ( ) == "RE" ) {
 			measurements::start ( "Algorithm", measurements::Type::MAIN );
 
-			regexp::UnboundedRegExp res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp ( terminalNodes.getValue ( ), height.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ) );
+			regexp::UnboundedRegExp < > res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp ( terminalNodes.getValue ( ), height.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ) );
 
 			measurements::end ( );
 			measurements::start ( "Output write", measurements::Type::AUXILIARY );
-- 
GitLab