From df42965d9cc5da5b8a34a6ce8565f628da4a4a2d Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Tue, 25 Oct 2016 16:05:38 +0200
Subject: [PATCH] adapt regexps to new visitor technique

---
 .../regexp/convert/ToAutomatonThompson.cpp    | 235 +++++++-----------
 .../src/regexp/convert/ToAutomatonThompson.h  |  36 ++-
 .../src/regexp/properties/RegExpEmpty.cpp     | 100 +++-----
 alib2algo/src/regexp/properties/RegExpEmpty.h |  38 ++-
 .../src/regexp/properties/RegExpEpsilon.cpp   | 108 +++-----
 .../src/regexp/properties/RegExpEpsilon.h     |  39 +--
 .../src/regexp/transform/RegExpDerivation.cpp | 124 ++++-----
 .../src/regexp/transform/RegExpDerivation.h   |  38 ++-
 .../src/regexp/transform/RegExpIntegral.cpp   | 107 +++-----
 .../src/regexp/transform/RegExpIntegral.h     |  38 ++-
 .../src/regexp/common/RegExpToXMLComposer.cpp |  69 ++---
 .../src/regexp/common/RegExpToXMLComposer.h   |  38 ++-
 .../regexp/formal/FormalRegExpAlternation.h   |   4 +-
 .../regexp/formal/FormalRegExpConcatenation.h |   4 +-
 .../src/regexp/formal/FormalRegExpElement.h   |  52 +++-
 .../src/regexp/formal/FormalRegExpEmpty.h     |   4 +-
 .../src/regexp/formal/FormalRegExpEpsilon.h   |   4 +-
 .../src/regexp/formal/FormalRegExpIteration.h |   4 +-
 .../regexp/formal/FormalRegExpStructure.cpp   |   2 +-
 .../src/regexp/formal/FormalRegExpSymbol.h    |   4 +-
 .../unbounded/UnboundedRegExpAlternation.h    |   4 +-
 .../unbounded/UnboundedRegExpConcatenation.h  |   4 +-
 .../regexp/unbounded/UnboundedRegExpElement.h |  52 +++-
 .../regexp/unbounded/UnboundedRegExpEmpty.h   |   4 +-
 .../regexp/unbounded/UnboundedRegExpEpsilon.h |   4 +-
 .../unbounded/UnboundedRegExpIteration.h      |   4 +-
 .../unbounded/UnboundedRegExpStructure.cpp    |   2 +-
 .../regexp/unbounded/UnboundedRegExpSymbol.h  |   4 +-
 .../src/regexp/RegExpToStringComposer.cpp     |  70 ++----
 alib2str/src/regexp/RegExpToStringComposer.h  |  36 +--
 30 files changed, 508 insertions(+), 724 deletions(-)

diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
index 150947b19d..d2af830fab 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
@@ -19,15 +19,17 @@ automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::RegExp& reg
 
 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);
+	int nextState = 1;
+	const label::Label * headArg = nullptr;
+	const label::Label * tailArg = nullptr;
 
-	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
+	automaton::EpsilonNFA < > automaton ( label::labelFrom ( 0 ) );
 	automaton.setInputAlphabet(regexp.getAlphabet());
 
-	regexp.getRegExp().getStructure().Accept((void*) &out, ToAutomatonThompson::Formal::FORMAL);
+	regexp.getRegExp().getStructure().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
 
-	automaton.setInitialState(*std::get<2>(out));
-	automaton.setFinalStates(std::set<label::Label>{*std::get<3>(out)});
+	automaton.setInitialState ( * headArg );
+	automaton.setFinalStates ( std::set < label::Label > { * tailArg } );
 
 	automaton.removeState(label::labelFrom(0));
 
@@ -38,15 +40,17 @@ auto ToAutomatonThompsonFormalRegExp = ToAutomatonThompson::RegistratorWrapper<a
 
 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);
+	int nextState = 1;
+	const label::Label * headArg = nullptr;
+	const label::Label * tailArg = nullptr;
 
-	automaton::EpsilonNFA < >& automaton = std::get<0>(out);
+	automaton::EpsilonNFA < > automaton ( label::labelFrom ( 0 ) );
 	automaton.setInputAlphabet(regexp.getAlphabet());
 
-	regexp.getRegExp().getStructure().Accept((void*) &out, ToAutomatonThompson::Unbounded::UNBOUNDED);
+	regexp.getRegExp().getStructure().accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
 
-	automaton.setInitialState(*std::get<2>(out));
-	automaton.setFinalStates(std::set<label::Label>{*std::get<3>(out)});
+	automaton.setInitialState ( * headArg );
+	automaton.setFinalStates ( std::set < label::Label > { * tailArg } );
 
 	automaton.removeState(label::labelFrom(0));
 
@@ -57,211 +61,164 @@ auto ToAutomatonThompsonUnboundedRegExp = ToAutomatonThompson::RegistratorWrappe
 
 // ----------------------------------------------------------------------------
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpAlternation& 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);
 	automaton.addState(tail);
 
-	static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(userData, *this);
-	automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out));
-	automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail);
+	alternation.getLeftElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
+	automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg);
+	automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail);
 
-	static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(userData, *this);
-	automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out));
-	automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail);
+	alternation.getRightElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
+	automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg);
+	automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail);
 
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
-	static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(userData, *this);
-	const label::Label* leftHead = std::get<2>(out);
-	const label::Label* leftTail = std::get<3>(out);
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpConcatenation& 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;
 
-	static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this);
-	automaton.addTransition(*leftTail, string::Epsilon < >::EPSILON, *std::get<2>(out));
+	concatenation.getRightElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
+	automaton.addTransition(*leftTail, string::Epsilon < >::EPSILON, *headArg);
 
-	std::get<2>(out) = &(*automaton.getStates().find(*leftHead));
-	// std::get<3>(out) = std::get<3>(out);
+	headArg = &(*automaton.getStates().find(*leftHead));
+	// tailArg = tailArg;
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpIteration& 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);
 	automaton.addState(tail);
 
-	static_cast<const regexp::FormalRegExpElement&>(iteration.getElement()).Accept(userData, *this);
-	automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out));
+	iteration.getElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
+	automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg);
 	automaton.addTransition(head, string::Epsilon < >::EPSILON, tail);
-	automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail);
-	automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, *std::get<2>(out));
+	automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail);
+	automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, *headArg);
 
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpSymbol& 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);
 	automaton.addState(tail);
 
 	automaton.addTransition(head, symbol.getSymbol(), tail);
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEpsilon&, 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);
 	automaton.addState(tail);
 
 	automaton.addTransition(head, string::Epsilon < >::EPSILON, tail);
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEmpty&, 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);
 	automaton.addState(tail);
 
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-const ToAutomatonThompson::Formal ToAutomatonThompson::Formal::FORMAL;
-
 // ----------------------------------------------------------------------------
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpAlternation& 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);
 	automaton.addState(tail);
 
