diff --git a/alib2algo_experimental/src/grammar/parsing/First.cpp b/alib2algo_experimental/src/grammar/parsing/First.cpp
index 0cb7718c5eb83c4840120d0da9f756312868fa77..b182a1922666036bfea7b41057593d59cfa0783e 100644
--- a/alib2algo_experimental/src/grammar/parsing/First.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/First.cpp
@@ -23,115 +23,25 @@ namespace grammar {
 
 namespace parsing {
 
-ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > First::first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < DefaultSymbolType > & rhs ) {
-	 // 1. FIRST(\varepsilon) = { \varepsilon }
-	if ( rhs.size ( ) == 0 ) {
-		return { string::Epsilon < >::EPSILON };
-	}
-
-	 // 2. FIRST(a) = { a } forall a \in T
-	else if ( terminals.count ( rhs[0] ) ) {
-		return { rhs[0] };
-	}
-
-	 // 4. FIRST(A \alpha) = first(A) if A \in N and \varepsilon \notin first(A)
-	else if ( nonterminals.count ( rhs[0] ) && !firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < >::EPSILON ) ) {
-		return firstOfNonterminal.find ( rhs[0] )->second;
-	}
-
-	 // 5. FIRST(A \alpha) = (first(A) - \varepsilon) \cup FIRST(\alpha) if A \in N and \varepsilon \in first(A)
-	else if ( nonterminals.count ( rhs[0] ) && firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < >::EPSILON ) ) {
-		ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > res = firstOfNonterminal.find ( rhs[0] )->second;
-		res.erase ( string::Epsilon < >::EPSILON );
-
-		ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > next = first ( terminals, nonterminals, firstOfNonterminal, ext::vector < DefaultSymbolType > ( rhs.begin ( ) + 1, rhs.end ( ) ) );
-		res.insert ( next.begin ( ), next.end ( ) );
-		return res;
-	} else {
-		throw exception::CommonException ( "Cant be reached" );
-	}
-}
-
-ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > First::first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rules ) {
-	/*
-	 *
-	 * 1. foreach A \in N: first(A) = \emptyset
-	 * 2. foreach A \rightarrow \alpha:
-	 *	first(A) = first(A) \cup FIRST(\alpha)
-	 * 3. repeat step 2 if at least one set first(A) has changed
-	 *
-	 */
-	ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstOfNonterminal1;
-
-	for ( const DefaultSymbolType & nonterminal : nonterminals )
-		firstOfNonterminal1[nonterminal];
-
-	ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstOfNonterminal2 = firstOfNonterminal1;
-
-	do {
-		for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rule : rules )
-			for ( const ext::vector < DefaultSymbolType > & rhs : rule.second ) {
-				ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > newFirst = first ( terminals, nonterminals, firstOfNonterminal1, rhs );
-				firstOfNonterminal2[rule.first].insert ( newFirst.begin ( ), newFirst.end ( ) );
-			}
-
-		if ( firstOfNonterminal1 == firstOfNonterminal2 ) break;
-
-		firstOfNonterminal1 = std::move ( firstOfNonterminal2 );
-		firstOfNonterminal2.clear ( );
-
-	} while ( true );
-
-	return firstOfNonterminal1;
-}
-
-template < class T >
-ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > First::first ( const T & grammar ) {
-	ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
-
-	ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > res;
-
-	for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rule : grammar.getRawRules ( ) )
-		for ( const ext::vector < DefaultSymbolType > & rhs : rule.second )
-			res.insert ( std::make_pair ( rhs, first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ) ) );
-
-	return res;
-}
-
-template < class T >
-ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > First::first ( const T & grammar, const ext::vector < DefaultSymbolType > & rhs ) {
-	ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
-
-	return first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs );
-}
-
-auto FirstCFG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::CFG < > > ( First::first );
-auto FirstEpsilonFreeCFG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::EpsilonFreeCFG < > > ( First::first );
-auto FirstGNF = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::GNF < > > ( First::first );
-auto FirstCNF = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::CNF < > > ( First::first );
-auto FirstLG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::LG < > > ( First::first );
-auto FirstLeftLG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::LeftLG < > > ( First::first );
-auto FirstLeftRG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::LeftRG < > > ( First::first );
-auto FirstRightLG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::RightLG < > > ( First::first );
-auto FirstRightRG = registration::OverloadRegister < FirstBase1, FirstResult1, grammar::RightRG < > > ( First::first );
-
-ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > First::first ( const grammar::Grammar & grammar ) {
-	return FirstBase1::dispatch ( grammar.getData ( ) );
-}
-
-auto FirstCFG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::CFG < > > ( First::first );
-auto FirstEpsilonFreeCFG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::EpsilonFreeCFG < > > ( First::first );
-auto FirstGNF2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::GNF < > > ( First::first );
-auto FirstCNF2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::CNF < > > ( First::first );
-auto FirstLG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::LG < > > ( First::first );
-auto FirstLeftLG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::LeftLG < > > ( First::first );
-auto FirstLeftRG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::LeftRG < > > ( First::first );
-auto FirstRightLG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::RightLG < > > ( First::first );
-auto FirstRightRG2 = registration::OverloadRegister < FirstBase2, FirstResult2, grammar::RightRG < > > ( First::first );
-
-ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > First::first ( const grammar::Grammar & grammar, const ext::vector < DefaultSymbolType > & rhs ) {
-	return FirstBase2::dispatch ( grammar.getData ( ), rhs );
-}
+auto FirstCFG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CFG < > & > ( First::first );
+auto FirstEpsilonFreeCFG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::EpsilonFreeCFG < > & > ( First::first );
+auto FirstGNF = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::GNF < > & > ( First::first );
+auto FirstCNF = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CNF < > & > ( First::first );
+auto FirstLG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LG < > & > ( First::first );
+auto FirstLeftLG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftLG < > & > ( First::first );
+auto FirstLeftRG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftRG < > & > ( First::first );
+auto FirstRightLG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightLG < > & > ( First::first );
+auto FirstRightRG = registration::AbstractRegister < First, ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightRG < > & > ( First::first );
+
+auto FirstCFG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CFG < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstEpsilonFreeCFG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::EpsilonFreeCFG < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstGNF2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::GNF < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstCNF2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CNF < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstLG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LG < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstLeftLG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftLG < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstLeftRG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftRG < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstRightLG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightLG < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
+auto FirstRightRG2 = registration::AbstractRegister < First, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightRG < > &, const ext::vector < DefaultSymbolType > & > ( First::first );
 
 } /* namespace parsing */
 
