diff --git a/aconversions/src/re2fa/Glushkov.cpp b/aconversions/src/re2fa/Glushkov.cpp
index da982d3e97e52502f9da7ee53ab00f83b344fb19..b3c4e060c82a7b10bb621b18a6067c11a8a376b9 100644
--- a/aconversions/src/re2fa/Glushkov.cpp
+++ b/aconversions/src/re2fa/Glushkov.cpp
@@ -18,8 +18,7 @@ namespace conversions
 
 Glushkov::Glushkov( const RegExp & re ) : AbstractREtoFAConverter( re )
 {
-    //FIXME in alib!
-    m_regexpRoot = const_cast<RegExp&>( m_re ).getRegExp( );
+
 }
 
 FSM Glushkov::convert( void )
@@ -40,41 +39,66 @@ FSM Glushkov::convert( void )
     State q0( "q0" );
     m_fsm.addState( q0 );
     m_fsm.addInitialState( q0 );
-    for( const auto & ns : m_numberedSymbols )
-        m_fsm.addState( ns.m_state );
+    for( const auto & kv : m_numberedSymbols )
+        m_fsm.addState( kv.second.m_state );
 
     // step 6
     for( const auto & ns : m_beginSymbolSet )
-        m_fsm.addTransition( TransitionFSM ( q0, ns->m_alphabetSymbol, ns->m_state ) );
+        m_fsm.addTransition( q0, ns.m_alphabetSymbol, ns.m_state );
     for( const auto & ns : m_neighbourSymbolSet )
-        m_fsm.addTransition( TransitionFSM ( State( ns.first->m_state ), ns.second->m_alphabetSymbol, State( ns.second->m_state ) ) );
+    {
+        const NumberedSymbol & first  = m_numberedSymbols.find( ns.m_first )->second;
+        const NumberedSymbol & second = m_numberedSymbols.find( ns.m_second )->second;
+
+        m_fsm.addTransition( first.m_state, second.m_alphabetSymbol, first.m_state );
+    }
 
     // step 7
     for( const auto & ns : m_endSymbolSet )
-        m_fsm.addFinalState( State ( ns->m_state ) );
+        m_fsm.addFinalState( State ( ns.m_state ) );
 
-    if( m_regexpRoot->containsEmptyString( ) )
+    if( m_re.containsEmptyString( ) )
         m_fsm.addFinalState( q0 );
 
     return m_fsm;
 }
 
-// ----------------------------------------------------------------------------
+void Glushkov::initNumberSymbols( void )
+{
+    int id = 1;
+
+    for( const auto & symb : RegExpAlphabet::getSymbolsListInOrder( m_re ) )
+        m_numberedSymbols.insert( pair<const RegExpSymbol*, NumberedSymbol>( symb, NumberedSymbol( symb, id ++ ) ) );
+}
 
 void Glushkov::constructBeginSymbolSet( void )
 {
-    for( const auto & s : getLeftmostSymbolsInTree( m_regexpRoot ) )
-        m_beginSymbolSet.insert( getNumberedSymbol( s ) );
+    for( const auto & s : getLeftmostSymbolsInTree( m_re.getRegExp( ) ) )
+        m_beginSymbolSet.insert( m_numberedSymbols.find( s )->second );
 }
 
-const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpElement * node ) const
+void Glushkov::constructEndSymbolSet( void )
 {
-    Alternation* alternation = dynamic_cast<Alternation*>( node );
-    Concatenation* concatenation = dynamic_cast<Concatenation*>( node );
-    Iteration* iteration = dynamic_cast<Iteration*>( node );
-    RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node );
-    RegExpEmpty* empty = dynamic_cast<RegExpEmpty*>( node );
-    RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node );
+    for( const auto & s : getRightmostSymbolsInTree( m_re.getRegExp( ) ) )
+        m_endSymbolSet.insert( m_numberedSymbols.find( s )->second );
+}
+
+void Glushkov::constructNeighbourSymbolSet( void )
+{
+    for( const auto & n : getNeighbours( m_re.getRegExp( ) ) )
+        m_neighbourSymbolSet.insert( n );
+}
+
+// ----------------------------------------------------------------------------
+
+set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpElement * node ) const
+{
+    const Alternation* alternation = dynamic_cast<const Alternation*>( node );
+    const Concatenation* concatenation = dynamic_cast<const Concatenation*>( node );
+    const Iteration* iteration = dynamic_cast<const Iteration*>( node );
+    const RegExpSymbol* symbol = dynamic_cast<const RegExpSymbol*>( node );
+    const RegExpEmpty* empty = dynamic_cast<const RegExpEmpty*>( node );
+    const RegExpEpsilon* eps = dynamic_cast<const RegExpEpsilon*>( node );
 
     if( symbol )
         return getLeftmostSymbolsInTree( symbol );
@@ -92,26 +116,26 @@ const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpElement * nod
      throw AlibException( "Glushkov::getLeftmostSymbolsInTree - invalid RegExpElement node" );
 }
 
