diff --git a/alib2algo/src/rte/glushkov/GlushkovFirst.cpp b/alib2algo/src/rte/glushkov/GlushkovFirst.cpp
deleted file mode 100644
index 6648a418ca575ac6e4ed54d85e9449c6a49607da..0000000000000000000000000000000000000000
--- a/alib2algo/src/rte/glushkov/GlushkovFirst.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * GlushkovFirst.cpp
- *
- *  Created on: 14. 4. 2016
- *	  Author: Tomas Pecka
- */
-
-#include "GlushkovFirst.h"
-
-namespace rte {
-
-std::set < std::ranked_symbol < > > GlushkovFirst::first ( const rte::FormalRTE < > & rte ) {
-	return rte.getRTE ( ).getStructure ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( );
-}
-
-std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node ) {
-	std::set < std::ranked_symbol < > > ret, tmp;
-
-	tmp = node.getLeftElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( );
-	ret.insert ( tmp.begin ( ), tmp.end ( ) );
-
-	tmp = node.getRightElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( );
-	ret.insert ( tmp.begin ( ), tmp.end ( ) );
-
-	return ret;
-}
-
-std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node ) {
-	std::set < std::ranked_symbol < > > ret, tmp;
-
-	tmp = node.getLeftElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( );
-	ret.insert ( tmp.begin ( ), tmp.end ( ) );
-
-	 // First::Formal() returns a set. hence only one occurrence.
-	auto it = std::find_if ( ret.begin ( ), ret.end ( ), [node] ( const std::ranked_symbol < > & a ) {
-			return a == node.getSubstitutionSymbol ( ).getSymbol ( );
-		} );
-
-	if ( it != ret.end ( ) ) {
-		ret.erase ( it );
-		tmp = node.getRightElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( );
-		ret.insert ( tmp.begin ( ), tmp.end ( ) );
-	}
-
-	return ret;
-}
-
-std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node ) {
-	std::set < std::ranked_symbol < > > ret;
-
-	ret = node.getElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( );
-	ret.insert ( node.getSubstitutionSymbol ( ).getSymbol ( ) );
-	return ret;
-}
-
-std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node ) {
-	return std::set < std::ranked_symbol < > > { node.getSymbol ( ) };
-}
-
-std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node ) {
-	return std::set < std::ranked_symbol < > > { node.getSymbol ( ) };
-}
-
-std::set < std::ranked_symbol < > > GlushkovFirst::Formal::visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & /* node */ ) {
-	return std::set < std::ranked_symbol < > > ( );
-}
-
-} /* namespace rte */
diff --git a/alib2algo/src/rte/glushkov/GlushkovFirst.h b/alib2algo/src/rte/glushkov/GlushkovFirst.h
index b9c31490d5a4d0883fc50e0a08920c66ff8236b3..5c344b4aaa19b7759b51f6bf89b9370e840d6e9a 100644
--- a/alib2algo/src/rte/glushkov/GlushkovFirst.h
+++ b/alib2algo/src/rte/glushkov/GlushkovFirst.h
@@ -23,19 +23,84 @@ public:
 	 * @param re rte to probe
 	 * @return all rteSymbols which can be root of the tree.
 	 */
-	static std::set < std::ranked_symbol < > > first ( const rte::FormalRTE < > & re );
+	template < class SymbolType, class RankType >
+	static std::set < std::ranked_symbol < SymbolType, RankType > > first ( const rte::FormalRTE < SymbolType, RankType > & re );
 
+	template < class SymbolType, class RankType >
 	class Formal {
 	public:
-		static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node );
-		static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node );
-		static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node );
-		static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node );
-		static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node );
-		static std::set < std::ranked_symbol < > > visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & node );
+		static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node );
+		static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node );
+		static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node );
+		static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node );
+		static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node );
+		static std::set < std::ranked_symbol < SymbolType, RankType > > visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node );
 	};
 };
 
