diff --git a/alib2algo/src/grammar/parsing/First.cpp b/alib2algo/src/grammar/parsing/First.cpp
index fc00d75ead0c6d8251a4931b5b2bf1079f139e5f..61d290a23546da8484e27fcdc6216b91ec806834 100644
--- a/alib2algo/src/grammar/parsing/First.cpp
+++ b/alib2algo/src/grammar/parsing/First.cpp
@@ -6,54 +6,48 @@
  */
 
 #include "First.h"
-#include <algorithm>
-#include <string/Epsilon.h>
-#include <iterator>
 
-#include "setunion.h"
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/CNF.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/LG.h>
+#include <grammar/Regular/LeftLG.h>
+#include <grammar/Regular/LeftRG.h>
+#include <grammar/Regular/RightLG.h>
+#include <grammar/Regular/RightRG.h>
+#include <exception/AlibException.h>
 
 namespace grammar {
 
 namespace parsing {
 
-template<class T>
-std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::firstSeq(const T& grammar, const std::vector<alphabet::Symbol>& rhs, std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstNt)
-{
+std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& firstOfNonterminal, const std::vector<alphabet::Symbol>& rhs) {
 	// 1. FIRST(\varepsilon) = { \varepsilon }
-	if(rhs.empty()) return {string::Epsilon::EPSILON};
+	if(rhs.size() == 0)
+		return {string::Epsilon::EPSILON};
 
 	// 2. FIRST(a) = { a } forall a \in T
-	else if(grammar.getTerminalAlphabet().find(rhs[0]) != grammar.getTerminalAlphabet().end())
+	else if(terminals.count(rhs[0]))
 		return {rhs[0]};
 
-	// 3. FIRST(A) = first(A) forall A \in N
-	else if(rhs.size() == 1 && grammar.getNonterminalAlphabet().find(rhs[0]) != grammar.getNonterminalAlphabet().end())
-		return firstNt[rhs[0]];
-
 	// 4. FIRST(A \alpha) = first(A) if A \in N and \varepsilon \notin first(A)
-	else if(grammar.getNonterminalAlphabet().find(rhs[0]) != grammar.getNonterminalAlphabet().end() && firstNt[rhs[0]].find(string::Epsilon::EPSILON) == firstNt[rhs[0]].end())
-		return firstNt[rhs[0]];
+	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(grammar.getNonterminalAlphabet().find(rhs[0]) != grammar.getNonterminalAlphabet().end() && firstNt[rhs[0]].find(string::Epsilon::EPSILON) != firstNt[rhs[0]].end())
-	{
-		std::set<std::variant<alphabet::Symbol, string::Epsilon>> fiA = firstNt[rhs[0]];
-
-		auto it = fiA.find(string::Epsilon::EPSILON);
-		if(it != fiA.end()) fiA.erase(it);
+	else if(nonterminals.count(rhs[0]) && firstOfNonterminal.find(rhs[0])->second.count(string::Epsilon::EPSILON)) {
+		std::set<std::variant<alphabet::Symbol, string::Epsilon>> res = firstOfNonterminal.find(rhs[0])->second;
+		res.erase(string::Epsilon::EPSILON);
 
-		std::vector<alphabet::Symbol> alpha = rhs;
-		alpha.erase(alpha.begin());
-		std::set<std::variant<alphabet::Symbol, string::Epsilon>> FIA = firstSeq(grammar, alpha, firstNt);
-
-		return setunion(fiA, FIA);
-	}
-	throw exception::AlibException("Unhandled case in First.cpp");
+		std::set<std::variant<alphabet::Symbol, string::Epsilon>> next = first(terminals, nonterminals, firstOfNonterminal, std::vector<alphabet::Symbol>(rhs.begin() + 1, rhs.end()));
+		res.insert(next.begin(), next.end());
+		return res;
+	} else
+		throw exception::AlibException("Cant be reached");
 }
 
-template<class T>
-std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const T& grammar, const std::vector<alphabet::Symbol>& rhs)
-{
+std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> First::first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rules) {
 	/*
 	 *
 	 * 1. foreach A \in N: first(A) = \emptyset
@@ -62,134 +56,79 @@ std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const T&
 	 * 3. repeat step 2 if at least one set first(A) has changed
 	 *
 	 */
+	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstOfNonterminal1;
+	for(const alphabet::Symbol& nonterminal : nonterminals)
+		firstOfNonterminal1[nonterminal];
 
-	// (N u T)* -> T*
-	// rhs -> first(rhs)
-	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstNt;
-	for(const alphabet::Symbol& nt : grammar.getNonterminalAlphabet())
-		firstNt.insert(std::make_pair(nt, std::set<std::variant<alphabet::Symbol, string::Epsilon>>{}));
-
-	bool changed;
-	do
-	{
-		changed = false;
-
-		for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : grammar.getRawRules())
-		{
-			const alphabet::Symbol& lhs = rule.first;
-			for(const std::vector<alphabet::Symbol>& rhs : rule.second)
-			{
-				std::set<std::variant<alphabet::Symbol, string::Epsilon>> oldFirst;
-
-				oldFirst = firstNt[lhs];
-				firstNt[lhs] = setunion(firstNt[lhs], firstSeq(grammar, rhs, firstNt));
-				if(firstNt[lhs] != oldFirst)
-					changed = true;
+	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstOfNonterminal2 = firstOfNonterminal1;
+
+	do {
+		for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : rules) {
+			for(const std::vector<alphabet::Symbol>& rhs : rule.second) {
+				std::set<std::variant<alphabet::Symbol, string::Epsilon>> newFirst = first(terminals, nonterminals, firstOfNonterminal1, rhs);
+				firstOfNonterminal2[rule.first].insert(newFirst.begin(), newFirst.end());
 			}
 		}
-	}
-	while(changed);
-
-	/*
-	std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> res;
-	for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : grammar.getRawRules())
-		for(const std::vector<alphabet::Symbol>& rhs : rule.second)
-			res[rhs] = firstSeq(grammar, rhs, firstNt);
-	return res;
-	*/
-
-	return firstSeq(grammar, rhs, firstNt);
-}
-
-template<>
-std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const grammar::Grammar& grammar, const std::vector<alphabet::Symbol>& rhs) {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> data;
-	data.first = rhs;
-	grammar.getData().Accept((void*) &data, First::FIRST);
-	return data.second;
-}
-
-void First::Visit(void* data, const grammar::LeftLG& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->first(grammar, out.first);
-}
-
-void First::Visit(void* data, const grammar::LeftRG& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
 
-	out.second = this->first(grammar, out.first);
-}
-
-void First::Visit(void* data, const grammar::RightLG& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->first(grammar, out.first);
-}
-
-void First::Visit(void* data, const grammar::RightRG& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+		if(firstOfNonterminal1 == firstOfNonterminal2) break;
 
-	out.second = this->first(grammar, out.first);
-}
+		firstOfNonterminal1 = std::move(firstOfNonterminal2);
+		firstOfNonterminal2.clear();
 
-void First::Visit(void* data, const grammar::LG& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+	} while(true);
 
-	out.second = this->first(grammar, out.first);
+	return firstOfNonterminal1;
 }
 