-const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Alternation * node ) const
+set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const Alternation * node ) const
 {
-    set<RegExpSymbol*> ret;
+    set<const RegExpSymbol*> ret;
 
     for( const auto & e : node->getElements( ) )
     {
-        const set<RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e );
+        const set<const RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e );
         ret.insert( tmp.begin( ), tmp.end( ) );
     }
 
     return ret;
 }
 
-const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Concatenation * node ) const
+set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const Concatenation * node ) const
 {
-    set<RegExpSymbol*> ret;
+    set<const RegExpSymbol*> ret;
 
     for( const auto & e : node->getElements( ) )
     {
-        const set<RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e );
+        set<const RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e );
         ret.insert( tmp.begin( ), tmp.end( ) );
 
         if( ! e->containsEmptyString( ) ) // If this subtree can be epsilon, then we need to add next subtree also
@@ -121,41 +145,35 @@ const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Concatenation * nod
     return ret;
 }
 
-const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Iteration * node ) const
+set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const Iteration * node ) const
 {
     return getLeftmostSymbolsInTree( node->getElement( ) );
 }
 
-const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpSymbol * node ) const
+set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpSymbol * node ) const
 {
-    return set<RegExpSymbol*> { node };
+    return set<const RegExpSymbol*> { node };
 }
 
-const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpEpsilon * node ) const
+set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpEpsilon * node ) const
 {
-    return set<RegExpSymbol*>( );
+    return set<const RegExpSymbol*>( );
 }
 
-const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpEmpty * node ) const
+set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpEmpty * node ) const
 {
-    return set<RegExpSymbol*>( );
+    return set<const RegExpSymbol*>( );
 }
 // ----------------------------------------------------------------------------
 
-void Glushkov::constructEndSymbolSet( void )
-{
-    for( const auto & s : getRightmostSymbolsInTree( m_regexpRoot ) )
-        m_endSymbolSet.insert( getNumberedSymbol( s ) );
-}
-
-const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpElement * node ) const
+set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpElement * node ) const
 {
-    Alternation* alternation = dynamic_cast<Alternation*>( node );
-    Concatenation* concatenation = dynamic_cast<Concatenation*>( node );
-    Iteration* iteration = dynamic_cast<Iteration*>( node );
-    RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node );
-    RegExpEmpty* empty = dynamic_cast<RegExpEmpty*>( node );
-    RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node );
+    const Alternation* alternation = dynamic_cast<const Alternation*>( node );
+    const Concatenation* concatenation = dynamic_cast<const Concatenation*>( node );
+    const Iteration* iteration = dynamic_cast<const Iteration*>( node );
+    const RegExpSymbol* symbol = dynamic_cast<const RegExpSymbol*>( node );
+    const RegExpEmpty* empty = dynamic_cast<const RegExpEmpty*>( node );
+    const RegExpEpsilon* eps = dynamic_cast<const RegExpEpsilon*>( node );
 
     if( symbol )
         return getRightmostSymbolsInTree( symbol );
@@ -173,26 +191,26 @@ const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpElement * no
      throw AlibException( "Glushkov::getRightmostSymbolsInTree - invalid RegExpElement node" );
 }
 
-const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Alternation * node ) const
+set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const Alternation * node ) const
 {
-    set<RegExpSymbol*> ret;
+    set<const RegExpSymbol*> ret;
 
     for( const auto & e : node->getElements( ) )
     {
-        const set<RegExpSymbol*> tmp = getRightmostSymbolsInTree( e );
+        set<const RegExpSymbol*> tmp = getRightmostSymbolsInTree( e );
         ret.insert( tmp.begin( ), tmp.end( ) );
     }
 
     return ret;
 }
 
