diff --git a/alib2algo/src/equations/LeftRegularEquationSolver.cpp b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
index 6d404df1d30f9147c89de12be6970c599e950a5f..cc9fed801761292214289595d2801af941658e28 100644
--- a/alib2algo/src/equations/LeftRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
@@ -24,6 +24,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate( void ) {
 		 * => A = 10*B + 20*C
 		 */
 		regexp::UnboundedRegExpIteration loop( std::move( m_eqTransition[ a ][ a ] ) );
+		opt.optimize( loop );
 
 		// for all transitions from A apply Arden's Lemma
 		for( auto itB = std::next( itA ) ; itB != m_symbolsByDepth.rend( ); itB ++ ) {
@@ -34,6 +35,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate( void ) {
 			regexp::UnboundedRegExpAlternation alt;
 			alt.appendElement( std::move( concat ) );
 			m_eqTransition[ a ][ b ] = std::move( alt );
+			opt.optimize( m_eqTransition[ a ][ b ] );
 		}
 		regexp::UnboundedRegExpConcatenation concat;
 		concat.appendElement( std::move( m_eqFinal[ a ] ) );
@@ -41,6 +43,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate( void ) {
 		regexp::UnboundedRegExpAlternation alt;
 		alt.appendElement( std::move( concat ) );
 		m_eqFinal[ a ] = std::move( alt );
+		opt.optimize( m_eqFinal[ a ] );
 
 		/*
 		 * eliminate A from rest of the equations using this pattern:
@@ -58,7 +61,8 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate( void ) {
 				regexp::UnboundedRegExpAlternation alt;
 				alt.appendElement( std::move( m_eqTransition[ b ][ c ] ) );
 				alt.appendElement( std::move( concat ) );
-				m_eqTransition[ b ][ c ] = /* opt.optimize( */ std::move( alt ) /* ) */;
+				m_eqTransition[ b ][ c ] = std::move( alt );
+				opt.optimize( m_eqTransition[ b ][ c ] );
 			}
 
 			regexp::UnboundedRegExpConcatenation concat;
@@ -67,7 +71,8 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate( void ) {
 			regexp::UnboundedRegExpAlternation alt;
 			alt.appendElement( std::move( m_eqFinal[ b ] ) );
 			alt.appendElement( std::move( concat ) );
-			m_eqFinal[ b ] = /* opt.optimize( */ std::move( alt ) /* ) */;
+			m_eqFinal[ b ] = std::move( alt );
+			opt.optimize( m_eqFinal[ b ] );
 		}
 	}
 
diff --git a/alib2algo/src/equations/RightRegularEquationSolver.cpp b/alib2algo/src/equations/RightRegularEquationSolver.cpp
index 4a1ecbe5ae15c9767d851a831bac50bead72d802..b9d1dac2ea680a800396236f035b452b9d541d50 100644
--- a/alib2algo/src/equations/RightRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/RightRegularEquationSolver.cpp
@@ -24,6 +24,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate( void ) {
 		 * => A = 0*1B + 0*2C
 		 */
 		regexp::UnboundedRegExpIteration loop( std::move( m_eqTransition[ a ][ a ] ) );
+		opt.optimize( loop );
 
 		// for all transitions from A apply Arden's Lemma
 		for( auto itB = std::next( itA ) ; itB != m_symbolsByDepth.rend( ); itB ++ ) {
@@ -34,6 +35,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate( void ) {
 			regexp::UnboundedRegExpAlternation alt;
 			alt.appendElement( std::move( concat ) );
 			m_eqTransition[ a ][ b ] = std::move( alt );
+			opt.optimize( m_eqTransition[ a ][ b ] );
 		}
 		regexp::UnboundedRegExpConcatenation concat;
 		concat.appendElement( std::move( loop ) );
@@ -41,6 +43,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate( void ) {
 		regexp::UnboundedRegExpAlternation alt;
 		alt.appendElement( std::move( concat ) );
 		m_eqFinal[ a ] = std::move( alt );
+		opt.optimize( m_eqFinal[ a ] );
 
 		/*
 		 * eliminate A from rest of the equations using this pattern:
@@ -59,6 +62,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate( void ) {
 				alt.appendElement( std::move( m_eqTransition[ b ][ c ] ) );
 				alt.appendElement( std::move( concat ) );
 				m_eqTransition[ b ][ c ] = std::move( alt );
+				opt.optimize( m_eqTransition[ b ][ c ] );
 			}
 
 			regexp::UnboundedRegExpConcatenation concat;
@@ -68,6 +72,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate( void ) {
 			alt.appendElement( std::move( m_eqFinal[ b ] ) );
 			alt.appendElement( std::move( concat ) );
 			m_eqFinal[ b ] = std::move( alt );
+			opt.optimize( m_eqFinal[ b ] );
 		}
 	}
 
diff --git a/alib2algo/src/regexp/RegExpOptimize.cpp b/alib2algo/src/regexp/RegExpOptimize.cpp
index 0d247c7493db38d16aa107face5d2bd9063fbf61..e4c84ffc635658eac896fecec462d51f5274b1b5 100644
--- a/alib2algo/src/regexp/RegExpOptimize.cpp
+++ b/alib2algo/src/regexp/RegExpOptimize.cpp
@@ -2,7 +2,7 @@
  * RegExpOptimize.cpp
  *
  *  Created on: 20. 1. 2014
- *      Author: Tomas Pecka
+ *	  Author: Tomas Pecka
  */
 
 #include "RegExpOptimize.h"
@@ -15,136 +15,184 @@ namespace regexp {
 
 UnboundedRegExp RegExpOptimize::optimize( UnboundedRegExp const & regexp )
 {
-    UnboundedRegExpElement* optimized = optimize( & regexp.getRegExp( ) );
+	UnboundedRegExpElement* optimized = optimize( & regexp.getRegExp( ) );
 
-    UnboundedRegExp ret( std::move( * optimized ) );
+	UnboundedRegExp ret( std::move( * optimized ) );
 
-    delete optimized;
+	delete optimized;
 
-    return ret;
+	return ret;
+}
+
+void RegExpOptimize::optimize( UnboundedRegExpElement & element ) {
+	UnboundedRegExpElement* optimized = optimize( & element );
+
+	UnboundedRegExpAlternation * alternation = dynamic_cast<UnboundedRegExpAlternation *>( & element );
+	if( alternation ) {
+		UnboundedRegExpAlternation * alternationOptimized = dynamic_cast<UnboundedRegExpAlternation *>( optimized );
+		if( alternationOptimized ) {
+			* alternation = std::move( * alternationOptimized );
+			delete alternationOptimized;
+		} else {
+			* alternation = UnboundedRegExpAlternation { };
+			alternation->appendElement( std::move( * optimized ) );
+			delete optimized;
+		}
+		return;
+	}
+
+	UnboundedRegExpConcatenation * concatenation = dynamic_cast<UnboundedRegExpConcatenation *>( & element );
+	if( concatenation ) {
+		UnboundedRegExpConcatenation * concatenationOptimized = dynamic_cast<UnboundedRegExpConcatenation *>( optimized );
+		if( concatenationOptimized ) {
+			* concatenation = std::move( * concatenationOptimized );
+			delete concatenationOptimized;
+		} else {
+			* concatenation = UnboundedRegExpConcatenation { };
+			concatenation->appendElement( std::move( * optimized ) );
+			delete optimized;
+		}
+		return;
+	}
+
+	UnboundedRegExpIteration * iteration = dynamic_cast<UnboundedRegExpIteration *>( & element );
+	if( iteration ) {
+		UnboundedRegExpIteration * iterationOptimized = dynamic_cast<UnboundedRegExpIteration *>( optimized );
+		if( iterationOptimized ) {
+			* iteration = std::move( * iterationOptimized );
+			delete iterationOptimized;
+		} else {
+			* iteration = UnboundedRegExpIteration { std::move( * optimized ) };
+			delete optimized;
+		}
+		return;
+	}
+
+	// Nothing to optimize original element was UnboundedRegExpSymbol, UnboundedRegExpEpsilon, or UnboundedRegExpEmpty
+	return;
 }
 
 UnboundedRegExpElement* RegExpOptimize::optimize( UnboundedRegExpElement const * const & node )
 {
-    const UnboundedRegExpAlternation * alternation = dynamic_cast<const UnboundedRegExpAlternation*>( node );
-    if( alternation )
-        return optimize( alternation );
+	const UnboundedRegExpAlternation * alternation = dynamic_cast<const UnboundedRegExpAlternation*>( node );
+	if( alternation )
+		return optimize( alternation );
 
-    const UnboundedRegExpConcatenation * concatenation = dynamic_cast<const UnboundedRegExpConcatenation*>( node );
-    if( concatenation )
-        return optimize( concatenation );
+	const UnboundedRegExpConcatenation * concatenation = dynamic_cast<const UnboundedRegExpConcatenation*>( node );
+	if( concatenation )
+		return optimize( concatenation );
 
-    const UnboundedRegExpIteration * iteration = dynamic_cast<const UnboundedRegExpIteration*>( node );
-    if( iteration )
-        return optimize( iteration );
+	const UnboundedRegExpIteration * iteration = dynamic_cast<const UnboundedRegExpIteration*>( node );
+	if( iteration )
+		return optimize( iteration );
 
-    const UnboundedRegExpSymbol * symbol = dynamic_cast<const UnboundedRegExpSymbol*>( node );
-    if( symbol )
-        return optimize( symbol );
+	const UnboundedRegExpSymbol * symbol = dynamic_cast<const UnboundedRegExpSymbol*>( node );
+	if( symbol )
+		return optimize( symbol );
 
-    const UnboundedRegExpEmpty * empty= dynamic_cast<const UnboundedRegExpEmpty*>( node );
-    if( empty )
-        return optimize( empty );
+	const UnboundedRegExpEmpty * empty= dynamic_cast<const UnboundedRegExpEmpty*>( node );
+	if( empty )
+		return optimize( empty );
 
-    const UnboundedRegExpEpsilon * eps = dynamic_cast<const UnboundedRegExpEpsilon*>( node );
-    if( eps )
-        return optimize( eps );
+	const UnboundedRegExpEpsilon * eps = dynamic_cast<const UnboundedRegExpEpsilon*>( node );
+	if( eps )
+		return optimize( eps );
 
-    throw exception::AlibException( "RegExpOptimize::optimize - unknown UnboundedRegExpElement node" );
+	throw exception::AlibException( "RegExpOptimize::optimize - unknown UnboundedRegExpElement node" );
 }
 
 
 UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpAlternation const * const & node )
 {
-    UnboundedRegExpAlternation* alt = new UnboundedRegExpAlternation( );
+	UnboundedRegExpAlternation* alt = new UnboundedRegExpAlternation( );
 
-    for( const auto & child : node->elements )
-        alt->elements.push_back( optimize( child ) );
+	for( const auto & child : node->elements )
+		alt->elements.push_back( optimize( child ) );
 
-    // optimize while you can
-    while( A1( alt ) || A2( alt ) || A3( alt ) || A4( alt ) || A10( alt ) || V2( alt ) || V5( alt ) || V6( alt ) || X1( alt ) );
+	// optimize while you can
+	while( A1( alt ) || A2( alt ) || A3( alt ) || A4( alt ) || A10( alt ) || V2( alt ) || V5( alt ) || V6( alt ) || X1( alt ) );
 
-    if( alt->elements.size( ) == 1 )
-    {
-        UnboundedRegExpElement* ret = alt->elements.front( );
-        alt->elements.clear( );
-        delete alt;
-        return ret;
-    }
+	if( alt->elements.size( ) == 1 )
+	{
+		UnboundedRegExpElement* ret = alt->elements.front( );
+		alt->elements.clear( );
+		delete alt;
+		return ret;
+	}
 
-    if( alt->elements.size( ) == 0 ) {
-        delete alt;
-        return new UnboundedRegExpEmpty( );
-    }
+	if( alt->elements.size( ) == 0 ) {
+		delete alt;
+		return new UnboundedRegExpEmpty( );
+	}
 
-    return alt;
+	return alt;
 }
 
 UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpConcatenation const * const & node )
 {
-    UnboundedRegExpConcatenation* concat = new UnboundedRegExpConcatenation( );
-
-    for( const auto & child : node->elements )
-        concat->elements.push_back( optimize( child ) );
-
-    do
-    {
-        // A7 is implemented here ~ if not here, it went into infinite loop FIXME
-        if( std::any_of( concat->elements.begin( ), concat->elements.end( ), []( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpEmpty const *>( a ); } ) )
-        {
-            delete concat;
-            return new UnboundedRegExpEmpty( );
-        }
-    }
-    while( A5( concat ) || A6( concat ) || /* A7( concat ) || */ A8( concat ) || A9( concat ) || V8( concat ) );//|| V9( concat ) );
-
-    if( concat->elements.size( ) == 1 )
-    {
-        UnboundedRegExpElement* ret = concat->elements.front( );
-        concat->elements.clear( );
-        delete concat;
-        return ret;
-    }
-
-    if( concat->elements.size( ) == 0 ) {
-        delete concat;
-        return new UnboundedRegExpEpsilon( );
-    }
-
-    return concat;
+	UnboundedRegExpConcatenation* concat = new UnboundedRegExpConcatenation( );
+
+	for( const auto & child : node->elements )
+		concat->elements.push_back( optimize( child ) );
+
+	do
+	{
+		// A7 is implemented here ~ if not here, it went into infinite loop FIXME
+		if( std::any_of( concat->elements.begin( ), concat->elements.end( ), []( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpEmpty const *>( a ); } ) )
+		{
+			delete concat;
+			return new UnboundedRegExpEmpty( );
+		}
+	}
+	while( A5( concat ) || A6( concat ) || /* A7( concat ) || */ A8( concat ) || A9( concat ) || V8( concat ) );//|| V9( concat ) );
+
+	if( concat->elements.size( ) == 1 )
+	{
+		UnboundedRegExpElement* ret = concat->elements.front( );
+		concat->elements.clear( );
+		delete concat;
+		return ret;
+	}
+
+	if( concat->elements.size( ) == 0 ) {
+		delete concat;
+		return new UnboundedRegExpEpsilon( );
+	}
+
+	return concat;
 }
 
 UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpIteration const * const & node )
 {
-    UnboundedRegExpIteration* iter = new UnboundedRegExpIteration(* optimize( node->element ) );
-
-    do
-    {
-        // V1 is implemented right here
-        if( dynamic_cast<UnboundedRegExpEmpty*>( iter->element ) )
-        {
-            delete iter;
-            return new UnboundedRegExpEpsilon( );
-        }
-    }
-    while( A11( iter ) || V1( iter ) || V3( iter ) || V4( iter ) || V10( iter ) );
-
-    return iter;
+	UnboundedRegExpIteration* iter = new UnboundedRegExpIteration(* optimize( node->element ) );
+
+	do
+	{
+		// V1 is implemented right here
+		if( dynamic_cast<UnboundedRegExpEmpty*>( iter->element ) )
+		{
+			delete iter;
+			return new UnboundedRegExpEpsilon( );
+		}
+	}
+	while( A11( iter ) || V1( iter ) || V3( iter ) || V4( iter ) || V10( iter ) );
+
+	return iter;
 }
 
 UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpSymbol const * const & node )
 {
-    return node->clone( );
+	return node->clone( );
 }
 
 UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpEmpty const * const & node )
 {
-    return node->clone( );
+	return node->clone( );
 }
 
 UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpEpsilon const * const & node )
 {
-    return node->clone( );
+	return node->clone( );
 }
 
 // ----------------------------------------------------------------------------