-void First::Visit(void* data, const grammar::CFG& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->first(grammar, out.first);
-}
-
-void First::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->first(grammar, out.first);
-}
+template<class T>
+std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> First::first( const T & grammar ) {
+	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstNt = first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), grammar.getRawRules());
 
-void First::Visit(void* data, const grammar::CNF& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+	std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> res;
+	for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : grammar.getRawRules()) {
+		for(const std::vector<alphabet::Symbol>& rhs : rule.second) {
+			res.insert(make_pair(rhs, first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), firstNt, rhs)));
+		}
+	}
 
-	out.second = this->first(grammar, out.first);
+	return res;
 }
 
-void First::Visit(void* data, const grammar::GNF& grammar) const {
-	std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+template<class T>
+std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const T& grammar, const std::vector<alphabet::Symbol>& rhs) {
+	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstNt = first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), grammar.getRawRules());
 
-	out.second = this->first(grammar, out.first);
+	return first(grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet(), firstNt, rhs);
 }
 
-void First::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
+auto FirstCFG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::CFG>(First::getInstance1(), First::first);
+auto FirstEpsilonFreeCFG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::EpsilonFreeCFG>(First::getInstance1(), First::first);
+auto FirstGNF = FirstBase1::RegistratorWrapper<FirstResult1, grammar::GNF>(First::getInstance1(), First::first);
+auto FirstCNF = FirstBase1::RegistratorWrapper<FirstResult1, grammar::CNF>(First::getInstance1(), First::first);
+auto FirstLG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::LG>(First::getInstance1(), First::first);
+auto FirstLeftLG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::LeftLG>(First::getInstance1(), First::first);
+auto FirstLeftRG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::LeftRG>(First::getInstance1(), First::first);
+auto FirstRightLG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::RightLG>(First::getInstance1(), First::first);
+auto FirstRightRG = FirstBase1::RegistratorWrapper<FirstResult1, grammar::RightRG>(First::getInstance1(), First::first);
 