+template < class SymbolType, class RankType >
+std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::first ( const rte::FormalRTE < SymbolType, RankType > & rte ) {
+	return rte.getRTE ( ).getStructure ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( );
+}
+
+template < class SymbolType, class RankType >
+std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node ) {
+	std::set < std::ranked_symbol < SymbolType, RankType > > ret, tmp;
+
+	tmp = node.getLeftElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( );
+	ret.insert ( tmp.begin ( ), tmp.end ( ) );
+
+	tmp = node.getRightElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( );
+	ret.insert ( tmp.begin ( ), tmp.end ( ) );
+
+	return ret;
+}
+
+template < class SymbolType, class RankType >
+std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node ) {
+	std::set < std::ranked_symbol < SymbolType, RankType > > ret, tmp;
+
+	tmp = node.getLeftElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( );
+	ret.insert ( tmp.begin ( ), tmp.end ( ) );
+
+	 // First returns a set. hence only one occurrence.
+	auto it = std::find_if ( ret.begin ( ), ret.end ( ), [node] ( const std::ranked_symbol < SymbolType, RankType > & a ) {
+			return a == node.getSubstitutionSymbol ( ).getSymbol ( );
+		} );
+
+	if ( it != ret.end ( ) ) {
+		ret.erase ( it );
+		tmp = node.getRightElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( );
+		ret.insert ( tmp.begin ( ), tmp.end ( ) );
+	}
+
+	return ret;
+}
+
+template < class SymbolType, class RankType >
+std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node ) {
+	std::set < std::ranked_symbol < SymbolType, RankType > > ret;
+
+	ret = node.getElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( );
+	ret.insert ( node.getSubstitutionSymbol ( ).getSymbol ( ) );
+	return ret;
+}
+
+template < class SymbolType, class RankType >
+std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node ) {
+	return std::set < std::ranked_symbol < SymbolType, RankType > > { node.getSymbol ( ) };
+}
+
+template < class SymbolType, class RankType >
+std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node ) {
+	return std::set < std::ranked_symbol < SymbolType, RankType > > { node.getSymbol ( ) };
+}
+
+template < class SymbolType, class RankType >
+std::set < std::ranked_symbol < SymbolType, RankType > > GlushkovFirst::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */ ) {
+	return std::set < std::ranked_symbol < SymbolType, RankType > > ( );
+}
+
 } /* namespace rte */
 
 #endif /* RTE_GLUSHKOV_FIRST_H_ */