@@ -156,34 +204,34 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpEpsilon const
   */
 bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node )
 {
-    bool optimized = false;
+	bool optimized = false;
 
-    for( auto it = node->elements.begin( ); it != node->elements.end( ); )
-    {
-        UnboundedRegExpAlternation * const & childUnboundedRegExpAlternation = dynamic_cast<UnboundedRegExpAlternation *>( * it );
+	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
+	{
+		UnboundedRegExpAlternation * const & childUnboundedRegExpAlternation = dynamic_cast<UnboundedRegExpAlternation *>( * it );
 
-        if( childUnboundedRegExpAlternation )
-        {
-            it = node->elements.erase( it );
+		if( childUnboundedRegExpAlternation )
+		{
+			it = node->elements.erase( it );
 
-            size_t off = it - node->elements.begin();
-            node->elements.insert( it, childUnboundedRegExpAlternation->elements.begin( ), childUnboundedRegExpAlternation->elements.end( ) );
-            it = node->elements.begin() + off;
+			size_t off = it - node->elements.begin();
+			node->elements.insert( it, childUnboundedRegExpAlternation->elements.begin( ), childUnboundedRegExpAlternation->elements.end( ) );
+			it = node->elements.begin() + off;
 
-            //TODO on g++-4.9 use: it = node->elements.insert( it, childUnboundedRegExpAlternation->elements.begin( ), childUnboundedRegExpAlternation->elements.end( ) );
+			//TODO on g++-4.9 use: it = node->elements.insert( it, childUnboundedRegExpAlternation->elements.begin( ), childUnboundedRegExpAlternation->elements.end( ) );
 
-            childUnboundedRegExpAlternation->elements.clear( );
-            delete childUnboundedRegExpAlternation;
+			childUnboundedRegExpAlternation->elements.clear( );
+			delete childUnboundedRegExpAlternation;
 
-            optimized = true;
-        }
-        else
-        {
-            it ++;
-        }
-    }
+			optimized = true;
+		}
+		else
+		{
+			it ++;
+		}
+	}
 
-    return optimized;
+	return optimized;
 }
 
 /**
@@ -193,13 +241,13 @@ bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::A2( UnboundedRegExpAlternation * const & node )
 {
-    std::function<bool( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b )> cmp = [ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a < *b; };
+	std::function<bool( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b )> cmp = [ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a < *b; };
 
-    if( std::is_sorted( node->elements.begin( ), node->elements.end( ), cmp ) )
-        return false;
+	if( std::is_sorted( node->elements.begin( ), node->elements.end( ), cmp ) )
+		return false;
 
-    std::sort( node->elements.begin(), node->elements.end(), cmp );
-    return true;
+	std::sort( node->elements.begin(), node->elements.end(), cmp );
+	return true;
 }
 
 /**
@@ -209,30 +257,30 @@ bool RegExpOptimize::A2( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::A3( UnboundedRegExpAlternation * const & node )
 {
-    bool optimized = false;
+	bool optimized = false;
 
-    // input can be \0 + \0, so at least one element must be preserved
+	// input can be \0 + \0, so at least one element must be preserved
 
-    // FIXME: alib2 uses shared_ptrs, rewrite this using remove_if then
+	// FIXME: alib2 uses shared_ptrs, rewrite this using remove_if then
 
-    for( auto it = node->elements.begin( ); it != node->elements.end( ); )
-    {
-        UnboundedRegExpEmpty const * const & empty = dynamic_cast<UnboundedRegExpEmpty const *>( * it );
+	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
+	{
+		UnboundedRegExpEmpty const * const & empty = dynamic_cast<UnboundedRegExpEmpty const *>( * it );
 
-        if( empty && node->elements.size( ) > 1 )
-        {
-            it = node->elements.erase( it );
-            delete empty;
+		if( empty && node->elements.size( ) > 1 )
+		{
+			it = node->elements.erase( it );
+			delete empty;
 
-            optimized = true;
-        }
-        else
-        {
-            it ++;
-        }
-    }
+			optimized = true;
+		}
+		else
+		{
+			it ++;
+		}
+	}
 
-    return optimized;
+	return optimized;
 }
 
 /**
@@ -242,35 +290,35 @@ bool RegExpOptimize::A3( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node )
 {
-    /*
-     * two ways of implementing this opitimization:
-     * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts...
-     * - check every element against other ( O(n*n) )
-     *
-     * As we always sort in optimization, we can use the first version, but A4 must be __always__ called __after__ A2
-     */
-
-    // uncomment if smart ptrs used
-    // node->elements.unique( [ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool {
-    //     return *a == *b;
-    // } );
-
-    bool optimized = false;
-    if(node->elements.size() != 0) for( auto it = std::next( node->elements.begin( ) ); it != node->elements.end( ); )
-    {
-        if ( ** it == ** std::prev( it ) )
-        {
-            delete * it;
-            it = node->elements.erase( it );
-            optimized = true;
-        }
-        else
-        {
-            it ++;
-        }
-    }
-
-    return optimized;
+	/*
+	 * two ways of implementing this opitimization:
+	 * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts...
+	 * - check every element against other ( O(n*n) )
+	 *
+	 * As we always sort in optimization, we can use the first version, but A4 must be __always__ called __after__ A2
+	 */
+
+	// uncomment if smart ptrs used
+	// node->elements.unique( [ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool {
+	//	 return *a == *b;
+	// } );
+
+	bool optimized = false;
+	if(node->elements.size() != 0) for( auto it = std::next( node->elements.begin( ) ); it != node->elements.end( ); )
+	{
+		if ( ** it == ** std::prev( it ) )
+		{
+			delete * it;
+			it = node->elements.erase( it );
+			optimized = true;
+		}
+		else
+		{
+			it ++;
+		}
+	}
+
+	return optimized;
 }
 
 /**
@@ -280,32 +328,32 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::A5( UnboundedRegExpConcatenation * const & node )
 {
-    bool optimized = false;
+	bool optimized = false;
 
-    for( auto it = node->elements.begin( ); it != node->elements.end( ); )
-    {
-        UnboundedRegExpConcatenation * const & childUnboundedRegExpConcatenation = dynamic_cast<UnboundedRegExpConcatenation *>( * it );
+	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
+	{
+		UnboundedRegExpConcatenation * const & childUnboundedRegExpConcatenation = dynamic_cast<UnboundedRegExpConcatenation *>( * it );
 
-        if( childUnboundedRegExpConcatenation )
-        {
-            it = node->elements.erase( it );
+		if( childUnboundedRegExpConcatenation )
+		{
+			it = node->elements.erase( it );
 
-            size_t off = it - node->elements.begin();
-            node->elements.insert( it, childUnboundedRegExpConcatenation->elements.begin( ), childUnboundedRegExpConcatenation->elements.end( ) );
-            it = node->elements.begin() + off;
+			size_t off = it - node->elements.begin();
+			node->elements.insert( it, childUnboundedRegExpConcatenation->elements.begin( ), childUnboundedRegExpConcatenation->elements.end( ) );
+			it = node->elements.begin() + off;
 
-            //TODO on g++-4.9 use: it = node->elements.insert( it, childUnboundedRegExpConcatenation->elements.begin( ), childUnboundedRegExpConcatenation->elements.end( ) );
+			//TODO on g++-4.9 use: it = node->elements.insert( it, childUnboundedRegExpConcatenation->elements.begin( ), childUnboundedRegExpConcatenation->elements.end( ) );
 
-            childUnboundedRegExpConcatenation->elements.clear( );
-            delete childUnboundedRegExpConcatenation;
+			childUnboundedRegExpConcatenation->elements.clear( );
+			delete childUnboundedRegExpConcatenation;
 
-            optimized = true;
-        }
-        else
-            it ++;
-    }
+			optimized = true;
+		}
+		else
+			it ++;
+	}
 
-    return optimized;
+	return optimized;
 }
 
 /**
@@ -315,25 +363,25 @@ bool RegExpOptimize::A5( UnboundedRegExpConcatenation * const & node )
   */
 bool RegExpOptimize::A6( UnboundedRegExpConcatenation * const & node )
 {
-    bool optimized = false;
+	bool optimized = false;
 
-    // FIXME: alib2 uses shared_ptrs, rewrite this using remove_if then
+	// FIXME: alib2 uses shared_ptrs, rewrite this using remove_if then
 
-    for( auto it = node->elements.begin( ); it != node->elements.end( ); )
-    {
-        UnboundedRegExpEpsilon* epsilon = dynamic_cast<UnboundedRegExpEpsilon*>( * it );
-        if( epsilon && node->elements.size( ) > 1 )
-        {
-            delete * it;
-            it = node->elements.erase( it );
+	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
+	{
+		UnboundedRegExpEpsilon* epsilon = dynamic_cast<UnboundedRegExpEpsilon*>( * it );
+		if( epsilon && node->elements.size( ) > 1 )
+		{
+			delete * it;
+			it = node->elements.erase( it );
 
-            optimized = true;
-        }
-        else
-            it ++;
-    }
+			optimized = true;
+		}
+		else
+			it ++;
+	}
 
-    return optimized;
+	return optimized;
 }
 
 /**
@@ -343,22 +391,22 @@ bool RegExpOptimize::A6( UnboundedRegExpConcatenation * const & node )
   */
 bool RegExpOptimize::A7( UnboundedRegExpConcatenation * const & node )
 {
-    bool optimized = false;
+	bool optimized = false;
 
-    // FIXME: alib2 uses shared_ptrs, rewrite this using remove_if then
+	// FIXME: alib2 uses shared_ptrs, rewrite this using remove_if then
 
-    if( std::any_of( node->elements.begin( ), node->elements.end( ), []( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpEmpty const *>( a ); } ) )
-    {
-        for( auto const& child : node->elements )
-            delete child;
+	if( std::any_of( node->elements.begin( ), node->elements.end( ), []( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpEmpty const *>( a ); } ) )
+	{
+		for( auto const& child : node->elements )
+			delete child;
 
-        node->elements.clear( );
-        node->elements.push_back( new UnboundedRegExpEmpty( ) );
+		node->elements.clear( );
+		node->elements.push_back( new UnboundedRegExpEmpty( ) );
 
-        optimized = true;
-    }
+		optimized = true;
+	}
 
-    return optimized;
+	return optimized;
 }
 
 /**
@@ -369,44 +417,44 @@ bool RegExpOptimize::A7( UnboundedRegExpConcatenation * const & node )
 bool RegExpOptimize::A8( UnboundedRegExpConcatenation * const & node )
 {
 /*
-    bool optimized = false;
-
-    for( auto it = std::next( node->elements.begin( ) ); it != node->elements.end( ); )
-    {
-        UnboundedRegExpAlternation * alt = dynamic_cast<UnboundedRegExpAlternation*>( * it );
-        if( ! alt )
-        {
-            it ++;
-            continue;
-        }
-
-        // take everything to the left and copy it as prefix of every element in alternation.
-        UnboundedRegExpConcatenation * leftPart = new UnboundedRegExpConcatenation( );
-        leftPart->elements.insert( leftPart->elements.end( ), node->elements.begin( ), it );
-
-        for( auto altIt = alt->elements.begin( ); altIt != alt->elements.end( ); altIt ++ )
-        {
-            UnboundedRegExpConcatenation * altElem = new UnboundedRegExpConcatenation( );
-            altElem->elements.push_back( leftPart->clone( ) );
-            altElem->elements.push_back( * altIt );
-
-            * altIt = altElem;
-        }
-
-        UnboundedRegExpElement * optIt = optimize( * it );
-        delete *it;
-        *it = optIt;
-
-        delete leftPart;
-        it = node->elements.erase( node->elements.begin( ), it );
-
-        optimized = true;
-        it ++;
-    }
-
-    return optimized;
+	bool optimized = false;
+
+	for( auto it = std::next( node->elements.begin( ) ); it != node->elements.end( ); )
+	{
+		UnboundedRegExpAlternation * alt = dynamic_cast<UnboundedRegExpAlternation*>( * it );
+		if( ! alt )
+		{
+			it ++;
+			continue;
+		}
+
+		// take everything to the left and copy it as prefix of every element in alternation.
+		UnboundedRegExpConcatenation * leftPart = new UnboundedRegExpConcatenation( );
+		leftPart->elements.insert( leftPart->elements.end( ), node->elements.begin( ), it );
+
+		for( auto altIt = alt->elements.begin( ); altIt != alt->elements.end( ); altIt ++ )
+		{
+			UnboundedRegExpConcatenation * altElem = new UnboundedRegExpConcatenation( );
+			altElem->elements.push_back( leftPart->clone( ) );
+			altElem->elements.push_back( * altIt );
+
+			* altIt = altElem;
+		}
+
+		UnboundedRegExpElement * optIt = optimize( * it );
+		delete *it;
+		*it = optIt;
+
+		delete leftPart;
+		it = node->elements.erase( node->elements.begin( ), it );
+
+		optimized = true;
+		it ++;
+	}
+
+	return optimized;
 */