-	for(const auto& element : alternation.getElements())
-	{
-		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this);
-		automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out));
-		automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail);
+	for(const auto& element : alternation.getElements()) {
+		element->accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
+		automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg);
+		automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail);
 	}
 
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& 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())
-	{
-		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this);
-		tails.push_back(std::make_pair(std::get<2>(out), std::get<3>(out)));
+	for(const auto& element : concatenation.getElements()) {
+		element->accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
+		tails.push_back(std::make_pair(headArg, tailArg));
 	}
 
 	for(size_t i = 1; i < tails.size(); i++)
 		automaton.addTransition(*tails[i-1].second, string::Epsilon < >::EPSILON, *tails[i].first);
 
-	std::get<2>(out) = tails[0].first;
-	std::get<3>(out) = tails[tails.size()-1].second;
+	headArg = tails[0].first;
+	tailArg = tails[tails.size()-1].second;
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpIteration& 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);
 	automaton.addState(tail);
 
-	static_cast<const regexp::UnboundedRegExpElement&>(iteration.getElement()).Accept(userData, *this);
-	automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out));
+	iteration.getElement().accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg);
+	automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg);
 	automaton.addTransition(head, string::Epsilon < >::EPSILON, tail);
-	automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail);
-	automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, *std::get<2>(out));
+	automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail);
+	automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, *headArg);
 
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpSymbol& 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);
 	automaton.addState(tail);
 
 	automaton.addTransition(head, symbol.getSymbol(), tail);
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, 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);
 	automaton.addState(tail);
 
 	automaton.addTransition(head, string::Epsilon < >::EPSILON, tail);
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-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);
-
-	label::Label head = label::labelFrom(std::get<1>(out)++);
-	label::Label tail = label::labelFrom(std::get<1>(out)++);
+void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, 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);
 	automaton.addState(tail);
 
-	std::get<2>(out) = &(*automaton.getStates().find(head));
-	std::get<3>(out) = &(*automaton.getStates().find(tail));
+	headArg = &(*automaton.getStates().find(head));
+	tailArg = &(*automaton.getStates().find(tail));
 }
 
-const ToAutomatonThompson::Unbounded ToAutomatonThompson::Unbounded::UNBOUNDED;
-
 } /* namespace convert */
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.h b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
index 22329a8269..c5797afa03 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonThompson.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
@@ -41,32 +41,24 @@ public:
 	static automaton::EpsilonNFA < > convert(const regexp::FormalRegExp& regexp);
 	static automaton::EpsilonNFA < > convert(const regexp::UnboundedRegExp& regexp);
 
-	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	class Unbounded {
 	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;
+		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);
 	};
 
-	class Formal : public regexp::FormalRegExpElement::Visitor {
+	class Formal {
 	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;
+		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);
 	};
 
 };
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.cpp b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
index e1da9e26d5..ebd2075478 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
@@ -18,9 +18,7 @@ bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp) {
 }
 
 bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpElement& regexp) {
-	bool out;
-	regexp.Accept((void*) &out, RegExpEmpty::Formal::FORMAL);
-	return out;
+	return regexp.accept < bool, RegExpEmpty::Formal > ( );
 }
 
 bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpStructure& regexp) {
@@ -34,9 +32,7 @@ bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExp& regexp) {
 auto RegExpEmptyFormalRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::FormalRegExp>( RegExpEmpty::languageIsEmpty);
 
 bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpElement& regexp) {
-	bool out;
-	regexp.Accept((void*) &out, RegExpEmpty::Unbounded::UNBOUNDED);
-	return out;
+	return regexp.accept < bool, RegExpEmpty::Unbounded > ( );
 }
 
 bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpStructure& regexp) {
@@ -51,102 +47,66 @@ auto RegExpEmptyUnboundedRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::
 
 // ----------------------------------------------------------------------------
 
-void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const {
-	bool &ret = *(bool*) data;
-
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation) {
 	for(const auto& element : alternation.getElements()) {
-		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, *this);
-		if(! ret) {
-			ret = false;
-			return;
+		if(! element->accept < bool, RegExpEmpty::Unbounded > ( ) ) {
+			return false;
 		}
 	}
-	ret = true;
+	return true;
 }
 
-void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const {
-	bool &ret = *(bool*) data;
-
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation) {
 	for(const auto& element : concatenation.getElements()) {
-		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, *this);
-		if(ret) {
-			ret = true;
-			return;
+		if( element->accept < bool, RegExpEmpty::Unbounded > ( ) ) {
+			return true;
 		}
 	}
-	ret = false;
+	return false;
 }
 
-void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpIteration&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpIteration&) {
+	return false;
 }
 
-void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpSymbol&) {
+	return false;
 }
 
-void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const {
-	bool &ret = *(bool*) data;
-	ret = true;
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEmpty&) {
+	return true;
 }
 
-void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&) {
+	return false;
 }
 
-const RegExpEmpty::Unbounded RegExpEmpty::Unbounded::UNBOUNDED;
-
 // ----------------------------------------------------------------------------
 
-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);
-	bool retLeft = ret;
-
-	static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(data, *this);
-	bool retRight = ret;
-
-	ret = retLeft && retRight;
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpAlternation& alternation) {
+	return alternation.getLeftElement().accept < bool, RegExpEmpty::Formal > ( ) && alternation.getRightElement().accept < bool, RegExpEmpty::Formal > ( );
 }
 
-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);
-	bool retLeft = ret;
-
-	static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(data, *this);
-	bool retRight = ret;
-
-	ret = retLeft || retRight;
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation) {
+	return concatenation.getLeftElement().accept < bool, RegExpEmpty::Formal > ( ) || concatenation.getRightElement().accept < bool, RegExpEmpty::Formal > ( );
 }
 
-void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpIteration&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpIteration&) {
+	return false;
 }
 
-void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpSymbol&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpSymbol&) {
+	return false;
 }
 
-void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpEmpty&) const {
-	bool &ret = *(bool*) data;
-	ret = true;
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEmpty&) {
+	return true;
 }
 
-void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpEpsilon&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEpsilon&) {
+	return false;
 }
 
-const RegExpEmpty::Formal RegExpEmpty::Formal::FORMAL;
-
 } /* namespace properties */
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.h b/alib2algo/src/regexp/properties/RegExpEmpty.h
index 2551bccad7..6fb4455a71 100644
--- a/alib2algo/src/regexp/properties/RegExpEmpty.h
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.h
@@ -36,34 +36,24 @@ public:
 	static bool languageIsEmpty(const regexp::UnboundedRegExpStructure& regexp);
 	static bool languageIsEmpty(const regexp::UnboundedRegExp& regexp);
 