-const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Concatenation * node ) const
+set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const Concatenation * node ) const
 {
-    set<RegExpSymbol*> ret;
+    set<const RegExpSymbol*> ret;
 
     for( auto it = node->getElements( ).rbegin( ); it != node->getElements( ).rend( ) ; it ++ )
     {
-        const set<RegExpSymbol*> tmp = getRightmostSymbolsInTree( *it );
+        set<const RegExpSymbol*> tmp = getRightmostSymbolsInTree( *it );
         ret.insert( tmp.begin( ), tmp.end( ) );
 
         if( ! ( * it )->containsEmptyString( ) )
@@ -202,45 +220,36 @@ const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Concatenation * no
     return ret;
 }
 
-const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Iteration * node ) const
+set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const Iteration * node ) const
 {
     return getRightmostSymbolsInTree( node->getElement( ) );
 }
 
-const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpSymbol * node ) const
+set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpSymbol * node ) const
 {
-    return set<RegExpSymbol*> { node };
+    return set<const RegExpSymbol*> { node };
 }
 
-const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpEpsilon * node ) const
+set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpEpsilon * node ) const
 {
-    return set<RegExpSymbol*>( );
+    return set<const RegExpSymbol*>( );
 }
 
-const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpEmpty * node ) const
+set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpEmpty * node ) const
 {
-    return set<RegExpSymbol*>( );
+    return set<const RegExpSymbol*>( );
 }
 
 // ----------------------------------------------------------------------------
 
-void Glushkov::constructNeighbourSymbolSet( void )
+set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpElement * node )  const
 {
-    for( const auto & pair : getNeighbours( m_regexpRoot ) )
-    {
-        std::pair<const NumberedSymbol*, const NumberedSymbol*> p( getNumberedSymbol( pair.first ), getNumberedSymbol( pair.second ) );
-        m_neighbourSymbolSet.insert( p );
-    }
-}
-
-const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpElement * node )  const
-{
-    Alternation* alternation = dynamic_cast<Alternation*>( node );
-    Concatenation* concatenation = dynamic_cast<Concatenation*>( node );
-    Iteration* iteration = dynamic_cast<Iteration*>( node );
-    RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node );
-    RegExpEmpty* empty = dynamic_cast<RegExpEmpty*>( node );
-    RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node );
+    const Alternation* alternation = dynamic_cast<const Alternation*>( node );
+    const Concatenation* concatenation = dynamic_cast<const Concatenation*>( node );
+    const Iteration* iteration = dynamic_cast<const Iteration*>( node );
+    const RegExpSymbol* symbol = dynamic_cast<const RegExpSymbol*>( node );
+    const RegExpEmpty* empty = dynamic_cast<const RegExpEmpty*>( node );
+    const RegExpEpsilon* eps = dynamic_cast<const RegExpEpsilon*>( node );
 
     if( symbol )
         return getNeighbours( symbol );
@@ -258,25 +267,25 @@ const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbour
      throw AlibException( "Glushkov::getNeighbours - unknown RegExpElement* " );
 }
 
-const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( Alternation * node ) const
+set<Glushkov::Neighbours> Glushkov::getNeighbours( const Alternation * node ) const
 {
-    set<pair<const RegExpSymbol*, const RegExpSymbol*>> pairs;
+    set<Neighbours> n;
     for( const auto & e : node->getElements( ) )
     {
-        const set<pair<const RegExpSymbol*, const RegExpSymbol*>> tmp = getNeighbours( e );
-        pairs.insert( tmp.begin( ), tmp.end( ) );
+        set<Neighbours> tmp = getNeighbours( e );
+        n.insert( tmp.begin( ), tmp.end( ) );
     }
 
-    return pairs;
+    return n;
 }
 
-const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( Concatenation * node ) const
+set<Glushkov::Neighbours> Glushkov::getNeighbours( const Concatenation * node ) const
 {
-    set<pair<const RegExpSymbol*, const RegExpSymbol*>> pairs;
+    set<Neighbours> n;
     for( const auto & e : node->getElements( ) )
     {
-        const set<pair<const RegExpSymbol*, const RegExpSymbol*>> tmp = getNeighbours( e );
-        pairs.insert( tmp.begin( ), tmp.end( ) );
+        set<Neighbours> tmp = getNeighbours( e );
+        n.insert( tmp.begin( ), tmp.end( ) );
     }
 
     for( auto e = node->getElements( ).begin( ); e != node->getElements( ).end( ); e ++ )
@@ -285,70 +294,50 @@ const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbour
         if( f == node->getElements( ).end( ) )
             continue;
 
-        const set<RegExpSymbol*> rightmost = getRightmostSymbolsInTree( * e );
-
         for( f++ ; f != node->getElements( ).end( ); f ++ )
         {
-            const set<RegExpSymbol*> leftmost = getLeftmostSymbolsInTree( * f );
-            for( const auto & x : rightmost )
-                for( const auto & y : leftmost )
-                    pairs.insert( pair<const RegExpSymbol*, const RegExpSymbol*>( x, y ) );
+            for( const auto & x : getRightmostSymbolsInTree( * e ) )
+                for( const auto & y : getLeftmostSymbolsInTree( * f ) )
+                    n.insert( Neighbours( x, y ) );
 
             if( ! ( * f )->containsEmptyString( ) )
                 break;
         }
     }
 