diff --git a/alib2algo/src/rte/glushkov/GlushkovFollow.cpp b/alib2algo/src/rte/glushkov/GlushkovFollow.cpp
deleted file mode 100644
index 37a8cea54feb423899e17d4ab68fa64c7ed4bded..0000000000000000000000000000000000000000
--- a/alib2algo/src/rte/glushkov/GlushkovFollow.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * GlushkovFollow.cpp
- *
- *  Created on: 14. 4. 2016
- *	  Author: Tomas Pecka
- */
-
-#include "GlushkovFollow.h"
-#include "GlushkovFirst.h"
-#include "GlushkovPos.h"
-#include <iterator>
-#include <vector>
-
-namespace rte {
-
-std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::follow ( const rte::FormalRTE < > & rte, const std::ranked_symbol < > & symbol ) {
-	std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > subMap;
-
-	 /* Init substitution map, ie \forall a \in K: sub[a] = \emptyset */
-	for ( const std::ranked_symbol < > & ssymb : rte.getSubstitutionAlphabet ( ) )
-		subMap.insert ( std::make_pair ( ssymb, std::set < std::ranked_symbol < > > { } ) );
-
-	 /* recursively compute follow */
-	return rte.getRTE ( ).getStructure ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbol, rte.getSubstitutionAlphabet ( ), subMap );
-}
-
-// -----------------------------------------------------------------------------
-
-template < class T >
-void cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth ) {
-	if ( depth == input.size ( ) )
-		ret.push_back ( current );
-	else
-		for ( size_t i = 0; i < input[depth].size ( ); i++ ) {
-			current[depth] = input[depth][i];
-			cartesian_rec ( input, ret, current, depth + 1 );
-		}
-
-}
-
-template < class T >
-std::vector < std::vector < T > > cartesian ( const std::vector < std::vector < T > > & input ) {
-	std::vector < std::vector < T > > ret;
-	std::vector < T > current ( input.size ( ), std::ranked_symbol < > ( 0, 0 ) );
-
-	cartesian_rec ( input, ret, current, 0 );
-
-	return ret;
-}
-
-void preprocessSubMap ( const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) {
-	for ( bool change = true; change; change = false )
-		for ( std::pair < const std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & kv : subMap ) {
-			std::set < std::ranked_symbol < > > & substSet = kv.second;
-
-			for ( const auto & e : substSet ) {
-				if ( alphabetK.count ( e ) == 0 ) continue;
-
-				auto it = subMap.find ( e );
-				size_t oldSize = substSet.size ( );
-				substSet.insert ( it->second.begin ( ), it->second.end ( ) );
-				change = ( oldSize != substSet.size ( ) ); // something was added
-				substSet.erase ( e );
-			}
-		}
-}
-
-std::set < std::vector < std::ranked_symbol < > > > replaceConstants ( const std::set < std::ranked_symbol < > > & alphabetK, const std::vector < std::ranked_symbol < > > & follow, const std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap2 ) {
-	std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > subMap ( subMap2 );
-	preprocessSubMap ( alphabetK, subMap );
-
-	std::vector < std::vector < std::ranked_symbol < > > > input;
-
-	for ( const std::ranked_symbol < > & e : follow ) {
-		if ( alphabetK.count ( e ) > 0 )
-			input.push_back ( std::vector < std::ranked_symbol < > > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) );
-		else
-			input.push_back ( std::vector < std::ranked_symbol < > > { e } );
-	}
-
-	 /* now do the cartesian product on "input" */
-	std::vector < std::vector < std::ranked_symbol < > > > followSet = cartesian ( input );
-	return std::set < std::vector < std::ranked_symbol < > > > ( followSet.begin ( ), followSet.end ( ) );
-}
-
-// -----------------------------------------------------------------------------
-
-std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) {
-	std::set < std::vector < std::ranked_symbol < > > > ret, tmp;
-
-	tmp = node.getLeftElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap );
-	ret.insert ( tmp.begin ( ), tmp.end ( ) );
-
-	tmp = node.getRightElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap );
-	ret.insert ( tmp.begin ( ), tmp.end ( ) );
-
-	return ret;
-}
-
-std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) {
-
-	std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > subMap2 ( subMap );
-	auto itMap = subMap2.find ( node.getSubstitutionSymbol ( ).getSymbol ( ) );
-
-	itMap->second.clear ( );
-
-	for ( const auto & s : node.getRightElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ) )
-		itMap->second.insert ( s );
-
-	/*
-	 * E sub F
-	 *   1. if symbolF in F subtree, then Follow(F, symbolF);
-	 *   2. if symbolF in E subtree, then Follow(E, symbolF);
-	 */
-
-	if ( node.getLeftElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ) )
-		return node.getLeftElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap2 );
-	else
-		return node.getRightElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap );
-}
-
-std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) {
-
-	std::set < std::vector < std::ranked_symbol < > > > ret;
-
-	for ( const auto & s : node.getElement ( ).accept < std::set < std::ranked_symbol < > >, GlushkovFirst::Formal > ( ) )
-		subMap[node.getSubstitutionSymbol ( ).getSymbol ( )].insert ( s );
-
-	return node.getElement ( ).accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap );
-}
-
-std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subMap ) {
-
-	std::set < std::vector < std::ranked_symbol < > > > ret, tmp;
-
-	if ( symbolF == node.getSymbol ( ) ) {
-		std::vector < std::ranked_symbol < > > children;
-
-		for ( const std::smart_ptr < const rte::FormalRTESymbol < alphabet::Symbol, primitive::Unsigned > > & c : node.getElements ( ) )
-			children.push_back ( c->getSymbol ( ) );
-
-		return replaceConstants ( alphabetK, children, subMap );
-	}
-
-	for ( const auto & c : node.getElements ( ) ) {
-		tmp = c->accept < std::set < std::vector < std::ranked_symbol < > > >, GlushkovFollow::Formal > ( symbolF, alphabetK, subMap );
-		ret.insert ( tmp.begin ( ), tmp.end ( ) );
-	}
-
-	return ret;
-}
-
-std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & /* node */, const std::ranked_symbol < > & /* symbolF */, const std::set < std::ranked_symbol < > > & /* alphabetK */, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & /* subMap */ ) {
-	return std::set < std::vector < std::ranked_symbol < > > > ( );
-}
-
-std::set < std::vector < std::ranked_symbol < > > > GlushkovFollow::Formal::visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & /* node */, const std::ranked_symbol < > & /* symbolF */, const std::set < std::ranked_symbol < > > & /* alphabetK */, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & /* subMap */ ) {
-	return std::set < std::vector < std::ranked_symbol < > > > ( );
-}
-
-} /* namespace rte */
diff --git a/alib2algo/src/rte/glushkov/GlushkovFollow.h b/alib2algo/src/rte/glushkov/GlushkovFollow.h
index 0de211129a8a65811780871f77dccdd8fe2908b6..a1a072a764823ebc66478c60499ce279919bc5eb 100644
--- a/alib2algo/src/rte/glushkov/GlushkovFollow.h
+++ b/alib2algo/src/rte/glushkov/GlushkovFollow.h
@@ -17,29 +17,198 @@
 
 #include <alphabet/RankedSymbol.h>
 