-    return false;
+	return false;
 }
 
 /**
@@ -417,47 +465,47 @@ bool RegExpOptimize::A8( UnboundedRegExpConcatenation * const & node )
 bool RegExpOptimize::A9( UnboundedRegExpConcatenation * const & node )
 {
 /*
-    bool optimized = false;
-
-    for( auto it = node->elements.begin( ); it != std::prev( node->elements.end( ) ); )
-    {
-        UnboundedRegExpAlternation * alt = dynamic_cast<UnboundedRegExpAlternation*>( * it );
-        if( ! alt )
-        {
-            it ++;
-            continue;
-        }
-
-        // take everything to the right and copy it as suffix of every element in alternation.
-        UnboundedRegExpConcatenation * rest = new UnboundedRegExpConcatenation( );
-        rest->elements.insert( rest->elements.end( ), std::next( it ), node->elements.end( ) );
-
-        for( auto altIt = alt->elements.begin( ); altIt != alt->elements.end( ); altIt ++ )
-        {
-            UnboundedRegExpConcatenation * altElem = new UnboundedRegExpConcatenation( );
-            altElem->elements.push_back( * altIt );
-            altElem->elements.push_back( rest->clone( ) );
-
-            * altIt = altElem;
-        }
-
-        UnboundedRegExpElement * optIt = optimize( * it );
-        delete *it;
-        *it = optIt;
-
-        delete rest;
-        it = node->elements.erase( std::next( it ), node->elements.end( ) );
-        optimized = true;
-
-        // as we move (delete) the rest of this expression, it surely wont do another round. More optimizations to be performerd are in subtree now.
-        // we do not care about this here as method optimize(UnboundedRegExpAlternation) will take care of this in next iteration
-        // it ++;
-        break;
-    }
-
-    return optimized;
+	bool optimized = false;
+
+	for( auto it = node->elements.begin( ); it != std::prev( node->elements.end( ) ); )
+	{
+		UnboundedRegExpAlternation * alt = dynamic_cast<UnboundedRegExpAlternation*>( * it );
+		if( ! alt )
+		{
+			it ++;
+			continue;
+		}
+
+		// take everything to the right and copy it as suffix of every element in alternation.
+		UnboundedRegExpConcatenation * rest = new UnboundedRegExpConcatenation( );
+		rest->elements.insert( rest->elements.end( ), std::next( it ), node->elements.end( ) );
+
+		for( auto altIt = alt->elements.begin( ); altIt != alt->elements.end( ); altIt ++ )
+		{
+			UnboundedRegExpConcatenation * altElem = new UnboundedRegExpConcatenation( );
+			altElem->elements.push_back( * altIt );
+			altElem->elements.push_back( rest->clone( ) );
+
+			* altIt = altElem;
+		}
+
+		UnboundedRegExpElement * optIt = optimize( * it );
+		delete *it;
+		*it = optIt;
+
+		delete rest;
+		it = node->elements.erase( std::next( it ), node->elements.end( ) );
+		optimized = true;
+
+		// as we move (delete) the rest of this expression, it surely wont do another round. More optimizations to be performerd are in subtree now.
+		// we do not care about this here as method optimize(UnboundedRegExpAlternation) will take care of this in next iteration
+		// it ++;
+		break;
+	}
+
+	return optimized;
 */