diff --git a/alib2algo_experimental/src/grammar/parsing/First.h b/alib2algo_experimental/src/grammar/parsing/First.h
index b63bf80963ad9f55fbd4f1eb247314c68d3291e1..a1fcf5c1d211aac3ad1a712c3242a66bab23abc0 100644
--- a/alib2algo_experimental/src/grammar/parsing/First.h
+++ b/alib2algo_experimental/src/grammar/parsing/First.h
@@ -8,10 +8,8 @@
 #ifndef FIRST_H_
 #define FIRST_H_
 
-#include <core/multipleDispatch.hpp>
-#include <grammar/Grammar.h>
-#include <alphabet/Symbol.h>
 #include <string/Epsilon.h>
+#include <grammar/Grammar.h>
 #include <vector>
 #include <set>
 #include <variant>
@@ -20,32 +18,106 @@ namespace grammar {
 
 namespace parsing {
 
-class First;
-
-typedef ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > FirstResult1;
-typedef alib::SingleDispatch < First, FirstResult1, const grammar::GrammarBase & > FirstBase1;
-
-typedef ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > FirstResult2;
-typedef alib::SingleDispatch < First, FirstResult2, const grammar::GrammarBase &, const ext::vector < DefaultSymbolType > & > FirstBase2;
-
-class First : public FirstBase1, public FirstBase2 {
-	static ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < DefaultSymbolType > & rhs );
+class First {
+	template < class SymbolType >
+	static ext::set < ext::variant < SymbolType, string::Epsilon < > > > first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < SymbolType > & rhs );
 
-	static ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > first ( const ext::set < DefaultSymbolType > & terminals, const ext::set < DefaultSymbolType > & nonterminals, const ext::map < DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rules );
+	template < class SymbolType >
+	static ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > & rules );
 
 public:
-	template < class T >
-	static FirstResult1 first ( const T & grammar );
-
-	template < class T >
-	static FirstResult2 first ( const T & grammar, const ext::vector < DefaultSymbolType > & rhs );
-
-	static FirstResult1 first ( const grammar::Grammar & grammar );
-
-	static FirstResult2 first ( const grammar::Grammar & grammar, const ext::vector < DefaultSymbolType > & rhs );
+	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
+	static ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > first ( const T & grammar );
 
+	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
+	static ext::set < ext::variant < SymbolType, string::Epsilon < > > > first ( const T & grammar, const ext::vector < SymbolType > & rhs );
 };
 