+#include "GlushkovFirst.h"
+#include "GlushkovPos.h"
+#include <iterator>
+#include <vector>
+
 namespace rte {
 
 class GlushkovFollow {
+	template < class SymbolType, class RankType >
+	static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > replaceConstants ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap2 );
+	template < class SymbolType, class RankType >
+	static void preprocessSubMap ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap );
+	template < class T >
+	static std::vector < std::vector < T > > cartesian ( const std::vector < std::vector < T > > & input );
+	template < class T >
+	static void cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth );
 public:
 	/**
 	 * @param re rte to probe
 	 * @param symbol FormalRTESymbol for which we need the follow(), i.e., Follow(RTE, symbol)
 	 * @return all symbols that can follow specific symbol in word
 	 */
-	static std::set < std::vector < std::ranked_symbol < > > > follow ( const rte::FormalRTE < > & re, const std::ranked_symbol < > & symbol );
+	template < class SymbolType, class RankType >
+	static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > follow ( const rte::FormalRTE < SymbolType, RankType > & re, const std::ranked_symbol < SymbolType, RankType > & symbol );
 
+	template < class SymbolType, class RankType >
 	class Formal {
 	public:
-		static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTEElement < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM );
-		static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM );
-		static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM );
-		static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM );
-		static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM );
-		static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM );
-		static std::set < std::vector < std::ranked_symbol < > > > visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbol, const std::set < std::ranked_symbol < > > & alphabetK, std::map < std::ranked_symbol < >, std::set < std::ranked_symbol < > > > & subM );
+		static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEElement < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM );
+		static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM );
+		static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM );
+		static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM );
+		static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM );
+		static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM );
+		static std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbol, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subM );
 	};
 };
 
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::follow ( const rte::FormalRTE < SymbolType, RankType > & rte, const std::ranked_symbol < SymbolType, RankType > & symbol ) {
+	std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > subMap;
+
+	 /* Init substitution map, ie \forall a \in K: sub[a] = \emptyset */
+	for ( const std::ranked_symbol < SymbolType, RankType > & ssymb : rte.getSubstitutionAlphabet ( ) )
+		subMap.insert ( std::make_pair ( ssymb, std::set < std::ranked_symbol < SymbolType, RankType > > { } ) );
+
+	 /* recursively compute follow */
+	return rte.getRTE ( ).getStructure ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbol, rte.getSubstitutionAlphabet ( ), subMap );
+}
+
+// -----------------------------------------------------------------------------
+
+template < class T >
+void GlushkovFollow::cartesian_rec ( const std::vector < std::vector < T > > & input, std::vector < std::vector < T > > & ret, std::vector < T > & current, size_t depth ) {
+	if ( depth == input.size ( ) )
+		ret.push_back ( current );
+	else
+		for ( size_t i = 0; i < input[depth].size ( ); i++ ) {
+			current[depth] = input[depth][i];
+			cartesian_rec ( input, ret, current, depth + 1 );
+		}
+
+}
+
+template < class T >
+std::vector < std::vector < T > > GlushkovFollow::cartesian ( const std::vector < std::vector < T > > & input ) {
+	std::vector < std::vector < T > > ret;
+	std::vector < T > current ( input.size ( ), T ( 0, 0 ) );
+
+	cartesian_rec ( input, ret, current, 0 );
+
+	return ret;
+}
+
+template < class SymbolType, class RankType >
+void GlushkovFollow::preprocessSubMap ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) {
+	for ( bool change = true; change; change = false )
+		for ( std::pair < const std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & kv : subMap ) {
+			std::set < std::ranked_symbol < SymbolType, RankType > > & substSet = kv.second;
+
+			for ( const auto & e : substSet ) {
+				if ( alphabetK.count ( e ) == 0 ) continue;
+
+				auto it = subMap.find ( e );
+				size_t oldSize = substSet.size ( );
+				substSet.insert ( it->second.begin ( ), it->second.end ( ) );
+				change = ( oldSize != substSet.size ( ) ); // something was added
+				substSet.erase ( e );
+			}
+		}
+}
+
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::replaceConstants ( const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, const std::vector < std::ranked_symbol < SymbolType, RankType > > & follow, const std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap2 ) {
+	std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > subMap ( subMap2 );
+	preprocessSubMap ( alphabetK, subMap );
+
+	std::vector < std::vector < std::ranked_symbol < SymbolType, RankType > > > input;
+
+	for ( const std::ranked_symbol < SymbolType, RankType > & e : follow ) {
+		if ( alphabetK.count ( e ) > 0 )
+			input.push_back ( std::vector < std::ranked_symbol < SymbolType, RankType > > ( subMap.at ( e ).begin ( ), subMap.at ( e ).end ( ) ) );
+		else
+			input.push_back ( std::vector < std::ranked_symbol < SymbolType, RankType > > { e } );
+	}
+
+	 /* now do the cartesian product on "input" */
+	std::vector < std::vector < std::ranked_symbol < SymbolType, RankType > > > followSet = cartesian ( input );
+	return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( followSet.begin ( ), followSet.end ( ) );
+}
+
+// -----------------------------------------------------------------------------
+
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) {
+	std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret, tmp;
+
+	tmp = node.getLeftElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap );
+	ret.insert ( tmp.begin ( ), tmp.end ( ) );
+
+	tmp = node.getRightElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap );
+	ret.insert ( tmp.begin ( ), tmp.end ( ) );
+
+	return ret;
+}
+
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) {
+
+	std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > subMap2 ( subMap );
+	auto itMap = subMap2.find ( node.getSubstitutionSymbol ( ).getSymbol ( ) );
+
+	itMap->second.clear ( );
+
+	for ( const auto & s : node.getRightElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ) )
+		itMap->second.insert ( s );
+
+	/*
+	 * E sub F
+	 *   1. if symbolF in F subtree, then Follow(F, symbolF);
+	 *   2. if symbolF in E subtree, then Follow(E, symbolF);
+	 */
+
+	if ( node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) )
+		return node.getLeftElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap2 );
+	else
+		return node.getRightElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap );
+}
+
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) {
+
+	std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret;
+
+	for ( const auto & s : node.getElement ( ).template accept < std::set < std::ranked_symbol < SymbolType, RankType > >, GlushkovFirst::Formal < SymbolType, RankType > > ( ) )
+		subMap[node.getSubstitutionSymbol ( ).getSymbol ( )].insert ( s );
+
+	return node.getElement ( ).template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap );
+}
+
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF, const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabetK, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & subMap ) {
+
+	std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ret, tmp;
+
+	if ( symbolF == node.getSymbol ( ) ) {
+		std::vector < std::ranked_symbol < SymbolType, RankType > > children;
+
+		for ( const std::smart_ptr < const rte::FormalRTESymbol < SymbolType, RankType > > & c : node.getElements ( ) )
+			children.push_back ( c->getSymbol ( ) );
+
+		return replaceConstants ( alphabetK, children, subMap );
+	}
+
+	for ( const auto & c : node.getElements ( ) ) {
+		tmp = c->template accept < std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > >, GlushkovFollow::Formal < SymbolType, RankType > > ( symbolF, alphabetK, subMap );
+		ret.insert ( tmp.begin ( ), tmp.end ( ) );
+	}
+
+	return ret;
+}
+
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const std::set < std::ranked_symbol < SymbolType, RankType > > & /* alphabetK */, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & /* subMap */ ) {
+	return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( );
+}
+
+template < class SymbolType, class RankType >
+std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > GlushkovFollow::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */, const std::set < std::ranked_symbol < SymbolType, RankType > > & /* alphabetK */, std::map < std::ranked_symbol < SymbolType, RankType >, std::set < std::ranked_symbol < SymbolType, RankType > > > & /* subMap */ ) {
+	return std::set < std::vector < std::ranked_symbol < SymbolType, RankType > > > ( );
+}
+
 } /* namespace rte */
 
 #endif /* RTE_GLUSHKOV_FOLLOW_H_ */