-	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	class Unbounded {
 	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;
+		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);
 	};
 
-	class Formal : public regexp::FormalRegExpElement::Visitor {
+	class Formal {
 	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;
+		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);
 	};
 
 };
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
index bf0714503b..a7e9910cd9 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
@@ -18,9 +18,7 @@ bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp) {
 }
 
 bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpElement& regexp) {
-	bool out;
-	regexp.Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON);
-	return out;
+	return regexp.accept<bool, RegExpEpsilon::Formal>();
 }
 
 bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpStructure& regexp) {
@@ -34,9 +32,7 @@ bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp& regexp)
 auto RegExpEpsilonFormalRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::FormalRegExp>( RegExpEpsilon::languageContainsEpsilon);
 
 bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpElement& regexp) {
-	bool out;
-	regexp.Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON);
-	return out;
+	return regexp.accept<bool, RegExpEpsilon::Unbounded>();
 }
 
 bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpStructure& regexp) {
@@ -51,104 +47,64 @@ auto RegExpEpsilonUnboundedRegExp = RegExpEpsilon::RegistratorWrapper<bool, rege
 
 // ---------------------------------------------------------------------------
 
-void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const {
-	bool &ret = *(bool*) data;
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation) {
+	for ( const auto & element : alternation.getElements ( ) )
+		if ( element->accept < bool, RegExpEpsilon::Unbounded > ( ) )
+			return true;
 
-	for(const auto& element : alternation.getElements()) {
-		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
-		if(ret) {
-			ret = true;
-			return;
-		}
-	}
-	
-	ret = false;
+	return false;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const {
-	bool &ret = *(bool*) data;
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation) {
+	for ( const auto & element : concatenation.getElements ( ) )
+		if ( ! element->accept < bool, RegExpEpsilon::Unbounded > ( ) )
+			return false;
 
-	for(const auto& element : concatenation.getElements()) {
-		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
-		if(!ret) {
-			ret = false;
-			return;
-		}
-	}
-	
-	ret = true;
+	return true;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpIteration&) const {
-	bool &ret = *(bool*) data;
-	ret = true;
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpIteration&) {
+	return true;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpSymbol&) {
+	return false;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const {
-	bool &ret = *(bool*) data;
-	ret = true;
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&) {
+	return true;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEmpty&) {
+	return false;
 }
 
 // ----------------------------------------------------------------------------
 
-void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const {
-	bool &ret = *(bool*) data;
-
-	static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
-	bool retLeft = ret;
-
-	static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
-	bool retRight = ret;
-
-	ret = retLeft || retRight;
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpAlternation& alternation) {
+	return alternation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() || alternation.getRightElement().accept<bool, RegExpEpsilon::Formal>();
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const {
-	bool &ret = *(bool*) data;
-
-	static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
-	bool retLeft = ret;
-
-	static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
-	bool retRight = ret;
-
-	ret = retLeft && retRight;
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation) {
+	return concatenation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() && concatenation.getRightElement().accept<bool, RegExpEpsilon::Formal>();
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpIteration&) const {
-	bool &ret = *(bool*) data;
-	ret = true;
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpIteration&) {
+	return true;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpSymbol&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpSymbol&) {
+	return false;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpEmpty&) const {
-	bool &ret = *(bool*) data;
-	ret = false;
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEmpty&) {
+	return false;
 }
 
-void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpEpsilon&) const {
-	bool &ret = *(bool*) data;
-	ret = true;
+bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEpsilon&) {
+	return true;
 }
 
-// ---------------------------------------------------------------------------
-
-const RegExpEpsilon RegExpEpsilon::REG_EXP_EPSILON;
-
 } /* namespace properties */
 
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h
index 4ce6bb7349..e6002f7b1d 100644
--- a/alib2algo/src/regexp/properties/RegExpEpsilon.h
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h
@@ -24,10 +24,8 @@ namespace properties {
  * Checks, whether regexp (or its subtree) describes epsilon (empty string).
  *
  */
-class RegExpEpsilon : public std::SingleDispatch<RegExpEpsilon, bool, const regexp::RegExpBase &>, regexp::FormalRegExpElement::Visitor, regexp::UnboundedRegExpElement::Visitor {
+class RegExpEpsilon : public std::SingleDispatch<RegExpEpsilon, bool, const regexp::RegExpBase &> {
 public:
-	RegExpEpsilon() {}
-
 	static bool languageContainsEpsilon(const regexp::RegExp& regexp);
 
 	static bool languageContainsEpsilon(const regexp::FormalRegExpElement& regexp);
@@ -38,22 +36,25 @@ public:
 	static bool languageContainsEpsilon(const regexp::UnboundedRegExpStructure& regexp);
 	static bool languageContainsEpsilon(const regexp::UnboundedRegExp& 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 RegExpEpsilon REG_EXP_EPSILON;
+	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);
+	};
+
+	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);
+	};
 };
 
 } /* namespace properties */
diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.cpp b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
index ca1287e112..afd330d1e7 100644
--- a/alib2algo/src/regexp/transform/RegExpDerivation.cpp
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
@@ -20,11 +20,8 @@ regexp::RegExp RegExpDerivation::derivation(const regexp::RegExp& regexp, const
 regexp::FormalRegExp RegExpDerivation::derivation(const regexp::FormalRegExp& regexp, const string::LinearString < >& string) {
 	std::unique_ptr < regexp::FormalRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
-	for(const auto& symbol : string.getContent()) {
-		std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpDerivation::Formal::FORMAL);
-		newRegExp = std::move ( out.second );
-	}
+	for(const auto& symbol : string.getContent())
+		newRegExp = newRegExp->accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(symbol);
 
 	return regexp::FormalRegExp ( regexp::FormalRegExpStructure ( std::move ( * newRegExp ) ) );
 }
@@ -34,11 +31,8 @@ auto RegExpDerivationFormalRegExp = RegExpDerivation::RegistratorWrapper<regexp:
 regexp::UnboundedRegExp RegExpDerivation::derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string) {
 	std::unique_ptr < regexp::UnboundedRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
-	for(const auto& symbol : string.getContent()) {
-		std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpDerivation::Unbounded::UNBOUNDED);
-		newRegExp = std::move ( out.second );
-	}
+	for(const auto& symbol : string.getContent())
+		newRegExp = newRegExp->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( symbol );
 
 	return regexp::UnboundedRegExp ( regexp::UnboundedRegExpStructure ( std::move ( * newRegExp ) ) );
 }
@@ -47,85 +41,65 @@ auto RegExpDerivationUnboundedRegExp = RegExpDerivation::RegistratorWrapper<rege
 
 // ----------------------------------------------------------------------------
 