+template < class SymbolType >
+ext::set < ext::variant < SymbolType, string::Epsilon < > > > First::first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & firstOfNonterminal, const ext::vector < SymbolType > & rhs ) {
+	 // 1. FIRST(\varepsilon) = { \varepsilon }
+	if ( rhs.size ( ) == 0 ) {
+		return { string::Epsilon < >::EPSILON };
+	}
+
+	 // 2. FIRST(a) = { a } forall a \in T
+	else if ( terminals.count ( rhs[0] ) ) {
+		return { rhs[0] };
+	}
+
+	 // 4. FIRST(A \alpha) = first(A) if A \in N and \varepsilon \notin first(A)
+	else if ( nonterminals.count ( rhs[0] ) && !firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < >::EPSILON ) ) {
+		return firstOfNonterminal.find ( rhs[0] )->second;
+	}
+
+	 // 5. FIRST(A \alpha) = (first(A) - \varepsilon) \cup FIRST(\alpha) if A \in N and \varepsilon \in first(A)
+	else if ( nonterminals.count ( rhs[0] ) && firstOfNonterminal.find ( rhs[0] )->second.count ( string::Epsilon < >::EPSILON ) ) {
+		ext::set < ext::variant < SymbolType, string::Epsilon < > > > res = firstOfNonterminal.find ( rhs[0] )->second;
+		res.erase ( string::Epsilon < >::EPSILON );
+
+		ext::set < ext::variant < SymbolType, string::Epsilon < > > > next = first ( terminals, nonterminals, firstOfNonterminal, ext::vector < SymbolType > ( rhs.begin ( ) + 1, rhs.end ( ) ) );
+		res.insert ( next.begin ( ), next.end ( ) );
+		return res;
+	} else {
+		throw exception::CommonException ( "Cant be reached" );
+	}
+}
+
+template < class SymbolType >
+ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > First::first ( const ext::set < SymbolType > & terminals, const ext::set < SymbolType > & nonterminals, const ext::map < SymbolType, ext::set < ext::vector < SymbolType > > > & rules ) {
+	/*
+	 *
+	 * 1. foreach A \in N: first(A) = \emptyset
+	 * 2. foreach A \rightarrow \alpha:
+	 *	first(A) = first(A) \cup FIRST(\alpha)
+	 * 3. repeat step 2 if at least one set first(A) has changed
+	 *
+	 */
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstOfNonterminal1;
+
+	for ( const SymbolType & nonterminal : nonterminals )
+		firstOfNonterminal1[nonterminal];
+
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstOfNonterminal2 = firstOfNonterminal1;
+
+	do {
+		for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : rules )
+			for ( const ext::vector < SymbolType > & rhs : rule.second ) {
+				ext::set < ext::variant < SymbolType, string::Epsilon < > > > newFirst = first ( terminals, nonterminals, firstOfNonterminal1, rhs );
+				firstOfNonterminal2[rule.first].insert ( newFirst.begin ( ), newFirst.end ( ) );
+			}
+
+		if ( firstOfNonterminal1 == firstOfNonterminal2 )
+			break;
+
+		firstOfNonterminal1 = std::move ( firstOfNonterminal2 );
+		firstOfNonterminal2.clear ( );
+
+	} while ( true );
+
+	return firstOfNonterminal1;
+}
+
+template < class T, class SymbolType >
+ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > First::first ( const T & grammar ) {
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
+
+	ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > res;
+
+	for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) )
+		for ( const ext::vector < SymbolType > & rhs : rule.second )
+			res.insert ( std::make_pair ( rhs, first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs ) ) );
+
+	return res;
+}
+
+template < class T, class SymbolType >
+ext::set < ext::variant < SymbolType, string::Epsilon < > > > First::first ( const T & grammar, const ext::vector < SymbolType > & rhs ) {
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > firstNt = first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), grammar.getRawRules ( ) );
+
+	return first ( grammar.getTerminalAlphabet ( ), grammar.getNonterminalAlphabet ( ), firstNt, rhs );
+}
+
 } /* namespace parsing */
 
 } /* namespace grammar */