-void First::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> First::first(const grammar::Grammar& grammar) {
+	return getInstance1().dispatch(grammar.getData());
 }
 
-void First::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
+auto FirstCFG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::CFG>(First::getInstance2(), First::first);
+auto FirstEpsilonFreeCFG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::EpsilonFreeCFG>(First::getInstance2(), First::first);
+auto FirstGNF2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::GNF>(First::getInstance2(), First::first);
+auto FirstCNF2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::CNF>(First::getInstance2(), First::first);
+auto FirstLG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::LG>(First::getInstance2(), First::first);
+auto FirstLeftLG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::LeftLG>(First::getInstance2(), First::first);
+auto FirstLeftRG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::LeftRG>(First::getInstance2(), First::first);
+auto FirstRightLG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::RightLG>(First::getInstance2(), First::first);
+auto FirstRightRG2 = FirstBase2::RegistratorWrapper<FirstResult2, grammar::RightRG>(First::getInstance2(), First::first);
 
-void First::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+std::set<std::variant<alphabet::Symbol, string::Epsilon>> First::first(const grammar::Grammar& grammar, const std::vector<alphabet::Symbol>& rhs) {
+	return getInstance2().dispatch(grammar.getData(), rhs);
 }
 
-const First First::FIRST;
-
 } /* namespace parsing */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/parsing/First.h b/alib2algo/src/grammar/parsing/First.h
index 958a0a99a41d2f863f68547d03b5ab9c61fd3904..c01373e1a2dad0240bd3e2424cd92155c0e55f6c 100644
--- a/alib2algo/src/grammar/parsing/First.h
+++ b/alib2algo/src/grammar/parsing/First.h
@@ -2,56 +2,58 @@
  * First.h
  *
  *  Created on: 9. 6. 2015
- *	  Author: Tomas Pecka
+ *	  Author: Tomas Pecka, Jan Travnicek
  */
 
 #ifndef FIRST_H_
 #define FIRST_H_
 
+#include <common/multipleDispatch.hpp>
 #include <grammar/Grammar.h>