-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);
-	std::unique_ptr < regexp::FormalRegExpElement > leftDerivative = std::move ( out.second );
-
-	alternation.getRightElement().Accept(userData, *this);
+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);
 
-	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftDerivative ), std::move ( * out.second ) ) );
+	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftDerivative ), std::move ( * rightDerivative ) ) );
 }
 
-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);
+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);
 
-	concatenation.getLeftElement().Accept(userData, *this);
-
-	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpConcatenation( std::move ( * out.second ), std::move_copy ( concatenation.getRightElement ( ) ) ) );
+	std::unique_ptr < regexp::FormalRegExpElement > res ( new regexp::FormalRegExpConcatenation( std::move ( * leftDerivative ), std::move_copy ( concatenation.getRightElement ( ) ) ) );
 
 	if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(concatenation.getLeftElement())) {
-		std::unique_ptr < regexp::FormalRegExpElement > alternation = std::move ( out.second );
-		concatenation.getRightElement().Accept(userData, *this);
+		std::unique_ptr < regexp::FormalRegExpElement > rightDerivative = concatenation.getRightElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument);
 
-		out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation ( std::move ( * alternation ), std::move( * out.second ) ) );
+		res = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation ( std::move ( * res ), std::move( * rightDerivative ) ) );
 	}
-}
-
-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);
 
-	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpConcatenation( std::move ( * out.second ), iteration ) );
+	return res;
 }
 
-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);
+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 ) );
+}
 
-	if(out.first == symbol.getSymbol())
-		out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEpsilon() );
+std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument) {
+	if(argument == symbol.getSymbol())
+		return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEpsilon() );
 	else
-		out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
+		return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
 }
 
 
-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() );
+std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEpsilon&, const alphabet::Symbol&) {
+	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
 }
 
-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() );
+std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEmpty&, const alphabet::Symbol&) {
+	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() );
 }
 
-const RegExpDerivation::Formal RegExpDerivation::Formal::FORMAL;
-
 // ----------------------------------------------------------------------------
 
-
-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::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument) {
 	std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() );
 
-	for(const auto& child : alternation.getElements()) {
-		child->Accept(userData, *this);
-		ret->appendElement(std::move( * out.second ) );
-	}
+	for(const auto& child : alternation.getElements())
+		ret->appendElement( * ( child->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
 
-	out.second = std::move ( ret );
+	return ret;
 }
 
-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::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument) {
 	std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() );
 
 	for(auto child = concatenation.getElements().begin(); child != concatenation.getElements().end(); ++ child) {
 		std::unique_ptr < regexp::UnboundedRegExpConcatenation > concat ( new regexp::UnboundedRegExpConcatenation() );
-		(*child)->Accept(userData, *this);
-		concat->appendElement( std::move ( * out.second ) );
+		concat->appendElement( * ( (*child)->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
 
 		auto succeedingElement = child;
 		while(++succeedingElement != concatenation.getElements().end())
@@ -137,39 +111,29 @@ void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedR
 			break;
 	}
 
-	out.second = std::move ( ret );
+	return ret;
 }
 
-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);
-
+std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument) {
 	UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
-	con->appendElement ( std::move ( * out.second ) );
+	con->appendElement ( * ( iteration.getElement().accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) );
 	con->appendElement ( iteration );
-	out.second = std::unique_ptr < UnboundedRegExpElement > ( con );
+	return std::unique_ptr < UnboundedRegExpElement > ( con );
 }
 
-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())
-		out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEpsilon() );
+std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument) {
+	if(argument == symbol.getSymbol())
+		return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEpsilon() );
 	else
-		out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
+		return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
 }
 
-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() );
+std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, const alphabet::Symbol&) {
+	return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
 }
 
-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() );
+std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, const alphabet::Symbol&) {
+	return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() );
 }
 
-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 1c24962014..e145ebfbff 100644
--- a/alib2algo/src/regexp/transform/RegExpDerivation.h
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.h
@@ -40,34 +40,24 @@ public:
 	static regexp::UnboundedRegExp derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string);
 
 private:
-	class Formal : public regexp::FormalRegExpElement::Visitor {
+	class Formal {
 	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;
+		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);
 	};
 
-	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	class Unbounded {
 	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;
+		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);
 	};
 };
 
diff --git a/alib2algo/src/regexp/transform/RegExpIntegral.cpp b/alib2algo/src/regexp/transform/RegExpIntegral.cpp
index 047b2c5db8..f3f598ef49 100644
--- a/alib2algo/src/regexp/transform/RegExpIntegral.cpp
+++ b/alib2algo/src/regexp/transform/RegExpIntegral.cpp
@@ -18,11 +18,8 @@ regexp::RegExp RegExpIntegral::integral(const regexp::RegExp& regexp, const stri
 regexp::FormalRegExp RegExpIntegral::integral(const regexp::FormalRegExp& regexp, const string::LinearString < >& string) {
 	std::unique_ptr < regexp::FormalRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
-	for(const auto& symbol : string.getContent()) {
-		std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpIntegral::Formal::FORMAL);
-		newRegExp = std::move ( out.second );
-	}
+	for(const auto& symbol : string.getContent())
+		newRegExp = newRegExp->accept < std::unique_ptr < regexp::FormalRegExpElement >, RegExpIntegral::Formal > ( symbol );
 
 	return regexp::FormalRegExp ( regexp::FormalRegExpStructure ( * newRegExp ) );
 }
@@ -32,11 +29,8 @@ auto RegExpIntegralFormalRegExp = RegExpIntegral::RegistratorWrapper<regexp::For
 regexp::UnboundedRegExp RegExpIntegral::integral(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string) {
 	std::unique_ptr < regexp::UnboundedRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() );
 
-	for(const auto& symbol : string.getContent()) {
-		std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > out(symbol, nullptr);
-		newRegExp->Accept((void*) &out, RegExpIntegral::Unbounded::UNBOUNDED);
-		newRegExp = std::move ( out.second );
-	}
+	for(const auto& symbol : string.getContent())
+		newRegExp = newRegExp->accept < std::unique_ptr < regexp::UnboundedRegExpElement >, RegExpIntegral::Unbounded > ( symbol );
 
 	return regexp::UnboundedRegExp ( regexp::UnboundedRegExpStructure( * newRegExp ) );
 }
@@ -45,108 +39,77 @@ auto RegExpIntegralUnboundedRegExp = RegExpIntegral::RegistratorWrapper<regexp::
 
 // ----------------------------------------------------------------------------
 
-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);
+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 );
 
-	alternation.getLeftElement().Accept(userData, *this);
-	std::unique_ptr < regexp::FormalRegExpElement > leftIntegral = std::move ( out.second );
-
-	alternation.getRightElement().Accept(userData, *this);
-
-	out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftIntegral ), std::move ( * out.second ) ) );
+	return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftIntegral ), std::move ( * rightIntegral ) ) );
 }
 