diff --git a/alib2algo_experimental/src/grammar/parsing/Follow.cpp b/alib2algo_experimental/src/grammar/parsing/Follow.cpp
index fd1345a495d369b5c796ebc0b34ccbb1073cc003..e204ce31822809f59fcb34fb6afebb15a82b17d4 100644
--- a/alib2algo_experimental/src/grammar/parsing/Follow.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/Follow.cpp
@@ -6,10 +6,6 @@
  */
 
 #include "Follow.h"
-#include "First.h"
-#include <algorithm>
-#include <string/Epsilon.h>
-#include <iterator>
 
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
@@ -20,106 +16,31 @@
 #include <grammar/Regular/LeftRG.h>
 #include <grammar/Regular/RightLG.h>
 #include <grammar/Regular/RightRG.h>
-#include <exception/CommonException.h>
 #include <registration/AlgoRegistration.hpp>
 
 namespace grammar {
 
 namespace parsing {
 
-template < class T >
-void Follow::follow ( const T & grammar, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & followSet ) {
-	for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & rule : grammar.getRawRules ( ) ) {
-		const DefaultSymbolType & X = rule.first;
-
-		for ( const ext::vector < DefaultSymbolType > & rhs : rule.second )
-			 // every nt in rhs is Y
-			for ( ext::vector < DefaultSymbolType >::const_iterator it = rhs.begin ( ); it != rhs.end ( ); it++ ) {
-				const DefaultSymbolType & Y = * it;
-
-				if ( !grammar.getNonterminalAlphabet ( ).count ( Y ) ) continue;
-
-				ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > firstBeta = First::first ( grammar, ext::vector < DefaultSymbolType > ( std::next ( it ), rhs.end ( ) ) );
-
-				if ( firstBeta.count ( string::Epsilon < >::EPSILON ) ) {
-					firstBeta.erase ( string::Epsilon < >::EPSILON );
-					followSet[Y].insert ( followSet[X].begin ( ), followSet[X].end ( ) );
-				}
-
-				followSet[Y].insert ( firstBeta.begin ( ), firstBeta.end ( ) );
-			}
-
-	}
-}
-
-template < class T >
-ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > Follow::follow ( const T & grammar ) {
-	/*
-	 * 1. Follow(S) = { \varepsilon }
-	 *    Follow(A) = {} forall A \in N, A \neq S
-	 * 2. Forall p \in P:
-	 *      if p == X -> \alpha Y \beta
-	 *		Follow(Y) = Follow(Y) \cup (First(\beta) \setminus { \varepsilon})
-	 *	if p == X -> \alpha Y \beta \wedge \varepsilon \in First(\beta)
-	 *		Follow(Y) = Follow(Y) \cup Follow(X)
-	 * 3. goto 2 if any follow set was changed in prev step.
-	 */
-
-	ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > followSet1;
-
-	for ( const DefaultSymbolType & symb : grammar.getNonterminalAlphabet ( ) )
-		followSet1[symb];
-
-	followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon < >::EPSILON };
-
-	ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > followSet2 = followSet1;
-
-	do {
-		follow ( grammar, followSet2 );
-
-		if ( followSet1 == followSet2 ) break;
-
-		followSet1 = followSet2;
-	} while ( true );
-
-	return followSet1;
-}
-
-template < class T >
-ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > Follow::follow ( const T & grammar, const DefaultSymbolType & nt ) {
-	if ( !grammar.getNonterminalAlphabet ( ).count ( nt ) )
-		throw exception::CommonException ( "Follow: Given symbol is not nonterminal." );
-
-	return follow ( grammar )[nt];
-}
-
-auto FollowCFG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::CFG < > > ( Follow::follow );
-auto FollowEpsilonFreeCFG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::EpsilonFreeCFG < > > ( Follow::follow );
-auto FollowGNF = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::GNF < > > ( Follow::follow );
-auto FollowCNF = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::CNF < > > ( Follow::follow );
-auto FollowLG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::LG < > > ( Follow::follow );
-auto FollowLeftLG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::LeftLG < > > ( Follow::follow );
-auto FollowLeftRG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::LeftRG < > > ( Follow::follow );
-auto FollowRightLG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::RightLG < > > ( Follow::follow );
-auto FollowRightRG = registration::OverloadRegister < FollowBase1, FollowResult1, grammar::RightRG < > > ( Follow::follow );
-
-ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > Follow::follow ( const grammar::Grammar & grammar ) {
-	return FollowBase1::dispatch ( grammar.getData ( ) );
-}
-
-auto FollowCFG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::CFG < > > ( Follow::follow );
-auto FollowEpsilonFreeCFG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::EpsilonFreeCFG < > > ( Follow::follow );
-auto FollowGNF2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::GNF < > > ( Follow::follow );
-auto FollowCNF2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::CNF < > > ( Follow::follow );
-auto FollowLG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::LG < > > ( Follow::follow );
-auto FollowLeftLG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::LeftLG < > > ( Follow::follow );
-auto FollowLeftRG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::LeftRG < > > ( Follow::follow );
-auto FollowRightLG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::RightLG < > > ( Follow::follow );
-auto FollowRightRG2 = registration::OverloadRegister < FollowBase2, FollowResult2, grammar::RightRG < > > ( Follow::follow );
-
-ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > Follow::follow ( const grammar::Grammar & grammar, const DefaultSymbolType & nt ) {
-	return FollowBase2::dispatch ( grammar.getData ( ), nt );
-}
+auto FollowCFG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CFG < > & > ( Follow::follow );
+auto FollowEpsilonFreeCFG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::EpsilonFreeCFG < > & > ( Follow::follow );
+auto FollowGNF = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::GNF < > & > ( Follow::follow );
+auto FollowCNF = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::CNF < > & > ( Follow::follow );
+auto FollowLG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LG < > & > ( Follow::follow );
+auto FollowLeftLG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftLG < > & > ( Follow::follow );
+auto FollowLeftRG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::LeftRG < > & > ( Follow::follow );
+auto FollowRightLG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightLG < > & > ( Follow::follow );
+auto FollowRightRG = registration::AbstractRegister < Follow, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > >, const grammar::RightRG < > & > ( Follow::follow );
+
+auto FollowCFG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CFG < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowEpsilonFreeCFG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::EpsilonFreeCFG < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowGNF2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::GNF < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowCNF2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::CNF < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowLG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LG < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowLeftLG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftLG < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowLeftRG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::LeftRG < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowRightLG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightLG < > &, const DefaultSymbolType & > ( Follow::follow );
+auto FollowRightRG2 = registration::AbstractRegister < Follow, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > >, const grammar::RightRG < > &, const DefaultSymbolType & > ( Follow::follow );
 
 } /* namespace parsing */
 