-    return pairs;
+    return n;
 }
 
-const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( Iteration * node ) const
+set<Glushkov::Neighbours> Glushkov::getNeighbours( const Iteration * node ) const
 {
-    set<pair<const RegExpSymbol*, const RegExpSymbol*>> pairs;
-    const set<pair<const RegExpSymbol*, const RegExpSymbol*>> tmp = getNeighbours( node->getElement( ) );
-    pairs.insert( tmp.begin( ), tmp.end( ) );
+    set<Neighbours> n;
+    set<Neighbours> tmp = getNeighbours( node->getElement( ) );
+    n.insert( tmp.begin( ), tmp.end( ) );
 
-    const set<RegExpSymbol*> leftmost = getLeftmostSymbolsInTree( node->getElement( ) );
     for( const auto & x : getRightmostSymbolsInTree( node->getElement( ) ) )
-        for( const auto & y : leftmost )
-            pairs.insert( pair<const RegExpSymbol*, const RegExpSymbol*>( x, y ) );
+        for( const auto & y : getLeftmostSymbolsInTree( node->getElement( ) ) )
+            n.insert( Neighbours( x, y ) );
 
-    return pairs;
+    return n;
 }
 
-const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpSymbol * node ) const
+set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpSymbol * node ) const
 {
-    return set<pair<const RegExpSymbol*, const RegExpSymbol*>>();
+    return set<Neighbours>( );
 }
 
-const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpEpsilon * node ) const
+set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpEpsilon * node ) const
 {
-    return set<pair<const RegExpSymbol*, const RegExpSymbol*>>();
+    return set<Neighbours>( );
 }
 
-const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpEmpty * node ) const
+set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpEmpty * node ) const
 {
-    return set<pair<const RegExpSymbol*, const RegExpSymbol*>>();
+    return set<Neighbours>( );
 }
 
 // ----------------------------------------------------------------------------
 
-void Glushkov::initNumberSymbols( void )
-{
-    int iter = 1;
-
-    for( const auto & symb : RegExpAlphabet::getSymbolsListInOrder( m_re ) )
-        m_numberedSymbols.insert( NumberedSymbol( symb, iter ++ ) );
-}
-const Glushkov::NumberedSymbol * Glushkov::getNumberedSymbol( const RegExpSymbol * symbol ) const
-{
-    for( auto it = m_numberedSymbols.begin( ); it != m_numberedSymbols.end( ); it ++ )
-        if( it->m_regexpSymbol == symbol )
-            return & ( *it );
-
-     throw AlibException( "Glushkov::getNumberedSymbol - no symbol found!" );
-}
-
 bool Glushkov::NumberedSymbol::operator<( const NumberedSymbol & x ) const
 {
     return m_i < x.m_i;
@@ -356,11 +345,27 @@ bool Glushkov::NumberedSymbol::operator<( const NumberedSymbol & x ) const
 
 Glushkov::NumberedSymbol::NumberedSymbol( const RegExpSymbol * symbol, int i ) :
         m_i( i ),
-        m_regexpSymbol( symbol ),
-        m_alphabetSymbol( Symbol( m_regexpSymbol->getSymbol( ) ) ),
+        m_alphabetSymbol( symbol->getSymbol( ) ),
         m_state( State( "[" + m_alphabetSymbol.getSymbol( ) + "], id " + to_string( m_i ) ) )
 {
 
 }
 
+// ----------------------------------------------------------------------------
+
+Glushkov::Neighbours::Neighbours( const RegExpSymbol * first, const RegExpSymbol * second ) :
+        m_first( first ),
+        m_second( second )
+{
+
+}
+
+bool Glushkov::Neighbours::operator<( const Neighbours & x ) const
+{
+    if( m_first != x.m_first )
+        return m_first < x.m_first;
+    else
+        return m_second < x.m_second;
+}
+
 } /* namespace conversions */