diff --git a/alib2algo/src/rte/glushkov/GlushkovPos.cpp b/alib2algo/src/rte/glushkov/GlushkovPos.cpp
deleted file mode 100644
index c1ef63729b961f30335094ccbed5dca54e8f3913..0000000000000000000000000000000000000000
--- a/alib2algo/src/rte/glushkov/GlushkovPos.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * GlushkovPos.cpp
- *
- *  Created on: 14. 4. 2016
- *	  Author: Tomas Pecka
- */
-
-#include "GlushkovPos.h"
-#include <rte/formal/FormalRTEElements.h>
-
-namespace rte {
-
-bool GlushkovPos::pos ( const std::ranked_symbol < > & symbol, const rte::FormalRTE < > & rte ) {
-	return rte.getRTE ( ).getStructure ( ).accept < bool, GlushkovPos::Formal > ( symbol );
-}
-
-bool GlushkovPos::Formal::visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) {
-	return node.getLeftElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ) || node.getRightElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF );
-}
-
-bool GlushkovPos::Formal::visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) {
-	return node.getLeftElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF ) || node.getRightElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF );
-}
-
-bool GlushkovPos::Formal::visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) {
-	return node.getElement ( ).accept < bool, GlushkovPos::Formal > ( symbolF );
-}
-
-bool GlushkovPos::Formal::visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) {
-	if ( symbolF == node.getSymbol ( ) ) return true;
-
-	for ( const std::smart_ptr < const rte::FormalRTESymbol < alphabet::Symbol, primitive::Unsigned > > & element : node.getElements ( ) )
-		if ( element->accept < bool, GlushkovPos::Formal > ( symbolF ) )
-			return true;
-
-	return false;
-}
-
-bool GlushkovPos::Formal::visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbolF ) {
-	return symbolF == node.getSymbol ( );
-}
-
-bool GlushkovPos::Formal::visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & /* node */, const std::ranked_symbol < > & /* symbolF */ ) {
-	return false;
-}
-
-} /* namespace rte */
diff --git a/alib2algo/src/rte/glushkov/GlushkovPos.h b/alib2algo/src/rte/glushkov/GlushkovPos.h
index 5ca719fac7a3ec678da0fab57d4c3faa2d902109..99fbea1f2555c718539cf4bf446b61c526f729c7 100644
--- a/alib2algo/src/rte/glushkov/GlushkovPos.h
+++ b/alib2algo/src/rte/glushkov/GlushkovPos.h
@@ -10,6 +10,7 @@
 
 #include <rte/formal/FormalRTE.h>
 #include <rte/RTEFeatures.h>