diff --git a/alib2algo_experimental/src/grammar/parsing/Follow.h b/alib2algo_experimental/src/grammar/parsing/Follow.h
index 958517999e5d4c23795988b08c63604eab920a7f..b7ac8452b5037eaf0fab77987ae5f8e288fe1270 100644
--- a/alib2algo_experimental/src/grammar/parsing/Follow.h
+++ b/alib2algo_experimental/src/grammar/parsing/Follow.h
@@ -8,56 +8,102 @@
 #ifndef FOLLOW_H_
 #define FOLLOW_H_
 
-#include <core/multipleDispatch.hpp>
-#include <grammar/Grammar.h>
-#include <alphabet/Symbol.h>
-#include <string/Epsilon.h>
 #include <vector>
 #include <set>
 #include <variant>
+#include <algorithm>
+#include <iterator>
+
+#include <exception/CommonException.h>
+
+#include <grammar/Grammar.h>
+#include <string/Epsilon.h>
+
+#include "First.h"
 
 namespace grammar {
 
 namespace parsing {
 
-class Follow;
+class Follow {
+	template < class T, class SymbolType >
+	static void follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & followSet );
+
+public:
+	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
+	static ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > follow ( const T & grammar );
+
+	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
+	static ext::set < ext::variant < SymbolType, string::Epsilon < > > > follow ( const T & grammar, const SymbolType & nt );
+};
 
-typedef ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > FollowResult1;
-typedef alib::SingleDispatch < Follow, FollowResult1, const grammar::GrammarBase & > FollowBase1;
+template < class T, class SymbolType >
+void Follow::follow ( const T & grammar, ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > & followSet ) {
+	for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & rule : grammar.getRawRules ( ) ) {
+		const SymbolType & X = rule.first;
 
-typedef ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > FollowResult2;
-typedef alib::SingleDispatch < Follow, FollowResult2, const grammar::GrammarBase &, const DefaultSymbolType & > FollowBase2;
+		for ( const ext::vector < SymbolType > & rhs : rule.second )
+			 // every nt in rhs is Y
+			for ( typename ext::vector < SymbolType >::const_iterator it = rhs.begin ( ); it != rhs.end ( ); it++ ) {
+				const SymbolType & Y = * it;
 
-class Follow : public FollowBase1, public FollowBase2 {
-	template < class T >
-	static void follow ( const T & grammar, ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > & followSet );
+				if ( !grammar.getNonterminalAlphabet ( ).count ( Y ) )
+					continue;
 
-	static Follow & getInstance ( ) {
-		static Follow res;
+				ext::set < ext::variant < SymbolType, string::Epsilon < > > > firstBeta = First::first ( grammar, ext::vector < SymbolType > ( std::next ( it ), rhs.end ( ) ) );
+
+				if ( firstBeta.count ( string::Epsilon < >::EPSILON ) ) {
+					firstBeta.erase ( string::Epsilon < >::EPSILON );
+					followSet[Y].insert ( followSet[X].begin ( ), followSet[X].end ( ) );
+				}
+
+				followSet[Y].insert ( firstBeta.begin ( ), firstBeta.end ( ) );
+			}
 
-		return res;
 	}
+}
 
-public:
-	static FollowResult1 follow ( const grammar::Grammar & grammar );
+template < class T, class SymbolType >
+ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > Follow::follow ( const T & grammar ) {
+	/*
+	 * 1. Follow(S) = { \varepsilon }
+	 *    Follow(A) = {} forall A \in N, A \neq S
+	 * 2. Forall p \in P:
+	 *      if p == X -> \alpha Y \beta
+	 *		Follow(Y) = Follow(Y) \cup (First(\beta) \setminus { \varepsilon})
+	 *	if p == X -> \alpha Y \beta \wedge \varepsilon \in First(\beta)
+	 *		Follow(Y) = Follow(Y) \cup Follow(X)
+	 * 3. goto 2 if any follow set was changed in prev step.
+	 */
 
-	static FollowResult2 follow ( const grammar::Grammar & grammar, const DefaultSymbolType & nt );
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > followSet1;
 
-	template < class T >
-	static FollowResult1 follow ( const T & grammar );
+	for ( const SymbolType & symb : grammar.getNonterminalAlphabet ( ) )
+		followSet1[symb];
 
-	template < class T >
-	static FollowResult2 follow ( const T & grammar, const DefaultSymbolType & nt );
+	followSet1[grammar.getInitialSymbol ( )] = { string::Epsilon < >::EPSILON };
 
-	static FollowBase1 & getInstance1 ( ) {
-		return getInstance ( );
-	}
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > followSet2 = followSet1;
 
-	static FollowBase2 & getInstance2 ( ) {
-		return getInstance ( );
-	}
+	do {
+		follow ( grammar, followSet2 );
 
-};
+		if ( followSet1 == followSet2 )
+			break;
+
+		followSet1 = followSet2;
+	} while ( true );
+
+	return followSet1;
+}
+
+template < class T, class SymbolType >
+ext::set < ext::variant < SymbolType, string::Epsilon < > > > Follow::follow ( const T & grammar, const SymbolType & nt ) {
+	if ( !grammar.getNonterminalAlphabet ( ).count ( nt ) )
+		throw exception::CommonException ( "Follow: Given symbol is not nonterminal." );
+
+	return follow ( grammar )[nt];
+}
 
 } /* namespace parsing */
 