-    return false;
+	return false;
 }
 
 /**
@@ -467,71 +515,71 @@ bool RegExpOptimize::A9( UnboundedRegExpConcatenation * const & node )
   */
 bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node )
 {
-    bool optimized = false, optimizedIter = false;
-
-    /*
-     * problem:
-     * - \e + x*x = x*
-     * - but if we do not have the eps, but we do have iteration, then \e \in h(iter), therefore \e in h(node).
-     */
-
-    for( auto it = node->elements.begin( ); it != node->elements.end( ); )
-    {
-        optimizedIter = false;
-
-        // check if we have some epsilon or iteration left, else nothing to do
-        auto eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
-            return dynamic_cast<UnboundedRegExpEpsilon const *>( a ) || dynamic_cast<UnboundedRegExpIteration const*>( a );
-        });
-        if( eps == node->elements.end( ) )
-            break;
-
-        UnboundedRegExpConcatenation const * const & childConcat = dynamic_cast<UnboundedRegExpConcatenation const *>( *it );
-        if( childConcat )
-        {
-            // if iteration is first element of concatenation
-            UnboundedRegExpIteration const * const & iter = dynamic_cast<UnboundedRegExpIteration const *>( childConcat->elements.front( ) );
-
-            if( iter )
-            {
-                // concatenation without the iteration node
-                UnboundedRegExpConcatenation *tmpConcat = dynamic_cast<UnboundedRegExpConcatenation *>( childConcat->clone( ) );
-                delete tmpConcat->elements.front( );
-                tmpConcat->elements.erase( tmpConcat->elements.begin( ) );
-                UnboundedRegExpElement * tmpConcatOpt = optimize( tmpConcat );
-
-                // check if iteration element is the same subtree as rest of concatenation
-                if( * iter->element == * tmpConcatOpt )
-                {
-                    optimized = optimizedIter = true;
-
-                    node->elements.push_back( iter->clone( ) );
-
-                    delete childConcat;
-                    it = node->elements.erase( it );
-
-                    // find the eps again - invalidated after prev erase
-                    eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
-                        return dynamic_cast<UnboundedRegExpEpsilon const *>( a );
-                    });
-                    // if it was eps, delete it
-                    // if it was not the eps but iteration, keep it
-                    if( eps != node->elements.end( ) )
-                    {
-                        delete *eps;
-                        it = node->elements.erase( eps );
-                    }
-                }
-                delete tmpConcat;
-                delete tmpConcatOpt;
-            }
-        }
-
-        if( ! optimizedIter )
-            it ++;
-    }
-
-    return optimized;
+	bool optimized = false, optimizedIter = false;
+
+	/*
+	 * problem:
+	 * - \e + x*x = x*
+	 * - but if we do not have the eps, but we do have iteration, then \e \in h(iter), therefore \e in h(node).
+	 */
+
+	for( auto it = node->elements.begin( ); it != node->elements.end( ); )
+	{
+		optimizedIter = false;
+
+		// check if we have some epsilon or iteration left, else nothing to do
+		auto eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
+			return dynamic_cast<UnboundedRegExpEpsilon const *>( a ) || dynamic_cast<UnboundedRegExpIteration const*>( a );
+		});
+		if( eps == node->elements.end( ) )
+			break;
+
+		UnboundedRegExpConcatenation const * const & childConcat = dynamic_cast<UnboundedRegExpConcatenation const *>( *it );
+		if( childConcat )
+		{
+			// if iteration is first element of concatenation
+			UnboundedRegExpIteration const * const & iter = dynamic_cast<UnboundedRegExpIteration const *>( childConcat->elements.front( ) );
+
+			if( iter )
+			{
+				// concatenation without the iteration node
+				UnboundedRegExpConcatenation *tmpConcat = dynamic_cast<UnboundedRegExpConcatenation *>( childConcat->clone( ) );
+				delete tmpConcat->elements.front( );
+				tmpConcat->elements.erase( tmpConcat->elements.begin( ) );
+				UnboundedRegExpElement * tmpConcatOpt = optimize( tmpConcat );
+
+				// check if iteration element is the same subtree as rest of concatenation
+				if( * iter->element == * tmpConcatOpt )
+				{
+					optimized = optimizedIter = true;
+
+					node->elements.push_back( iter->clone( ) );
+
+					delete childConcat;
+					it = node->elements.erase( it );
+
+					// find the eps again - invalidated after prev erase
+					eps = find_if( node->elements.begin( ), node->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
+						return dynamic_cast<UnboundedRegExpEpsilon const *>( a );
+					});
+					// if it was eps, delete it
+					// if it was not the eps but iteration, keep it
+					if( eps != node->elements.end( ) )
+					{
+						delete *eps;
+						it = node->elements.erase( eps );
+					}
+				}
+				delete tmpConcat;
+				delete tmpConcatOpt;
+			}
+		}
+
+		if( ! optimizedIter )
+			it ++;
+	}
+
+	return optimized;
 }
 
 /**
@@ -541,28 +589,28 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node )
 {
-    bool optimized = false;
+	bool optimized = false;
 
-    UnboundedRegExpAlternation * const & childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node->element );
+	UnboundedRegExpAlternation * const & childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node->element );
 
-    if( childAlt )
-    {
-        // check if eps inside iteration's alternation
-        auto eps = find_if( childAlt->elements.begin( ), childAlt->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
-            return dynamic_cast<UnboundedRegExpEpsilon const *>( a );
-        });
+	if( childAlt )
+	{
+		// check if eps inside iteration's alternation
+		auto eps = find_if( childAlt->elements.begin( ), childAlt->elements.end( ), [ ]( UnboundedRegExpElement const * const & a ) -> bool {
+			return dynamic_cast<UnboundedRegExpEpsilon const *>( a );
+		});
 
-        // if no eps
-        if( eps == childAlt->elements.end( ) )
-            return false;
+		// if no eps
+		if( eps == childAlt->elements.end( ) )
+			return false;
 
-        // remove eps from alternation
-        optimized = true;
-        delete * eps;
-        childAlt->elements.erase( eps );
-    }
+		// remove eps from alternation
+		optimized = true;
+		delete * eps;
+		childAlt->elements.erase( eps );
+	}
 
-    return optimized;
+	return optimized;
 }
 
 /**
@@ -572,9 +620,9 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node )
   */
 bool RegExpOptimize::V1( UnboundedRegExpIteration * const & node )
 {
-    // implemented in optimize( UnboundedRegExpIteration )
+	// implemented in optimize( UnboundedRegExpIteration )
 
-    return false;
+	return false;
 }
 
 /**
@@ -584,74 +632,74 @@ bool RegExpOptimize::V1( UnboundedRegExpIteration * const & node )
   */
 bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node )
 {
-    bool optimized = false;
-
-    /*
-     * Bit tricky
-     * We need also to cover the cases like (a+b)* + a + b + c = (a+b)* + c
-     */
-
-    std::list<UnboundedRegExpElement*> iterElements;
-    // cache  iter elements because of operator invalidation after erase
-    for( const auto & n : node->elements )
-    {
-        UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( n );
-        if( iter )
-            iterElements.push_back( iter->element );
-    }
-
-    for( const auto & n : iterElements )
-    {
-        // if alternation is inside, we need to make sure that every element of alternation is inside node->elements. if so, delete them all
-        UnboundedRegExpAlternation * tmpAlt = dynamic_cast<UnboundedRegExpAlternation*>( n );
-        if( tmpAlt )
-        {
-            bool every = true;
-            for( const auto & altElem : tmpAlt->elements )
-            {
-                auto it = find_if( node->elements.begin( ), node->elements.end( ), [ altElem ]( UnboundedRegExpElement const * const & a ) -> bool {
-                    return *a == *altElem;
-                });
-
-                if( it == node->elements.end( ) )
-                    every = false;
-            }
-
-            if ( every == true )
-            {
-                optimized = true;
-
-                for( const auto & altElem : tmpAlt->elements )
-                {
-                    auto it = find_if( node->elements.begin( ), node->elements.end( ), [ altElem ]( UnboundedRegExpElement const * const & a ) -> bool {
-                        return *a == *altElem;
-                    });
-                    assert( it != node->elements.end( ) );
-
-                    delete *it;
-                    node->elements.erase( it );
-                }
-            }
-        }
-
-        // else
-        for( auto it = node->elements.begin( ); it != node->elements.end( ); )
-        {
-            if( *n == **it )
-            {
-                optimized = true;
-
-                delete *it;
-                it = node->elements.erase( it );
-            }
-            else
-            {
-                it ++;
-            }
-        }
-    }
-
-    return optimized;
+	bool optimized = false;
+
+	/*
+	 * Bit tricky
+	 * We need also to cover the cases like (a+b)* + a + b + c = (a+b)* + c
+	 */
+
+	std::list<UnboundedRegExpElement*> iterElements;
+	// cache  iter elements because of operator invalidation after erase
+	for( const auto & n : node->elements )
+	{
+		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( n );
+		if( iter )
+			iterElements.push_back( iter->element );
+	}
+
+	for( const auto & n : iterElements )
+	{
+		// if alternation is inside, we need to make sure that every element of alternation is inside node->elements. if so, delete them all
+		UnboundedRegExpAlternation * tmpAlt = dynamic_cast<UnboundedRegExpAlternation*>( n );
+		if( tmpAlt )
+		{
+			bool every = true;
+			for( const auto & altElem : tmpAlt->elements )
+			{
+				auto it = find_if( node->elements.begin( ), node->elements.end( ), [ altElem ]( UnboundedRegExpElement const * const & a ) -> bool {
+					return *a == *altElem;
+				});
+
+				if( it == node->elements.end( ) )
+					every = false;
+			}
+
+			if ( every == true )
+			{
+				optimized = true;
+
+				for( const auto & altElem : tmpAlt->elements )
+				{
+					auto it = find_if( node->elements.begin( ), node->elements.end( ), [ altElem ]( UnboundedRegExpElement const * const & a ) -> bool {
+						return *a == *altElem;
+					});
+					assert( it != node->elements.end( ) );
+
+					delete *it;
+					node->elements.erase( it );
+				}
+			}
+		}
+
+		// else
+		for( auto it = node->elements.begin( ); it != node->elements.end( ); )
+		{
+			if( *n == **it )
+			{
+				optimized = true;
+
+				delete *it;
+				it = node->elements.erase( it );
+			}
+			else
+			{
+				it ++;
+			}
+		}
+	}
+
+	return optimized;
 }
 
 /**
@@ -661,17 +709,17 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node )
 {
-    UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node->element );
-    if( childIter )
-    {
-        node->element = childIter->element;
-        childIter->element = NULL;
-        delete childIter;
+	UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node->element );
+	if( childIter )
+	{
+		node->element = childIter->element;
+		childIter->element = NULL;
+		delete childIter;
 
-        return true;
-    }
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 /**
@@ -681,25 +729,25 @@ bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node )
   */
 bool RegExpOptimize::V4( UnboundedRegExpIteration * const & node )
 {
-    // interpretation: if iteration's element is concat and every concat's element is iteration
-    UnboundedRegExpConcatenation* alt = dynamic_cast<UnboundedRegExpConcatenation*>( node->element );
-    if( ! alt || ! all_of( alt->elements.begin( ), alt->elements.end( ), [] ( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a ); } ) )
-        return false;
+	// interpretation: if iteration's element is concat and every concat's element is iteration
+	UnboundedRegExpConcatenation* alt = dynamic_cast<UnboundedRegExpConcatenation*>( node->element );
+	if( ! alt || ! all_of( alt->elements.begin( ), alt->elements.end( ), [] ( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a ); } ) )
+		return false;
 