+#include <rte/formal/FormalRTEElements.h>
 
 #include <alphabet/RankedSymbol.h>
 
@@ -20,19 +21,62 @@ public:
 	/**
 	 * @return bool true if symbol pointer is in this subtree
 	 */
-	static bool pos ( const std::ranked_symbol < > & symbol, const rte::FormalRTE < > & node );
+	template < class SymbolType, class RankType >
+	static bool pos ( const std::ranked_symbol < SymbolType, RankType > & symbol, const rte::FormalRTE < SymbolType, RankType > & node );
 
+	template < class SymbolType, class RankType >
 	class Formal {
 	public:
-		static bool visit ( const rte::FormalRTEAlternation < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch );
-		static bool visit ( const rte::FormalRTESubstitution < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch );
-		static bool visit ( const rte::FormalRTEIteration < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch );
-		static bool visit ( const rte::FormalRTESymbolAlphabet < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch );
-		static bool visit ( const rte::FormalRTESymbolSubst < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch );
-		static bool visit ( const rte::FormalRTEEmpty < alphabet::Symbol, primitive::Unsigned > & node, const std::ranked_symbol < > & symbSearch );
+		static bool visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch );
+		static bool visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch );
+		static bool visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch );
+		static bool visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch );
+		static bool visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch );
+		static bool visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbSearch );
 	};
 };
 
