diff --git a/alib2algo/src/grammar/simplify/ToCNF.cpp b/alib2algo/src/grammar/simplify/ToCNF.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c3e60d286d5212fe44922b439c9239bccef652b
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/ToCNF.cpp
@@ -0,0 +1,247 @@
+/*
+ * ToCNF.cpp
+ *
+ *  Created on: 24. 11. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "ToCNF.h"
+
+#include "EpsilonRemover.h"
+#include "SimpleRulesRemover.h"
+#include "alphabet/LabeledSymbol.h"
+#include "alphabet/SymbolPairSymbol.h"
+
+namespace grammar {
+
+namespace simplify {
+
+template<class T>
+std::pair<alphabet::Symbol, alphabet::Symbol> splitToPairs(T& grammar, const std::vector<alphabet::Symbol>& rhs, unsigned from, unsigned size, std::map<alphabet::Symbol, alphabet::Symbol>& createdSymbols) {
+	if(size == 2) {
+		return std::make_pair(rhs[from], rhs[from + 1]);
+	} else if(size == 3) {
+		alphabet::Symbol firstLhs {rhs[from]};
+
+		auto second = splitToPairs(grammar, rhs, from + 1, 2, createdSymbols);
+		alphabet::Symbol secondProposal{alphabet::SymbolPairSymbol(second)};
+		if(!createdSymbols.count(secondProposal)) {
+			createdSymbols.insert(std::make_pair(secondProposal, alphabet::createUniqueSymbol(secondProposal, grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet())));
+		}
+		grammar.addNonterminalSymbol(createdSymbols.find(secondProposal)->second);
+		grammar.addRawRule(createdSymbols.find(secondProposal)->second, {second.first, second.second});
+
+		return std::make_pair(firstLhs, createdSymbols.find(secondProposal)->second);
+	} else {
+		auto first = splitToPairs(grammar, rhs, from, size / 2, createdSymbols);
+		alphabet::Symbol firstProposal{alphabet::SymbolPairSymbol(first)};
+		if(!createdSymbols.count(firstProposal)) {
+			createdSymbols.insert(std::make_pair(firstProposal, alphabet::createUniqueSymbol(firstProposal, grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet())));
+		}
+		grammar.addNonterminalSymbol(createdSymbols.find(firstProposal)->second);
+		grammar.addRawRule(createdSymbols.find(firstProposal)->second, {first.first, first.second});
+
+		auto second = splitToPairs(grammar, rhs, from + size / 2, size - size / 2, createdSymbols);
+		alphabet::Symbol secondProposal{alphabet::SymbolPairSymbol(second)};
+		if(!createdSymbols.count(secondProposal)) {
+			createdSymbols.insert(std::make_pair(secondProposal, alphabet::createUniqueSymbol(secondProposal, grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet())));
+		}
+		grammar.addNonterminalSymbol(createdSymbols.find(secondProposal)->second);
+		grammar.addRawRule(createdSymbols.find(secondProposal)->second, {second.first, second.second});
+
+		return std::make_pair(createdSymbols.find(firstProposal)->second, createdSymbols.find(secondProposal)->second);
+	}
+}
+
+template<class T>
+grammar::CNF convertInternal( const T & origGrammar ) {
+	T grammarTmp(origGrammar.getInitialSymbol());
+
+	for( const auto & symbol : origGrammar.getNonterminalAlphabet() )
+		grammarTmp.addNonterminalSymbol( symbol );
+
+	for( const auto & symbol : origGrammar.getTerminalAlphabet() )
+		grammarTmp.addTerminalSymbol( symbol );
+
+	std::map<alphabet::Symbol, alphabet::Symbol> createdSymbols;
+	auto origRules = origGrammar.getRawRules();
+	for( const auto & origRule : origRules ) {
+		for( const auto& origRhs : origRule.second ) {
+			if(origRhs.size() == 1 || origRhs.size() == 2)
+				grammarTmp.addRawRule(origRule.first, origRhs);
+			else if(origRhs.size() > 2) {
+				auto second = splitToPairs(grammarTmp, origRhs, 0, origRhs.size(), createdSymbols);
+				grammarTmp.addRawRule(origRule.first, {second.first, second.second});
+			} else
+				throw exception::AlibException("Invalid rule in grammar");
+		}
+	}
+
+	grammarTmp.setGeneratesEpsilon(origGrammar.getGeneratesEpsilon());
+
+	grammar::CNF grammar(grammarTmp.getInitialSymbol());
+
+	for( const auto & symbol : grammarTmp.getNonterminalAlphabet() )
+		grammar.addNonterminalSymbol( symbol );
+
+	for( const auto & symbol : grammarTmp.getTerminalAlphabet() )
+		grammar.addTerminalSymbol( symbol );
+
+	std::map<alphabet::Symbol, alphabet::Symbol> terminalToShadowNonterminal;
+	for( const auto & symbol : grammarTmp.getTerminalAlphabet() ) {
+		alphabet::Symbol shadowSymbol = alphabet::createUniqueSymbol(symbol, grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		terminalToShadowNonterminal.insert( std::make_pair( symbol, shadowSymbol ));
+		grammar.addNonterminalSymbol( shadowSymbol );
+		grammar.addRule(shadowSymbol, symbol);
+	}
+
+	auto tmpRules = grammarTmp.getRawRules();
+	for( const auto & tmpRule : tmpRules ) {
+		for( const auto& tmpRhs : tmpRule.second ) {
+			if(tmpRhs.size() == 2) {
+				if(grammarTmp.getNonterminalAlphabet().count(tmpRhs[0])) {
+					if(grammarTmp.getNonterminalAlphabet().count(tmpRhs[1])) {
+						grammar.addRawRule(tmpRule.first, tmpRhs);
+					} else {
+						grammar.addRawRule(tmpRule.first, {tmpRhs[0], terminalToShadowNonterminal.find(tmpRhs[1])->second});
+					}
+				} else {
+					if(grammarTmp.getNonterminalAlphabet().count(tmpRhs[1])) {
+						grammar.addRawRule(tmpRule.first, {terminalToShadowNonterminal.find(tmpRhs[0])->second, tmpRhs[1]});
+					} else {
+						grammar.addRawRule(tmpRule.first, {terminalToShadowNonterminal.find(tmpRhs[0])->second, terminalToShadowNonterminal.find(tmpRhs[1])->second });
+					}
+				}
+			} else // tmpRhs.size() == 1
+				grammar.addRawRule(tmpRule.first, tmpRhs);
+		}
+	}
+
+	grammar.setGeneratesEpsilon(grammarTmp.getGeneratesEpsilon());
+
+	return grammar;
+}
+
+
+
+grammar::CNF ToCNF::convert(const grammar::CFG& origGrammar)
+{
+	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
+}
+
+grammar::CNF ToCNF::convert(const grammar::EpsilonFreeCFG& origGrammar)
+{
+	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(origGrammar));
+}
+
+grammar::CNF ToCNF::convert(const grammar::CNF& origGrammar)
+{
+	return origGrammar;
+}
+
+grammar::CNF ToCNF::convert(const grammar::GNF& origGrammar)
+{
+	return convertInternal(origGrammar);
+}
+
+grammar::CNF ToCNF::convert(const grammar::LG& origGrammar)
+{
+	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
+}
+
+grammar::CNF ToCNF::convert(const grammar::LeftLG& origGrammar)
+{
+	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
+}
+
+grammar::CNF ToCNF::convert(const grammar::LeftRG& origGrammar)
+{
+	return convertInternal(origGrammar);
+}
+
+grammar::CNF ToCNF::convert(const grammar::RightLG& origGrammar)
+{
+	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
+}
+
+grammar::CNF ToCNF::convert(const grammar::RightRG& origGrammar)
+{
+	return convertInternal(origGrammar);
+}
+
+
+
+grammar::Grammar ToCNF::convert(const grammar::Grammar& grammar) {
+	grammar::Grammar* out = NULL;
+	grammar.getData().Accept((void*) &out, ToCNF::TO_CNF);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToCNF::Visit(void* data, const grammar::LeftLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::LeftRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::RightLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::RightRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::LG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::CFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::CNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void* data, const grammar::GNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new Grammar(std::move(this->convert(grammar)));
+}
+
+void ToCNF::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void ToCNF::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void ToCNF::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void ToCNF::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const ToCNF ToCNF::TO_CNF;
+
+} /* namespace simplify */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/simplify/ToCNF.h b/alib2algo/src/grammar/simplify/ToCNF.h
new file mode 100644
index 0000000000000000000000000000000000000000..485a076e164b0648479cfa894be810e5834692d4
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/ToCNF.h
@@ -0,0 +1,67 @@
+/*
+ * ToCNF.h
+ *
+ *  Created on: 24. 11. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef TO_CNF_H_
+#define TO_CNF_H_
+
+#include <map>
+#include <algorithm>
+
+#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>
+
+namespace grammar {
+
+namespace simplify {
+
+class ToCNF : public grammar::VisitableGrammarBase::const_visitor_type {
+public:
+	static grammar::Grammar convert( const grammar::Grammar & grammar );
+
+	static grammar::CNF convert( const grammar::CFG & grammar );
+	static grammar::CNF convert( const grammar::EpsilonFreeCFG & grammar );
+	static grammar::CNF convert( const grammar::GNF & grammar );
+	static grammar::CNF convert( const grammar::CNF & grammar );
+	static grammar::CNF convert( const grammar::LG & grammar );
+	static grammar::CNF convert( const grammar::LeftLG & grammar );
+	static grammar::CNF convert( const grammar::LeftRG & grammar );
+	static grammar::CNF convert( const grammar::RightLG & grammar );
+	static grammar::CNF convert( const grammar::RightRG & grammar );
+
+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 ToCNF TO_CNF;
+};
+
+} /* namespace simplify */
+
+} /* namespace grammar */
+
+#endif /* TO_CNF_H_ */
diff --git a/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5619eb15b7a32a1cffa8e9ae0c9a34c7cadbc20a
--- /dev/null
+++ b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.cpp
@@ -0,0 +1,113 @@
+#include "GrammarToCNFTest.h"
+
+#include "grammar/simplify/ToCNF.h"
+
+#include "grammar/ContextFree/CFG.h"
+#include "grammar/ContextFree/CNF.h"
+
+#include "grammar/GrammarToStringComposer.h"
+#include "alphabet/SymbolPairSymbol.h"
+#include "alphabet/UniqueSymbol.h"
+#include "primitive/Integer.h"
+
+#include "std/pair.hpp"
+
+#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
+
+CPPUNIT_TEST_SUITE_REGISTRATION( GrammarToCNFTest );
+
+void GrammarToCNFTest::setUp() {
+}
+
+void GrammarToCNFTest::tearDown() {
+}
+
+void GrammarToCNFTest::testToCNFRules1() {
+	alphabet::Symbol S = alphabet::symbolFrom("S");
+	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 a = alphabet::symbolFrom("a");
+	alphabet::Symbol b = alphabet::symbolFrom("b");
+
+	alphabet::Symbol aP = alphabet::symbolFrom("a'");
+	alphabet::Symbol bP = alphabet::symbolFrom("b'");
+
+	grammar::CFG grammar1(S);
+	grammar1.setNonterminalAlphabet({S, A, B, C, D});
+	grammar1.setTerminalAlphabet({a, b});
+
+	grammar::CNF grammar2 = grammar::simplify::ToCNF::convert(grammar1);
+
+	grammar::CNF grammar3(S);
+	grammar3.setNonterminalAlphabet({S, A, B, C, D, aP, bP});
+	grammar3.setTerminalAlphabet({a, b});
+	grammar3.addRule(aP, a);
+	grammar3.addRule(bP, b);
+
+	std::cout << grammar2 << std::endl;
+	std::cout << grammar3 << std::endl;
+
+	CPPUNIT_ASSERT(grammar2 == grammar3);
+}
+
+void GrammarToCNFTest::testToCNFRules2() {
+	alphabet::Symbol S = alphabet::symbolFrom("S");
+	alphabet::Symbol X = alphabet::symbolFrom("X");
+	alphabet::Symbol Y = alphabet::symbolFrom("Y");
+
+	alphabet::Symbol a = alphabet::symbolFrom("a");
+	alphabet::Symbol b = alphabet::symbolFrom("b");
+	alphabet::Symbol c = alphabet::symbolFrom("c");
+
+	grammar::CFG grammar1(S);
+	grammar1.setNonterminalAlphabet({S, X, Y});
+	grammar1.setTerminalAlphabet({a, b, c});
+	grammar1.addRule({S}, {a, X, b, X});
+	grammar1.addRule({X}, {a, Y});
+	grammar1.addRule({X}, {b, Y});
+	grammar1.addRule({X}, {});
+	grammar1.addRule({Y}, {X});
+	grammar1.addRule({Y}, {c});
+
+	grammar::CNF grammar2 = grammar::simplify::ToCNF::convert(grammar1);
+	alphabet::Symbol aP = alphabet::symbolFrom("a'");
+	alphabet::Symbol bP = alphabet::symbolFrom("b'");
+	alphabet::Symbol cP = alphabet::symbolFrom("c'");
+	alphabet::Symbol Xb = alphabet::Symbol(alphabet::UniqueSymbol(alphabet::Symbol(alphabet::SymbolPairSymbol(std::make_pair(X, b))), primitive::Integer(0)));
+	alphabet::Symbol aX = alphabet::Symbol(alphabet::UniqueSymbol(alphabet::Symbol(alphabet::SymbolPairSymbol(std::make_pair(a, X))), primitive::Integer(0)));
+	alphabet::Symbol bX = alphabet::Symbol(alphabet::UniqueSymbol(alphabet::Symbol(alphabet::SymbolPairSymbol(std::make_pair(b, X))), primitive::Integer(0)));
+
+	grammar::CNF grammar3(S);
+	grammar3.setNonterminalAlphabet({S, X, Y, aP, bP, cP, Xb, aX, bX});
+	grammar3.setTerminalAlphabet({a, b, c});
+	grammar3.addRule(S, std::make_pair(aX, bX));
+	grammar3.addRule(S, std::make_pair(aP, bX));
+	grammar3.addRule(S, std::make_pair(aP, Xb));
+	grammar3.addRule(S, std::make_pair(aP, bP));
+	grammar3.addRule(aX, std::make_pair(aP, X));
+	grammar3.addRule(bX, std::make_pair(bP, X));
+	grammar3.addRule(Xb, std::make_pair(X, bP));
+	grammar3.addRule(X, std::make_pair(aP, Y));
+	grammar3.addRule(X, std::make_pair(bP, Y));
+	grammar3.addRule(X, a);
+	grammar3.addRule(X, b);
+	grammar3.addRule(Y, std::make_pair(aP, Y));
+	grammar3.addRule(Y, std::make_pair(bP, Y));
+	grammar3.addRule(Y, a);
+	grammar3.addRule(Y, b);
+	grammar3.addRule(Y, c);
+	grammar3.addRule(aP, a);
+	grammar3.addRule(bP, b);
+	grammar3.addRule(cP, c);
+
+	grammar::GrammarToStringComposer gscomp;
+
+	std::cout << gscomp.compose(grammar2) << std::endl;
+	std::cout << gscomp.compose(grammar3) << std::endl;
+
+	CPPUNIT_ASSERT(grammar2 == grammar3);
+}
+
diff --git a/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.h b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..85081c5b4db2efb8d2d54018e64beddedd814f5a
--- /dev/null
+++ b/alib2algo/test-src/grammar/simplify/GrammarToCNFTest.h
@@ -0,0 +1,21 @@
+#ifndef GRAMMAR_TO_CNF_TEST_H_
+#define GRAMMAR_TO_CNF_TEST_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class GrammarToCNFTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( GrammarToCNFTest );
+  CPPUNIT_TEST( testToCNFRules1 );
+  CPPUNIT_TEST( testToCNFRules2 );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void testToCNFRules1();
+  void testToCNFRules2();
+};
+
+#endif /* GRAMMAR_TO_CNF_TEST_H_ */