-    UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( );
+	UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( );
 
-    for( const auto & n : alt->elements )
-    {
-        UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( n );
-        newAlt->elements.push_back( iter->element );
-        iter->element = NULL;
-    }
+	for( const auto & n : alt->elements )
+	{
+		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( n );
+		newAlt->elements.push_back( iter->element );
+		iter->element = NULL;
+	}
 
-    node->element = optimize( newAlt );
-    delete alt;
-    delete newAlt;
+	node->element = optimize( newAlt );
+	delete alt;
+	delete newAlt;
 
-    return true;
+	return true;
 }
 
 /**
@@ -709,150 +757,150 @@ bool RegExpOptimize::V4( UnboundedRegExpIteration * const & node )
   */
 bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node )
 {
-    bool optimized = false;
-
-    // reinterpretation: ax*y = ay+ax*xy
-    //      so, if we find iter, a = everything that is before it (prefix)
-    //                           x = iter's content
-    //                           behind iter must be exactly iter's content
-    //                           y = rest (suffix)
-    // prefix.x*x.suffix + prefix.suffix = prefix.x*.suffix
-
-    for( auto itA = node->elements.begin( ); itA != node->elements.end( ); )
-    {
-        UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( * itA );
-        if( ! concat )
-        {
-            itA ++;
-            continue;
-        }
-
-        for( auto itC = concat->elements.begin( ); itC != std::prev( concat->elements.end( ) ); )
-        {
-            UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( *itC );
-            if( ! iter )
-            {
-                itC ++;
-                continue;
-            }
-
-            // iteration's element must follow the iteration (x*x)
-            auto itStartY = std::next( itC ); //itStartY points to y in expression x*xy
-
-            // if iter's element is concat
-            if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element ) )
-            {
-                UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
-
-                // std::cout << "....." << std::endl;
-                // std::cout << RegExp( concat ) << std::endl;
-                // std::cout << RegExp( iterConcat ) << std::endl;
-                // UnboundedRegExpConcatenation * tmp = new UnboundedRegExpConcatenation( );
-                // tmp->elements.insert( tmp->elements.end( ), std::next( itC ), concat->elements.end( ) );
-                // std::cout << RegExp( tmp) << std::endl;
-
-                if( distance( iterConcat->elements.begin( ), iterConcat->elements.end( ) ) != distance( std::next( itC ), concat->elements.end( ) )
-                 || ! equal( iterConcat->elements.begin( ), iterConcat->elements.end( ), std::next( itC ),
-                    [ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool{ return *a == *b; } ) )
-                {
-                    itC++;
-                    continue;
-                }
-                advance( itStartY, (int)iterConcat->elements.size( ) );
-            }
-            // else
-            else
-            {
-                if( * iter->element != ** std::next( itC ) )
-                {
-                    itC ++;
-                    continue;
-                }
-
-                advance( itStartY, 1 );
-            }
-
-            // store everything before iteration as "a"
-            UnboundedRegExpElement * regexpA;
-            if( concat->elements.begin( ) == itC )
-            {
-                regexpA = new UnboundedRegExpEpsilon( );
-            }
-            else
-            {
-                UnboundedRegExpConcatenation * tmpA = new UnboundedRegExpConcatenation( );
-                tmpA->elements.insert( tmpA->elements.end( ), concat->elements.begin( ), itC );
-                regexpA = optimize( tmpA );
-                tmpA->elements.clear( );
-                delete tmpA;
-            }
-
-            // store everything behind iteration's followup element as "y"
-            UnboundedRegExpElement * regexpY;
-            if( itStartY == concat->elements.end( ) )
-            {
-                regexpY = new UnboundedRegExpEpsilon( );
-            }
-            else
-            {
-                UnboundedRegExpConcatenation* tmpY = new UnboundedRegExpConcatenation( );
-                tmpY->elements.insert( tmpY->elements.end( ), itStartY, concat->elements.end( ) );
-                regexpY = optimize( tmpY );
-                tmpY->elements.clear( );
-                delete tmpY;
-            }
-
-            // concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node->elements )
-            UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( );
-            tmpAY->elements.push_back( regexpA );
-            tmpAY->elements.push_back( regexpY );
-            UnboundedRegExpElement * regexpAY = optimize( tmpAY );
-            tmpAY->elements.clear( );
-            delete tmpAY;
-
-            auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( UnboundedRegExpElement const * const & a ) -> bool{ return *a == *regexpAY; } );
-            if( iterAY == node->elements.end( ) )
-            {
-                itC ++;
-                continue;
-            }
-
-            // if AY exists, then we can simply do this:
-                //iterator invalidated, need to backup concat node
-            UnboundedRegExpElement * tmpItA = *itA;
-
-            delete *iterAY;
-            node->elements.erase( iterAY );
-
-                // iterator invalidated, need to recall before erase
-            itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( UnboundedRegExpElement const * const & a ) -> bool { return *a == *tmpItA; } );
-
-            UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( );
-            tmpAltered->elements.push_back( regexpA );
-            tmpAltered->elements.push_back( * itC );
-            tmpAltered->elements.push_back( regexpY );
-            UnboundedRegExpElement * regexpAltered = optimize( tmpAltered );
-
-            tmpAltered->elements.clear( );
-            delete tmpAltered;
-
-            delete regexpA;
-            delete regexpY;
-            delete regexpAY;
-
-            delete *itA;
-            itA = node->elements.erase( itA );
-
-            node->elements.insert( itA, regexpAltered );
-
-            optimized = true;
-            break;
-        }
-
-        itA ++;
-    }
-
-    return optimized;
+	bool optimized = false;
+
+	// reinterpretation: ax*y = ay+ax*xy
+	//	  so, if we find iter, a = everything that is before it (prefix)
+	//						   x = iter's content
+	//						   behind iter must be exactly iter's content
+	//						   y = rest (suffix)
+	// prefix.x*x.suffix + prefix.suffix = prefix.x*.suffix
+
+	for( auto itA = node->elements.begin( ); itA != node->elements.end( ); )
+	{
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( * itA );
+		if( ! concat )
+		{
+			itA ++;
+			continue;
+		}
+
+		for( auto itC = concat->elements.begin( ); itC != std::prev( concat->elements.end( ) ); )
+		{
+			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( *itC );
+			if( ! iter )
+			{
+				itC ++;
+				continue;
+			}
+
+			// iteration's element must follow the iteration (x*x)
+			auto itStartY = std::next( itC ); //itStartY points to y in expression x*xy
+
+			// if iter's element is concat
+			if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element ) )
+			{
+				UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+
+				// std::cout << "....." << std::endl;
+				// std::cout << RegExp( concat ) << std::endl;
+				// std::cout << RegExp( iterConcat ) << std::endl;
+				// UnboundedRegExpConcatenation * tmp = new UnboundedRegExpConcatenation( );
+				// tmp->elements.insert( tmp->elements.end( ), std::next( itC ), concat->elements.end( ) );
+				// std::cout << RegExp( tmp) << std::endl;
+
+				if( distance( iterConcat->elements.begin( ), iterConcat->elements.end( ) ) != distance( std::next( itC ), concat->elements.end( ) )
+				 || ! equal( iterConcat->elements.begin( ), iterConcat->elements.end( ), std::next( itC ),
+					[ ]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool{ return *a == *b; } ) )
+				{
+					itC++;
+					continue;
+				}
+				advance( itStartY, (int)iterConcat->elements.size( ) );
+			}
+			// else
+			else
+			{
+				if( * iter->element != ** std::next( itC ) )
+				{
+					itC ++;
+					continue;
+				}
+
+				advance( itStartY, 1 );
+			}
+
+			// store everything before iteration as "a"
+			UnboundedRegExpElement * regexpA;
+			if( concat->elements.begin( ) == itC )
+			{
+				regexpA = new UnboundedRegExpEpsilon( );
+			}
+			else
+			{
+				UnboundedRegExpConcatenation * tmpA = new UnboundedRegExpConcatenation( );
+				tmpA->elements.insert( tmpA->elements.end( ), concat->elements.begin( ), itC );
+				regexpA = optimize( tmpA );
+				tmpA->elements.clear( );
+				delete tmpA;
+			}
+
+			// store everything behind iteration's followup element as "y"
+			UnboundedRegExpElement * regexpY;
+			if( itStartY == concat->elements.end( ) )
+			{
+				regexpY = new UnboundedRegExpEpsilon( );
+			}
+			else
+			{
+				UnboundedRegExpConcatenation* tmpY = new UnboundedRegExpConcatenation( );
+				tmpY->elements.insert( tmpY->elements.end( ), itStartY, concat->elements.end( ) );
+				regexpY = optimize( tmpY );
+				tmpY->elements.clear( );
+				delete tmpY;
+			}
+
+			// concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node->elements )
+			UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( );
+			tmpAY->elements.push_back( regexpA );
+			tmpAY->elements.push_back( regexpY );
+			UnboundedRegExpElement * regexpAY = optimize( tmpAY );
+			tmpAY->elements.clear( );
+			delete tmpAY;
+
+			auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( UnboundedRegExpElement const * const & a ) -> bool{ return *a == *regexpAY; } );
+			if( iterAY == node->elements.end( ) )
+			{
+				itC ++;
+				continue;
+			}
+
+			// if AY exists, then we can simply do this:
+				//iterator invalidated, need to backup concat node
+			UnboundedRegExpElement * tmpItA = *itA;
+
+			delete *iterAY;
+			node->elements.erase( iterAY );
+
+				// iterator invalidated, need to recall before erase
+			itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( UnboundedRegExpElement const * const & a ) -> bool { return *a == *tmpItA; } );
+
+			UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( );
+			tmpAltered->elements.push_back( regexpA );
+			tmpAltered->elements.push_back( * itC );
+			tmpAltered->elements.push_back( regexpY );
+			UnboundedRegExpElement * regexpAltered = optimize( tmpAltered );
+
+			tmpAltered->elements.clear( );
+			delete tmpAltered;
+
+			delete regexpA;
+			delete regexpY;
+			delete regexpAY;
+
+			delete *itA;
+			itA = node->elements.erase( itA );
+
+			node->elements.insert( itA, regexpAltered );
+
+			optimized = true;
+			break;
+		}
+
+		itA ++;
+	}
+
+	return optimized;
 }
 
 /**
@@ -862,148 +910,148 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node )
 {
-    bool optimized = false;
-
-    // reinterpretation: ax*y = ay+axx*y
-    //      so, if we find iter, a = everything that is before it (prefix)
-    //                           x = iter's content
-    //                           before iter must be exactly iter's content
-    //                           y = rest (suffix)
-    // prefix.xx*.suffix + prefix.suffix = prefix.x*.suffix
-
-    for( auto itA = node->elements.begin( ); itA != node->elements.end( ); )
-    {
-        UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( * itA );
-        if( ! concat )
-        {
-            itA ++;
-            continue;
-        }
-
-        for( auto itC = std::next( concat->elements.begin( ) ); itC != concat->elements.end( ); )
-        {
-            UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( * itC );
-            if( ! iter )
-            {
-                itC ++;
-                continue;
-            }
-
-            // iteration's element must preceed the iteration (xx*)
-            auto itStartX = itC; //itStartX points to first x in expression xx*, everything before is therefore prefix - regexp "a"
-
-            // if iter's element is concat
-            if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element ) )
-            {
-                UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
-
-                if( distance( concat->elements.begin( ), itC ) < (int)iterConcat->elements.size( ) )
-                {
-                    itC ++;
-                    continue;
-                }
-                advance( itStartX, - (int)(iterConcat->elements.size( ) ) );
-
-                if( distance( iterConcat->elements.begin( ), iterConcat->elements.end( ) ) != distance( itStartX, concat->elements.end( ) )
-                    ||
-                    ! equal( iterConcat->elements.begin( ), iterConcat->elements.end( ), itStartX,
-                    []( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool{ return *a == *b; } ) )
-                {
-                    itC++;
-                    continue;
-                }
-            }
-            // else
-            else
-            {
-                if( * iter->element != ** std::prev( itC ) )
-                {
-                    itC ++;
-                    continue;
-                }
-
-                advance( itStartX, -1 );
-            }
-
-            // store everything before x as "a"
-            UnboundedRegExpElement * regexpA;
-            if( concat->elements.begin( ) == itStartX )
-            {
-                regexpA = new UnboundedRegExpEpsilon( );
-            }
-            else
-            {
-                UnboundedRegExpConcatenation* tmpA = new UnboundedRegExpConcatenation( );
-                tmpA->elements.insert( tmpA->elements.end( ), concat->elements.begin( ), itStartX );
-                regexpA = optimize( tmpA );
-                tmpA->elements.clear( );
-                delete tmpA;
-            }
-
-            // store everything behind iteration's followup element as "y"
-            UnboundedRegExpElement * regexpY;
-            if( std::next( itC ) == concat->elements.end( ) )
-            {
-                regexpY = new UnboundedRegExpEpsilon( );
-            }
-            else
-            {
-                UnboundedRegExpConcatenation* tmpY = new UnboundedRegExpConcatenation( );
-                tmpY->elements.insert( tmpY->elements.end( ), std::next( itC ), concat->elements.end( ) );
-                regexpY = optimize( tmpY );
-                tmpY->elements.clear( );
-                delete tmpY;
-            }
-
-            // concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node->elements )
-            UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( );
-            tmpAY->elements.push_back( regexpA );
-            tmpAY->elements.push_back( regexpY );
-            UnboundedRegExpElement * regexpAY = optimize( tmpAY );
-            tmpAY->elements.clear( );
-            delete tmpAY;
-
-            auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( UnboundedRegExpElement const * const & a ) -> bool{ return *a == *regexpAY; } );
-            if( iterAY == node->elements.end( ) )
-            {
-                itC ++;
-                continue;
-            }
-
-            // if AY exists, then we can simply do this:
-                //iterator invalidated, need to backup concat node
-            UnboundedRegExpElement * tmpItA = *itA;
-            delete *iterAY;
-            node->elements.erase( iterAY );
-
-                // iterator invalidated, need to recall before erase
-            itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( UnboundedRegExpElement const * const & a ) -> bool { return *a == *tmpItA; } );
-
-            UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( );
-            tmpAltered->elements.push_back( regexpA );
-            tmpAltered->elements.push_back( * itC );
-            tmpAltered->elements.push_back( regexpY );
-            UnboundedRegExpElement * regexpAltered = optimize( tmpAltered );
-
-            tmpAltered->elements.clear( );
-            delete tmpAltered;
-
-            delete regexpA;
-            delete regexpY;
-            delete regexpAY;
-
-            delete *itA;
-            itA = node->elements.erase( itA );
-
-            node->elements.insert( itA, regexpAltered );
-            optimized = true;
-            break;
-        }
-
-        itA ++;
-    }
-
-    return optimized;
+	bool optimized = false;
+
+	// reinterpretation: ax*y = ay+axx*y
+	//	  so, if we find iter, a = everything that is before it (prefix)
+	//						   x = iter's content
+	//						   before iter must be exactly iter's content
+	//						   y = rest (suffix)
+	// prefix.xx*.suffix + prefix.suffix = prefix.x*.suffix
+
+	for( auto itA = node->elements.begin( ); itA != node->elements.end( ); )
+	{
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( * itA );
+		if( ! concat )
+		{
+			itA ++;
+			continue;
+		}
+
+		for( auto itC = std::next( concat->elements.begin( ) ); itC != concat->elements.end( ); )
+		{
+			UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( * itC );
+			if( ! iter )
+			{
+				itC ++;
+				continue;
+			}
+
+			// iteration's element must preceed the iteration (xx*)
+			auto itStartX = itC; //itStartX points to first x in expression xx*, everything before is therefore prefix - regexp "a"
+
+			// if iter's element is concat
+			if( dynamic_cast<UnboundedRegExpConcatenation*>( iter->element ) )
+			{
+				UnboundedRegExpConcatenation * iterConcat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+
+				if( distance( concat->elements.begin( ), itC ) < (int)iterConcat->elements.size( ) )
+				{
+					itC ++;
+					continue;
+				}
+				advance( itStartX, - (int)(iterConcat->elements.size( ) ) );
+
+				if( distance( iterConcat->elements.begin( ), iterConcat->elements.end( ) ) != distance( itStartX, concat->elements.end( ) )
+					||
+					! equal( iterConcat->elements.begin( ), iterConcat->elements.end( ), itStartX,
+					[]( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool{ return *a == *b; } ) )
+				{
+					itC++;
+					continue;
+				}
+			}
+			// else
+			else
+			{
+				if( * iter->element != ** std::prev( itC ) )
+				{
+					itC ++;
+					continue;
+				}
+
+				advance( itStartX, -1 );
+			}
+
+			// store everything before x as "a"
+			UnboundedRegExpElement * regexpA;
+			if( concat->elements.begin( ) == itStartX )
+			{
+				regexpA = new UnboundedRegExpEpsilon( );
+			}
+			else
+			{
+				UnboundedRegExpConcatenation* tmpA = new UnboundedRegExpConcatenation( );
+				tmpA->elements.insert( tmpA->elements.end( ), concat->elements.begin( ), itStartX );
+				regexpA = optimize( tmpA );
+				tmpA->elements.clear( );
+				delete tmpA;
+			}
+
+			// store everything behind iteration's followup element as "y"
+			UnboundedRegExpElement * regexpY;
+			if( std::next( itC ) == concat->elements.end( ) )
+			{
+				regexpY = new UnboundedRegExpEpsilon( );
+			}
+			else
+			{
+				UnboundedRegExpConcatenation* tmpY = new UnboundedRegExpConcatenation( );
+				tmpY->elements.insert( tmpY->elements.end( ), std::next( itC ), concat->elements.end( ) );
+				regexpY = optimize( tmpY );
+				tmpY->elements.clear( );
+				delete tmpY;
+			}
+
+			// concatenate "a" and "y" and see if they exist somewhere in parent alternation ( node->elements )
+			UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( );
+			tmpAY->elements.push_back( regexpA );
+			tmpAY->elements.push_back( regexpY );
+			UnboundedRegExpElement * regexpAY = optimize( tmpAY );
+			tmpAY->elements.clear( );
+			delete tmpAY;
+
+			auto iterAY = find_if( node->elements.begin( ), node->elements.end( ), [ regexpAY ] ( UnboundedRegExpElement const * const & a ) -> bool{ return *a == *regexpAY; } );
+			if( iterAY == node->elements.end( ) )
+			{
+				itC ++;
+				continue;
+			}
+
+			// if AY exists, then we can simply do this:
+				//iterator invalidated, need to backup concat node
+			UnboundedRegExpElement * tmpItA = *itA;
+			delete *iterAY;
+			node->elements.erase( iterAY );
+
+				// iterator invalidated, need to recall before erase
+			itA = find_if( node->elements.begin( ), node->elements.end( ), [ tmpItA ]( UnboundedRegExpElement const * const & a ) -> bool { return *a == *tmpItA; } );
+
+			UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( );
+			tmpAltered->elements.push_back( regexpA );
+			tmpAltered->elements.push_back( * itC );
+			tmpAltered->elements.push_back( regexpY );
+			UnboundedRegExpElement * regexpAltered = optimize( tmpAltered );
+
+			tmpAltered->elements.clear( );
+			delete tmpAltered;
+
+			delete regexpA;
+			delete regexpY;
+			delete regexpAY;
+
+			delete *itA;
+			itA = node->elements.erase( itA );
+
+			node->elements.insert( itA, regexpAltered );
+			optimized = true;
+			break;
+		}
+
+		itA ++;
+	}
+
+	return optimized;
 }
 
 /**
@@ -1013,80 +1061,80 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node )
   */
 bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node )
 {
-    bool optimized = false;
-
-    // interpretation: if there is iteration in concatenation node, and element of iteration contains eps and is straight before this iteration, then this element can be omitted
-
-    for( auto it = next( node->elements.begin( ) ); it != node->elements.end( ); )
-    {
-        UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( * it );
-
-        if( ! iter )
-        {
-            it ++;
-            continue;
-        }
-
-        // if element of iteration is concatenation, we need to check this specially
-        UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
-
-        if( concat )
-        {
-            // check if not out of bounds
-            if( distance( node->elements.begin( ), it ) < distance( concat->elements.begin(), concat->elements.end() ) )
-            {
-                it ++;
-                continue;
-            }
-
-            //FIXME: int cast
-            auto it2 = it;
-            advance( it2, - (int)concat->elements.size( ) );
-
-            if( concat->containsEmptyString( ) &&
-                distance( concat->elements.begin( ), concat->elements.end( )) == distance ( it2, node->elements.end( ) ) &&
-                equal( concat->elements.begin( ), concat->elements.end( ), it2, [] ( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a == *b; } ) )
-            {
-                optimized = true;
-
-                for( auto delIt = it2 ; delIt != it ; delIt ++ )
-                    delete *delIt;
-                it = node->elements.erase( it2, it );
-            }
-            else
-            {
-                it ++;
-            }
-        }
-        // else
-        else
-        {
-            if( it == node->elements.begin( ) )
-            {
-                it++;
-                continue;
-            }
-
-            auto prev = std::prev( it );
-
-            if( iter->element->containsEmptyString( ) && *( iter->element ) == **prev )
-            {
-                delete * prev;
-                it = node->elements.erase( prev );
-                optimized = true;
-
-                // in case xxx*, we need to stay on the iter element, not to go behind it
-                if( it != node->elements.begin( ) )
-                    it = std::prev( it );
-            }
-            else
-            {
-                it ++;
-            }
-        }
-    }
-
-    return optimized;
+	bool optimized = false;
+
+	// interpretation: if there is iteration in concatenation node, and element of iteration contains eps and is straight before this iteration, then this element can be omitted
+
+	for( auto it = next( node->elements.begin( ) ); it != node->elements.end( ); )
+	{
+		UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( * it );
+
+		if( ! iter )
+		{
+			it ++;
+			continue;
+		}
+
+		// if element of iteration is concatenation, we need to check this specially
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+
+		if( concat )
+		{
+			// check if not out of bounds
+			if( distance( node->elements.begin( ), it ) < distance( concat->elements.begin(), concat->elements.end() ) )
+			{
+				it ++;
+				continue;
+			}
+
+			//FIXME: int cast
+			auto it2 = it;
+			advance( it2, - (int)concat->elements.size( ) );
+
+			if( concat->containsEmptyString( ) &&
+				distance( concat->elements.begin( ), concat->elements.end( )) == distance ( it2, node->elements.end( ) ) &&
+				equal( concat->elements.begin( ), concat->elements.end( ), it2, [] ( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a == *b; } ) )
+			{
+				optimized = true;
+
+				for( auto delIt = it2 ; delIt != it ; delIt ++ )
+					delete *delIt;
+				it = node->elements.erase( it2, it );
+			}
+			else
+			{
+				it ++;
+			}
+		}
+		// else
+		else
+		{
+			if( it == node->elements.begin( ) )
+			{
+				it++;
+				continue;
+			}
+
+			auto prev = std::prev( it );
+
+			if( iter->element->containsEmptyString( ) && *( iter->element ) == **prev )
+			{
+				delete * prev;
+				it = node->elements.erase( prev );
+				optimized = true;
+
+				// in case xxx*, we need to stay on the iter element, not to go behind it
+				if( it != node->elements.begin( ) )
+					it = std::prev( it );
+			}
+			else
+			{
+				it ++;
+			}
+		}
+	}
+
+	return optimized;
 }
 
 /**
@@ -1096,62 +1144,62 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node )
   */
 bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & node )
 {
-    bool optimized = false;
-
-    // interpretation: if concat (C1) with iter && iteration's element is concat (C2), then:
-    //      simultaneously iterate through C1 and C2. (axy)*axz=ax(yax)*z -> get ax that is same and relocate them...
-
-    for( auto it = node->elements.begin( ) ; it != node->elements.end( ) ; )
-    {
-        UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( * it );
-        if ( ! iter )
-        {
-            it++;
-            continue;
-        }
-        UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
-        if( ! concat )
-        {
-            it++;
-            continue;
-        }
-
-        // find range from <it+1;sth> and <concat.begin;sth> that is equal
-        auto c1Iter = std::next( it ), c2Iter = concat->elements.begin( );
-        while( c1Iter != node->elements.end() && c2Iter != concat->elements.end( ) && **c1Iter == ** c2Iter )
-        {
-            c1Iter ++;
-            c2Iter ++;
-        }
-
-        if( c1Iter == std::next( it ) )
-        {
-            it ++;
-            continue;
-        }
-
-        // std::cout << "xy" << std::endl;
-        // UnboundedRegExpConcatenation* tmp = new UnboundedRegExpConcatenation( );
-        // tmp->elements.insert( tmp->elements.end( ), std::next( it ), c1Iter );
-        // std::cout << RegExp( tmp ) << std::endl;
-
-        // copy the range <it;sth>, delete it and go back to the iter node
+	bool optimized = false;
+
+	// interpretation: if concat (C1) with iter && iteration's element is concat (C2), then:
+	//	  simultaneously iterate through C1 and C2. (axy)*axz=ax(yax)*z -> get ax that is same and relocate them...
+
+	for( auto it = node->elements.begin( ) ; it != node->elements.end( ) ; )
+	{
+		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( * it );
+		if ( ! iter )
+		{
+			it++;
+			continue;
+		}
+		UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( iter->element );
+		if( ! concat )
+		{
+			it++;
+			continue;
+		}
+
+		// find range from <it+1;sth> and <concat.begin;sth> that is equal
+		auto c1Iter = std::next( it ), c2Iter = concat->elements.begin( );
+		while( c1Iter != node->elements.end() && c2Iter != concat->elements.end( ) && **c1Iter == ** c2Iter )
+		{
+			c1Iter ++;
+			c2Iter ++;
+		}
+
+		if( c1Iter == std::next( it ) )
+		{
+			it ++;
+			continue;
+		}
+
+		// std::cout << "xy" << std::endl;
+		// UnboundedRegExpConcatenation* tmp = new UnboundedRegExpConcatenation( );
+		// tmp->elements.insert( tmp->elements.end( ), std::next( it ), c1Iter );
+		// std::cout << RegExp( tmp ) << std::endl;
+
+		// copy the range <it;sth>, delete it and go back to the iter node
 	std::vector<UnboundedRegExpElement*> copyRange;
-        copyRange.insert( copyRange.end(), std::next( it ), c1Iter );
-        it = node->elements.erase( std::next( it ), c1Iter );
-        it = std::prev( it );
+		copyRange.insert( copyRange.end(), std::next( it ), c1Iter );
+		it = node->elements.erase( std::next( it ), c1Iter );
+		it = std::prev( it );
 
-        // insert that range before it position
-        node->elements.insert( it, copyRange.begin( ), copyRange.end( ) );
+		// insert that range before it position
+		node->elements.insert( it, copyRange.begin( ), copyRange.end( ) );
 
-        // alter the iteration's concat node
-        copyRange.clear( );
-        copyRange.insert( copyRange.end(), concat->elements.begin( ), c2Iter );
-        concat->elements.erase( concat->elements.begin( ), c2Iter );
-        concat->elements.insert( concat->elements.end(), copyRange.begin( ), copyRange.end( ) );
-    }
+		// alter the iteration's concat node
+		copyRange.clear( );
+		copyRange.insert( copyRange.end(), concat->elements.begin( ), c2Iter );
+		concat->elements.erase( concat->elements.begin( ), c2Iter );
+		concat->elements.insert( concat->elements.end(), copyRange.begin( ), copyRange.end( ) );
+	}
 
-    return optimized;
+	return optimized;
 }
 
 /**
@@ -1161,25 +1209,25 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & node )
   */
 bool RegExpOptimize::V10( UnboundedRegExpIteration * const & node )
 {
-    // interpretation: if iter's child is alternation where its every child is iteration, then they do not have to be iteration
-    UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node->element );
-    if( ! alt || ! all_of( alt->elements.begin( ), alt->elements.end( ), [] ( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a ); } ) )
-        return false;
+	// interpretation: if iter's child is alternation where its every child is iteration, then they do not have to be iteration
+	UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node->element );
+	if( ! alt || ! all_of( alt->elements.begin( ), alt->elements.end( ), [] ( UnboundedRegExpElement const * const & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration const * const >( a ); } ) )
+		return false;
 