+template < class SymbolType, class RankType >
+bool GlushkovPos::pos ( const std::ranked_symbol < SymbolType, RankType > & symbol, const rte::FormalRTE < SymbolType, RankType > & rte ) {
+	return rte.getRTE ( ).getStructure ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbol );
+}
+
+template < class SymbolType, class RankType >
+bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEAlternation < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) {
+	return node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) || node.getRightElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF );
+}
+
+template < class SymbolType, class RankType >
+bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESubstitution < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) {
+	return node.getLeftElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) || node.getRightElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF );
+}
+
+template < class SymbolType, class RankType >
+bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEIteration < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) {
+	return node.getElement ( ).template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF );
+}
+
+template < class SymbolType, class RankType >
+bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) {
+	if ( symbolF == node.getSymbol ( ) ) return true;
+
+	for ( const std::smart_ptr < const rte::FormalRTESymbol < SymbolType, RankType > > & element : node.getElements ( ) )
+		if ( element->template accept < bool, GlushkovPos::Formal < SymbolType, RankType > > ( symbolF ) )
+			return true;
+
+	return false;
+}
+
+template < class SymbolType, class RankType >
+bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTESymbolSubst < SymbolType, RankType > & node, const std::ranked_symbol < SymbolType, RankType > & symbolF ) {
+	return symbolF == node.getSymbol ( );
+}
+
+template < class SymbolType, class RankType >
+bool GlushkovPos::Formal < SymbolType, RankType >::visit ( const rte::FormalRTEEmpty < SymbolType, RankType > & /* node */, const std::ranked_symbol < SymbolType, RankType > & /* symbolF */ ) {
+	return false;
+}
+
 } /* namespace rte */
 
 #endif /* RTE_GLUSHKOV_POS_H_ */