diff --git a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
index a56757aeadd19601ca3f3637448ba72950454e0e..431a0291a4a41e16053b4d4c5966f6d30305bf14 100644
--- a/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
@@ -95,8 +95,7 @@ void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA& automat
 		const automaton::State q0 = automaton::createUniqueState(initState, automaton.getStates());
 		automaton.addState(q0);
 
-		regexp::UnboundedRegExp regexp;
-		regexp.setRegExp(regexp::UnboundedRegExpEpsilon());
+		regexp::UnboundedRegExp regexp { regexp::UnboundedRegExpEpsilon() };
 		automaton.addTransition(q0, regexp::RegExp{regexp}, initState);
 
 		automaton.setInitialState(q0);
@@ -110,8 +109,7 @@ void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA& automat
 		const std::set<automaton::State> automatonFinalStates = automaton.getFinalStates();
 		for(const auto &state : automatonFinalStates)
 		{
-			regexp::UnboundedRegExp regexp;
-			regexp.setRegExp(regexp::UnboundedRegExpEpsilon());
+			regexp::UnboundedRegExp regexp { regexp::UnboundedRegExpEpsilon() };
 			automaton.addTransition(state, regexp::RegExp{regexp}, f);
 
 			automaton.removeFinalState(state);
diff --git a/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
index a06ce7938f856f7eb84e050ddf89db10e26b7b04..838212229e13f517dca73903573390754c276d0c 100644
--- a/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
@@ -9,8 +9,7 @@ namespace regexp {
 
 namespace simplify {
 
-FormalRegExpElement* RegExpOptimize::optimize( FormalRegExpElement const * const & node ) const
-{
+FormalRegExpElement* RegExpOptimize::optimize( FormalRegExpElement const * const & node ) const {
 	FormalRegExpElement* elem = node->clone();
 
 	// optimize while you can
@@ -21,21 +20,20 @@ FormalRegExpElement* RegExpOptimize::optimize( FormalRegExpElement const * const
 	return elem;
 }
 
-bool RegExpOptimize::S( FormalRegExpElement * & node ) const
-{
+bool RegExpOptimize::S( FormalRegExpElement * & node ) const {
 	bool optimized = false;
 	FormalRegExpAlternation * alternation = dynamic_cast<FormalRegExpAlternation*>( node );
 	if( alternation ) {
-		FormalRegExpElement * tmp = optimize ( alternation->left.get() );
-		if(tmp != alternation->left.get()) {
+		FormalRegExpElement * tmp = optimize ( & alternation->getLeftElement ( ) );
+		if(* tmp != alternation->getLeftElement ( ) ) {
 			optimized = true;
-			alternation->left = std::smart_ptr < FormalRegExpElement > ( tmp );
+			alternation->setLeftElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
 		}
 
-		tmp = optimize ( alternation->right.get() );
-		if(tmp != alternation->right.get()) {
+		tmp = optimize ( & alternation->getRightElement ( ) );
+		if(* tmp != alternation->getRightElement ( ) ) {
 			optimized = true;
-			alternation->right = std::smart_ptr < FormalRegExpElement > ( tmp );
+			alternation->setRightElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
 		}
 
 		return optimized;
@@ -43,16 +41,16 @@ bool RegExpOptimize::S( FormalRegExpElement * & node ) const
 
 	FormalRegExpConcatenation * concatenation = dynamic_cast<FormalRegExpConcatenation*>( node );
 	if( concatenation ) {
-		FormalRegExpElement* tmp = optimize ( concatenation->left.get() );
-		if(tmp != concatenation->left.get()) {
+		FormalRegExpElement* tmp = optimize ( & concatenation->getLeftElement() );
+		if(* tmp != concatenation->getLeftElement ( ) ) {
 			optimized = true;
-			concatenation->left = std::smart_ptr < FormalRegExpElement > ( tmp );
+			concatenation->setLeftElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
 		}
 
-		tmp = optimize ( concatenation->right.get());
-		if(tmp != concatenation->right.get()) {
+		tmp = optimize ( & concatenation->getRightElement ( ));
+		if(* tmp != concatenation->getRightElement ( )) {
 			optimized = true;
-			concatenation->right = std::smart_ptr < FormalRegExpElement > ( tmp );
+			concatenation->setRightElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
 		}
 
 		return optimized;
@@ -60,13 +58,13 @@ bool RegExpOptimize::S( FormalRegExpElement * & node ) const
 
 	FormalRegExpIteration * iteration = dynamic_cast<FormalRegExpIteration*>( node );
 	if( iteration ) {
-		FormalRegExpElement* tmp = optimize ( iteration->element.get() );
+		FormalRegExpElement* tmp = optimize ( & iteration->getElement() );
 
-		if(tmp != iteration->element.get()) {
+		if(* tmp != iteration->getElement ( ) ) {
 			optimized = true;
-			iteration->element = std::smart_ptr < FormalRegExpElement > ( tmp );
+			iteration->setElement ( * std::smart_ptr < FormalRegExpElement > ( tmp ) );
 		}
-		return iteration;
+		return optimized;
 	}
 
 	return optimized;
@@ -78,23 +76,21 @@ bool RegExpOptimize::S( FormalRegExpElement * & node ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A1( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A1( FormalRegExpElement * & n ) const {
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpAlternation * leftAlt = dynamic_cast<FormalRegExpAlternation *>( node->left.get() );
+	if( dynamic_cast<FormalRegExpAlternation *>( node->getLeft().get() ) ) {
+		std::smart_ptr < FormalRegExpAlternation > leftAlt ( static_cast<FormalRegExpAlternation *>( node->getLeft().release() ) );
 
-	if( leftAlt ) {
-		leftAlt = static_cast<FormalRegExpAlternation *>( node->left.release() );
-		std::smart_ptr < FormalRegExpElement > x = std::move ( leftAlt->left );
-		std::smart_ptr < FormalRegExpElement > y = std::move ( leftAlt->right );
-		std::smart_ptr < FormalRegExpElement > z = std::move ( node->right );
+		std::smart_ptr < FormalRegExpElement > x = std::move ( leftAlt->getLeft() );
+		std::smart_ptr < FormalRegExpElement > y = std::move ( leftAlt->getRight() );
+		std::smart_ptr < FormalRegExpElement > z = std::move ( node->getRight() );
 
-		leftAlt->left = std::move ( y );
-		leftAlt->right = std::move ( z );
-		node->left = std::move ( x );
-		node->right = std::smart_ptr < FormalRegExpElement > ( leftAlt );
+		leftAlt->setLeft ( std::move ( y ) );
+		leftAlt->setRight ( std::move ( z ) );
+		node->setLeft ( std::move ( x ) );
+		node->setRight ( std::move ( leftAlt ) );
 
 		return true;
 	}
@@ -107,20 +103,23 @@ bool RegExpOptimize::A1( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A2( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A2( FormalRegExpElement * & n ) const {
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpAlternation * rightAlt = dynamic_cast<FormalRegExpAlternation *>( node->right.get() );
+	if( dynamic_cast<FormalRegExpAlternation *>( node->getRight().get() ) ) {
+		FormalRegExpAlternation * rightAlt = static_cast < FormalRegExpAlternation * > ( node->getRight ( ).get ( ) );
 
-	if( rightAlt ) {
-		FormalRegExpElement * x = node->left.get();
-		FormalRegExpElement * y = rightAlt->left.get();
+		std::smart_ptr < FormalRegExpElement > x = std::move ( node->getLeft ( ) );
+		std::smart_ptr < FormalRegExpElement > y = std::move ( rightAlt->getLeft ( ) );
 
 		if(*x > *y) {
-			std::swap ( node->left, rightAlt->left );
+			node->setLeft ( std::move ( y ) );
+			rightAlt->setLeft ( std::move ( x ) );
+			return true;
 		} else {
+			node->setLeft ( std::move ( x ) );
+			rightAlt->setLeft ( std::move ( y ) );
 			return false;
 		}
 	}
@@ -133,25 +132,20 @@ bool RegExpOptimize::A2( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A3( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A3( FormalRegExpElement * & n ) const {
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
 	// input can be \0 + \0, so at least one element must be preserved
 
-	FormalRegExpEmpty * rightEmp = dynamic_cast<FormalRegExpEmpty *>( node->right.get() );
-	if( rightEmp ) {
-		rightEmp = nullptr;
-		n = node->left.release();
+	if( dynamic_cast<FormalRegExpEmpty *>( node->getRight().get() ) ) {
+		n = node->getLeft().release();
 		delete node;
 		return true;
 	}
 
-	FormalRegExpEmpty * leftEmp = dynamic_cast<FormalRegExpEmpty *>( node->left.release() );
-	if( leftEmp ) {
-		leftEmp = nullptr;
-		n = node->right.release();
+	if( dynamic_cast<FormalRegExpEmpty *>( node->getLeft().get() ) ) {
+		n = node->getRight().release();
 		delete node;
 		return true;
 	}
@@ -164,8 +158,7 @@ bool RegExpOptimize::A3( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A4( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A4( FormalRegExpElement * & n ) const {
 	/*
 	 * two ways of implementing this opitimization:
 	 * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts...
@@ -177,9 +170,8 @@ bool RegExpOptimize::A4( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	if( *node->left == *node->right ) {
-		delete node->left.release();
-		n = node->right.release();
+	if( node->getLeftElement() == node->getRightElement() ) {
+		n = node->getRight().release();
 		delete node;
 		return true;
 	}
@@ -192,23 +184,21 @@ bool RegExpOptimize::A4( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A5( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A5( FormalRegExpElement * & n ) const {
 	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->left.get() );
+	if( dynamic_cast<FormalRegExpConcatenation *>( node->getLeft().get() ) ) {
+		std::smart_ptr < FormalRegExpConcatenation > leftCon ( static_cast<FormalRegExpConcatenation *>( node->getLeft().release() ) );
 
-	if( leftCon ) {
-		leftCon = static_cast<FormalRegExpConcatenation *>( node->left.release() );
-		std::smart_ptr < FormalRegExpElement > x = std::move ( leftCon->left );
-		std::smart_ptr < FormalRegExpElement > y = std::move ( leftCon->right );
-		std::smart_ptr < FormalRegExpElement > z = std::move ( node->right );
+		std::smart_ptr < FormalRegExpElement > x = std::move ( leftCon->getLeft() );
+		std::smart_ptr < FormalRegExpElement > y = std::move ( leftCon->getRight() );
+		std::smart_ptr < FormalRegExpElement > z = std::move ( node->getRight() );
 
-		leftCon->left = std::move ( y );
-		leftCon->right = std::move ( z );
-		node->left = std::move ( x );
-		node->right = std::smart_ptr < FormalRegExpElement > ( leftCon );
+		leftCon->setLeft ( std::move ( y ) );
+		leftCon->setRight ( std::move ( z ) );
+		node->setLeft ( std::move ( x ) );
+		node->setRight ( std::move ( leftCon ) );
 
 		return true;
 	}
@@ -221,25 +211,20 @@ bool RegExpOptimize::A5( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A6( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A6( FormalRegExpElement * & n ) const {
 	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
 	if( ! node ) return false;
 
 	// input can be \e + \e, so at least one element must be preserved
 
-	FormalRegExpEpsilon * rightEmp = dynamic_cast<FormalRegExpEpsilon *>( node->right.get() );
-	if( rightEmp ) {
-		rightEmp = nullptr;
-		n = node->left.release();
+	if( dynamic_cast<FormalRegExpEpsilon *>( node->getRight().get() ) ) {
+		n = node->getLeft().release();
 		delete node;
 		return true;
 	}
 
-	FormalRegExpEpsilon * leftEmp = dynamic_cast<FormalRegExpEpsilon *>( node->left.get() );
-	if( leftEmp ) {
-		leftEmp = nullptr;
-		n = node->right.release();
+	if( dynamic_cast<FormalRegExpEpsilon *>( node->getLeft().get() ) ) {
+		n = node->getRight().release();
 		delete node;
 		return true;
 	}
@@ -252,12 +237,11 @@ bool RegExpOptimize::A6( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A7( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A7( FormalRegExpElement * & n ) const {
 	FormalRegExpConcatenation * node = dynamic_cast<FormalRegExpConcatenation *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpEmpty *>( node->right.get() ) || dynamic_cast<FormalRegExpEmpty *>( node->left.get() ) ) {
+	if( dynamic_cast<FormalRegExpEmpty *>( node->getRight().get() ) || dynamic_cast<FormalRegExpEmpty *>( node->getLeft().get() ) ) {
 		delete node;
 		n = new FormalRegExpEmpty { };
 		return true;
@@ -271,8 +255,7 @@ bool RegExpOptimize::A7( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A8( FormalRegExpElement * & /* n */) const
-{
+bool RegExpOptimize::A8( FormalRegExpElement * & /* n */) const {
 	return false; //TODO
 }
 
@@ -281,8 +264,7 @@ bool RegExpOptimize::A8( FormalRegExpElement * & /* n */) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A9( FormalRegExpElement * & /* n */) const
-{
+bool RegExpOptimize::A9( FormalRegExpElement * & /* n */) const {
 	return false; //TODO
 }
 
@@ -291,8 +273,7 @@ bool RegExpOptimize::A9( FormalRegExpElement * & /* n */) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A10( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A10( FormalRegExpElement * & n ) const {
 	/*
 	 * problem:
 	 * - \e + x*x = x*
@@ -302,48 +283,46 @@ bool RegExpOptimize::A10( FormalRegExpElement * & n ) const
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpEpsilon * leftEps = dynamic_cast<FormalRegExpEpsilon *>( node->left.get() );
-	if( leftEps ) {
-		FormalRegExpConcatenation * rightCon = dynamic_cast<FormalRegExpConcatenation *>( node->right.get() );
+	if( dynamic_cast<FormalRegExpEpsilon *>( node->getLeft().get() ) ) {
+		FormalRegExpConcatenation * rightCon = dynamic_cast<FormalRegExpConcatenation *>( node->getRight().get() );
 		if( ! rightCon ) return false;
 
-		FormalRegExpIteration * rightLeftIte = dynamic_cast<FormalRegExpIteration *>( rightCon->left.get() );
+		FormalRegExpIteration * rightLeftIte = dynamic_cast<FormalRegExpIteration *>( rightCon->getLeft().get() );
 		if( rightLeftIte ) {
-			if(*rightLeftIte->element == *rightCon->right) {
-				n = rightCon->left.release();
+			if(rightLeftIte->getElement() == rightCon->getRightElement()) {
+				n = rightCon->getLeft().release();
 				delete node;
 				return true;
 			}
 		}
 
-		FormalRegExpIteration * rightRightIte = dynamic_cast<FormalRegExpIteration *>( rightCon->right.get() );
+		FormalRegExpIteration * rightRightIte = dynamic_cast<FormalRegExpIteration *>( rightCon->getRight().get() );
 		if( rightRightIte ) {
-			if(*rightLeftIte->element == *rightCon->left) {
-				n = rightCon->right.release();
+			if(rightRightIte->getElement() == rightCon->getLeftElement()) {
+				n = rightCon->getRight().release();
 				delete node;
 				return true;
 			}
 		}
 	}
 
-	FormalRegExpEpsilon * rightEps = dynamic_cast<FormalRegExpEpsilon *>( node->right.get() );
-	if( rightEps ) {
-		FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->left.get() );
+	if( dynamic_cast<FormalRegExpEpsilon *>( node->getRight().get() ) ) {
+		FormalRegExpConcatenation * leftCon = dynamic_cast<FormalRegExpConcatenation *>( node->getLeft().get() );
 		if( ! leftCon ) return false;
 
-		FormalRegExpIteration * leftLeftIte = dynamic_cast<FormalRegExpIteration *>( leftCon->left.get() );
+		FormalRegExpIteration * leftLeftIte = dynamic_cast<FormalRegExpIteration *>( leftCon->getLeft().get() );
 		if( leftLeftIte ) {
-			if(*leftLeftIte->element == *leftCon->right) {
-				n = leftCon->left.release();
+			if(leftLeftIte->getElement() == leftCon->getRightElement()) {
+				n = leftCon->getLeft().release();
 				delete node;
 				return true;
 			}
 		}
 
-		FormalRegExpIteration * leftRightIte = dynamic_cast<FormalRegExpIteration *>( leftCon->right.get() );
+		FormalRegExpIteration * leftRightIte = dynamic_cast<FormalRegExpIteration *>( leftCon->getRight().get() );
 		if( leftRightIte ) {
-			if(*leftLeftIte->element == *leftCon->left) {
-				n = leftCon->right.release();
+			if(leftRightIte->getElement() == leftCon->getLeftElement()) {
+				n = leftCon->getRight().release();
 				delete node;
 				return true;
 			}
@@ -358,20 +337,18 @@ bool RegExpOptimize::A10( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::A11( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::A11( FormalRegExpElement * & n ) const {
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpAlternation * childAlt = dynamic_cast<FormalRegExpAlternation *>( node->element.get() );
-	if( childAlt )
-	{
-		if(dynamic_cast<FormalRegExpEpsilon*>(childAlt->left.get())) {
-			node->element = std::move ( childAlt->right );
+	FormalRegExpAlternation * childAlt = dynamic_cast<FormalRegExpAlternation *>( node->getChild().get() );
+	if( childAlt ) {
+		if( dynamic_cast < FormalRegExpEpsilon * > ( childAlt->getLeft ( ).get ( ) ) ) {
+			node->setChild ( std::move ( childAlt->getRight ( ) ) );
 			return true;
 		}
-		if(dynamic_cast<FormalRegExpEpsilon*>(childAlt->right.get())) {
-			node->element = std::move ( childAlt->left );
+		if( dynamic_cast < FormalRegExpEpsilon * > ( childAlt->getRight ( ).get ( ) ) ) {
+			node->setChild ( std::move ( childAlt->getLeft ( ) ) );
 			return true;
 		}
 	}
@@ -384,13 +361,11 @@ bool RegExpOptimize::A11( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V1( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::V1( FormalRegExpElement * & n ) const {
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	if( dynamic_cast<FormalRegExpEmpty*>( node->element.get() ) )
-	{
+	if( dynamic_cast<FormalRegExpEmpty*>( node->getChild ( ).get() ) ) {
 		delete node;
 		n = new FormalRegExpEpsilon( );
 		return true;
@@ -403,24 +378,23 @@ bool RegExpOptimize::V1( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V2( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::V2( FormalRegExpElement * & n ) const {
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left.get() );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->getLeft().get() );
 	if( leftIte ) {
-		if(*leftIte->element == *node->right) {
-			n = node->left.release();
+		if(leftIte->getElement() == node->getRightElement()) {
+			n = node->getLeft().release();
 			delete node;
 			return true;
 		}
 	}
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right.get() );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->getRight().get() );
 	if( rightIte ) {
-		if(*rightIte->element == *node->left) {
-			n = node->right.release();
+		if(rightIte->getElement() == node->getLeftElement()) {
+			n = node->getRight().release();
 			delete node;
 			return true;
 		}
@@ -434,15 +408,13 @@ bool RegExpOptimize::V2( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V3( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::V3( FormalRegExpElement * & n ) const {
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration* childIter = dynamic_cast<FormalRegExpIteration*>( node->element.get() );
-	if( childIter )
-	{
-		node->element = std::move ( childIter->element );
+	FormalRegExpIteration* childIter = dynamic_cast<FormalRegExpIteration*>( node->getChild().get() );
+	if( childIter ) {
+		node->setChild ( std::move ( childIter->getChild ( ) ) );
 		return true;
 	}
 
@@ -454,21 +426,20 @@ bool RegExpOptimize::V3( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V4( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::V4( FormalRegExpElement * & n ) const {
 	FormalRegExpIteration * node = dynamic_cast<FormalRegExpIteration *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpConcatenation * child = dynamic_cast<FormalRegExpConcatenation *>( node->element.get() );
+	FormalRegExpConcatenation * child = dynamic_cast<FormalRegExpConcatenation *>( node->getChild().get() );
 	if( ! child ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( child->left.get() );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( child->getLeft().get() );
 	if( ! leftIte ) return false;
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( child->right.get() );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( child->getRight().get() );
 	if( ! rightIte ) return false;
 
-	n = new FormalRegExpIteration( FormalRegExpAlternation(std::move( * leftIte->element ), std::move( * rightIte->element)));
+	n = new FormalRegExpIteration( FormalRegExpAlternation(std::move( leftIte->getElement ( ) ), std::move( rightIte->getElement ( ) ) ) );
 
 	delete node;
 	return true;
@@ -479,8 +450,7 @@ bool RegExpOptimize::V4( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V5( FormalRegExpElement * & /* n */) const
-{
+bool RegExpOptimize::V5( FormalRegExpElement * & /* n */) const {
 	return false; //TODO
 }
 
@@ -489,8 +459,7 @@ bool RegExpOptimize::V5( FormalRegExpElement * & /* n */) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V6( FormalRegExpElement * & /* n */) const
-{
+bool RegExpOptimize::V6( FormalRegExpElement * & /* n */) const {
 	return false; //TODO
 }
 
@@ -499,8 +468,7 @@ bool RegExpOptimize::V6( FormalRegExpElement * & /* n */) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V8( FormalRegExpElement * & /* n */) const
-{
+bool RegExpOptimize::V8( FormalRegExpElement * & /* n */) const {
 	return false; //TODO
 }
 
@@ -509,8 +477,7 @@ bool RegExpOptimize::V8( FormalRegExpElement * & /* n */) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V9( FormalRegExpElement * & /* n */) const
-{
+bool RegExpOptimize::V9( FormalRegExpElement * & /* n */) const {
 	return false; //TODO
 }
 
@@ -519,18 +486,17 @@ bool RegExpOptimize::V9( FormalRegExpElement * & /* n */) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::V10( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::V10( FormalRegExpElement * & n ) const {
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left.get() );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->getLeft().get() );
 	if( ! leftIte ) return false;
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right.get() );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->getRight().get() );
 	if( ! rightIte ) return false;
 
-	n = new FormalRegExpConcatenation(std::move( * leftIte->element ), std::move( * rightIte->element ) );
+	n = new FormalRegExpConcatenation(std::move( leftIte->getElement() ), std::move( rightIte->getElement() ) );
 
 	delete node;
 	return true;
@@ -541,24 +507,23 @@ bool RegExpOptimize::V10( FormalRegExpElement * & n ) const
   * @param node FormalRegExpElement node
   * @return bool true if optimization applied else false
   */
-bool RegExpOptimize::X1( FormalRegExpElement * & n ) const
-{
+bool RegExpOptimize::X1( FormalRegExpElement * & n ) const {
 	FormalRegExpAlternation * node = dynamic_cast<FormalRegExpAlternation *>( n );
 	if( ! node ) return false;
 
-	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->left.get() );
+	FormalRegExpIteration * leftIte = dynamic_cast<FormalRegExpIteration *>( node->getLeft().get() );
 	if( leftIte ) {
-		if(dynamic_cast<FormalRegExpEpsilon*>(node->right.get())) {
-			n = node->left.release();
+		if(dynamic_cast<FormalRegExpEpsilon*>(node->getRight().get())) {
+			n = node->getLeft().release();
 			delete node;
 			return true;
 		}
 	}
 
-	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->right.get() );
+	FormalRegExpIteration * rightIte = dynamic_cast<FormalRegExpIteration *>( node->getRight().get() );
 	if( rightIte ) {
-		if(dynamic_cast<FormalRegExpEpsilon*>(node->left.get())) {
-			n = node->right.release();
+		if(dynamic_cast<FormalRegExpEpsilon*>(node->getLeft().get())) {
+			n = node->getRight().release();
 			delete node;
 			return true;
 		}
diff --git a/alib2data/src/regexp/formal/FormalRegExp.cpp b/alib2data/src/regexp/formal/FormalRegExp.cpp
index 34b278604c292d4e9e475b5f5b459d4dbe11d1e8..5e89e7de567cd585dddb1deb0ca6ace0afc5615e 100644
--- a/alib2data/src/regexp/formal/FormalRegExp.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExp.cpp
@@ -44,14 +44,6 @@ FormalRegExp::FormalRegExp ( const FormalRegExpElement & regExp ) : FormalRegExp
 FormalRegExp::FormalRegExp ( const UnboundedRegExp & other ) : FormalRegExp ( other.getAlphabet ( ), std::move ( * other.getRegExp ( ).asFormal ( ) ) ) {
 }
 
-FormalRegExp::FormalRegExp ( const FormalRegExp & other ) : std::Components < FormalRegExp, alphabet::Symbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( other.getAlphabet ( ) ), std::tuple < > ( ) ), regExp ( other.regExp ) {
-	this->regExp->attachRegExp ( this );
-}
-
-FormalRegExp::FormalRegExp ( FormalRegExp && other ) noexcept : std::Components < FormalRegExp, alphabet::Symbol, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::move ( other.accessComponent < GeneralAlphabet > ( ).get ( ) ) ), std::tuple < > ( ) ), regExp ( std::move ( other.regExp ) ) {
-	this->regExp->attachRegExp ( this );
-}
-
 RegExpBase * FormalRegExp::clone ( ) const {
 	return new FormalRegExp ( * this );
 }
@@ -60,25 +52,6 @@ RegExpBase * FormalRegExp::plunder ( ) && {
 	return new FormalRegExp ( std::move ( * this ) );
 }
 
-FormalRegExp & FormalRegExp::operator =( const FormalRegExp & other ) {
-	if ( this == & other )
-		return * this;
-
-	* this = FormalRegExp ( other );
-
-	return * this;
-}
-
-FormalRegExp & FormalRegExp::operator =( FormalRegExp && other ) noexcept {
-	std::swap ( this->regExp, other.regExp );
-	std::swap ( accessComponent < GeneralAlphabet > ( ).get ( ), other.accessComponent < GeneralAlphabet > ( ).get ( ) );
-
-	return * this;
-}
-
-FormalRegExp::~FormalRegExp ( ) noexcept {
-}
-
 const FormalRegExpElement & FormalRegExp::getRegExp ( ) const {
 	return * regExp;
 }
@@ -94,7 +67,7 @@ void FormalRegExp::setRegExp ( const FormalRegExpElement & regExp ) {
 void FormalRegExp::setRegExp ( FormalRegExpElement && param ) {
 	this->regExp = std::smart_ptr < FormalRegExpElement > ( std::move ( param ).plunder ( ) );
 
-	if ( !regExp->attachRegExp ( this ) )
+	if ( !regExp->checkAlphabet ( getAlphabet ( ) ) )
 		throw exception::CommonException ( "Input symbols not in the alphabet." );
 }
 
diff --git a/alib2data/src/regexp/formal/FormalRegExp.h b/alib2data/src/regexp/formal/FormalRegExp.h
index 86fad7b7dabe9868a6eaa6b31d4793c90270b2cf..f3e90fc68731d9e542f07a9634e87a86d2ee8e90 100644
--- a/alib2data/src/regexp/formal/FormalRegExp.h
+++ b/alib2data/src/regexp/formal/FormalRegExp.h
@@ -48,16 +48,6 @@ public:
 	explicit FormalRegExp ( const FormalRegExpElement & regExp );
 	explicit FormalRegExp ( const UnboundedRegExp & other );
 
-	/**
-	 * Copy constructor.
-	 * @param other RegExp to copy
-	 */
-	FormalRegExp ( const FormalRegExp & other );
-	FormalRegExp ( FormalRegExp && other ) noexcept;
-	FormalRegExp & operator =( const FormalRegExp & other );
-	FormalRegExp & operator =( FormalRegExp && other ) noexcept;
-	~FormalRegExp ( ) noexcept;
-
 	/**
 	 * @return Root node of the regular expression tree
 	 */
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
index 61b5c57284498483c06df80dc0e915e515284eef..d77b5973bae5c4a3dabc92eab251394a0c7e9bd0 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.cpp
@@ -12,65 +12,30 @@
 
 namespace regexp {
 
-FormalRegExpAlternation::FormalRegExpAlternation ( FormalRegExpElement && leftElement, FormalRegExpElement && rightElement ) : left ( nullptr ), right ( nullptr ) {
-	setLeftElement ( std::move ( leftElement ) );
-	setRightElement ( std::move ( rightElement ) );
+FormalRegExpAlternation::FormalRegExpAlternation ( FormalRegExpElement && leftElement, FormalRegExpElement && rightElement ) : BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpAlternation > ( std::smart_ptr < FormalRegExpElement > ( std::move ( leftElement ).plunder ( ) ), std::smart_ptr < FormalRegExpElement > ( std::move ( rightElement ).plunder ( ) ) ) {
 }
 
 FormalRegExpAlternation::FormalRegExpAlternation ( const FormalRegExpElement & left, const FormalRegExpElement & right ) : FormalRegExpAlternation ( std::move_copy ( left ), std::move_copy ( right ) ) {
 }
 
-FormalRegExpAlternation::FormalRegExpAlternation ( const FormalRegExpAlternation & other ) : left ( other.left ), right ( other.right ) {
-}
-
-FormalRegExpAlternation::FormalRegExpAlternation ( FormalRegExpAlternation && other ) noexcept : left ( std::move ( other.left ) ), right ( std::move ( other.right ) ) {
-	left->attachRegExp ( NULL );
-	right->attachRegExp ( NULL );
-}
-
-FormalRegExpAlternation & FormalRegExpAlternation::operator =( const FormalRegExpAlternation & other ) {
-	if ( this == & other )
-		return * this;
-
-	* this = FormalRegExpAlternation ( other );
-
-	return * this;
-}
-
-FormalRegExpAlternation & FormalRegExpAlternation::operator =( FormalRegExpAlternation && other ) noexcept {
-	std::swap ( this->left, other.left );
-	std::swap ( this->right, other.right );
-
-	this->left->attachRegExp ( this->parentRegExp );
-	this->right->attachRegExp ( this->parentRegExp );
-
-	return * this;
-}
-
-FormalRegExpAlternation::~FormalRegExpAlternation ( ) noexcept {
-}
-
 const FormalRegExpElement & FormalRegExpAlternation::getLeftElement ( ) const {
-	return * left;
+	return * getLeft ( );
 }
 
 const FormalRegExpElement & FormalRegExpAlternation::getRightElement ( ) const {
-	return * right;
+	return * getRight ( );
 }
 
 FormalRegExpElement & FormalRegExpAlternation::getLeftElement ( ) {
-	return * left;
+	return * getLeft ( );
 }
 
 FormalRegExpElement & FormalRegExpAlternation::getRightElement ( ) {
-	return * right;
+	return * getRight ( );
 }
 
 void FormalRegExpAlternation::setLeftElement ( FormalRegExpElement && element ) {
-	this->left = std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) );
-
-	if ( this->parentRegExp && !left->attachRegExp ( this->parentRegExp ) )
-		throw exception::CommonException ( "Input symbols not in the alphabet." );
+	setLeft ( std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) ) );
 }
 
 void FormalRegExpAlternation::setLeftElement ( const FormalRegExpElement & element ) {
@@ -78,10 +43,7 @@ void FormalRegExpAlternation::setLeftElement ( const FormalRegExpElement & eleme
 }
 
 void FormalRegExpAlternation::setRightElement ( FormalRegExpElement && element ) {
-	this->right = std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) );
-
-	if ( this->parentRegExp && !right->attachRegExp ( this->parentRegExp ) )
-		throw exception::CommonException ( "Input symbols not in the alphabet." );
+	setRight ( std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) ) );
 }
 
 void FormalRegExpAlternation::setRightElement ( const FormalRegExpElement & element ) {
@@ -99,45 +61,42 @@ FormalRegExpElement * FormalRegExpAlternation::plunder ( ) && {
 std::smart_ptr < UnboundedRegExpElement > FormalRegExpAlternation::asUnbounded ( ) const {
 	UnboundedRegExpAlternation * res = new UnboundedRegExpAlternation ( );
 
-	res->appendElement ( std::move ( * left->asUnbounded ( ) ) );
-	res->appendElement ( std::move ( * right->asUnbounded ( ) ) );
+	res->appendElement ( std::move ( * getLeftElement ( ).asUnbounded ( ) ) );
+	res->appendElement ( std::move ( * getRightElement ( ).asUnbounded ( ) ) );
 
 	return std::smart_ptr < UnboundedRegExpElement > ( res );
 }
 
 int FormalRegExpAlternation::compare ( const FormalRegExpAlternation & other ) const {
-	int res = left->compare ( * other.left );
+	int res = getLeftElement ( ).compare ( other.getLeftElement ( ) );
 
-	if ( res == 0 ) res = right->compare ( * other.right );
+	if ( res == 0 ) res = getRightElement ( ).compare ( other.getRightElement ( ) );
 
 	return res;
 }
 
 void FormalRegExpAlternation::operator >>( std::ostream & out ) const {
 	out << "(FormalRegExpAlternation";
-	out << " " << * left;
-	out << " " << * right;
+	out << " " << getLeft ( );
+	out << " " << getRight ( );
 	out << ")";
 }
 
 bool FormalRegExpAlternation::testSymbol ( const alphabet::Symbol & symbol ) const {
-	if ( left->testSymbol ( symbol ) ) return true;
+	if ( getLeft ( )->testSymbol ( symbol ) ) return true;
 
-	if ( right->testSymbol ( symbol ) ) return true;
+	if ( getRight ( )->testSymbol ( symbol ) ) return true;
 
 	return false;
 }
 
-bool FormalRegExpAlternation::attachRegExp ( const FormalRegExp * regexp ) {
-	if ( this->parentRegExp == regexp ) return true;
-
-	this->parentRegExp = regexp;
-	return left->attachRegExp ( regexp ) && right->attachRegExp ( regexp );
+void FormalRegExpAlternation::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
+	getLeftElement ( ).computeMinimalAlphabet ( alphabet );
+	getRightElement ( ).computeMinimalAlphabet ( alphabet );
 }
 
-void FormalRegExpAlternation::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
-	left->computeMinimalAlphabet ( alphabet );
-	right->computeMinimalAlphabet ( alphabet );
+bool FormalRegExpAlternation::checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const {
+	return getLeftElement ( ).checkAlphabet ( alphabet ) && getRightElement ( ).checkAlphabet ( alphabet );
 }
 
 FormalRegExpAlternation::operator std::string ( ) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
index ed47a69605b289aed0816ad3905866934684d540..d1e341bee89510b4107a99e50c1aed454a6ae177 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
@@ -23,16 +23,7 @@ class RegExpOptimize;
  * Represents alternation operator in the regular expression. Contains list of FormalRegExpElement
  * as operands of the operator.
  */
-class FormalRegExpAlternation : public FormalRegExpElement {
-protected:
-	std::smart_ptr < FormalRegExpElement > left;
-	std::smart_ptr < FormalRegExpElement > right;
-
-	/**
-	 * @copydoc FormalRegExpElement::attachRegExp()
-	 */
-	virtual bool attachRegExp ( const FormalRegExp * regexp );
-
+class FormalRegExpAlternation : public FormalRegExpElement, public std::BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpAlternation > {
 public:
 	void Accept ( void * userData, const FormalRegExpElementVisitor & visitor ) const {
 		visitor.Visit ( userData, * this );
@@ -42,13 +33,6 @@ public:
 
 	explicit FormalRegExpAlternation ( const FormalRegExpElement & left, const FormalRegExpElement & right );
 
-	FormalRegExpAlternation ( const FormalRegExpAlternation & other );
-	FormalRegExpAlternation ( FormalRegExpAlternation && other ) noexcept;
-	FormalRegExpAlternation & operator =( const FormalRegExpAlternation & other );
-	FormalRegExpAlternation & operator =( FormalRegExpAlternation && other ) noexcept;
-
-	virtual ~FormalRegExpAlternation ( ) noexcept;
-
 	/**
 	 * @copydoc FormalRegExpElement::clone() const
 	 */
@@ -74,6 +58,11 @@ public:
 	 */
 	virtual void computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const;
 
+	/**
+	 * @copydoc FormalRegExpElement::checkAlphabet()
+	 */
+	virtual bool checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const;
+
 	/**
 	 * @return elements
 	 */
@@ -111,8 +100,6 @@ public:
 	 */
 	virtual void operator >>( std::ostream & out ) const;
 
-	friend class simplify::RegExpOptimize;
-
 	virtual explicit operator std::string ( ) const;
 };
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
index bc494f0ee1b0e26230d2bbbee2cfcb9d415b07a1..2086479799e014278e327c3cab4a5b4be872822a 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.cpp
@@ -11,65 +11,30 @@
 
 namespace regexp {
 
-FormalRegExpConcatenation::FormalRegExpConcatenation ( FormalRegExpElement && leftElement, FormalRegExpElement && rightElement ) : left ( nullptr ), right ( nullptr ) {
-	setLeftElement ( std::move ( leftElement ) );
-	setRightElement ( std::move ( rightElement ) );
+FormalRegExpConcatenation::FormalRegExpConcatenation ( FormalRegExpElement && leftElement, FormalRegExpElement && rightElement ) : BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpConcatenation > ( std::smart_ptr < FormalRegExpElement > ( std::move ( leftElement ).plunder ( ) ), std::smart_ptr < FormalRegExpElement > ( std::move ( rightElement ).plunder ( ) ) ) {
 }
 
 FormalRegExpConcatenation::FormalRegExpConcatenation ( const FormalRegExpElement & left, const FormalRegExpElement & right ) : FormalRegExpConcatenation ( std::move_copy ( left ), std::move_copy ( right ) ) {
 }
 
-FormalRegExpConcatenation::FormalRegExpConcatenation ( const FormalRegExpConcatenation & other ) : left ( other.left ), right ( other.right ) {
-}
-
-FormalRegExpConcatenation::FormalRegExpConcatenation ( FormalRegExpConcatenation && other ) noexcept : left ( std::move ( other.left ) ), right ( std::move ( other.right ) ) {
-	left->attachRegExp ( NULL );
-	right->attachRegExp ( NULL );
-}
-
-FormalRegExpConcatenation & FormalRegExpConcatenation::operator =( const FormalRegExpConcatenation & other ) {
-	if ( this == & other )
-		return * this;
-
-	* this = FormalRegExpConcatenation ( other );
-
-	return * this;
-}
-
-FormalRegExpConcatenation & FormalRegExpConcatenation::operator =( FormalRegExpConcatenation && other ) noexcept {
-	std::swap ( this->left, other.left );
-	std::swap ( this->right, other.right );
-
-	this->left->attachRegExp ( this->parentRegExp );
-	this->right->attachRegExp ( this->parentRegExp );
-
-	return * this;
-}
-
-FormalRegExpConcatenation::~FormalRegExpConcatenation ( ) noexcept {
-}
-
 const FormalRegExpElement & FormalRegExpConcatenation::getLeftElement ( ) const {
-	return * left;
+	return * getLeft ( );
 }
 
 const FormalRegExpElement & FormalRegExpConcatenation::getRightElement ( ) const {
-	return * right;
+	return * getRight ( );
 }
 
 FormalRegExpElement & FormalRegExpConcatenation::getLeftElement ( ) {
-	return * left;
+	return * getLeft ( );
 }
 
 FormalRegExpElement & FormalRegExpConcatenation::getRightElement ( ) {
-	return * right;
+	return * getRight ( );
 }
 
 void FormalRegExpConcatenation::setLeftElement ( FormalRegExpElement && element ) {
-	this->left = std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) );
-
-	if ( this->parentRegExp && !left->attachRegExp ( this->parentRegExp ) )
-		throw exception::CommonException ( "Input symbols not in the alphabet." );
+	setLeft( std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) ) );
 }
 
 void FormalRegExpConcatenation::setLeftElement ( const FormalRegExpElement & element ) {
@@ -77,10 +42,7 @@ void FormalRegExpConcatenation::setLeftElement ( const FormalRegExpElement & ele
 }
 
 void FormalRegExpConcatenation::setRightElement ( FormalRegExpElement && element ) {
-	this->right = std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) );
-
-	if ( this->parentRegExp && !right->attachRegExp ( this->parentRegExp ) )
-		throw exception::CommonException ( "Input symbols not in the alphabet." );
+	setRight ( std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) ) );
 }
 
 void FormalRegExpConcatenation::setRightElement ( const FormalRegExpElement & element ) {
@@ -94,8 +56,8 @@ FormalRegExpElement * FormalRegExpConcatenation::clone ( ) const {
 std::smart_ptr < UnboundedRegExpElement > FormalRegExpConcatenation::asUnbounded ( ) const {
 	UnboundedRegExpConcatenation * res = new UnboundedRegExpConcatenation ( );
 
-	res->appendElement ( * left->asUnbounded ( ) );
-	res->appendElement ( * right->asUnbounded ( ) );
+	res->appendElement ( std::move ( * getLeftElement ( ).asUnbounded ( ) ) );
+	res->appendElement ( std::move ( * getRightElement ( ).asUnbounded ( ) ) );
 
 	return std::smart_ptr < UnboundedRegExpElement > ( res );
 }
@@ -105,34 +67,31 @@ FormalRegExpElement * FormalRegExpConcatenation::plunder ( ) && {
 }
 
 int FormalRegExpConcatenation::compare ( const FormalRegExpConcatenation & other ) const {
-	int res = left->compare ( * other.left );
+	int res = getLeftElement ( ).compare ( other.getLeftElement ( ) );
 
-	if ( res == 0 ) res = right->compare ( * other.right );
+	if ( res == 0 ) res = getRightElement ( ).compare ( other.getRightElement ( ) );
 
 	return res;
 }
 
 void FormalRegExpConcatenation::operator >>( std::ostream & out ) const {
 	out << "(FormalRegExpConcatenation";
-	out << " " << * left;
-	out << " " << * right;
+	out << " " << getLeft ( );
+	out << " " << getRight ( );
 	out << ")";
 }
 
 bool FormalRegExpConcatenation::testSymbol ( const alphabet::Symbol & symbol ) const {
-	return left->testSymbol ( symbol ) && right->testSymbol ( symbol );
+	return getLeft ( )->testSymbol ( symbol ) && getRight ( )->testSymbol ( symbol );
 }
 
-bool FormalRegExpConcatenation::attachRegExp ( const FormalRegExp * regexp ) {
-	if ( this->parentRegExp == regexp ) return true;
-
-	this->parentRegExp = regexp;
-	return left->attachRegExp ( regexp ) && right->attachRegExp ( regexp );
+void FormalRegExpConcatenation::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
+	getLeftElement ( ).computeMinimalAlphabet ( alphabet );
+	getRightElement ( ).computeMinimalAlphabet ( alphabet );
 }
 
-void FormalRegExpConcatenation::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
-	left->computeMinimalAlphabet ( alphabet );
-	right->computeMinimalAlphabet ( alphabet );
+bool FormalRegExpConcatenation::checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const {
+	return getLeftElement ( ).checkAlphabet ( alphabet ) && getRightElement ( ).checkAlphabet ( alphabet );
 }
 
 FormalRegExpConcatenation::operator std::string ( ) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
index 6ec455ce9961d226d6c860a223b95d8424a55fe0..fa2bb726987bf70a7a3bf9970dbcc50f579fa907 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
@@ -25,16 +25,7 @@ class RegExpOptimize;
  * Represents concatenation operator in the regular expression. Contains list of FormalRegExpElement
  * as operands of the operator.
  */
-class FormalRegExpConcatenation : public FormalRegExpElement {
-protected:
-	std::smart_ptr < FormalRegExpElement > left;
-	std::smart_ptr < FormalRegExpElement > right;
-
-	/**
-	 * @copydoc FormalRegExpElement::attachRegExp()
-	 */
-	virtual bool attachRegExp ( const FormalRegExp * regexp );
-
+class FormalRegExpConcatenation : public FormalRegExpElement, public std::BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpConcatenation > {
 public:
 	void Accept ( void * userData, const FormalRegExpElementVisitor & visitor ) const {
 		visitor.Visit ( userData, * this );
@@ -43,12 +34,6 @@ public:
 	explicit FormalRegExpConcatenation ( FormalRegExpElement && left, FormalRegExpElement && right );
 	explicit FormalRegExpConcatenation ( const FormalRegExpElement & left, const FormalRegExpElement & right );
 
-	FormalRegExpConcatenation ( const FormalRegExpConcatenation & other );
-	FormalRegExpConcatenation ( FormalRegExpConcatenation && other ) noexcept;
-	FormalRegExpConcatenation & operator =( const FormalRegExpConcatenation & other );
-	FormalRegExpConcatenation & operator =( FormalRegExpConcatenation && other ) noexcept;
-	virtual ~FormalRegExpConcatenation ( ) noexcept;
-
 	/**
 	 * @copydoc FormalRegExpElement::clone() const
 	 */
@@ -74,6 +59,11 @@ public:
 	 */
 	virtual void computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const;
 
+	/**
+	 * @copydoc FormalRegExpElement::checkAlphabet()
+	 */
+	virtual bool checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const;
+
 	/**
 	 * @return elements
 	 */
@@ -108,8 +98,6 @@ public:
 	 */
 	virtual void operator >>( std::ostream & out ) const;
 
-	friend class simplify::RegExpOptimize;
-
 	virtual explicit operator std::string ( ) const;
 };
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.cpp b/alib2data/src/regexp/formal/FormalRegExpElement.cpp
index 2238a9aeddebbddf9870cbd04ddb4988f8ac0094..17fa6b6b9d1673cc020de2861c2d70aa27474847 100644
--- a/alib2data/src/regexp/formal/FormalRegExpElement.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpElement.cpp
@@ -16,9 +16,6 @@
 
 namespace regexp {
 
-FormalRegExpElement::FormalRegExpElement ( ) : parentRegExp ( NULL ) {
-}
-
 std::set < alphabet::Symbol > FormalRegExpElement::computeMinimalAlphabet ( ) const {
 	std::set < alphabet::Symbol > res;
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.h b/alib2data/src/regexp/formal/FormalRegExpElement.h
index 7593b82e9bee9c96e165506a63041feeed6801d1..9588ad3560a0e7230852fe996decbc3c6ac65758 100644
--- a/alib2data/src/regexp/formal/FormalRegExpElement.h
+++ b/alib2data/src/regexp/formal/FormalRegExpElement.h
@@ -11,11 +11,10 @@
 #include <XmlApi.hpp>
 #include "../../alphabet/Symbol.h"
 #include <set>
+#include <tree>
 
 namespace regexp {
 
-class FormalRegExp;
-
 class FormalRegExpAlternation;
 class FormalRegExpConcatenation;
 class FormalRegExpIteration;
@@ -36,29 +35,15 @@ public:
 };
 
 /**
- * Abstract class representing element in the regular expression. Can be operator or symbol.
+ * Abstract class representing element in the formal regular expression. Can be operator or symbol.
  */
-class FormalRegExpElement : public alib::CommonBase < FormalRegExpElement > {
-protected:
-	/*
-	 * Parent regexp contanining this instance of RegExpElement
-	 */
-	const FormalRegExp * parentRegExp;
-
-	/**
-	 * Attaches the regexp to this instance and all its childs
-	 * @param regexp parent regexp to attach as parent
-	 * @return true if symbols used in regexp element are in the regexp's alphabet
-	 */
-	virtual bool attachRegExp ( const FormalRegExp * regexp ) = 0;
-
+class FormalRegExpElement : public alib::CommonBase < FormalRegExpElement >, public std::BaseNode < FormalRegExpElement > {
 public:
 	virtual void Accept ( void * userData, const FormalRegExpElementVisitor & visitor ) const = 0;
 
-	explicit FormalRegExpElement ( );
-
 	/**
 	 * Creates copy of the element.
+	 *
 	 * @return copy of the element
 	 */
 	virtual std::smart_ptr < UnboundedRegExpElement > asUnbounded ( ) const = 0;
@@ -80,18 +65,19 @@ public:
 	virtual void computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const = 0;
 
 	/**
-	 * @copydoc RankedNode::computeMinimalAlphabet()
+	 * Traverses the regexp tree and checks whether all symbols in the regexp tree are in the alphabet
+	 *
+	 * @param alphabet
+	 * @return true if symbols in the regexp are in the alphabet, false otherwise
 	 */
-	std::set < alphabet::Symbol > computeMinimalAlphabet ( ) const;
+	virtual bool checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const = 0;
 
-	friend class FormalRegExp;
-
-	friend class FormalRegExpAlternation;
-	friend class FormalRegExpConcatenation;
-	friend class FormalRegExpIteration;
-	friend class FromalRegExpSymbol;
-	friend class FormalRegExpEmpty;
-	friend class FormalRegExpEpsilon;
+	/**
+	 * Traverses the regexp tree computing minimal alphabet needed by regexp
+	 *
+	 * @return the minimal alphabet needed by the regexp
+	 */
+	std::set < alphabet::Symbol > computeMinimalAlphabet ( ) const;
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
index ce3726babd8e247b21afec370fbe78e7b7039bfd..6de54de689e3b6cca73037dc1379587a23e85e95 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.cpp
@@ -14,24 +14,6 @@ FormalRegExpEmpty::FormalRegExpEmpty ( ) {
 	// so that default constructor is available
 }
 
-FormalRegExpEmpty::FormalRegExpEmpty ( const FormalRegExpEmpty & ) {
-	// so that copy constructor is available
-}
-
-FormalRegExpEmpty::FormalRegExpEmpty ( FormalRegExpEmpty && ) noexcept {
-	this->attachRegExp ( NULL );
-}
-
-FormalRegExpEmpty & FormalRegExpEmpty::operator =( const FormalRegExpEmpty & ) {
-	 // this is actually different than default implementation
-	return * this;
-}
-
-FormalRegExpEmpty & FormalRegExpEmpty::operator =( FormalRegExpEmpty && ) noexcept {
-	 // this is actually different than default implementation
-	return * this;
-}
-
 FormalRegExpElement * FormalRegExpEmpty::clone ( ) const {
 	return new FormalRegExpEmpty ( * this );
 }
@@ -56,14 +38,11 @@ bool FormalRegExpEmpty::testSymbol ( const alphabet::Symbol & ) const {
 	return false;
 }
 
-bool FormalRegExpEmpty::attachRegExp ( const FormalRegExp * regexp ) {
-	if ( this->parentRegExp == regexp ) return true;
-
-	this->parentRegExp = regexp;
-	return true;
+void FormalRegExpEmpty::computeMinimalAlphabet ( std::set < alphabet::Symbol > & ) const {
 }
 
-void FormalRegExpEmpty::computeMinimalAlphabet ( std::set < alphabet::Symbol > & ) const {
+bool FormalRegExpEmpty::checkAlphabet ( const std::set < alphabet::Symbol > & ) const {
+	return true;
 }
 
 FormalRegExpEmpty::operator std::string ( ) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.h b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
index 41a95dbb880f43c48e947e027feb1624744ed420..44796c4af0b6b47849565501f0dfd97a85ddb2bf 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEmpty.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.h
@@ -16,23 +16,13 @@ namespace regexp {
 /**
  * Represents empty regular expression in the regular expression.
  */
-class FormalRegExpEmpty : public FormalRegExpElement {
-protected:
-	/**
-	 * @copydoc FormalRegExpElement::attachRegExp()
-	 */
-	virtual bool attachRegExp ( const FormalRegExp * regexp );
-
+class FormalRegExpEmpty : public FormalRegExpElement, public std::NularyNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpSymbol > {
 public:
 	void Accept ( void * userData, const FormalRegExpElementVisitor & visitor ) const {
 		visitor.Visit ( userData, * this );
 	}
 
 	explicit FormalRegExpEmpty ( );
-	FormalRegExpEmpty ( const FormalRegExpEmpty & other );
-	FormalRegExpEmpty ( FormalRegExpEmpty && other ) noexcept;
-	FormalRegExpEmpty & operator =( const FormalRegExpEmpty & other );
-	FormalRegExpEmpty & operator =( FormalRegExpEmpty && other ) noexcept;
 
 	/**
 	 * @copydoc FormalRegExpElement::clone() const
@@ -59,6 +49,11 @@ public:
 	 */
 	virtual void computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const;
 
+	/**
+	 * @copydoc FormalRegExpElement::checkAlphabet()
+	 */
+	virtual bool checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const;
+
 	virtual int compare ( const FormalRegExpElement & other ) const {
 		if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other );
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
index a981ed04f6ee4064991931a7a438838b05d56059..63eb7669354a8b5d78f6f98797367223c9b702fd 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.cpp
@@ -15,24 +15,6 @@ FormalRegExpEpsilon::FormalRegExpEpsilon ( ) {
 	// so that default constructor is available
 }
 
-FormalRegExpEpsilon::FormalRegExpEpsilon ( const FormalRegExpEpsilon & ) {
-	// so that copy constructor is available
-}
-
-FormalRegExpEpsilon::FormalRegExpEpsilon ( FormalRegExpEpsilon && ) noexcept {
-	this->attachRegExp ( NULL );
-}
-
-FormalRegExpEpsilon & FormalRegExpEpsilon::operator =( const FormalRegExpEpsilon & ) {
-	 // this is actually different than default implementation
-	return * this;
-}
-
-FormalRegExpEpsilon & FormalRegExpEpsilon::operator =( FormalRegExpEpsilon && ) noexcept {
-	 // this is actually different than default implementation
-	return * this;
-}
-
 FormalRegExpElement * FormalRegExpEpsilon::clone ( ) const {
 	return new FormalRegExpEpsilon ( * this );
 }
@@ -57,14 +39,11 @@ bool FormalRegExpEpsilon::testSymbol ( const alphabet::Symbol & ) const {
 	return false;
 }
 
-bool FormalRegExpEpsilon::attachRegExp ( const FormalRegExp * regexp ) {
-	if ( this->parentRegExp == regexp ) return true;
-
-	this->parentRegExp = regexp;
-	return true;
+void FormalRegExpEpsilon::computeMinimalAlphabet ( std::set < alphabet::Symbol > & ) const {
 }
 
-void FormalRegExpEpsilon::computeMinimalAlphabet ( std::set < alphabet::Symbol > & ) const {
+bool FormalRegExpEpsilon::checkAlphabet ( const std::set < alphabet::Symbol > & ) const {
+	return true;
 }
 
 FormalRegExpEpsilon::operator std::string ( ) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
index 0fe13c68e18d903139c032bc8ff38e4a555ed0cb..65f81947013f5290c8da81a8de91d203fd7257f8 100644
--- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
+++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h
@@ -16,23 +16,13 @@ namespace regexp {
 /**
  * Represents epsilon in the regular expression.
  */
-class FormalRegExpEpsilon : public FormalRegExpElement {
-protected:
-	/**
-	 * @copydoc FormalRegExpElement::attachRegExp()
-	 */
-	virtual bool attachRegExp ( const FormalRegExp * regexp );
-
+class FormalRegExpEpsilon : public FormalRegExpElement, public std::NularyNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpSymbol > {
 public:
 	void Accept ( void * userData, const FormalRegExpElementVisitor & visitor ) const {
 		visitor.Visit ( userData, * this );
 	}
 
 	explicit FormalRegExpEpsilon ( );
-	FormalRegExpEpsilon ( const FormalRegExpEpsilon & other );
-	FormalRegExpEpsilon ( FormalRegExpEpsilon && other ) noexcept;
-	FormalRegExpEpsilon & operator =( const FormalRegExpEpsilon & other );
-	FormalRegExpEpsilon & operator =( FormalRegExpEpsilon && other ) noexcept;
 
 	/**
 	 * @copydoc FormalRegExpElement::clone() const
@@ -59,6 +49,11 @@ public:
 	 */
 	virtual void computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const;
 
+	/**
+	 * @copydoc FormalRegExpElement::checkAlphabet()
+	 */
+	virtual bool checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const;
+
 	virtual int compare ( const FormalRegExpElement & other ) const {
 		if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other );
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.cpp b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
index 3ab481043f76e230970383abc0c54f76fe825346..dc7a7670f3afcd66c288f20791ffeeea6821815b 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.cpp
@@ -13,54 +13,22 @@
 
 namespace regexp {
 
-FormalRegExpIteration::FormalRegExpIteration ( FormalRegExpElement && element ) : element ( nullptr ) {
-	setElement ( std::move ( element ) );
+FormalRegExpIteration::FormalRegExpIteration ( FormalRegExpElement && element ) : UnaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpIteration > ( std::smart_ptr < FormalRegExpElement > ( std::move ( element ).plunder ( ) ) ) {
 }
 
 FormalRegExpIteration::FormalRegExpIteration ( const FormalRegExpElement & element ) : FormalRegExpIteration ( std::move_copy ( element ) ) {
 }
 
-FormalRegExpIteration::FormalRegExpIteration ( const FormalRegExpIteration & other ) : element ( other.element ) {
-}
-
-FormalRegExpIteration::FormalRegExpIteration ( FormalRegExpIteration && other ) noexcept : element ( std::move ( other.element ) ) {
-	element->attachRegExp ( NULL );
-}
-
-FormalRegExpIteration & FormalRegExpIteration::operator =( const FormalRegExpIteration & other ) {
-	if ( this == & other )
-		return * this;
-
-	* this = FormalRegExpIteration ( other );
-
-	return * this;
-}
-
-FormalRegExpIteration & FormalRegExpIteration::operator =( FormalRegExpIteration && other ) noexcept {
-	std::swap ( this->element, other.element );
-	std::swap ( this->parentRegExp, other.parentRegExp );
-
-	this->attachRegExp ( other.parentRegExp );
-
-	return * this;
-}
-
-regexp::FormalRegExpIteration::~FormalRegExpIteration ( ) noexcept {
-}
-
 const FormalRegExpElement & FormalRegExpIteration::getElement ( ) const {
-	return * element;
+	return * getChild ( );
 }
 
 FormalRegExpElement & FormalRegExpIteration::getElement ( ) {
-	return * element;
+	return * getChild ( );
 }
 
 void FormalRegExpIteration::setElement ( FormalRegExpElement && elementParam ) {
-	element = std::smart_ptr < FormalRegExpElement > ( std::move ( elementParam ).plunder ( ) );
-
-	if ( this->parentRegExp && !element->attachRegExp ( this->parentRegExp ) )
-		throw exception::CommonException ( "Input symbols not in the alphabet." );
+	setChild ( std::smart_ptr < FormalRegExpElement > ( std::move ( elementParam ).plunder ( ) ) );
 }
 
 void FormalRegExpIteration::setElement ( const FormalRegExpElement & elementParam ) {
@@ -76,30 +44,27 @@ FormalRegExpElement * FormalRegExpIteration::plunder ( ) && {
 }
 
 std::smart_ptr < UnboundedRegExpElement > FormalRegExpIteration::asUnbounded ( ) const {
-	return std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpIteration ( * element->asUnbounded ( ) ) );
+	return std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpIteration ( * getElement ( ).asUnbounded ( ) ) );
 }
 
 int FormalRegExpIteration::compare ( const FormalRegExpIteration & other ) const {
-	return element->compare ( * other.element );
+	return getElement ( ).compare ( other.getElement ( ) );
 }
 
 void FormalRegExpIteration::operator >>( std::ostream & out ) const {
-	out << "(RegExpFormalRegExpIteration " << * element << ")";
+	out << "(RegExpFormalRegExpIteration " << getElement ( ) << ")";
 }
 
 bool FormalRegExpIteration::testSymbol ( const alphabet::Symbol & symbol ) const {
-	return element->testSymbol ( symbol );
+	return getChild ( )->testSymbol ( symbol );
 }
 
-bool FormalRegExpIteration::attachRegExp ( const FormalRegExp * regexp ) {
-	if ( this->parentRegExp == regexp ) return true;
-
-	this->parentRegExp = regexp;
-	return this->element->attachRegExp ( regexp );
+void FormalRegExpIteration::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
+	getElement ( ).computeMinimalAlphabet ( alphabet );
 }
 
-void FormalRegExpIteration::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
-	element->computeMinimalAlphabet ( alphabet );
+bool FormalRegExpIteration::checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const {
+	return getElement ( ).checkAlphabet ( alphabet );
 }
 
 FormalRegExpIteration::operator std::string ( ) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h
index 4f711b3238aacb276b0da51484d88108d82625ad..5a2e4633dcae4f782171da2907413d323785d494 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.h
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h
@@ -23,15 +23,7 @@ class RegExpOptimize;
  * Represents iteration operator in the regular expression. Contains one FormalRegExpElement
  * as operand.
  */
-class FormalRegExpIteration : public FormalRegExpElement {
-protected:
-	std::smart_ptr < FormalRegExpElement > element;
-
-	/**
-	 * @copydoc FormalRegExpElement::attachRegExp()
-	 */
-	virtual bool attachRegExp ( const FormalRegExp * regexp );
-
+class FormalRegExpIteration : public FormalRegExpElement, public std::UnaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpIteration > {
 public:
 	void Accept ( void * userData, const FormalRegExpElementVisitor & visitor ) const {
 		visitor.Visit ( userData, * this );
@@ -39,11 +31,6 @@ public:
 
 	explicit FormalRegExpIteration ( FormalRegExpElement && );
 	explicit FormalRegExpIteration ( const FormalRegExpElement & );
-	FormalRegExpIteration ( const FormalRegExpIteration & other );
-	FormalRegExpIteration ( FormalRegExpIteration && other ) noexcept;
-	FormalRegExpIteration & operator =( const FormalRegExpIteration & other );
-	FormalRegExpIteration & operator =( FormalRegExpIteration && other ) noexcept;
-	virtual ~FormalRegExpIteration ( ) noexcept;
 
 	/**
 	 * @copydoc FormalRegExpElement::clone() const
@@ -70,6 +57,11 @@ public:
 	 */
 	virtual void computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const;
 
+	/**
+	 * @copydoc FormalRegExpElement::checkAlphabet()
+	 */
+	virtual bool checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const;
+
 	/**
 	 * @return element
 	 */
@@ -99,8 +91,6 @@ public:
 	 */
 	virtual void operator >>( std::ostream & out ) const;
 
-	friend class simplify::RegExpOptimize;
-
 	virtual explicit operator std::string ( ) const;
 };
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
index f1be72e085993d98881e97211ca942ac06db4d6a..34d57eb8d4dd101f459d0c50402abe9826e3439c 100644
--- a/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
+++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.cpp
@@ -23,30 +23,6 @@ FormalRegExpSymbol::FormalRegExpSymbol ( const std::string & label ) : symbol (
 FormalRegExpSymbol::FormalRegExpSymbol ( alphabet::Symbol symbol ) : symbol ( std::move ( symbol ) ) {
 }
 
-FormalRegExpSymbol::FormalRegExpSymbol ( const FormalRegExpSymbol & other ) : symbol ( other.symbol ) {
-}
-
-FormalRegExpSymbol::FormalRegExpSymbol ( FormalRegExpSymbol && other ) noexcept : symbol ( std::move ( other.symbol ) ) {
-}
-
-FormalRegExpSymbol & FormalRegExpSymbol::operator =( const FormalRegExpSymbol & other ) {
-	if ( this == & other )
-		return * this;
-
-	* this = FormalRegExpSymbol ( other );
-
-	return * this;
-}
-
-FormalRegExpSymbol & FormalRegExpSymbol::operator =( FormalRegExpSymbol && other ) noexcept {
-	std::swap ( this->symbol, other.symbol );
-	std::swap ( this->parentRegExp, other.parentRegExp );
-
-	this->attachRegExp ( other.parentRegExp );
-
-	return * this;
-}
-
 FormalRegExpElement * FormalRegExpSymbol::clone ( ) const {
 	return new FormalRegExpSymbol ( * this );
 }
@@ -71,22 +47,16 @@ bool FormalRegExpSymbol::testSymbol ( const alphabet::Symbol & symbol ) const {
 	return symbol == this->symbol;
 }
 
-bool FormalRegExpSymbol::attachRegExp ( const FormalRegExp * regexp ) {
-	if ( this->parentRegExp == regexp ) return true;
-
-	this->parentRegExp = regexp;
-
-	if ( regexp == NULL ) return true;
-
-	return this->parentRegExp->getAlphabet ( ).find ( this->symbol ) != this->parentRegExp->getAlphabet ( ).end ( );
+void FormalRegExpSymbol::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
+	alphabet.insert ( symbol );
 }
 
-void FormalRegExpSymbol::computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const {
-	alphabet.insert ( this->symbol );
+bool FormalRegExpSymbol::checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const {
+	return alphabet.count ( symbol );
 }
 
 const alphabet::Symbol & FormalRegExpSymbol::getSymbol ( ) const {
-	return this->symbol;
+	return symbol;
 }
 
 FormalRegExpSymbol::operator std::string ( ) const {
diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.h b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
index ac2f55858e386b33062c75cd37006d7eb602e720..57b232ad0b95b85776c7d9084b35005b2650c20b 100644
--- a/alib2data/src/regexp/formal/FormalRegExpSymbol.h
+++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.h
@@ -16,15 +16,9 @@ namespace regexp {
 /**
  * Represents symbol in the regular expression. Contains name of the symbol.
  */
-class FormalRegExpSymbol : public FormalRegExpElement {
-protected:
+class FormalRegExpSymbol : public FormalRegExpElement, public std::NularyNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpSymbol > {
 	alphabet::Symbol symbol;
 
-	/**
-	 * @copydoc FormalRegExpElement::attachRegExp()
-	 */
-	virtual bool attachRegExp ( const FormalRegExp * regexp );
-
 public:
 	void Accept ( void * userData, const FormalRegExpElementVisitor & visitor ) const {
 		visitor.Visit ( userData, * this );
@@ -36,11 +30,6 @@ public:
 
 	explicit FormalRegExpSymbol ( alphabet::Symbol symbol );
 
-	FormalRegExpSymbol ( const FormalRegExpSymbol & other );
-	FormalRegExpSymbol ( FormalRegExpSymbol && other ) noexcept;
-	FormalRegExpSymbol & operator =( const FormalRegExpSymbol & other );
-	FormalRegExpSymbol & operator =( FormalRegExpSymbol && other ) noexcept;
-
 	/**
 	 * @copydoc FormalRegExpElement::clone() const
 	 */
@@ -66,6 +55,11 @@ public:
 	 */
 	virtual void computeMinimalAlphabet ( std::set < alphabet::Symbol > & alphabet ) const;
 
+	/**
+	 * @copydoc FormalRegExpElement::checkAlphabet()
+	 */
+	virtual bool checkAlphabet ( const std::set < alphabet::Symbol > & alphabet ) const;
+
 	virtual int compare ( const FormalRegExpElement & other ) const {
 		if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other );
 
diff --git a/alib2data/test-src/regexp/RegExpTest.cpp b/alib2data/test-src/regexp/RegExpTest.cpp
index 5aeee504f49eda9d75a8b801b217c04815f06638..0a8ec51bb1cadaaab4a13b7f88a998da975ac06c 100644
--- a/alib2data/test-src/regexp/RegExpTest.cpp
+++ b/alib2data/test-src/regexp/RegExpTest.cpp
@@ -70,6 +70,23 @@ void RegExpTest::testCopyConstruct() {
 
 		CPPUNIT_ASSERT( regexp2 == regexp3 );
 	}
+	{
+		regexp::FormalRegExpSymbol l1 = regexp::FormalRegExpSymbol("1");
+		regexp::FormalRegExpSymbol l2 = regexp::FormalRegExpSymbol("2");
+
+		regexp::FormalRegExpConcatenation con = regexp::FormalRegExpConcatenation(l1, l2);
+
+		regexp::FormalRegExpIteration ite = regexp::FormalRegExpIteration(l1);
+
+		regexp::FormalRegExpAlternation alt = regexp::FormalRegExpAlternation(con, ite);
+
+		regexp::FormalRegExp regexp({alphabet::symbolFrom("1"), alphabet::symbolFrom("3")}, regexp::FormalRegExpEmpty { });
+
+		CPPUNIT_ASSERT_THROW(
+			regexp.setRegExp ( alt ),
+			exception::CommonException
+		);
+	}
 }
 
 void RegExpTest::testXMLParser() {
diff --git a/alib2str/src/regexp/RegExpToStringComposer.h b/alib2str/src/regexp/RegExpToStringComposer.h
index 868a53e72d40ccf76e903ca70d6b70c2e24d817c..5fe4b9b64da6074fe635d33a9f15c0667478975e 100644
--- a/alib2str/src/regexp/RegExpToStringComposer.h
+++ b/alib2str/src/regexp/RegExpToStringComposer.h
@@ -11,7 +11,9 @@
 #include <string>
 #include <core/multipleDispatch.hpp>
 #include "regexp/RegExp.h"
+#include "regexp/unbounded/UnboundedRegExp.h"
 #include "regexp/unbounded/UnboundedRegExpElement.h"
+#include "regexp/formal/FormalRegExp.h"
 #include "regexp/formal/FormalRegExpElement.h"
 
 namespace regexp {