diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
index ffe7c1f07e4e7f14c77ed65464af77004ca154cf..e8d2b461316091f80dc7ee754ad59e5a18aa36c7 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
@@ -17,15 +17,14 @@ automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::RegExp& reg
 	return dispatch(regexp.getData());
 }
 
-template<class T>
-automaton::EpsilonNFA < > ToAutomatonThompson::convert(const T& 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
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> out(automaton::EpsilonNFA < >(label::labelFrom(0)), 1, nullptr, nullptr);
 
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 	automaton.setInputAlphabet(regexp.getAlphabet());
 
-	regexp.getRegExp().Accept((void*) &out, ToAutomatonThompson::TO_AUTOMATON_THOMPSON);
+	regexp.getRegExp().Accept((void*) &out, ToAutomatonThompson::Formal::FORMAL);
 
 	automaton.setInitialState(*std::get<2>(out));
 	automaton.setFinalStates(std::set<label::Label>{*std::get<3>(out)});
@@ -36,12 +35,29 @@ automaton::EpsilonNFA < > ToAutomatonThompson::convert(const T& regexp) {
 }
 
 auto ToAutomatonThompsonFormalRegExp = ToAutomatonThompson::RegistratorWrapper<automaton::EpsilonNFA < >, regexp::FormalRegExp>(ToAutomatonThompson::convert);
+
+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
+	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> out(automaton::EpsilonNFA < >(label::labelFrom(0)), 1, nullptr, nullptr);
+
+	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
+	automaton.setInputAlphabet(regexp.getAlphabet());
+
+	regexp.getRegExp().Accept((void*) &out, ToAutomatonThompson::Unbounded::UNBOUNDED);
+
+	automaton.setInitialState(*std::get<2>(out));
+	automaton.setFinalStates(std::set<label::Label>{*std::get<3>(out)});
+
+	automaton.removeState(label::labelFrom(0));
+
+	return automaton;
+}
+
 auto ToAutomatonThompsonUnboundedRegExp = ToAutomatonThompson::RegistratorWrapper<automaton::EpsilonNFA < >, regexp::UnboundedRegExp>(ToAutomatonThompson::convert);
 
 // ----------------------------------------------------------------------------
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const
-{
+void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 
@@ -62,8 +78,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpAltern
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const
-{
+void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
@@ -79,8 +94,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpConcat
 	// std::get<3>(out) = std::get<3>(out);
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const
-{
+void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
@@ -100,8 +114,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpIterat
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const
-{
+void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
@@ -116,8 +129,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpSymbol
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const
-{
+void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
@@ -132,8 +144,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEpsilo
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const
-{
+void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpEmpty&) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
@@ -147,10 +158,11 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEmpty&
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
+const ToAutomatonThompson::Formal ToAutomatonThompson::Formal::FORMAL;
+
 // ----------------------------------------------------------------------------
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const
-{
+void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 
@@ -170,8 +182,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpAlt
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const
-{
+void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 
@@ -189,8 +200,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpCon
 	std::get<3>(out) = tails[tails.size()-1].second;
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const
-{
+void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 
@@ -209,8 +219,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpIte
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const
-{
+void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 
@@ -224,8 +233,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpSym
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const
-{
+void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 
@@ -239,8 +247,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEps
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const
-{
+void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const {
 	std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData;
 	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
 
@@ -253,7 +260,7 @@ void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEmp
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-const ToAutomatonThompson ToAutomatonThompson::TO_AUTOMATON_THOMPSON;
+const ToAutomatonThompson::Unbounded ToAutomatonThompson::Unbounded::UNBOUNDED;
 
 } /* namespace convert */
 
diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.h b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
index db03923803cd441d5e23bf1a6f87c500bb62cb61..22329a8269c1d89aceffdced13d87c3871ceb14c 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonThompson.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
@@ -29,10 +29,8 @@ namespace convert {
  *  http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.21.7450&rep=rep1&type=ps
  *  Melichar 2.112
  */
-class ToAutomatonThompson : public std::SingleDispatch<ToAutomatonThompson, automaton::EpsilonNFA < >, const regexp::RegExpBase &>, regexp::FormalRegExpElement::Visitor, regexp::UnboundedRegExpElement::Visitor {
+class ToAutomatonThompson : public std::SingleDispatch<ToAutomatonThompson, automaton::EpsilonNFA < >, const regexp::RegExpBase &> {
 public:
-	ToAutomatonThompson() {}
-
 	/**
 	 * Performs conversion.
 	 * @param regexp regexp to convert
@@ -40,25 +38,36 @@ public:
 	 */
 	static automaton::EpsilonNFA < > convert(const regexp::RegExp& regexp);
 
-	template<class T>
-	static automaton::EpsilonNFA < > convert(const T& regexp);
+	static automaton::EpsilonNFA < > convert(const regexp::FormalRegExp& regexp);
+	static automaton::EpsilonNFA < > convert(const regexp::UnboundedRegExp& regexp);
 
-private:
-	 void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const;
-	 void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const;
-	 void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const;
-	 void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const;
-	 void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const;
-	 void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const;
+	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	public:
+		Unbounded ( ) { }
+	
+		static const Unbounded UNBOUNDED;
+	private:
+		void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const;
+		void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const;
+		void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const;
+		void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const;
+		void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const;
+		void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const;
+	};
 
-	 void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const;
-	 void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const;
-	 void Visit(void*, const regexp::FormalRegExpIteration& iteration) const;
-	 void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const;
-	 void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
-	 void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
+	class Formal : public regexp::FormalRegExpElement::Visitor {
+	public:
+		Formal ( ) { }
 
-	 static const ToAutomatonThompson TO_AUTOMATON_THOMPSON;
+		static const Formal FORMAL;
+	private:
+		void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const;
+		void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const;
+		void Visit(void*, const regexp::FormalRegExpIteration& iteration) const;
+		void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const;
+		void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
+		void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
+	};
 
 };
 
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.cpp b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
index f48545af05d5d4f4a03c4ecd8244b70fe3129f52..beb2250f6e14eee87105281f3dbe2075848bbfb5 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
@@ -19,7 +19,7 @@ bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp) {
 
 bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpElement& regexp) {
 	bool out;
-	regexp.Accept((void*) &out, RegExpEmpty::REG_EXP_EMPTY);
+	regexp.Accept((void*) &out, RegExpEmpty::Formal::FORMAL);
 	return out;
 }
 
@@ -31,7 +31,7 @@ auto RegExpEmptyFormalRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::For
 
 bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpElement& regexp) {
 	bool out;
-	regexp.Accept((void*) &out, RegExpEmpty::REG_EXP_EMPTY);
+	regexp.Accept((void*) &out, RegExpEmpty::Unbounded::UNBOUNDED);
 	return out;
 }
 
@@ -43,7 +43,7 @@ auto RegExpEmptyUnboundedRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::
 
 // ----------------------------------------------------------------------------
 
-void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const {
+void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const {
 	bool &ret = *(bool*) data;
 
 	for(const auto& element : alternation.getElements()) {
@@ -56,7 +56,7 @@ void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpAlternation& al
 	ret = true;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const {
+void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const {
 	bool &ret = *(bool*) data;
 
 	for(const auto& element : concatenation.getElements()) {
@@ -69,29 +69,31 @@ void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpConcatenation&
 	ret = false;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpIteration&) const {
+void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpIteration&) const {
 	bool &ret = *(bool*) data;
 	ret = false;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const {
+void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const {
 	bool &ret = *(bool*) data;
 	ret = false;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const {
+void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const {
 	bool &ret = *(bool*) data;
 	ret = true;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const {
+void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const {
 	bool &ret = *(bool*) data;
 	ret = false;
 }
 
+const RegExpEmpty::Unbounded RegExpEmpty::Unbounded::UNBOUNDED;
+
 // ----------------------------------------------------------------------------
 
-void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const {
+void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const {
 	bool &ret = *(bool*) data;
 
 	static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(data, *this);
@@ -103,7 +105,7 @@ void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpAlternation& alter
 	ret = retLeft && retRight;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const {
+void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const {
 	bool &ret = *(bool*) data;
 
 	static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(data, *this);
@@ -115,29 +117,27 @@ void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpConcatenation& con
 	ret = retLeft || retRight;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpIteration&) const {
+void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpIteration&) const {
 	bool &ret = *(bool*) data;
 	ret = false;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpSymbol&) const {
+void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpSymbol&) const {
 	bool &ret = *(bool*) data;
 	ret = false;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpEmpty&) const {
+void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpEmpty&) const {
 	bool &ret = *(bool*) data;
 	ret = true;
 }
 
-void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpEpsilon&) const {
+void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpEpsilon&) const {
 	bool &ret = *(bool*) data;
 	ret = false;
 }
 
-// ----------------------------------------------------------------------------
-
-const RegExpEmpty RegExpEmpty::REG_EXP_EMPTY;
+const RegExpEmpty::Formal RegExpEmpty::Formal::FORMAL;
 
 } /* namespace properties */
 
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.h b/alib2algo/src/regexp/properties/RegExpEmpty.h
index 3d4a53012c26a3d4ad6e10735df4160b193b13ac..945096ba328f9b5b139cbf4e398f7c3f0448d4bb 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.h
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.h
@@ -24,10 +24,8 @@ namespace properties {
  * Determines whether regular expression is empty (regexp == \0)
  *
  */
-class RegExpEmpty : public std::SingleDispatch<RegExpEmpty, bool, const regexp::RegExpBase &>, regexp::FormalRegExpElement::Visitor, regexp::UnboundedRegExpElement::Visitor {
+class RegExpEmpty : public std::SingleDispatch<RegExpEmpty, bool, const regexp::RegExpBase &> {
 public:
-	RegExpEmpty() {}
-
 	static bool languageIsEmpty(const regexp::RegExp& regexp);
 
 	static bool languageIsEmpty(const regexp::FormalRegExpElement& regexp);
@@ -36,22 +34,35 @@ public:
 	static bool languageIsEmpty(const regexp::UnboundedRegExp& regexp);
 	static bool languageIsEmpty(const regexp::UnboundedRegExpElement& regexp);
 
-private:
-	void Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const;
-	void Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const;
-	void Visit(void* data, const regexp::UnboundedRegExpIteration& iteration) const;
-	void Visit(void* data, const regexp::UnboundedRegExpSymbol& symbol) const;
-	void Visit(void* data, const regexp::UnboundedRegExpEmpty& empty) const;
-	void Visit(void* data, const regexp::UnboundedRegExpEpsilon& epsilon) const;
-
-	void Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const;
-	void Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const;
-	void Visit(void* data, const regexp::FormalRegExpIteration& iteration) const;
-	void Visit(void* data, const regexp::FormalRegExpSymbol& symbol) const;
-	void Visit(void* data, const regexp::FormalRegExpEmpty& empty) const;
-	void Visit(void* data, const regexp::FormalRegExpEpsilon& epsilon) const;
-
-	static const RegExpEmpty REG_EXP_EMPTY;
+	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	public:
+		Unbounded ( ) { }
+
+		static const Unbounded UNBOUNDED;
+
+	private:
+		void Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const;
+		void Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const;
+		void Visit(void* data, const regexp::UnboundedRegExpIteration& iteration) const;
+		void Visit(void* data, const regexp::UnboundedRegExpSymbol& symbol) const;
+		void Visit(void* data, const regexp::UnboundedRegExpEmpty& empty) const;
+		void Visit(void* data, const regexp::UnboundedRegExpEpsilon& epsilon) const;
+	};
+
+	class Formal : public regexp::FormalRegExpElement::Visitor {
+	public:
+		Formal ( ) { }
+
+		static const Formal FORMAL;
+
+	private:
+		void Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const;
+		void Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const;
+		void Visit(void* data, const regexp::FormalRegExpIteration& iteration) const;
+		void Visit(void* data, const regexp::FormalRegExpSymbol& symbol) const;
+		void Visit(void* data, const regexp::FormalRegExpEmpty& empty) const;
+		void Visit(void* data, const regexp::FormalRegExpEpsilon& epsilon) const;
+	};
 
 };
 
diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.cpp b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
index 79a7ca3b9480ae7e730f4025c0e539f00d21c4ea..2414c50ba79ea01c6e7ffc88ec7e4db952480e2a 100644
--- a/alib2algo/src/regexp/transform/RegExpDerivation.cpp
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
@@ -22,7 +22,7 @@ regexp::FormalRegExp RegExpDerivation::derivation(const regexp::FormalRegExp& re
 
 	for(const auto& symbol : string.getContent()) {
 		std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpDerivation::REGEXP_DERIVATION);
+		newRegExp->Accept((void*) &out, RegExpDerivation::Formal::FORMAL);
 		newRegExp = std::move ( out.second );
 	}
 
@@ -36,7 +36,7 @@ regexp::UnboundedRegExp RegExpDerivation::derivation(const regexp::UnboundedRegE
 
 	for(const auto& symbol : string.getContent()) {
 		std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpDerivation::REGEXP_DERIVATION);
+		newRegExp->Accept((void*) &out, RegExpDerivation::Unbounded::UNBOUNDED);
 		newRegExp = std::move ( out.second );
 	}
 
@@ -47,7 +47,7 @@ auto RegExpDerivationUnboundedRegExp = RegExpDerivation::RegistratorWrapper<rege
 
 // ----------------------------------------------------------------------------
 
-void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const {
+void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	alternation.getLeftElement().Accept(userData, *this);
@@ -58,7 +58,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpAlternati
 	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftDerivative ), std::move ( * out.second ) ) );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const {
+void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	concatenation.getLeftElement().Accept(userData, *this);
@@ -73,7 +73,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpConcatena
 	}
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const {
+void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	iteration.getElement().Accept(userData, *this);
@@ -81,7 +81,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpIteration
 	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpConcatenation( std::move ( * out.second ), iteration ) );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const {
+void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	if(out.first == symbol.getSymbol())
@@ -91,20 +91,22 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpSymbol& s
 }
 
 
-void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const {
+void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpEmpty&) const {
+void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpEmpty&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
 }
 
+const RegExpDerivation::Formal RegExpDerivation::Formal::FORMAL;
+
 // ----------------------------------------------------------------------------
 
 
-void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const {
+void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData);
 	std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() );
 
@@ -116,7 +118,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpAltern
 	out.second = std::move ( ret );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const {
+void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData);
 	std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() );
 
@@ -138,7 +140,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcat
 	out.second = std::move ( ret );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const {
+void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData);
 
 	iteration.getElement().Accept(userData, *this);
@@ -149,7 +151,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpIterat
 	out.second = std::unique_ptr < UnboundedRegExpElement > ( con );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const {
+void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData);
 
 	if(out.first == symbol.getSymbol())
@@ -158,16 +160,16 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpSymbol
 		out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const {
+void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData);
 	out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
 }
 
-void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const {
+void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData);
 	out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
 }
 
-const RegExpDerivation RegExpDerivation::REGEXP_DERIVATION;
+const RegExpDerivation::Unbounded RegExpDerivation::Unbounded::UNBOUNDED;
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.h b/alib2algo/src/regexp/transform/RegExpDerivation.h
index 678fa129c16e068561ff043f291b7fdb503859e5..fc5230ff1e1b6a04a6b73483e470038211482a88 100644
--- a/alib2algo/src/regexp/transform/RegExpDerivation.h
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.h
@@ -27,7 +27,7 @@ namespace regexp {
  *  - Melichar, definition 2.91 in chapter 2.4.3
  *  - Brzozowski, J. A. - Derivatives of regular expressions (1964)
  */
-class RegExpDerivation : public std::SingleDispatch < RegExpDerivation, regexp::RegExp, const regexp::RegExpBase &, const string::LinearString < >&>, regexp::FormalRegExpElement::Visitor, regexp::UnboundedRegExpElement::Visitor {
+class RegExpDerivation : public std::SingleDispatch < RegExpDerivation, regexp::RegExp, const regexp::RegExpBase &, const string::LinearString < >&> {
 public:
 	RegExpDerivation() {}
 
@@ -42,21 +42,35 @@ public:
 	static regexp::UnboundedRegExp derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string);
 
 private:
-	void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const;
-	void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const;
-	void Visit(void*, const regexp::FormalRegExpIteration& iteration) const;
-	void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const;
-	void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
-	void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
-
-	void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const;
-	void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const;
-	void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const;
-	void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const;
-	void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const;
-	void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const;
-
-	static const RegExpDerivation REGEXP_DERIVATION;
+	class Formal : public regexp::FormalRegExpElement::Visitor {
+	public:
+		Formal ( ) { }
+
+		static const Formal FORMAL;
+
+	private:
+		void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const;
+		void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const;
+		void Visit(void*, const regexp::FormalRegExpIteration& iteration) const;
+		void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const;
+		void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
+		void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
+	};
+
+	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	public:
+		Unbounded ( ) { }
+
+		static const Unbounded UNBOUNDED;
+
+	private:
+		void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const;
+		void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const;
+		void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const;
+		void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const;
+		void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const;
+		void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const;
+	};
 };
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpIntegral.cpp b/alib2algo/src/regexp/transform/RegExpIntegral.cpp
index 064b3934b77e121584c62be3b42ce19f1ff385bb..15442a71bd2af4d998de0d260011c9caedd256e7 100644
--- a/alib2algo/src/regexp/transform/RegExpIntegral.cpp
+++ b/alib2algo/src/regexp/transform/RegExpIntegral.cpp
@@ -20,7 +20,7 @@ regexp::FormalRegExp RegExpIntegral::integral(const regexp::FormalRegExp& regexp
 
 	for(const auto& symbol : string.getContent()) {
 		std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpIntegral::REGEXP_INTEGRAL);
+		newRegExp->Accept((void*) &out, RegExpIntegral::Formal::FORMAL);
 		newRegExp = std::move ( out.second );
 	}
 
@@ -34,7 +34,7 @@ regexp::UnboundedRegExp RegExpIntegral::integral(const regexp::UnboundedRegExp&
 
 	for(const auto& symbol : string.getContent()) {
 		std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpIntegral::REGEXP_INTEGRAL);
+		newRegExp->Accept((void*) &out, RegExpIntegral::Unbounded::UNBOUNDED);
 		newRegExp = std::move ( out.second );
 	}
 
@@ -45,7 +45,7 @@ auto RegExpIntegralUnboundedRegExp = RegExpIntegral::RegistratorWrapper<regexp::
 
 // ----------------------------------------------------------------------------
 
-void RegExpIntegral::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const {
+void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	alternation.getLeftElement().Accept(userData, *this);
@@ -56,38 +56,40 @@ void RegExpIntegral::Visit(void* userData, const regexp::FormalRegExpAlternation
 	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftIntegral ), std::move ( * out.second ) ) );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const {
+void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( out.first ), concatenation ) );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const {
+void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( out.first ), iteration ) );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const {
+void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 
 	out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( out.first ), symbol ) );
 }
 
 
-void RegExpIntegral::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const {
+void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 	out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpSymbol( out.first ) );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::FormalRegExpEmpty&) const {
+void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpEmpty&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData);
 	out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpEmpty( ) );
 }
 
+const RegExpIntegral::Formal RegExpIntegral::Formal::FORMAL;
+
 // ----------------------------------------------------------------------------
 
-void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const
+void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const
 {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData);
 
@@ -101,7 +103,7 @@ void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpAlternat
 	out.second = std::unique_ptr < UnboundedRegExpElement > ( alt );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const {
+void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData);
 
 	regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
@@ -113,7 +115,7 @@ void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpConcaten
 	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const {
+void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData);
 
 	regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
@@ -123,7 +125,7 @@ void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpIteratio
 	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const {
+void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData);
 
 	regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
@@ -133,18 +135,18 @@ void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpSymbol&
 	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const {
+void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData);
 
 	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpSymbol( out.first ) );
 }
 
-void RegExpIntegral::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const {
+void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const {
 	std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData);
 
 	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty( ) );
 }
 
-const RegExpIntegral RegExpIntegral::REGEXP_INTEGRAL;
+const RegExpIntegral::Unbounded RegExpIntegral::Unbounded::UNBOUNDED;
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/transform/RegExpIntegral.h b/alib2algo/src/regexp/transform/RegExpIntegral.h
index 8b829d9d210eda5650b93159d1945e92224832ce..d86b72587244bad5cb222961eb2ac7cdcdf74a18 100644
--- a/alib2algo/src/regexp/transform/RegExpIntegral.h
+++ b/alib2algo/src/regexp/transform/RegExpIntegral.h
@@ -24,7 +24,7 @@ namespace regexp {
  * Calculates integral of regular expression
  * Source: Melichar definition 2.93 in chapter 2.4.4
  */
-class RegExpIntegral : public std::SingleDispatch < RegExpIntegral, regexp::RegExp, const regexp::RegExpBase &, const string::LinearString < >&>, regexp::FormalRegExpElement::Visitor, regexp::UnboundedRegExpElement::Visitor {
+class RegExpIntegral : public std::SingleDispatch < RegExpIntegral, regexp::RegExp, const regexp::RegExpBase &, const string::LinearString < >&> {
 public:
 	RegExpIntegral() {}
 
@@ -39,21 +39,35 @@ public:
 	static regexp::UnboundedRegExp integral(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string);
 
 private:
-	void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const;
-	void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const;
-	void Visit(void*, const regexp::FormalRegExpIteration& iteration) const;
-	void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const;
-	void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
-	void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
-
-	void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const;
-	void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const;
-	void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const;
-	void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const;
-	void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const;
-	void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const;
-
-	static const RegExpIntegral REGEXP_INTEGRAL;
+	class Formal : public regexp::FormalRegExpElement::Visitor {
+	public:
+		Formal ( ) { }
+
+		static const Formal FORMAL;
+
+	private:
+		void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const;
+		void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const;
+		void Visit(void*, const regexp::FormalRegExpIteration& iteration) const;
+		void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const;
+		void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
+		void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
+	};
+
+	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	public:
+		Unbounded ( ) { }
+
+		static const Unbounded UNBOUNDED;
+
+	private:
+		void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const;
+		void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const;
+		void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const;
+		void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const;
+		void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const;
+		void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const;
+	};
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/common/RegExpToXMLComposer.cpp b/alib2data/src/regexp/common/RegExpToXMLComposer.cpp
index f941aa4ceac17e0743794fcee01ca345e60afb42..0cc3a3372bdb62556ccaa2e62a6c6643e7b90046 100644
--- a/alib2data/src/regexp/common/RegExpToXMLComposer.cpp
+++ b/alib2data/src/regexp/common/RegExpToXMLComposer.cpp
@@ -16,7 +16,7 @@
 
 namespace regexp {
 
-void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const {
+void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("alternation", sax::Token::TokenType::START_ELEMENT);
@@ -26,7 +26,7 @@ void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpAlternation
 	out.emplace_back("alternation", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const {
+void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("concatenation", sax::Token::TokenType::START_ELEMENT);
@@ -37,7 +37,7 @@ void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpConcatenati
 
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpIteration& iteration) const {
+void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpIteration& iteration) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("iteration", sax::Token::TokenType::START_ELEMENT);
@@ -45,27 +45,27 @@ void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpIteration&
 	out.emplace_back("iteration", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const {
+void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	alib::xmlApi<alphabet::Symbol>::compose(out, symbol.getSymbol());
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpEpsilon&) const {
+void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpEpsilon&) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("epsilon", sax::Token::TokenType::START_ELEMENT);
 	out.emplace_back("epsilon", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const UnboundedRegExpEmpty&) const {
+void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpEmpty&) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("empty", sax::Token::TokenType::START_ELEMENT);
 	out.emplace_back("empty", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpAlternation& alternation) const {
+void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpAlternation& alternation) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("alternation", sax::Token::TokenType::START_ELEMENT);
@@ -74,7 +74,7 @@ void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpAlternation& a
 	out.emplace_back("alternation", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const {
+void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("concatenation", sax::Token::TokenType::START_ELEMENT);
@@ -84,7 +84,7 @@ void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpConcatenation&
 
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpIteration& iteration) const {
+void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpIteration& iteration) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("iteration", sax::Token::TokenType::START_ELEMENT);
@@ -92,20 +92,20 @@ void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpIteration& ite
 	out.emplace_back("iteration", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpSymbol& symbol) const {
+void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpSymbol& symbol) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	alib::xmlApi<alphabet::Symbol>::compose(out, symbol.getSymbol());
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpEpsilon&) const {
+void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpEpsilon&) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("epsilon", sax::Token::TokenType::START_ELEMENT);
 	out.emplace_back("epsilon", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Visit(void* userData, const FormalRegExpEmpty&) const {
+void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpEmpty&) const {
 	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
 
 	out.emplace_back("empty", sax::Token::TokenType::START_ELEMENT);
@@ -120,6 +120,7 @@ void RegExpToXMLComposer::composeAlphabet(std::deque<sax::Token>& out, const std
 	out.emplace_back("alphabet", sax::Token::TokenType::END_ELEMENT);
 }
 
-RegExpToXMLComposer RegExpToXMLComposer::REGEXP_TO_XML_COMPOSER;
+RegExpToXMLComposer::Unbounded RegExpToXMLComposer::Unbounded::UNBOUNDED;
+RegExpToXMLComposer::Formal RegExpToXMLComposer::Formal::FORMAL;
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/common/RegExpToXMLComposer.h b/alib2data/src/regexp/common/RegExpToXMLComposer.h
index 522973afc8bc6921a75cac2be86add3cf288f747..e6bc3fa8be1b2fa1c53b4aaf0f59bb5e78d492e8 100644
--- a/alib2data/src/regexp/common/RegExpToXMLComposer.h
+++ b/alib2data/src/regexp/common/RegExpToXMLComposer.h
@@ -19,29 +19,39 @@ namespace regexp {
 /**
  * This class contains methods to print XML representation of regular expression to the output stream.
  */
-class RegExpToXMLComposer : public UnboundedRegExpElement::Visitor, public FormalRegExpElement::Visitor {
+class RegExpToXMLComposer {
 public:
-	RegExpToXMLComposer() {}
-
-	static RegExpToXMLComposer REGEXP_TO_XML_COMPOSER;
-
 	static void composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::Symbol>& alphabet);
 
-private:
-	void Visit(void*, const UnboundedRegExpAlternation& alternation) const;
-	void Visit(void*, const UnboundedRegExpConcatenation& concatenation) const;
-	void Visit(void*, const UnboundedRegExpIteration& iteration) const;
-	void Visit(void*, const UnboundedRegExpSymbol& symbol) const;
-	void Visit(void*, const UnboundedRegExpEpsilon& epsilon) const;
-	void Visit(void*, const UnboundedRegExpEmpty& empty) const;
-
-
-	void Visit(void*, const FormalRegExpAlternation& alternation) const;
-	void Visit(void*, const FormalRegExpConcatenation& concatenation) const;
-	void Visit(void*, const FormalRegExpIteration& iteration) const;
-	void Visit(void*, const FormalRegExpSymbol& symbol) const;
-	void Visit(void*, const FormalRegExpEpsilon& epsilon) const;
-	void Visit(void*, const FormalRegExpEmpty& empty) const;
+	class Unbounded : public UnboundedRegExpElement::Visitor {
+	public:
+		Unbounded() {}
+
+		static Unbounded UNBOUNDED;
+
+	private:
+		void Visit(void*, const UnboundedRegExpAlternation& alternation) const;
+		void Visit(void*, const UnboundedRegExpConcatenation& concatenation) const;
+		void Visit(void*, const UnboundedRegExpIteration& iteration) const;
+		void Visit(void*, const UnboundedRegExpSymbol& symbol) const;
+		void Visit(void*, const UnboundedRegExpEpsilon& epsilon) const;
+		void Visit(void*, const UnboundedRegExpEmpty& empty) const;
+	};
+
+	class Formal : public FormalRegExpElement::Visitor {
+	public:
+		Formal() {}
+
+		static Formal FORMAL;
+
+	private:
+		void Visit(void*, const FormalRegExpAlternation& alternation) const;
+		void Visit(void*, const FormalRegExpConcatenation& concatenation) const;
+		void Visit(void*, const FormalRegExpIteration& iteration) const;
+		void Visit(void*, const FormalRegExpSymbol& symbol) const;
+		void Visit(void*, const FormalRegExpEpsilon& epsilon) const;
+		void Visit(void*, const FormalRegExpEmpty& empty) const;
+	};
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.cpp b/alib2data/src/regexp/formal/FormalRegExpElement.cpp
index 17fa6b6b9d1673cc020de2861c2d70aa27474847..5ba40c0c06b48ed00f172d13f085fe6d080f0c32 100644
--- a/alib2data/src/regexp/formal/FormalRegExpElement.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpElement.cpp
@@ -36,7 +36,7 @@ bool xmlApi < regexp::FormalRegExpElement >::first ( const std::deque < sax::Tok
 }
 
 void xmlApi < regexp::FormalRegExpElement >::compose ( std::deque < sax::Token > & output, const regexp::FormalRegExpElement & data ) {
-	data.Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::REGEXP_TO_XML_COMPOSER );
+	data.Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::Formal::FORMAL );
 }
 
 } /* namespace alib */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp
index 9a6082ffb8a550dba8c4698e8703a18559b75d66..6b0a3f8924279d59773af708543c595b0385a103 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.cpp
@@ -36,7 +36,7 @@ bool xmlApi < regexp::UnboundedRegExpElement >::first ( const std::deque < sax::
 }
 
 void xmlApi < regexp::UnboundedRegExpElement >::compose ( std::deque < sax::Token > & output, const regexp::UnboundedRegExpElement & data ) {
-	data.Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::REGEXP_TO_XML_COMPOSER );
+	data.Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::Unbounded::UNBOUNDED );
 }
 
 } /* namespace alib */