diff --git a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp
index 9c04c5c6b5f1fd2231591686ead5410ff40db07c..e8e061dad535947e443d526007391d5d6f9aad17 100644
--- a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.cpp
@@ -6,8 +6,6 @@
  */
 
 #include "LL1ParseTable.h"
-#include "First.h"
-#include "Follow.h"
 
 #include <grammar/ContextFree/CFG.h>
 #include <grammar/ContextFree/EpsilonFreeCFG.h>
@@ -24,46 +22,15 @@ namespace grammar {
 
 namespace parsing {
 
-template < class T >
-ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > LL1ParseTable::parseTable ( const T & grammar ) {
-	ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > res;
-
-	ext::map < ext::vector < DefaultSymbolType >, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > first = First::first ( grammar );
-	ext::map < DefaultSymbolType, ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > > follow = Follow::follow ( grammar );
-
-	for ( const std::pair < const DefaultSymbolType, ext::set < ext::vector < DefaultSymbolType > > > & transition : grammar.getRawRules ( ) ) {
-		const DefaultSymbolType & lhs = transition.first;
-
-		for ( const ext::vector < DefaultSymbolType > & rhs : transition.second ) {
-			for ( const ext::variant < DefaultSymbolType, string::Epsilon < > > & firstElem : first[rhs] ) {
-				if ( firstElem.is < string::Epsilon < > > ( ) ) continue;
-
-				res [ ext::make_pair ( firstElem, lhs ) ].insert ( rhs );
-			}
-
-			if ( first[rhs].count ( string::Epsilon < >::EPSILON ) )
-				for ( const ext::variant < DefaultSymbolType, string::Epsilon < > > & followElem : follow[lhs] )
-					res [ ext::make_pair ( followElem, lhs ) ].insert ( rhs );
-
-		}
-	}
-
-	return res;
-}
-
-auto LL1ParseTableCFG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::CFG < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableEpsilonFreeCFG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::EpsilonFreeCFG < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableGNF = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::GNF < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableCNF = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::CNF < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableLG  = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::LG < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableLeftLG  = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::LeftLG < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableLeftRG  = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::LeftRG < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableRightLG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::RightLG < > > ( LL1ParseTable::parseTable );
-auto LL1ParseTableRightRG = registration::OverloadRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, grammar::RightRG < > > ( LL1ParseTable::parseTable );
-
-ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > LL1ParseTable::parseTable ( const grammar::Grammar & grammar ) {
-	return dispatch ( grammar.getData ( ) );
-}
+auto LL1ParseTableCFG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::CFG < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableEpsilonFreeCFG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::EpsilonFreeCFG < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableGNF = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::GNF < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableCNF = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::CNF < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableLG  = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LG < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableLeftLG  = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LeftLG < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableLeftRG  = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::LeftRG < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableRightLG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::RightLG < > & > ( LL1ParseTable::parseTable );
+auto LL1ParseTableRightRG = registration::AbstractRegister < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::RightRG < > & > ( LL1ParseTable::parseTable );
 
 } /* namespace parsing */
 
diff --git a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h
index af5d6ac199ef1478b2a5c72b6877a2a0353e0f87..d7c0a9da1985aa60d761da91d06dccfcb4f5e96d 100644
--- a/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h
+++ b/alib2algo_experimental/src/grammar/parsing/LL1ParseTable.h
@@ -8,28 +8,56 @@
 #ifndef LL_1_PARSE_TABLE_H_
 #define LL_1_PARSE_TABLE_H_
 
-#include <core/multipleDispatch.hpp>
-#include <grammar/Grammar.h>
-#include <alphabet/Symbol.h>
-#include <string/Epsilon.h>
 #include <vector>
 #include <variant>
 #include <set>
 #include <map>
 
+#include <grammar/Grammar.h>
+#include <string/Epsilon.h>
+
+#include "First.h"
+#include "Follow.h"
+
 namespace grammar {
 
 namespace parsing {
 
-class LL1ParseTable : public alib::SingleDispatch < LL1ParseTable, ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > >, const grammar::GrammarBase & > {
+class LL1ParseTable {
 public:
-	template < class T >
-	static ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > parseTable ( const T & grammar );
-
-	static ext::map < ext::pair < ext::variant < DefaultSymbolType, string::Epsilon < > >, DefaultSymbolType >, ext::set < ext::vector < DefaultSymbolType > > > parseTable ( const grammar::Grammar & grammar );
+	template < class T, class SymbolType = typename grammar::SymbolTypeOfGrammar < T > >
+	static ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolType >, ext::set < ext::vector < SymbolType > > > parseTable ( const T & grammar );
 
 };
 
+template < class T, class SymbolType >
+ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolType >, ext::set < ext::vector < SymbolType > > > LL1ParseTable::parseTable ( const T & grammar ) {
+	ext::map < ext::pair < ext::variant < SymbolType, string::Epsilon < > >, SymbolType >, ext::set < ext::vector < SymbolType > > > res;
+
+	ext::map < ext::vector < SymbolType >, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > first = First::first ( grammar );
+	ext::map < SymbolType, ext::set < ext::variant < SymbolType, string::Epsilon < > > > > follow = Follow::follow ( grammar );
+
+	for ( const std::pair < const SymbolType, ext::set < ext::vector < SymbolType > > > & transition : grammar.getRawRules ( ) ) {
+		const SymbolType & lhs = transition.first;
+
+		for ( const ext::vector < SymbolType > & rhs : transition.second ) {
+			for ( const ext::variant < SymbolType, string::Epsilon < > > & firstElem : first[rhs] ) {
+				if ( firstElem.template is < string::Epsilon < > > ( ) )
+					continue;
+
+				res [ ext::make_pair ( firstElem, lhs ) ].insert ( rhs );
+			}
+
+			if ( first[rhs].count ( string::Epsilon < >::EPSILON ) )
+				for ( const ext::variant < SymbolType, string::Epsilon < > > & followElem : follow[lhs] )
+					res [ ext::make_pair ( followElem, lhs ) ].insert ( rhs );
+
+		}
+	}
+
+	return res;
+}
+
 } /* namespace parsing */
 
 } /* namespace grammar */
diff --git a/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h b/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h
index e13f3db71ea6deb855ad596614cbf2b226317e92..e698e2225b882da54b2a13e9638f45bcd412a160 100644
--- a/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h
+++ b/alib2algo_experimental/src/grammar/parsing/LeftFactorize.h
@@ -8,7 +8,6 @@
 #ifndef LEFT_FACTORIZE_H_
 #define LEFT_FACTORIZE_H_
 
-#include <core/multipleDispatch.hpp>
 #include <alphabet/Symbol.h>
 #include <grammar/GrammarFeatures.h>
 
diff --git a/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp b/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp
index a62e2e21de793b44becec6bbebdf2b657229467b..cd77940f7668f08bb82453aa0f4cb5f4f4a62e13 100644
--- a/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp
+++ b/alib2algo_experimental/src/grammar/parsing/SLR1ParseTable.cpp
@@ -45,7 +45,7 @@ LRActionTable SLR1ParseTable::getActionTable ( grammar::CFG < > originalGrammar
 						continue;
 					}
 
-					grammar::parsing::FollowResult2 followSet = grammar::parsing::Follow::follow ( augmentedGrammar, leftHandSide );
+					ext::set < ext::variant < DefaultSymbolType, string::Epsilon < > > > followSet = grammar::parsing::Follow::follow ( augmentedGrammar, leftHandSide );
 					ext::pair < DefaultSymbolType, ext::vector < DefaultSymbolType > > currentRule = { leftHandSide, rightHandSide };
 					for ( const ext::variant < DefaultSymbolType, string::Epsilon < > > & followSymbol : followSet ) {
 						if ( followSymbol.is < DefaultSymbolType > ( ) ) {
diff --git a/alib2algo_experimental/src/grammar/parsing/common/Substitute.h b/alib2algo_experimental/src/grammar/parsing/common/Substitute.h
index 398cbb000bf97537f1e6db5dbaac65af9864da59..f6a9ac46e4e58b6afa415cb0a84a34e4a5d24d8c 100644
--- a/alib2algo_experimental/src/grammar/parsing/common/Substitute.h
+++ b/alib2algo_experimental/src/grammar/parsing/common/Substitute.h
@@ -8,7 +8,6 @@
 #ifndef SUBSTITUTE_H_
 #define SUBSTITUTE_H_
 
-#include <core/multipleDispatch.hpp>
 #include <grammar/GrammarFeatures.h>
 #include <alphabet/Symbol.h>
 #include <vector>
@@ -17,7 +16,7 @@ namespace grammar {
 
 namespace parsing {
 
-class Substitute { 
+class Substitute {
 public:
 	static void substitute ( const grammar::CFG < > & orig, grammar::CFG < > & res, const DefaultSymbolType & origLHS, const ext::vector < DefaultSymbolType > & origRHS, ext::vector < DefaultSymbolType >::const_iterator nonterminal );