diff --git a/aconversions/src/re2fa/Glushkov.h b/aconversions/src/re2fa/Glushkov.h
index 6fd433892c7249dd681181194ad57bbeb3cbeef9..525750b4b60fc37d93c927048c25285a5e0ae00e 100644
--- a/aconversions/src/re2fa/Glushkov.h
+++ b/aconversions/src/re2fa/Glushkov.h
@@ -37,7 +37,6 @@ private:
     struct NumberedSymbol
     {
         const int m_i;
-        const regexp::RegExpSymbol * m_regexpSymbol;
         const alphabet::Symbol m_alphabetSymbol;
         const automaton::State m_state;
 
@@ -45,44 +44,47 @@ private:
         bool operator<( const NumberedSymbol & x ) const;
     };
 
-    void initNumberSymbols( void );
-    const NumberedSymbol * getNumberedSymbol( const regexp::RegExpSymbol * symbol ) const;
+    struct Neighbours
+    {
+        const regexp::RegExpSymbol * m_first, * m_second;
 
+        Neighbours( const regexp::RegExpSymbol * first, const regexp::RegExpSymbol * second );
+        bool operator<( const Neighbours & x ) const;
+    };
+
+    void initNumberSymbols( void );
     void constructBeginSymbolSet( void );
     void constructEndSymbolSet( void );
     void constructNeighbourSymbolSet( void );
 
     // TODO: consider moving these to independent class or regexputils
-    const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpElement * node ) const;
-    const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::Alternation * node ) const;
-    const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::Concatenation * node ) const;
-    const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::Iteration * node ) const;
-    const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpSymbol * node ) const;
-    const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpEmpty * node ) const;
-    const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpEpsilon * node ) const;
-
-    const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpElement * node ) const;
-    const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::Alternation * node ) const;
-    const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::Concatenation * node ) const;
-    const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::Iteration * node ) const;
-    const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpSymbol * node ) const;
-    const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpEmpty * node ) const;
-    const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpEpsilon * node ) const;
-
-    const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpElement * node ) const;
-    const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::Alternation * node ) const;
-    const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::Concatenation * node ) const;
-    const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::Iteration * node ) const;
-    const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpSymbol * node ) const;
-    const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpEmpty * node ) const;
-    const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpEpsilon * node ) const;
-
-    regexp::RegExpElement* m_regexpRoot;
-
-    //TODO: Lists would be better here for complexity issues of set insert method
-    std::set<NumberedSymbol> m_numberedSymbols;
-    std::set<const NumberedSymbol*> m_beginSymbolSet, m_endSymbolSet;
-    std::set<std::pair<const NumberedSymbol*, const NumberedSymbol*>> m_neighbourSymbolSet;
+    std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpElement * node ) const;
+    std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::Alternation * node ) const;
+    std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::Concatenation * node ) const;
+    std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::Iteration * node ) const;
+    std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpSymbol * node ) const;
+    std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpEmpty * node ) const;
+    std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpEpsilon * node ) const;
+
+    std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpElement * node ) const;
+    std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::Alternation * node ) const;
+    std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::Concatenation * node ) const;
+    std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::Iteration * node ) const;
+    std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpSymbol * node ) const;
+    std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpEmpty * node ) const;
+    std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpEpsilon * node ) const;
+
+    std::set<Neighbours> getNeighbours( const regexp::RegExpElement * node ) const;
+    std::set<Neighbours> getNeighbours( const regexp::Alternation * node ) const;
+    std::set<Neighbours> getNeighbours( const regexp::Concatenation * node ) const;
+    std::set<Neighbours> getNeighbours( const regexp::Iteration * node ) const;
+    std::set<Neighbours> getNeighbours( const regexp::RegExpSymbol * node ) const;
+    std::set<Neighbours> getNeighbours( const regexp::RegExpEmpty * node ) const;
+    std::set<Neighbours> getNeighbours( const regexp::RegExpEpsilon * node ) const;
+
+    std::map<const regexp::RegExpElement*, NumberedSymbol> m_numberedSymbols;
+    std::set<NumberedSymbol> m_beginSymbolSet, m_endSymbolSet;
+    std::set<Neighbours> m_neighbourSymbolSet;
 
 };