-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 ) );
+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 ) );
 }
 
-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 ) );
+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 ) );
 }
 
-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 ) );
+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 ) );
 }
 
 
-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 ) );
+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 ) );
 }
 
-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( ) );
+std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpEmpty&, const alphabet::Symbol&) {
+	return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpEmpty( ) );
 }
 
-const RegExpIntegral::Formal RegExpIntegral::Formal::FORMAL;
-
 // ----------------------------------------------------------------------------
 
-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);
-
+std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument) {
 	regexp::UnboundedRegExpAlternation* alt = new regexp::UnboundedRegExpAlternation();
 
-	for(const auto& child : alternation.getElements()) {
-		child->Accept(userData, *this);
-		alt->appendElement(std::move(*out.second));
-	}
+	for(const auto& child : alternation.getElements())
+		alt->appendElement(* ( child->accept < std::unique_ptr < regexp::UnboundedRegExpElement >, RegExpIntegral::Unbounded > (argument) ) );
 
-	out.second = std::unique_ptr < UnboundedRegExpElement > ( alt );
+	return std::unique_ptr < UnboundedRegExpElement > ( alt );
 }
 
-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);
-
+std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument) {
 	regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( );
 
-	con->appendElement ( regexp::UnboundedRegExpSymbol ( out.first ) );
+	con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) );
 	for ( const auto & element : concatenation.getElements() )
 		con->appendElement ( * element );
 
-	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
+	return std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
 }
 
-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);
-
+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 ( out.first ) );
+	con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) );
 	con->appendElement ( iteration );
 
-	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
+	return std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
 }
 
-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);
-
+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 ( out.first ) );
+	con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) );
 	con->appendElement ( symbol );
 
-	out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
+	return std::unique_ptr < regexp::UnboundedRegExpElement > ( con );
 }
 
-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 ) );
+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 ) );
 }
 
-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( ) );
+std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, const alphabet::Symbol&) {
+	return std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty( ) );
 }
 
-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 3a9fa67313..ab84ebd42f 100644
--- a/alib2algo/src/regexp/transform/RegExpIntegral.h
+++ b/alib2algo/src/regexp/transform/RegExpIntegral.h
@@ -37,34 +37,24 @@ public:
 	static regexp::UnboundedRegExp integral(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string);
 
 private:
-	class Formal : public regexp::FormalRegExpElement::Visitor {
+	class Formal {
 	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;
+		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);
 	};
 
-	class Unbounded : public regexp::UnboundedRegExpElement::Visitor {
+	class Unbounded {
 	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;
+		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);
 	};
 };
 