-
-#include <grammar/ContextFree/CFG.h>
-#include <grammar/ContextFree/EpsilonFreeCFG.h>
-#include <grammar/ContextFree/CNF.h>
-#include <grammar/ContextFree/GNF.h>
-#include <grammar/ContextFree/LG.h>
-#include <grammar/Regular/LeftLG.h>
-#include <grammar/Regular/LeftRG.h>
-#include <grammar/Regular/RightLG.h>
-#include <grammar/Regular/RightRG.h>
-#include <exception/AlibException.h>
+#include <alphabet/Symbol.h>
+#include <string/Epsilon.h>
+#include <vector>
+#include <set>
+#include <variant>
 
 namespace grammar {
 
 namespace parsing {
 
-class First : public grammar::VisitableGrammarBase::const_visitor_type {
+typedef std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> FirstResult1;
+typedef std::SingleDispatch<FirstResult1, grammar::GrammarBase> FirstBase1;
 
-public:
-	First() {}
+typedef std::set<std::variant<alphabet::Symbol, string::Epsilon>> FirstResult2;
+typedef std::SingleDispatchLastStaticParam<FirstResult2, grammar::GrammarBase, const std::vector<alphabet::Symbol>&> FirstBase2;
+
+class First : public FirstBase1, public FirstBase2 {
+	static std::set<std::variant<alphabet::Symbol, string::Epsilon>> first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& firstOfNonterminal, const std::vector<alphabet::Symbol>& rhs);
+
+	static std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> first(const std::set<alphabet::Symbol>& terminals, const std::set<alphabet::Symbol>& nonterminals, const std::map<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rules);
+
+	static First& getInstance() {
+		static First res;
+		return res;
+	}
 
+public:
 	template<class T>
-	static std::set<std::variant<alphabet::Symbol, string::Epsilon>> first(const T& grammar, const std::vector<alphabet::Symbol>& rhs);
+	static FirstResult1 first( const T & grammar );
 
-private:
 	template<class T>
-	static std::set<std::variant<alphabet::Symbol, string::Epsilon>> firstSeq(const T& grammar, const std::vector<alphabet::Symbol>& rhs, std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> firstNt);
-
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const First FIRST;
+	static FirstResult2 first(const T& grammar, const std::vector<alphabet::Symbol>& rhs);
+
+	static FirstResult1 first(const grammar::Grammar& grammar);
+
+	static FirstResult2 first(const grammar::Grammar& grammar, const std::vector<alphabet::Symbol>& rhs);
+
+	static FirstBase1& getInstance1() {
+		return getInstance();
+	}
+
+	static FirstBase2& getInstance2() {
+		return getInstance();
+	}
 };
 
 } /* namespace parsing */
diff --git a/alib2algo/src/grammar/parsing/Follow.cpp b/alib2algo/src/grammar/parsing/Follow.cpp
index afd058b5f75ce537697ad97c7dec4bf9dd5550ff..dfc2ec98a83025619e1f9ea44009f6ce67457f4c 100644
--- a/alib2algo/src/grammar/parsing/Follow.cpp
+++ b/alib2algo/src/grammar/parsing/Follow.cpp
@@ -11,16 +11,47 @@
 #include <string/Epsilon.h>
 #include <iterator>
 
-#include "setunion.h"
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/CNF.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/LG.h>
+#include <grammar/Regular/LeftLG.h>
+#include <grammar/Regular/LeftRG.h>
+#include <grammar/Regular/RightLG.h>
+#include <grammar/Regular/RightRG.h>
+#include <exception/AlibException.h>
 
 namespace grammar {
 
 namespace parsing {
 
 template<class T>
-std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const T& grammar, const alphabet::Symbol& nt)
-{
-	if(grammar.getNonterminalAlphabet().find(nt) == grammar.getNonterminalAlphabet().end())
+void Follow::follow(const T& grammar, std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& followSet) {
+	for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : grammar.getRawRules()) {
+		const alphabet::Symbol& X = rule.first;
+		for(const std::vector<alphabet::Symbol>& rhs : rule.second) {
+			// every nt in rhs is Y
+			for(std::vector<alphabet::Symbol>::const_iterator it = rhs.begin(); it != rhs.end(); it++) {
+				const alphabet::Symbol& Y = *it;
+				if(!grammar.getNonterminalAlphabet().count(Y)) continue;
+
+				std::set<std::variant<alphabet::Symbol, string::Epsilon>> firstBeta = First::first(grammar, std::vector<alphabet::Symbol>(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>
+std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const T& grammar, const alphabet::Symbol& nt) {
+	if(!grammar.getNonterminalAlphabet().count(nt))
 		throw exception::AlibException("Follow: Given symbol is not nonterminal.");
 
 	/*
@@ -34,144 +65,40 @@ std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const T
 	 * 3. goto 2 if any follow set was changed in prev step.
 	 */
 
-	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> followSet;
+	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> followSet1;
 
 	for(const alphabet::Symbol& symb : grammar.getNonterminalAlphabet())
-		followSet[symb] = {};
-
-	followSet[grammar.getInitialSymbol()] = {string::Epsilon::EPSILON};
-
-	bool changed;
-	do
-	{
-		changed = false;
-
-		for(const std::pair<alphabet::Symbol, std::set<std::vector<alphabet::Symbol>>>& rule : grammar.getRawRules())
-		{
-			const alphabet::Symbol& X = rule.first;
-			for(const std::vector<alphabet::Symbol>& rhs : rule.second)
-			{
-				// every nt in rhs is Y
-				for(std::vector<alphabet::Symbol>::const_iterator it = rhs.begin(); it != rhs.end(); it++)
-				{
-					const alphabet::Symbol& Y = *it;
-
-					if(grammar.getNonterminalAlphabet().find(Y) == grammar.getNonterminalAlphabet().end())
-						continue;
-
-					std::vector<alphabet::Symbol> beta(std::next(it), rhs.end());
-					std::set<std::variant<alphabet::Symbol, string::Epsilon>> oldFollow, firstBeta = First::first(grammar, beta);
-
-					auto epsIt = firstBeta.find(string::Epsilon::EPSILON);
-					if(epsIt != firstBeta.end())
-					{
-						firstBeta.erase(epsIt);
-
-						oldFollow = followSet[Y];
-						followSet[Y] = setunion(followSet[Y], followSet[X]);
-						if(oldFollow != followSet[Y]) changed = true;
-					}
-
-					oldFollow = followSet[Y];
-					followSet[Y] = setunion(followSet[Y], firstBeta);
-					if(oldFollow != followSet[Y]) changed = true;
-				}
-			}
-		}
-	}
-	while(changed);
-
-	return followSet[nt];
-}
-
-template<>
-std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const grammar::Grammar& grammar, const alphabet::Symbol& nt) {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> data(nt, {});
-	grammar.getData().Accept((void*) &data, Follow::FOLLOW);
-	return data.second;
-}
-
-void Follow::Visit(void* data, const grammar::LeftLG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->follow(grammar, out.first);
-}
-
-void Follow::Visit(void* data, const grammar::LeftRG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->follow(grammar, out.first);
-}
-
-void Follow::Visit(void* data, const grammar::RightLG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->follow(grammar, out.first);
-}
-
-void Follow::Visit(void* data, const grammar::RightRG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->follow(grammar, out.first);
-}
-
-void Follow::Visit(void* data, const grammar::LG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
-
-	out.second = this->follow(grammar, out.first);
-}
-
-void Follow::Visit(void* data, const grammar::CFG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+		followSet1[symb];
 
-	out.second = this->follow(grammar, out.first);
-}
-
-void Follow::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+	followSet1[grammar.getInitialSymbol()] = {string::Epsilon::EPSILON};
 
-	out.second = this->follow(grammar, out.first);
-}
+	std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> followSet2 = followSet1;
 
-void Follow::Visit(void* data, const grammar::CNF& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+	do {
+		follow(grammar, followSet2);
 
-	out.second = this->follow(grammar, out.first);
-}
+		if(followSet1 == followSet2) break;
 
-void Follow::Visit(void* data, const grammar::GNF& grammar) const {
-	std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& out =
-		*((std::pair<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>*) data);
+		followSet1 = followSet2;
+	} while(true);
 
-	out.second = this->follow(grammar, out.first);
+	return followSet1[nt];
 }
 
-void Follow::Visit(void*, const grammar::CSG&) const {
-	throw exception::AlibException("Unsupported grammar type CSG");
-}
+auto FollowCFG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::CFG>(Follow::getInstance(), Follow::follow);
+auto FollowEpsilonFreeCFG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::EpsilonFreeCFG>(Follow::getInstance(), Follow::follow);
+auto FollowGNF = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::GNF>(Follow::getInstance(), Follow::follow);
+auto FollowCNF = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::CNF>(Follow::getInstance(), Follow::follow);
+auto FollowLG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::LG>(Follow::getInstance(), Follow::follow);
+auto FollowLeftLG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::LeftLG>(Follow::getInstance(), Follow::follow);
+auto FollowLeftRG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::LeftRG>(Follow::getInstance(), Follow::follow);
+auto FollowRightLG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::RightLG>(Follow::getInstance(), Follow::follow);
+auto FollowRightRG = Follow::RegistratorWrapper<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::RightRG>(Follow::getInstance(), Follow::follow);
 
-void Follow::Visit(void*, const grammar::NonContractingGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
-}
-
-void Follow::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
-}
-
-void Follow::Visit(void*, const grammar::UnrestrictedGrammar&) const {
-	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+std::set<std::variant<alphabet::Symbol, string::Epsilon>> Follow::follow(const grammar::Grammar& grammar, const alphabet::Symbol& nt) {
+	return getInstance().dispatch(grammar.getData(), nt);
 }
 
-const Follow Follow::FOLLOW;
-
 } /* namespace parsing */
 
 } /* namespace grammar */
diff --git a/alib2algo/src/grammar/parsing/Follow.h b/alib2algo/src/grammar/parsing/Follow.h
index 3d1e4b40bbbe91ba19c0a20e495cc23f616286e3..e5d6a0800ac05864e3e6affb8873d6558f96536e 100644
--- a/alib2algo/src/grammar/parsing/Follow.h
+++ b/alib2algo/src/grammar/parsing/Follow.h
@@ -8,47 +8,32 @@
 #ifndef FOLLOW_H_
 #define FOLLOW_H_
 
+#include <common/multipleDispatch.hpp>
 #include <grammar/Grammar.h>
-
-#include <grammar/ContextFree/CFG.h>
-#include <grammar/ContextFree/EpsilonFreeCFG.h>
-#include <grammar/ContextFree/CNF.h>
-#include <grammar/ContextFree/GNF.h>
-#include <grammar/ContextFree/LG.h>
-#include <grammar/Regular/LeftLG.h>
-#include <grammar/Regular/LeftRG.h>
-#include <grammar/Regular/RightLG.h>
-#include <grammar/Regular/RightRG.h>
-#include <exception/AlibException.h>
+#include <alphabet/Symbol.h>
+#include <string/Epsilon.h>
+#include <vector>
+#include <set>
+#include <variant>
 
 namespace grammar {
 
 namespace parsing {
 
-class Follow : public grammar::VisitableGrammarBase::const_visitor_type {
+class Follow : public std::SingleDispatchLastStaticParam<std::set<std::variant<alphabet::Symbol, string::Epsilon>>, grammar::GrammarBase, const alphabet::Symbol&> {
+	template<class T>
+	static void follow(const T& grammar, std::map<alphabet::Symbol, std::set<std::variant<alphabet::Symbol, string::Epsilon>>>& followSet);
 
 public:
-	Follow() {}
+	static std::set<std::variant<alphabet::Symbol, string::Epsilon>> follow(const grammar::Grammar& grammar, const alphabet::Symbol& nt);
 
 	template<class T>
 	static std::set<std::variant<alphabet::Symbol, string::Epsilon>> follow(const T& grammar, const alphabet::Symbol& nt);
 
-private:
-	void Visit(void*, const grammar::LeftLG& grammar) const;
-	void Visit(void*, const grammar::LeftRG& grammar) const;
-	void Visit(void*, const grammar::RightLG& grammar) const;
-	void Visit(void*, const grammar::RightRG& grammar) const;
-	void Visit(void*, const grammar::LG& grammar) const;
-	void Visit(void*, const grammar::CFG& grammar) const;
-	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
-	void Visit(void*, const grammar::CNF& grammar) const;
-	void Visit(void*, const grammar::GNF& grammar) const;
-	void Visit(void*, const grammar::CSG& grammar) const;
-	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
-	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
-	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
-
-	static const Follow FOLLOW;
+	static Follow& getInstance() {
+		static Follow res;
+		return res;
+	}
 };
 
 } /* namespace parsing */
diff --git a/alib2algo/src/grammar/parsing/setunion.h b/alib2algo/src/grammar/parsing/setunion.h
deleted file mode 100644
index c69b35061aec537a9cd2a9bbc2362162c826ca27..0000000000000000000000000000000000000000
--- a/alib2algo/src/grammar/parsing/setunion.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __SETUNION_H__
-#define __SETUNION_H__
-
-namespace grammar {
-
-namespace parsing {
-
-template<class T>
-std::set<T> setunion(const std::set<T>& a, const std::set<T>& b)
-{
-	std::set<T> res;
-	std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::inserter(res, res.begin()));
-	return res;
-}
-
-} /* namespace parsing */
-
-} /* namespace grammar */
-
-#endif /* __SETUNION_H__ */
diff --git a/alib2algo/test-src/grammar/parsing/FirstTest.cpp b/alib2algo/test-src/grammar/parsing/FirstTest.cpp
index ad3f5fbf29cf79c6acdb6c9b3384735ebc47dd8b..f80149c9b369182390d49ab893510e6ccca10a76 100644
--- a/alib2algo/test-src/grammar/parsing/FirstTest.cpp
+++ b/alib2algo/test-src/grammar/parsing/FirstTest.cpp
@@ -2,6 +2,7 @@
 
 #include "grammar/parsing/First.h"
 #include "string/Epsilon.h"
+#include "grammar/ContextFree/CFG.h"
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FirstTest, "grammar" );
 CPPUNIT_TEST_SUITE_REGISTRATION( FirstTest );
@@ -142,3 +143,52 @@ void FirstTest::testFirst() {
 	}
 }
 
+void FirstTest::testFirst2() {
+	alphabet::Symbol A = alphabet::symbolFrom('A');
+	alphabet::Symbol c = alphabet::symbolFrom('c');
+	alphabet::Symbol d = alphabet::symbolFrom('d');
+
+	grammar::CFG grammar(A);
+	grammar.setTerminalAlphabet({c, d});
+	grammar.setNonterminalAlphabet({{A}});
+	grammar.setInitialSymbol(A);
+
+	grammar.addRule(A, std::vector<alphabet::Symbol>{ A, c });
+	grammar.addRule(A, std::vector<alphabet::Symbol>{ d });
+
+	std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> res = {{{d}, {d}}, {{A, c}, {d}}};
+	CPPUNIT_ASSERT(res == grammar::parsing::First::first(grammar));
+}
+
+void FirstTest::testFirst3() {
+	alphabet::Symbol S = alphabet::symbolFrom('S');
+	alphabet::Symbol A = alphabet::symbolFrom('A');
+	alphabet::Symbol B = alphabet::symbolFrom('B');
+	alphabet::Symbol a = alphabet::symbolFrom('a');
+	alphabet::Symbol b = alphabet::symbolFrom('b');
+	alphabet::Symbol c = alphabet::symbolFrom('c');
+	alphabet::Symbol d = alphabet::symbolFrom('d');
+	alphabet::Symbol f = alphabet::symbolFrom('f');
+
+	grammar::CFG grammar(S);
+	grammar.setTerminalAlphabet({a, b, c, d, f});
+	grammar.setNonterminalAlphabet({{S, A, B}});
+	grammar.setInitialSymbol(S);
+
+	grammar.addRule(S, std::vector<alphabet::Symbol>{ A, a });
+	grammar.addRule(S, std::vector<alphabet::Symbol>{ b, S });
+	grammar.addRule(A, std::vector<alphabet::Symbol>{ c, A, d });
+	grammar.addRule(A, std::vector<alphabet::Symbol>{ B });
+	grammar.addRule(B, std::vector<alphabet::Symbol>{ f, S });
+	grammar.addRule(B, std::vector<alphabet::Symbol>{ });
+
+	std::map<std::vector<alphabet::Symbol>, std::set<std::variant<alphabet::Symbol, string::Epsilon>>> res = {
+		{{A, a}, {c, f, a}},
+		{{b, S}, {b}},
+		{{c, A, d}, {c}},
+		{{B}, {f, string::Epsilon::EPSILON}},
+		{{f, S}, {f}},
+		{{}, {string::Epsilon::EPSILON}}};
+	CPPUNIT_ASSERT(res == grammar::parsing::First::first(grammar));
+}
+
diff --git a/alib2algo/test-src/grammar/parsing/FirstTest.h b/alib2algo/test-src/grammar/parsing/FirstTest.h
index 5bb36cef0f8b7bf193d35c799568ab92e6961eba..46c90bab689a5a8a9728fc00d2c7883fb6097b22 100644
--- a/alib2algo/test-src/grammar/parsing/FirstTest.h
+++ b/alib2algo/test-src/grammar/parsing/FirstTest.h
@@ -7,6 +7,8 @@ class FirstTest : public CppUnit::TestFixture
 {
   CPPUNIT_TEST_SUITE( FirstTest );
   CPPUNIT_TEST( testFirst );
+  CPPUNIT_TEST( testFirst2 );
+  CPPUNIT_TEST( testFirst3 );
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -14,6 +16,8 @@ public:
   void tearDown();
 
   void testFirst();
+  void testFirst2();
+  void testFirst3();
 };
 
 #endif /* FIRST_TEST_H_ */
diff --git a/alib2algo/test-src/grammar/parsing/FollowTest.cpp b/alib2algo/test-src/grammar/parsing/FollowTest.cpp
index fb2c2eb95045f99581a042ab4fa70ef458fc6214..2a2d17f044795572b071109dce98089b57c028db 100644
--- a/alib2algo/test-src/grammar/parsing/FollowTest.cpp
+++ b/alib2algo/test-src/grammar/parsing/FollowTest.cpp
@@ -2,6 +2,7 @@
 
 #include "grammar/parsing/Follow.h"
 #include "string/Epsilon.h"
+#include "grammar/ContextFree/CFG.h"
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FollowTest, "grammar" );
 CPPUNIT_TEST_SUITE_REGISTRATION( FollowTest );