-    UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( );
+	UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( );
 
-    for( const auto & n : alt->elements )
-    {
-        UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( n );
-        newAlt->elements.push_back( iter->element );
-        iter->element = NULL;
-    }
+	for( const auto & n : alt->elements )
+	{
+		UnboundedRegExpIteration * iter = dynamic_cast<UnboundedRegExpIteration*>( n );
+		newAlt->elements.push_back( iter->element );
+		iter->element = NULL;
+	}
 
-    node->element = optimize( newAlt );
-    delete alt;
-    delete newAlt;
+	node->element = optimize( newAlt );
+	delete alt;
+	delete newAlt;
 
-    return true;
+	return true;
 }
 
 /**
@@ -1189,20 +1237,20 @@ bool RegExpOptimize::V10( UnboundedRegExpIteration * const & node )
   */
 bool RegExpOptimize::X1( UnboundedRegExpAlternation * const & node )
 {
-    // theorem: In regexp like a* + \e, \e is described twice, first in a*, second in \e.
-    //  therefore we can delete the \e as it is redundant
+	// theorem: In regexp like a* + \e, \e is described twice, first in a*, second in \e.
+	//  therefore we can delete the \e as it is redundant
 
-    auto iter = find_if( node->elements.begin( ), node->elements.end( ), [] (UnboundedRegExpElement const * const & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration const * const>( a );} );
-    auto eps = find_if( node->elements.begin( ), node->elements.end( ), [] (UnboundedRegExpElement const * const & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon const * const>( a );} );
+	auto iter = find_if( node->elements.begin( ), node->elements.end( ), [] (UnboundedRegExpElement const * const & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration const * const>( a );} );
+	auto eps = find_if( node->elements.begin( ), node->elements.end( ), [] (UnboundedRegExpElement const * const & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon const * const>( a );} );
 
-    if( iter != node->elements.end( ) && eps != node->elements.end( ) )
-    {
-        delete *eps;
-        node->elements.erase( eps );
-        return true;
-    }
+	if( iter != node->elements.end( ) && eps != node->elements.end( ) )
+	{
+		delete *eps;
+		node->elements.erase( eps );
+		return true;
+	}
 
-    return false;
+	return false;
 }
 
 }
diff --git a/alib2algo/src/regexp/RegExpOptimize.h b/alib2algo/src/regexp/RegExpOptimize.h
index afb794762d06822b1c70e821867dcb223f2dca05..0e97409eee8503cffd0375b00c9220d420a44008 100644
--- a/alib2algo/src/regexp/RegExpOptimize.h
+++ b/alib2algo/src/regexp/RegExpOptimize.h
@@ -58,6 +58,7 @@ class RegExpOptimize
 {
 public:
     regexp::UnboundedRegExp optimize( const regexp::UnboundedRegExp & regexp );
+    void optimize( regexp::UnboundedRegExpElement & regexp );
 private:
     regexp::UnboundedRegExpElement * optimize( regexp::UnboundedRegExpElement const * const & node );
     regexp::UnboundedRegExpElement * optimize( regexp::UnboundedRegExpAlternation const * const & node );