diff --git a/alib2data/src/regexp/common/RegExpToXMLComposer.cpp b/alib2data/src/regexp/common/RegExpToXMLComposer.cpp
index 0cc3a3372b..a985ff877e 100644
--- a/alib2data/src/regexp/common/RegExpToXMLComposer.cpp
+++ b/alib2data/src/regexp/common/RegExpToXMLComposer.cpp
@@ -16,98 +16,72 @@
 
 namespace regexp {
 
-void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpAlternation& alternation, std::deque<sax::Token>& out) {
 	out.emplace_back("alternation", sax::Token::TokenType::START_ELEMENT);
 	for (const auto& element : alternation.getElements()) {
-		element->Accept(userData, *this);
+		element->accept < void, RegExpToXMLComposer::Unbounded > ( out );
 	}
 	out.emplace_back("alternation", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpConcatenation& concatenation, std::deque<sax::Token>& out) {
 	out.emplace_back("concatenation", sax::Token::TokenType::START_ELEMENT);
 	for (auto element : concatenation.getElements()) {
-		element->Accept(userData, *this);
+		element->accept < void, RegExpToXMLComposer::Unbounded > ( out );
 	}
 	out.emplace_back("concatenation", sax::Token::TokenType::END_ELEMENT);
-
 }
 
-void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpIteration& iteration) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpIteration& iteration, std::deque<sax::Token>& out) {
 	out.emplace_back("iteration", sax::Token::TokenType::START_ELEMENT);
-	iteration.getElement().Accept(userData, *this);
+	iteration.getElement().accept < void, RegExpToXMLComposer::Unbounded > ( out );
 	out.emplace_back("iteration", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpSymbol& symbol, std::deque<sax::Token>& out) {
 	alib::xmlApi<alphabet::Symbol>::compose(out, symbol.getSymbol());
 }
 
-void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpEpsilon&) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpEpsilon&, std::deque<sax::Token>& out) {
 	out.emplace_back("epsilon", sax::Token::TokenType::START_ELEMENT);
 	out.emplace_back("epsilon", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpEmpty&) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpEmpty&, std::deque<sax::Token>& out) {
 	out.emplace_back("empty", sax::Token::TokenType::START_ELEMENT);
 	out.emplace_back("empty", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpAlternation& alternation) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Formal::visit(const FormalRegExpAlternation& alternation, std::deque<sax::Token>& out) {
 	out.emplace_back("alternation", sax::Token::TokenType::START_ELEMENT);
-	alternation.getLeftElement().Accept(userData, *this);
-	alternation.getRightElement().Accept(userData, *this);
+	alternation.getLeftElement().accept < void, RegExpToXMLComposer::Formal > ( out );
+	alternation.getRightElement().accept < void, RegExpToXMLComposer::Formal > ( out );
 	out.emplace_back("alternation", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Formal::visit(const FormalRegExpConcatenation& concatenation, std::deque<sax::Token>& out) {
 	out.emplace_back("concatenation", sax::Token::TokenType::START_ELEMENT);
-	concatenation.getLeftElement().Accept(userData, *this);
-	concatenation.getRightElement().Accept(userData, *this);
+	concatenation.getLeftElement().accept < void, RegExpToXMLComposer::Formal > ( out );
+	concatenation.getRightElement().accept < void, RegExpToXMLComposer::Formal > ( out );
 	out.emplace_back("concatenation", sax::Token::TokenType::END_ELEMENT);
-
 }
 
-void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpIteration& iteration) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Formal::visit(const FormalRegExpIteration& iteration, std::deque<sax::Token>& out) {
 	out.emplace_back("iteration", sax::Token::TokenType::START_ELEMENT);
-	iteration.getElement().Accept(userData, *this);
+	iteration.getElement().accept < void, RegExpToXMLComposer::Formal > ( out );
 	out.emplace_back("iteration", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpSymbol& symbol) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Formal::visit(const FormalRegExpSymbol& symbol, std::deque<sax::Token>& out) {
 	alib::xmlApi<alphabet::Symbol>::compose(out, symbol.getSymbol());
 }
 
-void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpEpsilon&) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Formal::visit(const FormalRegExpEpsilon&, std::deque<sax::Token>& out) {
 	out.emplace_back("epsilon", sax::Token::TokenType::START_ELEMENT);
 	out.emplace_back("epsilon", sax::Token::TokenType::END_ELEMENT);
 }
 
-void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpEmpty&) const {
-	std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData);
-
+void RegExpToXMLComposer::Formal::visit(const FormalRegExpEmpty&, std::deque<sax::Token>& out) {
 	out.emplace_back("empty", sax::Token::TokenType::START_ELEMENT);
 	out.emplace_back("empty", sax::Token::TokenType::END_ELEMENT);
 }
@@ -120,7 +94,4 @@ void RegExpToXMLComposer::composeAlphabet(std::deque<sax::Token>& out, const std
 	out.emplace_back("alphabet", sax::Token::TokenType::END_ELEMENT);
 }
 
-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 e6bc3fa8be..09f64ac523 100644
--- a/alib2data/src/regexp/common/RegExpToXMLComposer.h
+++ b/alib2data/src/regexp/common/RegExpToXMLComposer.h
@@ -23,34 +23,24 @@ class RegExpToXMLComposer {
 public:
 	static void composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::Symbol>& alphabet);
 
-	class Unbounded : public UnboundedRegExpElement::Visitor {
+	class Unbounded {
 	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;
+		static void visit( const UnboundedRegExpAlternation& alternation, std::deque < sax::Token > & output);
+		static void visit( const UnboundedRegExpConcatenation& concatenation, std::deque < sax::Token > & output);
+		static void visit( const UnboundedRegExpIteration& iteration, std::deque < sax::Token > & output);
+		static void visit( const UnboundedRegExpSymbol& symbol, std::deque < sax::Token > & output);
+		static void visit( const UnboundedRegExpEpsilon& epsilon, std::deque < sax::Token > & output);
+		static void visit( const UnboundedRegExpEmpty& empty, std::deque < sax::Token > & output);
 	};
 
-	class Formal : public FormalRegExpElement::Visitor {
+	class Formal {
 	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;
+		static void visit( const FormalRegExpAlternation& alternation, std::deque < sax::Token > & output);
+		static void visit( const FormalRegExpConcatenation& concatenation, std::deque < sax::Token > & output);
+		static void visit( const FormalRegExpIteration& iteration, std::deque < sax::Token > & output);
+		static void visit( const FormalRegExpSymbol& symbol, std::deque < sax::Token > & output);
+		static void visit( const FormalRegExpEpsilon& epsilon, std::deque < sax::Token > & output);
+		static void visit( const FormalRegExpEmpty& empty, std::deque < sax::Token > & output);
 	};
 };
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
index 4bc686593f..fd534ac2de 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
@@ -19,8 +19,8 @@ namespace regexp {
  */
 class FormalRegExpAlternation : public FormalRegExpElement, public std::BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpAlternation > {
 public:
-	void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( FormalRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit FormalRegExpAlternation ( FormalRegExpElement && left, FormalRegExpElement && right );
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
index d15208d7fe..51ce41638e 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
@@ -21,8 +21,8 @@ namespace regexp {
  */
 class FormalRegExpConcatenation : public FormalRegExpElement, public std::BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpConcatenation > {
 public:
-	void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( FormalRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit FormalRegExpConcatenation ( FormalRegExpElement && left, FormalRegExpElement && right );
diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.h b/alib2data/src/regexp/formal/FormalRegExpElement.h
index b694ce8ba4..944dc753f5 100644
--- a/alib2data/src/regexp/formal/FormalRegExpElement.h
+++ b/alib2data/src/regexp/formal/FormalRegExpElement.h
@@ -12,6 +12,7 @@
 #include "../../alphabet/Symbol.h"
 #include <set>
 #include <tree>
+#include <core/visitor.hpp>
 
 namespace regexp {
 
@@ -31,15 +32,52 @@ class FormalRegExpElement : public alib::CommonBase < FormalRegExpElement >, pub
 public:
 	class Visitor {
 	public:
-		virtual void Visit ( void *, const FormalRegExpAlternation & ) const = 0;
-		virtual void Visit ( void *, const FormalRegExpConcatenation & ) const = 0;
-		virtual void Visit ( void *, const FormalRegExpIteration & ) const = 0;
-		virtual void Visit ( void *, const FormalRegExpSymbol & ) const = 0;
-		virtual void Visit ( void *, const FormalRegExpEmpty & ) const = 0;
-		virtual void Visit ( void *, const FormalRegExpEpsilon & ) const = 0;
+		virtual void visit ( const FormalRegExpAlternation & ) = 0;
+		virtual void visit ( const FormalRegExpConcatenation & ) = 0;
+		virtual void visit ( const FormalRegExpIteration & ) = 0;
+		virtual void visit ( const FormalRegExpSymbol & ) = 0;
+		virtual void visit ( const FormalRegExpEmpty & ) = 0;
+		virtual void visit ( const FormalRegExpEpsilon & ) = 0;
 	};
 
-	virtual void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const = 0;
+	template < class ReturnType, class Visitorr, class ... Params >
+	class VisitorContext : public std::VisitorContextAux < ReturnType, Visitorr, Params ... >, public FormalRegExpElement::Visitor {
+	public:
+		using std::VisitorContextAux < ReturnType, Visitorr, Params ... >::VisitorContextAux;
+
+		void visit ( const FormalRegExpAlternation & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const FormalRegExpConcatenation & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const FormalRegExpIteration & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const FormalRegExpSymbol & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const FormalRegExpEmpty & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const FormalRegExpEpsilon & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+	};
+
+	template < class ReturnType, class Visitorr, class ... Params >
+	ReturnType accept ( Params && ... params ) const {
+		VisitorContext < ReturnType, Visitorr, Params ... > context ( std::forward < Params > ( params ) ... );
+		accept ( context );
+		return context.getResult ( );
+	}
+
+	virtual void accept ( FormalRegExpElement::Visitor & visitor ) const = 0;
 
 	/**
 	 * Creates copy of the element.
diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.h b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
index 5f41279146..0609c82297 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEmpty.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
@@ -18,8 +18,8 @@ namespace regexp {
  */
 class FormalRegExpEmpty : public FormalRegExpElement, public std::NullaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpSymbol > {
 public:
-	void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( FormalRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit FormalRegExpEmpty ( );
diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
index 2260db4c3f..77deb0fe33 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
@@ -18,8 +18,8 @@ namespace regexp {
  */
 class FormalRegExpEpsilon : public FormalRegExpElement, public std::NullaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpSymbol > {
 public:
-	void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( FormalRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit FormalRegExpEpsilon ( );
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h
index c799ec2811..c687dea427 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.h
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h
@@ -19,8 +19,8 @@ namespace regexp {
  */
 class FormalRegExpIteration : public FormalRegExpElement, public std::UnaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpIteration > {
 public:
-	void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( FormalRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit FormalRegExpIteration ( FormalRegExpElement && );
diff --git a/alib2data/src/regexp/formal/FormalRegExpStructure.cpp b/alib2data/src/regexp/formal/FormalRegExpStructure.cpp
index ba50e5ef31..5e90d8b1f3 100644
--- a/alib2data/src/regexp/formal/FormalRegExpStructure.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpStructure.cpp
@@ -58,7 +58,7 @@ bool xmlApi < regexp::FormalRegExpStructure >::first ( const std::deque < sax::T
 }
 
 void xmlApi < regexp::FormalRegExpStructure >::compose ( std::deque < sax::Token > & output, const regexp::FormalRegExpStructure & data ) {
-	data.getStructure ( ).Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::Formal::FORMAL );
+	data.getStructure ( ).accept < void, regexp::RegExpToXMLComposer::Formal > ( output );
 }
 
 } /* namespace alib */
diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.h b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
index 568770a84a..5847ac8cde 100644
--- a/alib2data/src/regexp/formal/FormalRegExpSymbol.h
+++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
@@ -20,8 +20,8 @@ class FormalRegExpSymbol : public FormalRegExpElement, public std::NullaryNode <
 	alphabet::Symbol symbol;
 
 public:
-	void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( FormalRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit FormalRegExpSymbol ( int number ); // TODO remove these
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
index 7575e133a7..fdccbd1b19 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
@@ -19,8 +19,8 @@ namespace regexp {
  */
 class UnboundedRegExpAlternation : public UnboundedRegExpElement, public std::VararyNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpAlternation > {
 public:
-	void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( UnboundedRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit UnboundedRegExpAlternation ( );
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
index 4703c0b027..f077f872b3 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
@@ -19,8 +19,8 @@ namespace regexp {
  */
 class UnboundedRegExpConcatenation : public UnboundedRegExpElement, public std::VararyNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpConcatenation > {
 public:
-	void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( UnboundedRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit UnboundedRegExpConcatenation ( );
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
index dbccf48789..cc832c5e5f 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
@@ -12,6 +12,7 @@
 #include "../../alphabet/Symbol.h"
 #include <set>
 #include <tree>
+#include <core/visitor.hpp>
 
 namespace regexp {
 
@@ -31,15 +32,52 @@ class UnboundedRegExpElement : public alib::CommonBase < UnboundedRegExpElement
 public:
 	class Visitor {
 	public:
-		virtual void Visit ( void *, const UnboundedRegExpAlternation & ) const = 0;
-		virtual void Visit ( void *, const UnboundedRegExpConcatenation & ) const = 0;
-		virtual void Visit ( void *, const UnboundedRegExpIteration & ) const = 0;
-		virtual void Visit ( void *, const UnboundedRegExpSymbol & ) const = 0;
-		virtual void Visit ( void *, const UnboundedRegExpEmpty & ) const = 0;
-		virtual void Visit ( void *, const UnboundedRegExpEpsilon & ) const = 0;
+		virtual void visit ( const UnboundedRegExpAlternation & ) = 0;
+		virtual void visit ( const UnboundedRegExpConcatenation & ) = 0;
+		virtual void visit ( const UnboundedRegExpIteration & ) = 0;
+		virtual void visit ( const UnboundedRegExpSymbol & ) = 0;
+		virtual void visit ( const UnboundedRegExpEmpty & ) = 0;
+		virtual void visit ( const UnboundedRegExpEpsilon & ) = 0;
 	};
 
-	virtual void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const = 0;
+	template < class ReturnType, class Visitorr, class ... Params >
+	class VisitorContext : public std::VisitorContextAux < ReturnType, Visitorr, Params ... >, public UnboundedRegExpElement::Visitor {
+	public:
+		using std::VisitorContextAux < ReturnType, Visitorr, Params ... >::VisitorContextAux;
+
+		void visit ( const UnboundedRegExpAlternation & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const UnboundedRegExpConcatenation & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const UnboundedRegExpIteration & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const UnboundedRegExpSymbol & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const UnboundedRegExpEmpty & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+
+		void visit ( const UnboundedRegExpEpsilon & inherit ) override {
+			this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } );
+		}
+	};
+
+	template < class ReturnType, class Visitorr, class ... Params >
+	ReturnType accept ( Params && ... params ) const {
+		VisitorContext < ReturnType, Visitorr, Params ... > context ( std::forward < Params > ( params ) ... );
+		accept ( context );
+		return context.getResult ( );
+	}
+
+	virtual void accept ( UnboundedRegExpElement::Visitor & visitor ) const = 0;
 
 	/**
 	 * Creates copy of the element.
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
index 860c16dfb0..cdfec770e2 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
@@ -17,8 +17,8 @@ namespace regexp {
  */
 class UnboundedRegExpEmpty : public UnboundedRegExpElement, public std::NullaryNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpSymbol > {
 public:
-	void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( UnboundedRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit UnboundedRegExpEmpty ( );
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
index 24c240d7e7..32b8eeed32 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
@@ -17,8 +17,8 @@ namespace regexp {
  */
 class UnboundedRegExpEpsilon : public UnboundedRegExpElement, public std::NullaryNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpSymbol > {
 public:
-	void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( UnboundedRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit UnboundedRegExpEpsilon ( );
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
index e6b3d06210..54d9d0b0e0 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
@@ -19,8 +19,8 @@ namespace regexp {
  */
 class UnboundedRegExpIteration : public UnboundedRegExpElement, public std::UnaryNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpIteration > {
 public:
-	void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( UnboundedRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit UnboundedRegExpIteration ( UnboundedRegExpElement && );
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp
index dd47bb4a0b..36f1c9ba71 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp
@@ -58,7 +58,7 @@ bool xmlApi < regexp::UnboundedRegExpStructure >::first ( const std::deque < sax
 }
 
 void xmlApi < regexp::UnboundedRegExpStructure >::compose ( std::deque < sax::Token > & output, const regexp::UnboundedRegExpStructure & data ) {
-	data.getStructure ( ).Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::Unbounded::UNBOUNDED );
+	data.getStructure ( ).accept < void, regexp::RegExpToXMLComposer::Unbounded > ( output );
 }
 
 } /* namespace alib */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
index 013de4c1fe..fdddca278a 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
@@ -20,8 +20,8 @@ class UnboundedRegExpSymbol : public UnboundedRegExpElement, public std::Nullary
 	alphabet::Symbol symbol;
 
 public:
-	void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const {
-		visitor.Visit ( userData, * this );
+	void accept ( UnboundedRegExpElement::Visitor & visitor ) const {
+		visitor.visit ( * this );
 	}
 
 	explicit UnboundedRegExpSymbol ( int number );
diff --git a/alib2str/src/regexp/RegExpToStringComposer.cpp b/alib2str/src/regexp/RegExpToStringComposer.cpp
index a0ac860672..2e5aa43494 100644
--- a/alib2str/src/regexp/RegExpToStringComposer.cpp
+++ b/alib2str/src/regexp/RegExpToStringComposer.cpp
@@ -24,8 +24,7 @@ RegExpToStringComposer::RegistratorWrapper<void, UnboundedRegExp> RegExpToString
 void RegExpToStringComposer::compose(std::ostream& output, const UnboundedRegExpStructure& regexp) {
 	Priority tmp = Priority::ALTERNATION;
 	std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output);
-	RegExpToStringComposer composer;
-	regexp.getStructure().Accept((void*) &out, composer);
+	regexp.getStructure().accept<void, RegExpToStringComposer::Unbounded > (out);
 }
 
 void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExp& regexp) {
@@ -37,17 +36,14 @@ RegExpToStringComposer::RegistratorWrapper<void, FormalRegExp> RegExpToStringCom
 void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExpStructure& regexp) {
 	Priority tmp = Priority::ALTERNATION;
 	std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output);
-	RegExpToStringComposer composer;
-	regexp.getStructure().Accept((void*) &out, composer);
+	regexp.getStructure().accept<void, RegExpToStringComposer::Formal > (out);
 }
 
-void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out ) {
 	if(alternation.getElements().size() == 0) {
 		std::get<1>(out) << "#0";
 	} else if(alternation.getElements().size() == 1) {
-		alternation.getElements()[0]->Accept(userData, *this);
+		alternation.getElements()[0]->accept<void, RegExpToStringComposer::Unbounded > (out);
 	} else {
 		Priority outerPriorityMinimum = std::get<0>(out);
 		if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '(';
@@ -59,20 +55,18 @@ void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternat
 				std::get<1>(out) << '+';
 			}
 			std::get<0>(out) = Priority::ALTERNATION;
-			element->Accept(userData, *this);
+			element->accept<void, RegExpToStringComposer::Unbounded > (out);
 		}
 		if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')';
 	}
 }
 
-void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & out ) {
 	Priority outerPriorityMinimum = std::get<0>(out);
 	if(concatenation.getElements().size() == 0) {
 		std::get<1>(out) << "#E";
 	} else if(concatenation.getElements().size() == 1) {
-		concatenation.getElements()[0]->Accept(userData, *this);
+		concatenation.getElements()[0]->accept<void, RegExpToStringComposer::Unbounded > (out);
 	} else {
 		if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '(';
 		bool first = true;
@@ -83,85 +77,69 @@ void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpConcaten
 				std::get<1>(out) << ' ';
 			}
 			std::get<0>(out) = Priority::CONCATENATION;
-			element->Accept(userData, *this);
+			element->accept<void, RegExpToStringComposer::Unbounded > (out);
 		}
 		if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')';
 	}
 }
 
-void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpIteration& iteration) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<0>(out) = Priority::FACTOR;
-	iteration.getElement().Accept(userData, *this);
+	iteration.getElement().accept<void, RegExpToStringComposer::Unbounded > (out);
 	std::get<1>(out) << "*";
 }
 
-void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & out ) {
 	alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol());
 }
 
-void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEpsilon&) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEpsilon&, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<1>(out) << "#E";
 }
 
-void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEmpty&) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
+void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEmpty&, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<1>(out) << "#0";
 }
 
-void RegExpToStringComposer::Visit(void* userData, const FormalRegExpAlternation& alternation) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Formal::visit( const FormalRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out ) {
 	Priority outerPriorityMinimum = std::get<0>(out);
 	if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '(';
 
 	std::get<0>(out) = Priority::ALTERNATION;
-	alternation.getLeftElement().Accept(userData, *this);
+	alternation.getLeftElement().accept<void, RegExpToStringComposer::Formal > (out);
 	std::get<1>(out) << '+';
-	alternation.getRightElement().Accept(userData, *this);
+	alternation.getRightElement().accept<void, RegExpToStringComposer::Formal > (out);
 
 	if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')';
 }
 
-void RegExpToStringComposer::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Formal::visit( const FormalRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & out ) {
 	Priority outerPriorityMinimum = std::get<0>(out);
 	if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '(';
 
 	std::get<0>(out) = Priority::CONCATENATION;
-	concatenation.getLeftElement().Accept(userData, *this);
+	concatenation.getLeftElement().accept<void, RegExpToStringComposer::Formal > (out);
 	std::get<1>(out) << ' ';
-	concatenation.getRightElement().Accept(userData, *this);
+	concatenation.getRightElement().accept<void, RegExpToStringComposer::Formal > (out);
 
 	if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')';
 }
 
-void RegExpToStringComposer::Visit(void* userData, const FormalRegExpIteration& iteration) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Formal::visit( const FormalRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<0>(out) = Priority::FACTOR;
-	iteration.getElement().Accept(userData, *this);
+	iteration.getElement().accept<void, RegExpToStringComposer::Formal > (out);
 	std::get<1>(out) << "*";
 }
 
-void RegExpToStringComposer::Visit(void* userData, const FormalRegExpSymbol& symbol) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
-
+void RegExpToStringComposer::Formal::visit( const FormalRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & out ) {
 	alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol());
 }
 
-void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEpsilon&) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
+void RegExpToStringComposer::Formal::visit( const FormalRegExpEpsilon&, std::tuple<Priority&, std::ostream &> & out ) {
 	std::get<1>(out) << "#E";
 }
 
-void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEmpty&) const {
-	std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData);
+void RegExpToStringComposer::Formal::visit( const FormalRegExpEmpty&, 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 4d74dbe4fc..6323c8dc2f 100644
--- a/alib2str/src/regexp/RegExpToStringComposer.h
+++ b/alib2str/src/regexp/RegExpToStringComposer.h
@@ -18,22 +18,8 @@
 
 namespace regexp {
 
-class RegExpToStringComposer : public std::SingleDispatchFirstStaticParam<RegExpToStringComposer, void, std::ostream&, const RegExpBase &>, UnboundedRegExpElement::Visitor, FormalRegExpElement::Visitor {
+class RegExpToStringComposer : public std::SingleDispatchFirstStaticParam<RegExpToStringComposer, void, std::ostream&, const RegExpBase &> {
 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;
-
 	enum class Priority {
 		ALTERNATION,
 		CONCATENATION,
@@ -52,6 +38,26 @@ public:
 	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);
+
+	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);
+	};
+
+	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);
+	};
 };
 
 } /* namespace regexp */
-- 
GitLab