diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index afda692fa116d3b259174cc8c777b3d66deb1a03..99955d0f316c62077b76c6e3c9623520b97b8a31 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -7,25 +7,24 @@
 
 #include "ConversionHandler.h"
 
-#include "conversions/fa2re/StateElimination.h"
-#include "conversions/fa2re/Algebraic.h"
+#include "automaton/convert/ToRegExpStateElimination.h"
+#include "automaton/convert/ToRegExpAlgebraic.h"
+#include "automaton/convert/ToGrammarLeftRG.h"
+#include "automaton/convert/ToGrammarRightRG.h"
 
-#include "conversions/re2fa/GlushkovNFA.h"
-#include "conversions/re2fa/Thompson.h"
-#include "conversions/re2fa/BrzozowskiDerivation.h"
+#include "regexp/convert/ToAutomatonGlushkov.h"
+#include "regexp/convert/ToAutomatonThompson.h"
+#include "regexp/convert/ToAutomatonDerivation.h"
 
-#include "conversions/fa2rg/fa2lrg/FAtoLRGConverter.h"
-#include "conversions/fa2rg/fa2rrg/FAtoRRGConverter.h"
+#include "grammar/convert/ToAutomaton.h"
 
-#include "conversions/rg2fa/RGtoFA.h"
+#include "grammar/convert/ToRegExpAlgebraic.h"
 
-#include "conversions/rg2re/Algebraic.h"
+#include "regexp/convert/ToGrammarRightRGGlushkov.h"
+#include "regexp/convert/ToGrammarRightRGDerivation.h"
 
-#include "conversions/re2rg/re2rrg/GlushkovNFA.h"
-#include "conversions/re2rg/re2rrg/BrzozowskiDerivation.h"
-
-#include "conversions/rg2rg/LeftToRightRegularGrammar.h"
-#include "conversions/rg2rg/RightToLeftRegularGrammar.h"
+#include "grammar/convert/ToGrammarRightRG.h"
+#include "grammar/convert/ToGrammarLeftRG.h"
 
 
 using namespace alib;
@@ -107,11 +106,11 @@ void ConversionHandler::convertFSMtoRE( void )
 			std::string xmlMark = m_tokens.front( ).getData( );
 			if( xmlMark == "NFA") {
 				const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );
-				regexp::UnboundedRegExp re = conversions::fa2re::Algebraic::convert( fsm );
+				regexp::UnboundedRegExp re = automaton::convert::ToRegExpAlgebraic::convert( fsm );
 				alib::DataFactory::toStdout(re);
 			} else if( xmlMark == "DFA") {
 				const automaton::DFA fsm = alib::DataFactory::fromTokens<automaton::DFA>( m_tokens );
-				regexp::UnboundedRegExp re = conversions::fa2re::Algebraic::convert( fsm );
+				regexp::UnboundedRegExp re = automaton::convert::ToRegExpAlgebraic::convert( fsm );
 				alib::DataFactory::toStdout(re);
 			} else {
 				throw exception::AlibException("Unrecognised formalism");
@@ -120,7 +119,7 @@ void ConversionHandler::convertFSMtoRE( void )
 		}
 	case STATE_ELIMINATION:
 	default: {
-			alib::DataFactory::toStdout(conversions::fa2re::StateElimination::convert(automaton));
+			alib::DataFactory::toStdout(automaton::convert::ToRegExpStateElimination::convert(automaton));
 			break;
 		}
 	}
@@ -143,8 +142,7 @@ void ConversionHandler::convertFSMtoRRG( void )
 	switch( m_algorithm )
 	{
 	default: {
-			conversions::fa2rg::FAtoRRGConverter conv;
-			alib::DataFactory::toStdout(conv.convert(fsm));
+			alib::DataFactory::toStdout(automaton::convert::ToGrammarRightRG::convert(fsm));
 			break;
 		}
 	}
@@ -157,8 +155,7 @@ void ConversionHandler::convertFSMtoLRG( void )
 	switch( m_algorithm )
 	{
 	default: {
-			conversions::fa2rg::FAtoLRGConverter conv;
-			alib::DataFactory::toStdout(conv.convert(fsm));
+			alib::DataFactory::toStdout(automaton::convert::ToGrammarLeftRG::convert(fsm));
 			break;
 		}
 	}
@@ -173,16 +170,16 @@ void ConversionHandler::convertREtoFSM( void )
 	switch( m_algorithm )
 	{
 	case BRZOZOWSKI_DERIVATION: {
-			alib::DataFactory::toStdout(conversions::re2fa::BrzozowskiDerivation::convert(regexp));
+			alib::DataFactory::toStdout(regexp::convert::ToAutomatonDerivation::convert(regexp));
 			break;
 		}
 	case THOMPSON_NFA: {
-			alib::DataFactory::toStdout(conversions::re2fa::Thompson::convert(regexp));
+			alib::DataFactory::toStdout(regexp::convert::ToAutomatonThompson::convert(regexp));
 			break;
 		}
 	case GLUSHKOV_NFA:
 	default: {
-			alib::DataFactory::toStdout(conversions::re2fa::GlushkovNFA::convert(regexp));
+			alib::DataFactory::toStdout(regexp::convert::ToAutomatonGlushkov::convert(regexp));
 			break;
 		}
 	}
@@ -205,11 +202,11 @@ void ConversionHandler::convertREtoRRG( void )
 	switch(m_algorithm)
 	{
 	case BRZOZOWSKI_DERIVATION: {
-			alib::DataFactory::toStdout(conversions::re2rg::BrzozowskiDerivation::convert(regexp));
+			alib::DataFactory::toStdout(regexp::convert::ToGrammarRightRGDerivation::convert(regexp));
 			break;
 		}
 	default: {
-			alib::DataFactory::toStdout(conversions::re2rg::GlushkovNFA::convert(regexp));
+			alib::DataFactory::toStdout(regexp::convert::ToGrammarRightRGGlushkov::convert(regexp));
 			break;
 		}
 	}
@@ -220,7 +217,7 @@ void ConversionHandler::convertREtoRRG( void )
 void ConversionHandler::convertRGtoFSM( void )
 {
 	const grammar::Grammar grammar = alib::DataFactory::fromTokens<grammar::Grammar>(m_tokens);
-    alib::DataFactory::toStdout(conversions::rg2fa::RGtoFA::convert(grammar));
+    alib::DataFactory::toStdout(grammar::convert::ToAutomaton::convert(grammar));
 }
 
 void ConversionHandler::convertRGtoRG( void )
@@ -245,7 +242,7 @@ void ConversionHandler::convertRGtoRE( void )
 	{
 	case BRZOZOWSKI_ALGEBRAIC:
 	default:
-		alib::DataFactory::toStdout(conversions::rg2re::Algebraic::convert(grammar));
+		alib::DataFactory::toStdout(grammar::convert::ToRegExpAlgebraic::convert(grammar));
         break;
 	}
 }
@@ -257,7 +254,7 @@ void ConversionHandler::convertLRGtoRRG( void )
 	switch( m_algorithm )
 	{
 	default:
-		alib::DataFactory::toStdout(conversions::rg2rg::LeftToRightRegularGrammar::convert(lrg));
+		alib::DataFactory::toStdout(grammar::convert::ToGrammarRightRG::convert(lrg));
 		break;
 	}
 }
@@ -269,7 +266,7 @@ void ConversionHandler::convertRRGtoLRG( void )
 	switch( m_algorithm )
 	{
 	default:
-		alib::DataFactory::toStdout(conversions::rg2rg::RightToLeftRegularGrammar::convert(rrg));
+		alib::DataFactory::toStdout(grammar::convert::ToGrammarLeftRG::convert(rrg));
 		break;
 	}
 }
diff --git a/aderivation2/src/aderivation.cpp b/aderivation2/src/aderivation.cpp
index a4eb0bb26d53be2df8322b1725e77c0642546a98..b3021c88dccdc1f9cb160b954442e1e321929e0b 100644
--- a/aderivation2/src/aderivation.cpp
+++ b/aderivation2/src/aderivation.cpp
@@ -10,7 +10,7 @@
 #include <factory/DataFactory.hpp>
 #include <exception/AlibException.h>
 
-#include "regexp/RegExpDerivation.h"
+#include "regexp/transform/RegExpDerivation.h"
 
 int main(int argc, char** argv)
 {
diff --git a/adeterminize2/src/adeterminize.cpp b/adeterminize2/src/adeterminize.cpp
index 3b8086cbb2205a0ec3224ac23138c04631147cd9..8b37b6a25af7d0bdbad5c21abd0b6d46ca6f1bce 100644
--- a/adeterminize2/src/adeterminize.cpp
+++ b/adeterminize2/src/adeterminize.cpp
@@ -10,12 +10,9 @@
 #include "factory/DataFactory.hpp"
 #include "exception/AlibException.h"
 
-#include "determinize/nfa/NFADeterminizer.h"
-#include "determinize/idpda/IDPDADeterminizer.h"
-#include "determinize/vpa/VPADeterminizer.h"
-#include "determinize/hdpda/HDPDADeterminizer.h"
-#include "automaton/PDAToRHPDA.h"
-#include "automaton/RHPDAToPDA.h"
+#include "automaton/determinize/Determinize.h"
+#include "automaton/transform/PDAToRHPDA.h"
+#include "automaton/transform/RHPDAToPDA.h"
 
 #define VERSION "0.0.1"
 
@@ -93,7 +90,7 @@ int main(int argc, char** argv) {
 			std::string xmlMark = tokens.front( ).getData( );
 			if(xmlMark == "NFA") {
 				automaton::NFA nfa = alib::DataFactory::fromTokens<automaton::NFA>(tokens);
-				automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa);
+				automaton::DFA dfa = automaton::determinize::Determinize::determinize(nfa);
 				alib::DataFactory::toStdout(dfa);
 				return 0;
 			} else if(xmlMark == "DFA") {
@@ -106,18 +103,18 @@ int main(int argc, char** argv) {
 
 		} else if (type == TYPE_IDPDA) {
 			automaton::InputDrivenNPDA npda = alib::DataFactory::fromTokens<automaton::InputDrivenNPDA>(tokens);
-			automaton::DPDA dpda = determinize::IDPDADeterminizer::determinize(npda);
+			automaton::DPDA dpda = automaton::determinize::Determinize::determinize(npda);
 			alib::DataFactory::toStdout(dpda);
 			return 0;
 		} else if (type == TYPE_VPA) {
 			automaton::VisiblyPushdownNPDA npda = alib::DataFactory::fromTokens<automaton::VisiblyPushdownNPDA>(tokens);
-			automaton::VisiblyPushdownDPDA dpda = determinize::VPADeterminizer::determinize(npda);
+			automaton::VisiblyPushdownDPDA dpda = automaton::determinize::Determinize::determinize(npda);
 			alib::DataFactory::toStdout(dpda);
 			return 0;
 		} else if (type == TYPE_RHDPDA) {
 			automaton::NPDA npda = alib::DataFactory::fromTokens<automaton::NPDA>(tokens);
 			automaton::RealTimeHeightDeterministicNPDA rhpda = automaton::PDAToRHPDA::convert(npda);
-			automaton::RealTimeHeightDeterministicDPDA dpda = determinize::HDPDADeterminizer::determinize(rhpda);
+			automaton::RealTimeHeightDeterministicDPDA dpda = automaton::determinize::Determinize::determinize(rhpda);
 			automaton::DPDA dpda2 = automaton::RHPDAToPDA::convert(dpda);
 			alib::DataFactory::toStdout(dpda2);
 			return 0;
diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp
index 2baf53dc82a8e98287a078c6d89316368a4db80d..0256a31544d80620a1918386877f46efd574c891 100644
--- a/aepsilon2/src/aepsilon.cpp
+++ b/aepsilon2/src/aepsilon.cpp
@@ -8,7 +8,7 @@
 #include <factory/DataFactory.hpp>
 #include <exception/AlibException.h>
 
-#include "epsilon/fsm/FSMEpsilonRemover.h"
+#include "automaton/simplify/EpsilonRemover.h"
 
 int main(int argc, char** argv) {
 
@@ -17,9 +17,9 @@ int main(int argc, char** argv) {
 			std::cout << "Remove epsilon transitions from automaton." << std::endl << "Usage: aepsilon [automaton.xml]" << std::endl;
 			return -1;
 		} else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) {
-			alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>()));
+			alib::DataFactory::toStdout(automaton::simplify::EpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>()));
 		} else if (argc == 2) {
-			alib::DataFactory::toStdout(epsilon::FSMEpsilonRemover::remove(alib::DataFactory::fromStdin<automaton::Automaton>()));
+			alib::DataFactory::toStdout(automaton::simplify::EpsilonRemover::remove(alib::DataFactory::fromFile<automaton::Automaton>(argv[1])));
 		} else {
 			std::cout << "Automaton minimize require deterministic finite automaton" << std::endl;
 			return 1;
diff --git a/aintegral2/src/aintegral.cpp b/aintegral2/src/aintegral.cpp
index 9ca873cc68f49cae022f5b125b36c58ccd94c753..0a4d0e9a56e6a473284876a9602d32125972c46b 100644
--- a/aintegral2/src/aintegral.cpp
+++ b/aintegral2/src/aintegral.cpp
@@ -10,7 +10,7 @@
 #include <factory/DataFactory.hpp>
 #include <exception/AlibException.h>
 
-#include "regexp/RegExpIntegral.h"
+#include "regexp/transform/RegExpIntegral.h"
 
 int main(int argc, char** argv)
 {
diff --git a/alib2algo/src/automaton/convert/ToGrammar.cpp b/alib2algo/src/automaton/convert/ToGrammar.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d182191a0aa40d7a01859d263d4813f478e36ed0
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToGrammar.cpp
@@ -0,0 +1,94 @@
+/*
+ * ToGrammarLeftRG.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#include "ToGrammar.h"
+#include "ToGrammarRightRG.h"
+#include <exception/AlibException.h>
+
+namespace automaton {
+
+namespace convert {
+
+grammar::Grammar ToGrammar::convert(const automaton::Automaton& automaton) {
+	grammar::Grammar* out = NULL;
+	automaton.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToGrammar::Visit(void*, const automaton::EpsilonNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
+}
+
+void ToGrammar::Visit(void*, const automaton::MultiInitialStateNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA");
+}
+
+void ToGrammar::Visit(void* data, const automaton::NFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(ToGrammarRightRG::convert(automaton));
+}
+
+void ToGrammar::Visit(void* data, const automaton::DFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(ToGrammarRightRG::convert(automaton));
+}
+
+void ToGrammar::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
+}
+
+void ToGrammar::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type CompactNFA");
+}
+
+void ToGrammar::Visit(void*, const DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void ToGrammar::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void ToGrammar::Visit(void*, const InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void ToGrammar::Visit(void*, const VisiblyPushdownDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
+}
+
+void ToGrammar::Visit(void*, const VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void ToGrammar::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
+}
+
+void ToGrammar::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
+}
+
+void ToGrammar::Visit(void*, const NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void ToGrammar::Visit(void*, const SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void ToGrammar::Visit(void*, const OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const ToGrammar ToGrammar::TO_GRAMMAR;
+
+} /* namespace convert */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a25ba02cb7e845e89115acaac28c2587d52a295
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToGrammar.h
@@ -0,0 +1,55 @@
+/*
+ * ToGrammar.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef _AUTOMATON_TO_GRAMMAR_H__
+#define _AUTOMATON_TO_GRAMMAR_H__
+
+#include <grammar/Regular/LeftRG.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <grammar/Grammar.h>
+#include <automaton/Automaton.h>
+
+namespace automaton {
+
+namespace convert {
+
+class ToGrammar : public automaton::VisitableAutomatonBase::const_visitor_type {
+public:
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static grammar::Grammar convert(const automaton::Automaton& automaton);
+
+private:
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const MultiInitialStateNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const DPDA& automaton) const;
+	void Visit(void*, const SinglePopDPDA& automaton) const;
+	void Visit(void*, const InputDrivenNPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownDPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const;
+	void Visit(void*, const NPDA& automaton) const;
+	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
+
+	static const ToGrammar TO_GRAMMAR;
+};
+
+} /* namespace convert */
+
+} /* namespace automaton */
+
+#endif /* _AUTOMATON_TO_GRAMMAR_H__ */
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
similarity index 77%
rename from alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
rename to alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
index 5fffa8038cc2c02c8d46eb9d80d2630e6fe572f9..f82e91eeb5c61004e466b06b7b0cdcecf02d2a30 100644
--- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.cpp
@@ -1,17 +1,22 @@
-#include "FAtoLRGConverter.h"
+/*
+ * ToGrammarLeftRG.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Tomas Pecka
+ */
+
+#include "ToGrammarLeftRG.h"
 #include <map>
 
 #include <alphabet/LabeledSymbol.h>
 
 #include <exception/AlibException.h>
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2rg
-{
+namespace convert {
 
-grammar::LeftRG FAtoLRGConverter::convert(const automaton::NFA& automaton)
+grammar::LeftRG ToGrammarLeftRG::convert(const automaton::NFA& automaton)
 {
 	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
 	// step 2
@@ -59,7 +64,7 @@ grammar::LeftRG FAtoLRGConverter::convert(const automaton::NFA& automaton)
 	return grammar;
 }
 
-grammar::LeftRG FAtoLRGConverter::convert(const automaton::DFA& automaton)
+grammar::LeftRG ToGrammarLeftRG::convert(const automaton::DFA& automaton)
 {
 	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
 	// step 2
@@ -105,42 +110,42 @@ grammar::LeftRG FAtoLRGConverter::convert(const automaton::DFA& automaton)
 	return grammar;
 }
 
-grammar::Grammar FAtoLRGConverter::convert(const automaton::Automaton& automaton) {
+grammar::Grammar ToGrammarLeftRG::convert(const automaton::Automaton& automaton) {
 	grammar::Grammar* out = NULL;
-	automaton.getData().Accept((void*) &out, FAtoLRGConverter::FA_TO_LRG_CONVERTER);
+	automaton.getData().Accept((void*) &out, ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG);
 	grammar::Grammar res = std::move(*out);
 	delete out;
 	return res;
 }
 
-void FAtoLRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const {
+void ToGrammarLeftRG::Visit(void*, const automaton::EpsilonNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
 }
 
-void FAtoLRGConverter::Visit(void*, const automaton::MultiInitialStateNFA& ) const {
+void ToGrammarLeftRG::Visit(void*, const automaton::MultiInitialStateNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA");
 }
 
-void FAtoLRGConverter::Visit(void* data, const automaton::NFA& automaton) const {
+void ToGrammarLeftRG::Visit(void* data, const automaton::NFA& automaton) const {
 	grammar::Grammar* & out = *((grammar::Grammar**) data);
 	out = new grammar::Grammar(this->convert(automaton));
 }
 
-void FAtoLRGConverter::Visit(void* data, const automaton::DFA& automaton) const {
+void ToGrammarLeftRG::Visit(void* data, const automaton::DFA& automaton) const {
 	grammar::Grammar* & out = *((grammar::Grammar**) data);
 	out = new grammar::Grammar(this->convert(automaton));
 }
 
-void FAtoLRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const {
+void ToGrammarLeftRG::Visit(void*, const automaton::ExtendedNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
 }
 
-void FAtoLRGConverter::Visit(void*, const automaton::CompactNFA& ) const {
+void ToGrammarLeftRG::Visit(void*, const automaton::CompactNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type CompactNFA");
 }
 
-const FAtoLRGConverter FAtoLRGConverter::FA_TO_LRG_CONVERTER;
+const ToGrammarLeftRG ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG;
 
-} /* namespace fa2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
similarity index 70%
rename from alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
rename to alib2algo/src/automaton/convert/ToGrammarLeftRG.h
index 37056683d83d9f8b557e7e2b2ef7ebf461f800e2..26e7f96752801e4e64d3172026879e10694fb0b7 100644
--- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
+++ b/alib2algo/src/automaton/convert/ToGrammarLeftRG.h
@@ -1,5 +1,12 @@
-#ifndef __FATOLRGCONVERTER_H__
-#define __FATOLRGCONVERTER_H__
+/*
+ * ToGrammarLeftRG.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Tomas Pecka
+ */
+
+#ifndef __TO_GRAMMAR_LEFT_RG_H__
+#define __TO_GRAMMAR_LEFT_RG_H__
 
 #include <grammar/Regular/LeftRG.h>
 #include <automaton/FSM/NFA.h>
@@ -8,18 +15,15 @@
 #include <grammar/Grammar.h>
 #include <automaton/Automaton.h>
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2rg
-{
+namespace convert {
 
 /**
  * Finite automaton to right regular grammar converter.
  * Source: My own :)
  */
-class FAtoLRGConverter : public automaton::VisitableConstFSMBase
-{
+class ToGrammarLeftRG : public automaton::VisitableConstFSMBase {
 public:
 	/**
 	 * Performs conversion.
@@ -38,11 +42,11 @@ private:
 	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
 	void Visit(void*, const automaton::CompactNFA& automaton) const;
 
-	static const FAtoLRGConverter FA_TO_LRG_CONVERTER;
+	static const ToGrammarLeftRG TO_GRAMMAR_LEFT_RG;
 };
 
-} /* namespace fa2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
 
-#endif /* __FATOLRGCONVERTER_H__ */
+#endif /* __TO_GRAMMAR_LEFT_RG_H__ */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
similarity index 81%
rename from alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
rename to alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
index 4825bf5e7a6667b97b7756c40a9381d8acdd155a..39e72428a7f24a1c41f3f648eed49f33354f32b5 100644
--- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.cpp
@@ -1,16 +1,19 @@
-#include "FAtoRRGConverter.h"
-
+/*
+ * ToGrammarRightRG.cpp
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Tomas Pecka
+ */
+
+#include "ToGrammarRightRG.h"
 #include <alphabet/LabeledSymbol.h>
-
 #include <exception/AlibException.h>
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2rg
-{
+namespace convert {
 
-grammar::RightRG FAtoRRGConverter::convert(const automaton::NFA& automaton)
+grammar::RightRG ToGrammarRightRG::convert(const automaton::NFA& automaton)
 {
 	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
 
@@ -55,7 +58,7 @@ grammar::RightRG FAtoRRGConverter::convert(const automaton::NFA& automaton)
 	return grammar;
 }
 
-grammar::RightRG FAtoRRGConverter::convert(const automaton::DFA& automaton)
+grammar::RightRG ToGrammarRightRG::convert(const automaton::DFA& automaton)
 {
 	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
 
@@ -99,41 +102,41 @@ grammar::RightRG FAtoRRGConverter::convert(const automaton::DFA& automaton)
 	return grammar;
 }
 
-grammar::Grammar FAtoRRGConverter::convert(const automaton::Automaton& automaton) {
+grammar::Grammar ToGrammarRightRG::convert(const automaton::Automaton& automaton) {
 	grammar::Grammar* out = NULL;
-	automaton.getData().Accept((void*) &out, FAtoRRGConverter::FA_TO_RRG_CONVERTER);
+	automaton.getData().Accept((void*) &out, ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG);
 	grammar::Grammar res = std::move(*out);
 	delete out;
 	return res;
 }
 
-void FAtoRRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const {
+void ToGrammarRightRG::Visit(void*, const automaton::EpsilonNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
 }
 
-void FAtoRRGConverter::Visit(void*, const automaton::MultiInitialStateNFA& ) const {
+void ToGrammarRightRG::Visit(void*, const automaton::MultiInitialStateNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA");
 }
 
-void FAtoRRGConverter::Visit(void* data, const automaton::NFA& automaton) const {
+void ToGrammarRightRG::Visit(void* data, const automaton::NFA& automaton) const {
 	grammar::Grammar* & out = *((grammar::Grammar**) data);
 	out = new grammar::Grammar(this->convert(automaton));
 }
 
-void FAtoRRGConverter::Visit(void* data, const automaton::DFA& automaton) const {
+void ToGrammarRightRG::Visit(void* data, const automaton::DFA& automaton) const {
 	grammar::Grammar* & out = *((grammar::Grammar**) data);
 	out = new grammar::Grammar(this->convert(automaton));
 }
-void FAtoRRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const {
+void ToGrammarRightRG::Visit(void*, const automaton::ExtendedNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
 }
 
-void FAtoRRGConverter::Visit(void*, const automaton::CompactNFA& ) const {
+void ToGrammarRightRG::Visit(void*, const automaton::CompactNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type CompactNFA");
 }
 
-const FAtoRRGConverter FAtoRRGConverter::FA_TO_RRG_CONVERTER;
+const ToGrammarRightRG ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG;
 
-} /* namespace fa2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
similarity index 70%
rename from alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
rename to alib2algo/src/automaton/convert/ToGrammarRightRG.h
index 1c301fc2b62da66b78625d149d0bab4389229cc0..448e32e38cb9f9282e733e859da2a37484020b57 100644
--- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
+++ b/alib2algo/src/automaton/convert/ToGrammarRightRG.h
@@ -1,5 +1,12 @@
-#ifndef __FATORRGCONVERTER_H__
-#define __FATORRGCONVERTER_H__
+/*
+ * ToGrammarRightRG.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Tomas Pecka
+ */
+
+#ifndef __TO_GRAMMAR_RIGHT_RG_H__
+#define __TO_GRAMMAR_RIGHT_RG_H__
 
 #include <grammar/Regular/RightRG.h>
 #include <automaton/FSM/NFA.h>
@@ -8,18 +15,15 @@
 #include <grammar/Grammar.h>
 #include <automaton/Automaton.h>
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2rg
-{
+namespace convert {
 
 /**
  * Finite automaton to right regular grammar converter.
  * Source: Melichar 2.104
  */
-class FAtoRRGConverter : public automaton::VisitableConstFSMBase
-{
+class ToGrammarRightRG : public automaton::VisitableConstFSMBase {
 public:
 	/**
 	 * Performs conversion.
@@ -38,11 +42,11 @@ private:
 	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
 	void Visit(void*, const automaton::CompactNFA& automaton) const;
 
-	static const FAtoRRGConverter FA_TO_RRG_CONVERTER;
+	static const ToGrammarRightRG TO_GRAMMAR_RIGHT_RG;
 };
 
-} /* namespace fa2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
 
-#endif /* __FATORRGCONVERTER_H__ */
+#endif /* __TO_GRAMMAR_RIGHT_RG_H__ */
diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9335fe353db028e7b743db90870eb6ed37741341
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToRegExp.cpp
@@ -0,0 +1,98 @@
+/*
+ * ToRegExpLeftRG.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#include "ToRegExp.h"
+#include "ToRegExpStateElimination.h"
+#include <exception/AlibException.h>
+
+namespace automaton {
+
+namespace convert {
+
+regexp::RegExp ToRegExp::convert(const automaton::Automaton& automaton) {
+	regexp::RegExp* out = NULL;
+	automaton.getData().Accept((void*) &out, ToRegExp::TO_REGEXP);
+	regexp::RegExp res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToRegExp::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::NFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::DFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::ExtendedNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::CompactNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void*, const DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void ToRegExp::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void ToRegExp::Visit(void*, const InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void ToRegExp::Visit(void*, const VisiblyPushdownDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
+}
+
+void ToRegExp::Visit(void*, const VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void ToRegExp::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
+}
+
+void ToRegExp::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
+}
+
+void ToRegExp::Visit(void*, const NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void ToRegExp::Visit(void*, const SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void ToRegExp::Visit(void*, const OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const ToRegExp ToRegExp::TO_REGEXP;
+
+} /* namespace convert */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h
new file mode 100644
index 0000000000000000000000000000000000000000..b5251819501291bee36f5e3556a8c1fa074e6dd9
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToRegExp.h
@@ -0,0 +1,56 @@
+/*
+ * ToRegExp.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef _AUTOMATON_TO_REGEXP_H__
+#define _AUTOMATON_TO_REGEXP_H__
+
+#include <automaton/FSM/DFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <regexp/unbounded/UnboundedRegExp.h>
+
+#include <automaton/Automaton.h>
+#include <regexp/RegExp.h>
+
+namespace automaton {
+
+namespace convert {
+
+class ToRegExp : public automaton::VisitableAutomatonBase::const_visitor_type {
+public:
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static regexp::RegExp convert(const automaton::Automaton& automaton);
+
+private:
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const MultiInitialStateNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const DPDA& automaton) const;
+	void Visit(void*, const SinglePopDPDA& automaton) const;
+	void Visit(void*, const InputDrivenNPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownDPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const;
+	void Visit(void*, const NPDA& automaton) const;
+	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
+
+	static const ToRegExp TO_REGEXP;
+};
+
+} /* namespace convert */
+
+} /* namespace automaton */
+
+#endif /* _AUTOMATON_TO_REGEXP_H__ */
diff --git a/alib2algo/src/conversions/fa2re/Algebraic.cpp b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
similarity index 79%
rename from alib2algo/src/conversions/fa2re/Algebraic.cpp
rename to alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
index 959996376c9d64e233fc5fabadd70c5d6df70738..49711c8239066135fb061bad75f5ca1465b2b115 100644
--- a/alib2algo/src/conversions/fa2re/Algebraic.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.cpp
@@ -1,11 +1,11 @@
 /*
- * Algebraic.cpp
+ * ToRegExpAlgebraic.cpp
  *
  *  Created on: 11. 2. 2014
  *	  Author: Tomas Pecka
  */
 
-#include "Algebraic.h"
+#include "ToRegExpAlgebraic.h"
 
 #include <alphabet/Symbol.h>
 #include <automaton/FSM/DFA.h>
@@ -16,20 +16,19 @@
 
 #include "../../equations/RightRegularEquationSolver.h"
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2re {
+namespace convert {
 
-regexp::RegExp Algebraic::convert(const automaton::Automaton& automaton) {
+regexp::RegExp ToRegExpAlgebraic::convert(const automaton::Automaton& automaton) {
 	regexp::RegExp* out = NULL;
-	automaton.getData().Accept((void*) &out, Algebraic::ALGEBRAIC);
+	automaton.getData().Accept((void*) &out, ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC);
 	regexp::RegExp res = std::move(*out);
 	delete out;
 	return res;
 }
 
-regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automaton ) {
+regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::EpsilonNFA & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -56,7 +55,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::EpsilonNFA & automa
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState().getName() ) ) );
 }
 
-regexp::UnboundedRegExp Algebraic::convert( const automaton::MultiInitialStateNFA & automaton ) {
+regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::MultiInitialStateNFA & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -85,7 +84,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::MultiInitialStateNF
 	return regexp::UnboundedRegExp { alternation };
 }
 
-regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) {
+regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::NFA & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -106,7 +105,7 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::NFA & automaton ) {
 	return solver.solve( alphabet::Symbol( alphabet::LabeledSymbol (automaton.getInitialState().getName() ) ) );
 }
 
-regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) {
+regexp::UnboundedRegExp ToRegExpAlgebraic::convert( const automaton::DFA & automaton ) {
 	equations::RightRegularEquationSolver solver;
 
 	// initialize equations
@@ -126,36 +125,36 @@ regexp::UnboundedRegExp Algebraic::convert( const automaton::DFA & automaton ) {
 }
 
 
-void Algebraic::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
+void ToRegExpAlgebraic::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
 	regexp::RegExp* & out = *((regexp::RegExp**) data);
 	out = new regexp::RegExp(this->convert(automaton));
 }
 
-void Algebraic::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
+void ToRegExpAlgebraic::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
 	regexp::RegExp* & out = *((regexp::RegExp**) data);
 	out = new regexp::RegExp(this->convert(automaton));
 }
 
-void Algebraic::Visit(void* data, const automaton::NFA& automaton) const {
+void ToRegExpAlgebraic::Visit(void* data, const automaton::NFA& automaton) const {
 	regexp::RegExp* & out = *((regexp::RegExp**) data);
 	out = new regexp::RegExp(this->convert(automaton));
 }
 
-void Algebraic::Visit(void* data, const automaton::DFA& automaton) const {
+void ToRegExpAlgebraic::Visit(void* data, const automaton::DFA& automaton) const {
 	regexp::RegExp* & out = *((regexp::RegExp**) data);
 	out = new regexp::RegExp(this->convert(automaton));
 }
 
-void Algebraic::Visit(void*, const automaton::ExtendedNFA& ) const {
+void ToRegExpAlgebraic::Visit(void*, const automaton::ExtendedNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
 }
 
-void Algebraic::Visit(void*, const automaton::CompactNFA& ) const {
+void ToRegExpAlgebraic::Visit(void*, const automaton::CompactNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type CompactNFA");
 }
 
-const Algebraic Algebraic::ALGEBRAIC;
+const ToRegExpAlgebraic ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC;
 
-} /* namespace fa2re */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
diff --git a/alib2algo/src/conversions/fa2re/Algebraic.h b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
similarity index 78%
rename from alib2algo/src/conversions/fa2re/Algebraic.h
rename to alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
index a03bc8a78775eaddc5da14f9a8176a9c2f4c46ad..54d1f89f7bf7c424d2b0d1033c7dc49c4b6b408b 100644
--- a/alib2algo/src/conversions/fa2re/Algebraic.h
+++ b/alib2algo/src/automaton/convert/ToRegExpAlgebraic.h
@@ -1,12 +1,12 @@
 /*
- * Algebraic.h
+ * ToRegExpAlgebraic.h
  *
  *  Created on: 11. 2. 2014
  *	  Author: Tomas Pecka
  */
 
-#ifndef FA2RE_ALGEBRAIC_H_
-#define FA2RE_ALGEBRAIC_H_
+#ifndef AUTOMATON_TO_REG_EXP_ALGEBRAIC_H_
+#define AUTOMATON_TO_REG_EXP_ALGEBRAIC_H_
 
 #include <deque>
 #include <map>
@@ -16,11 +16,9 @@
 #include <regexp/unbounded/UnboundedRegExpElements.h>
 #include <automaton/Automaton.h>
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2re
-{
+namespace convert {
 
 // http://cs.stackexchange.com/questions/2016/how-to-convert-finite-automata-to-regular-expressions
 // https://github.com/ferno/greenery/blob/bcc0a136335edbe94cd7725fc6e8cce0268d850c/fsm.py
@@ -29,8 +27,7 @@ namespace fa2re
  * Converts FA to RE using Brzozowski's algebraic method using right regular equations.
  * Source : Melichar 2.122
  */
-class Algebraic : public automaton::VisitableConstFSMBase
-{
+class ToRegExpAlgebraic : public automaton::VisitableConstFSMBase {
 public:
 	/**
 	 * Performs conversion.
@@ -51,11 +48,11 @@ private:
 	void Visit(void*, const automaton::ExtendedNFA&) const;
 	void Visit(void*, const automaton::CompactNFA&) const;
 
-	static const Algebraic ALGEBRAIC;
+	static const ToRegExpAlgebraic TO_REG_EXP_ALGEBRAIC;
 };
 
-} /* namespace fa2re */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
 
-#endif /* FA2RE_ALGEBRAIC_H_ */
+#endif /* AUTOMATON_TO_REG_EXP_ALGEBRAIC_H_ */
diff --git a/alib2algo/src/conversions/fa2re/StateElimination.cpp b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
similarity index 69%
rename from alib2algo/src/conversions/fa2re/StateElimination.cpp
rename to alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
index 1c22f40119392b4cf26a2b8ad967676b4ed3d023..88bdb12a9beb6e42701ec060efaa225a08757542 100644
--- a/alib2algo/src/conversions/fa2re/StateElimination.cpp
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.cpp
@@ -1,37 +1,35 @@
 /*
- * StateEliminationUnbounded.cpp
+ * ToRegExpStateElimination.cpp
  *
  *  Created on: 9. 2. 2014
  *      Author: Tomas Pecka
  */
 
-#include "StateElimination.h"
+#include "ToRegExpStateElimination.h"
 
 #include <regexp/unbounded/UnboundedRegExp.h>
 #include <exception/AlibException.h>
 
-#include "../../regexp/RegExpOptimize.h"
-#include "../../regexp/RegExpAlternate.h"
-#include "../../regexp/RegExpConcatenate.h"
-#include "../../regexp/RegExpIterate.h"
+#include "../../regexp/simplify/RegExpOptimize.h"
+#include "../../regexp/transform/RegExpAlternate.h"
+#include "../../regexp/transform/RegExpConcatenate.h"
+#include "../../regexp/transform/RegExpIterate.h"
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2re
-{
+namespace convert {
 
-regexp::RegExp StateElimination::convert(const automaton::Automaton& automaton)
+regexp::RegExp ToRegExpStateElimination::convert(const automaton::Automaton& automaton)
 {
 	regexp::RegExp* out = NULL;
-	automaton.getData().Accept((void*) &out, StateElimination::STATE_ELIMINATION);
+	automaton.getData().Accept((void*) &out, ToRegExpStateElimination::TO_REG_EXP_STATE_ELIMINATION);
 	regexp::RegExp res = std::move(*out);
 	delete out;
 	return res;
 }
 
 template<class T>
-regexp::RegExp StateElimination::convert(const T& automaton)
+regexp::RegExp ToRegExpStateElimination::convert(const T& automaton)
 {
     if(automaton.getFinalStates().size() == 0)
         return regexp::RegExp(regexp::UnboundedRegExp(regexp::UnboundedRegExpEmpty()));
@@ -50,15 +48,13 @@ regexp::RegExp StateElimination::convert(const T& automaton)
         extendedAutomaton = eliminateState(extendedAutomaton, state);
 
     // step 4
-    regexp::RegExpOptimize opt;
-
-    return regexp::RegExpOptimize::optimize(regexp::RegExpConcatenate::concatenate(
+    return regexp::simplify::RegExpOptimize::optimize(regexp::RegExpConcatenate::concatenate(
 				transition(extendedAutomaton, extendedAutomaton.getInitialState(), *extendedAutomaton.getFinalStates().begin()),
 				regexp::RegExpIterate::iterate(transition(extendedAutomaton, *extendedAutomaton.getFinalStates().begin(), *extendedAutomaton.getFinalStates().begin()))));
 }
 
 
-automaton::ExtendedNFA StateElimination::eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const automaton::State& q)
+automaton::ExtendedNFA ToRegExpStateElimination::eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const automaton::State& q)
 {
     automaton::ExtendedNFA newAutomaton(extendedAutomaton.getInitialState()); // sure that q is neither initial nor final (follows from step 2 - extending ExtendedNFA)
     newAutomaton.setStates(extendedAutomaton.getStates());
@@ -66,8 +62,6 @@ automaton::ExtendedNFA StateElimination::eliminateState(const automaton::Extende
     newAutomaton.setInputSymbols(extendedAutomaton.getInputAlphabet());
     newAutomaton.setFinalStates(extendedAutomaton.getFinalStates());
 
-    regexp::RegExpOptimize opt;
-
     for(const auto& p: newAutomaton.getStates())
     {
         for(const auto& r : newAutomaton.getStates())
@@ -78,26 +72,25 @@ automaton::ExtendedNFA StateElimination::eliminateState(const automaton::Extende
 
             regexp::RegExp alt = regexp::RegExpAlternate::alternate(concat, transition(extendedAutomaton, p, r));
 
-            newAutomaton.addTransition(p, regexp::RegExpOptimize::optimize(alt), r);
+            newAutomaton.addTransition(p, regexp::simplify::RegExpOptimize::optimize(alt), r);
         }
     }
 
     return newAutomaton;
 }
 
-const regexp::RegExp StateElimination::transition(const automaton::ExtendedNFA& automaton, const automaton::State& from, const automaton::State& to)
+const regexp::RegExp ToRegExpStateElimination::transition(const automaton::ExtendedNFA& automaton, const automaton::State& from, const automaton::State& to)
 {
-    regexp::RegExpOptimize opt;
     regexp::RegExp ret(regexp::UnboundedRegExp(regexp::UnboundedRegExpEmpty { }));
 
     for(const auto& transition: automaton.getTransitionsFromState(from))
         if(transition.second.count(to) > 0)
             ret = regexp::RegExpAlternate::alternate(ret, transition.first.second);
 
-    return regexp::RegExpOptimize::optimize(ret);
+    return regexp::simplify::RegExpOptimize::optimize(ret);
 }
 
-void StateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton)
+void ToRegExpStateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton)
 {
     const automaton::State& initState = automaton.getInitialState();
     if(automaton.getFinalStates().count(initState) > 0 || automaton.getTransitionsToState(initState).size() > 0 )
@@ -131,44 +124,44 @@ void StateElimination::extendExtendedNFA(automaton::ExtendedNFA& automaton)
     }
 }
 
-void StateElimination::Visit(void* data, const automaton::EpsilonNFA& automaton) const
+void ToRegExpStateElimination::Visit(void* data, const automaton::EpsilonNFA& automaton) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) data);
     out = new regexp::RegExp(convert(automaton));
 }
 
-void StateElimination::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const
+void ToRegExpStateElimination::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) data);
     out = new regexp::RegExp(convert(automaton));
 }
 
-void StateElimination::Visit(void* data, const automaton::NFA& automaton) const
+void ToRegExpStateElimination::Visit(void* data, const automaton::NFA& automaton) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) data);
     out = new regexp::RegExp(convert(automaton));
 }
 
-void StateElimination::Visit(void* data, const automaton::DFA& automaton) const
+void ToRegExpStateElimination::Visit(void* data, const automaton::DFA& automaton) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) data);
     out = new regexp::RegExp(convert(automaton));
 }
 
-void StateElimination::Visit(void* data, const automaton::ExtendedNFA& automaton) const
+void ToRegExpStateElimination::Visit(void* data, const automaton::ExtendedNFA& automaton) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) data);
     out = new regexp::RegExp(convert(automaton));
 }
 
-void StateElimination::Visit(void* data, const automaton::CompactNFA& automaton) const
+void ToRegExpStateElimination::Visit(void* data, const automaton::CompactNFA& automaton) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) data);
     out = new regexp::RegExp(convert(automaton));
 }
 
-const StateElimination StateElimination::STATE_ELIMINATION;
+const ToRegExpStateElimination ToRegExpStateElimination::TO_REG_EXP_STATE_ELIMINATION;
 
-} /* namespace fa2re */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
diff --git a/alib2algo/src/conversions/fa2re/StateElimination.h b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
similarity index 79%
rename from alib2algo/src/conversions/fa2re/StateElimination.h
rename to alib2algo/src/automaton/convert/ToRegExpStateElimination.h
index ab54785825b8d9aaefa96fb8cceab9030eacb7cb..a70f35786f360798690a08044790f78f12cbb04a 100644
--- a/alib2algo/src/conversions/fa2re/StateElimination.h
+++ b/alib2algo/src/automaton/convert/ToRegExpStateElimination.h
@@ -1,12 +1,12 @@
 /*
- * StateElimination.h
+ * ToRegExpStateElimination.h
  *
  *  Created on: 9. 2. 2014
  *      Author: Tomas Pecka
  */
 
-#ifndef STATEELIMINATION_H_
-#define STATEELIMINATION_H_
+#ifndef TO_REG_EXP_STATE_ELIMINATION_H_
+#define TO_REG_EXP_STATE_ELIMINATION_H_
 
 #include <regexp/RegExp.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
@@ -18,18 +18,15 @@
 #include <automaton/FSM/EpsilonNFA.h>
 #include <automaton/FSM/ExtendedNFA.h>
 
-namespace conversions
-{
+namespace automaton {
 
-namespace fa2re
-{
+namespace convert {
 
 /**
  * Converts FSM to RE using State Elimination algorithm.
  * Source: Melichar 2.118
  */
-class StateElimination : public automaton::VisitableConstFSMBase
-{
+class ToRegExpStateElimination : public automaton::VisitableConstFSMBase {
 public:
     /**
      * Performs conversion.
@@ -55,11 +52,11 @@ private:
 
     static automaton::ExtendedNFA eliminateState(const automaton::ExtendedNFA& extendedAutomaton, const automaton::State& state);
 
-    static const StateElimination STATE_ELIMINATION;
+    static const ToRegExpStateElimination TO_REG_EXP_STATE_ELIMINATION;
 };
 
-} /* namespace fa2re */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace automaton */
 
-#endif /* STATEELIMINATION_H_ */
+#endif /* TO_REG_EXP_STATE_ELIMINATION_H_ */
diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3a9357d29f87e0189d2164e713d9e176648edc8b
--- /dev/null
+++ b/alib2algo/src/automaton/determinize/Determinize.cpp
@@ -0,0 +1,101 @@
+/*
+ * Determinize.cpp
+ *
+ *  Created on: 16. 1. 2014
+ *	  Author: Jan Vesely
+ */
+
+#include "Determinize.h"
+
+namespace automaton {
+
+namespace determinize {
+
+automaton::Automaton Determinize::determinize(const automaton::Automaton& automaton) {
+	automaton::Automaton* out = NULL;
+	automaton.getData().Accept((void*) &out, Determinize::DETERMINIZE);
+	automaton::Automaton res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void Determinize::Visit(void*, const automaton::EpsilonNFA&) const {
+	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
+}
+
+void Determinize::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->determinize(automaton));
+}
+
+void Determinize::Visit(void* data, const automaton::NFA& automaton) const {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->determinize(automaton));
+}
+
+void Determinize::Visit(void*, const automaton::DFA&) const {
+	throw exception::AlibException("Unsupported automaton type DFA");
+}
+
+void Determinize::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
+}
+
+void Determinize::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type CompactNFA");
+}
+
+void Determinize::Visit(void*, const automaton::DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void Determinize::Visit(void*, const automaton::SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void Determinize::Visit(void* data, const automaton::InputDrivenNPDA& automaton) const {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->determinize(automaton));
+}
+
+void Determinize::Visit(void*, const automaton::VisiblyPushdownDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
+}
+
+void Determinize::Visit(void* data, const automaton::VisiblyPushdownNPDA& automaton) const {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->determinize(automaton));
+}
+
+void Determinize::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
+}
+
+void Determinize::Visit(void* data, const automaton::RealTimeHeightDeterministicNPDA& automaton) const {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->determinize(automaton));
+}
+
+void Determinize::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void Determinize::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void Determinize::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const Determinize Determinize::DETERMINIZE;
+
+} /* namespace determinize */
+
+} /* namespace automaton */
+
+#include "DeterminizeNFAPart.cxx"
+#include "DeterminizeIDPDAPart.cxx"
+#include "DeterminizeVPAPart.cxx"
+#include "DeterminizeRHDPDAPart.cxx"
+
diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.h b/alib2algo/src/automaton/determinize/Determinize.h
similarity index 73%
rename from alib2algo/src/determinize/nfa/NFADeterminizer.h
rename to alib2algo/src/automaton/determinize/Determinize.h
index 87f05f9b3725d594427c5dc3ee6edc1a6424aed7..2fc78ff1e37ac55c8529d0b28d9f485804398392 100644
--- a/alib2algo/src/determinize/nfa/NFADeterminizer.h
+++ b/alib2algo/src/automaton/determinize/Determinize.h
@@ -5,25 +5,28 @@
  *	  Author: Jan Vesely
  */
 
-#ifndef NFA_DETERMINIZER_H_
-#define NFA_DETERMINIZER_H_
+#ifndef DETERMINIZE_H_
+#define DETERMINIZE_H_
 
 #include <set>
 
 #include <automaton/common/State.h>
 #include <automaton/Automaton.h>
-#include <automaton/FSM/NFA.h>
-#include <automaton/FSM/MultiInitialStateNFA.h>
 #include <automaton/FSM/DFA.h>
+#include <automaton/PDA/DPDA.h>
+#include <automaton/PDA/VisiblyPushdownDPDA.h>
+#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h>
 
 #include <exception/AlibException.h>
 
+namespace automaton {
+
 namespace determinize {
 
 /**
  * Class for running determinization algorithm on fsm.
  */
-class NFADeterminizer : public automaton::VisitableAutomatonBase::const_visitor_type {
+class Determinize : public automaton::VisitableAutomatonBase::const_visitor_type {
 private:
 	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
 	void Visit(void*, const automaton::MultiInitialStateNFA& automaton) const;
@@ -42,7 +45,7 @@ private:
 	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
 	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
 
-	static const NFADeterminizer NFA_DETERMINIZER;
+	static const Determinize DETERMINIZE;
 
 public:
 
@@ -55,8 +58,13 @@ public:
 
 	static automaton::DFA determinize(const automaton::NFA& nfa);
 	static automaton::DFA determinize(const automaton::MultiInitialStateNFA& nfa);
+	static automaton::VisiblyPushdownDPDA determinize(const automaton::VisiblyPushdownNPDA& nondeterministic);
+	static automaton::DPDA determinize(const automaton::InputDrivenNPDA& nfa);
+	static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicNPDA& nondeterministic);
 };
 
 } /* namespace determinize */
 
-#endif /* NFA_DETERMINIZER_H_ */
+} /* namespace automaton */
+
+#endif /* DETERMINIZE_H_ */
diff --git a/alib2algo/src/determinize/idpda/IDPDADeterminizer.cpp b/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx
similarity index 87%
rename from alib2algo/src/determinize/idpda/IDPDADeterminizer.cpp
rename to alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx
index 36cd28c3029c6efc3d8550ac853b3f62a01885f6..1f85414a8d3e65b9d2feb088eff4acb16689c277 100644
--- a/alib2algo/src/determinize/idpda/IDPDADeterminizer.cpp
+++ b/alib2algo/src/automaton/determinize/DeterminizeIDPDAPart.cxx
@@ -5,16 +5,17 @@
  *	  Author: Jan Vesely
  */
 
-#include "IDPDADeterminizer.h"
-#include "../common/NFACommon.h"
+#include "common/NFACommon.h"
 
+#include <automaton/PDA/InputDrivenNPDA.h>
 #include <deque>
 #include <algorithm>
 
-namespace determinize {
+namespace automaton {
 
+namespace determinize {
 
-automaton::DPDA IDPDADeterminizer::determinize(const automaton::InputDrivenNPDA& nfa) {
+automaton::DPDA Determinize::determinize(const automaton::InputDrivenNPDA& nfa) {
 	// 1, 4
 	automaton::State initialState(createDFAState(nfa.getInitialStates()));
 	automaton::DPDA res(initialState, nfa.getInitialSymbol());
@@ -63,4 +64,6 @@ automaton::DPDA IDPDADeterminizer::determinize(const automaton::InputDrivenNPDA&
 	return res;
 }
 
-}
+} /* namespace determinize */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e156c3c8f16f54055897c6fbb1618e0691e9e5d6
--- /dev/null
+++ b/alib2algo/src/automaton/determinize/DeterminizeNFAPart.cxx
@@ -0,0 +1,115 @@
+/*
+ * NFADeterminizer.cpp
+ *
+ *  Created on: 16. 1. 2014
+ *	  Author: Jan Vesely
+ */
+
+#include "common/NFACommon.h"
+
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/MultiInitialStateNFA.h>
+#include <deque>
+#include <algorithm>
+
+namespace automaton {
+
+namespace determinize {
+
+automaton::DFA Determinize::determinize(const automaton::MultiInitialStateNFA& nfa) {
+	// 1, 4
+	automaton::State initialState(createDFAState(nfa.getInitialStates()));
+	automaton::DFA res(initialState);
+	res.setInputSymbols(nfa.getInputAlphabet());
+	
+	// 2
+	std::deque<automaton::State> todo;
+	todo.push_back(initialState);
+	
+	do {
+		// 3a, c
+		automaton::State state = todo.front();
+		todo.pop_front();
+
+		// 3b
+		for (const auto& input : nfa.getInputAlphabet()) {
+			std::set<automaton::State> targetNFAStates;
+			for(const auto& nfaState : recreateNFAStates(state)) {
+				auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input));
+				if(iter != nfa.getTransitions().end()) {
+					targetNFAStates.insert(iter->second.begin(), iter->second.end());
+				}
+			}
+			automaton::State dfaState = createDFAState(targetNFAStates);
+
+			// 4
+			bool existed = !res.addState(dfaState);
+
+			// 3b
+			res.addTransition(state, input, dfaState);
+
+			if(!existed) todo.push_back(dfaState);
+		}
+	} while(!todo.empty());
+	
+	// 5
+	for (const auto& dfaState : res.getStates()) {
+		std::set<automaton::State> nfaStates = recreateNFAStates(dfaState);
+		if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) {
+			res.addFinalState(dfaState);
+		}
+	}
+	
+	return res;
+}
+
+automaton::DFA Determinize::determinize(const automaton::NFA& nfa) {
+	// 1, 4
+	automaton::State initialState(createDFAState({nfa.getInitialState()}));
+	automaton::DFA res(initialState);
+	res.setInputSymbols(nfa.getInputAlphabet());
+	
+	// 2
+	std::deque<automaton::State> todo;
+	todo.push_back(initialState);
+	
+	do {
+		// 3a, c
+		automaton::State state = todo.front();
+		todo.pop_front();
+
+		// 3b
+		for (const auto& input : nfa.getInputAlphabet()) {
+			std::set<automaton::State> targetNFAStates;
+			for(const auto& nfaState : recreateNFAStates(state)) {
+				auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input));
+				if(iter != nfa.getTransitions().end()) {
+					targetNFAStates.insert(iter->second.begin(), iter->second.end());
+				}
+			}
+			automaton::State dfaState = createDFAState(targetNFAStates);
+
+			// 4
+			bool existed = !res.addState(dfaState);
+
+			// 3b
+			res.addTransition(state, input, dfaState);
+
+			if(!existed) todo.push_back(dfaState);
+		}
+	} while(!todo.empty());
+	
+	// 5
+	for (const auto& dfaState : res.getStates()) {
+		std::set<automaton::State> nfaStates = recreateNFAStates(dfaState);
+		if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) {
+			res.addFinalState(dfaState);
+		}
+	}
+	
+	return res;
+}
+
+} /* namespace determinize */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.cpp b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx
similarity index 96%
rename from alib2algo/src/determinize/hdpda/HDPDADeterminizer.cpp
rename to alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx
index 9c01e6c99210bdf890807acd1edeeb33804aa5d3..321b6e544020df05bd4410ac69688ce5022e573b 100644
--- a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.cpp
+++ b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx
@@ -1,6 +1,13 @@
-#include "HDPDADeterminizer.h"
-#include "../common/RHDPDACommon.h"
+/*
+ * NFADeterminizer.cpp
+ *
+ *  Created on: 16. 1. 2014
+ *	  Author: Jan Travnicek
+ */
 
+#include "common/RHDPDACommon.h"
+
+#include <automaton/PDA/RealTimeHeightDeterministicNPDA.h>
 #include "automaton/common/State.h"
 #include "alphabet/Symbol.h"
 #include "alphabet/LabeledSymbol.h"
@@ -9,6 +16,8 @@
 #include <std/set.hpp>
 #include <iostream>
 
+namespace automaton {
+
 namespace determinize {
 
 void addRetTransition(const automaton::State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& dvpdaSymbol, const automaton::State& to, automaton::RealTimeHeightDeterministicDPDA& deterministic) {
@@ -185,7 +194,7 @@ std::tuple<std::set<std::variant<string::Epsilon, alphabet::Symbol>>, std::set<s
 	return std::make_tuple(local, call, ret);
 }
 
-automaton::RealTimeHeightDeterministicDPDA HDPDADeterminizer::determinize(const automaton::RealTimeHeightDeterministicNPDA& n) {
+automaton::RealTimeHeightDeterministicDPDA Determinize::determinize(const automaton::RealTimeHeightDeterministicNPDA& n) {
 	label::Label initialLabel = packToStateLabel(createIdentity(retrieveLabels(n.getInitialStates())));
 
 	automaton::RealTimeHeightDeterministicDPDA d(automaton::State(initialLabel), n.getBottomOfTheStackSymbol());
@@ -239,4 +248,6 @@ automaton::RealTimeHeightDeterministicDPDA HDPDADeterminizer::determinize(const
 	return d;
 }
 
-}
+} /* namespace determinize */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/determinize/vpa/VPADeterminizer.cpp b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx
similarity index 95%
rename from alib2algo/src/determinize/vpa/VPADeterminizer.cpp
rename to alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx
index 136cf49c2c8a96427fbc5dd6be3b9bde7a2ef656..1a1e7ebca54a3fa1db5e6d6063d2a6d1bedcf4fc 100644
--- a/alib2algo/src/determinize/vpa/VPADeterminizer.cpp
+++ b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx
@@ -1,6 +1,13 @@
-#include "VPADeterminizer.h"
-#include "../common/RHDPDACommon.h"
+/*
+ * NFADeterminizer.cpp
+ *
+ *  Created on: 16. 1. 2014
+ *	  Author: Jan Travnicek
+ */
 
+#include "common/RHDPDACommon.h"
+
+#include <automaton/PDA/VisiblyPushdownNPDA.h>
 #include "automaton/common/State.h"
 #include "alphabet/Symbol.h"
 #include "alphabet/LabeledSymbol.h"
@@ -8,6 +15,8 @@
 #include <std/set.hpp>
 #include <iostream>
 
+namespace automaton {
+
 namespace determinize {
 
 void addRetTransition(const automaton::State& from, const alphabet::Symbol& input, const alphabet::Symbol& dvpdaSymbol, const automaton::State& to, automaton::VisiblyPushdownDPDA& deterministic) {
@@ -150,7 +159,7 @@ void local(const automaton::State& state, const alphabet::Symbol& input, const a
 	addLocalTransition(state, input, automaton::State(packToStateLabel(std::move(S1))), deterministic);
 }
 
-automaton::VisiblyPushdownDPDA VPADeterminizer::determinize(const automaton::VisiblyPushdownNPDA& n) {
+automaton::VisiblyPushdownDPDA Determinize::determinize(const automaton::VisiblyPushdownNPDA& n) {
 	label::Label initialLabel = packToStateLabel(createIdentity(retrieveLabels(n.getInitialStates())));
 	
 	automaton::VisiblyPushdownDPDA d(automaton::State(initialLabel), n.getBottomOfTheStackSymbol());
@@ -194,4 +203,6 @@ automaton::VisiblyPushdownDPDA VPADeterminizer::determinize(const automaton::Vis
 	return d;
 }
 
-}
+} /* namespace determinize */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/determinize/common/NFACommon.cpp b/alib2algo/src/automaton/determinize/common/NFACommon.cpp
similarity index 90%
rename from alib2algo/src/determinize/common/NFACommon.cpp
rename to alib2algo/src/automaton/determinize/common/NFACommon.cpp
index 7a99e583251737d89f36aae9e055611135f8c11b..f86c2eff6754a6ed1b2937b764853746135955a3 100644
--- a/alib2algo/src/determinize/common/NFACommon.cpp
+++ b/alib2algo/src/automaton/determinize/common/NFACommon.cpp
@@ -11,6 +11,8 @@
 #include <deque>
 #include <algorithm>
 
+namespace automaton {
+
 namespace determinize {
 
 automaton::State createDFAState(const std::set<automaton::State>& nfaStates) {
@@ -29,4 +31,6 @@ std::set<automaton::State> recreateNFAStates(const automaton::State& dfaState) {
 	return states;
 }
 
-}
+} /* namespace determinize */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/determinize/common/NFACommon.h b/alib2algo/src/automaton/determinize/common/NFACommon.h
similarity index 95%
rename from alib2algo/src/determinize/common/NFACommon.h
rename to alib2algo/src/automaton/determinize/common/NFACommon.h
index d68e98f97911e6900768468fe6a5d82445f786fd..2265efdf84cab10999f5441fdeba3781d5a471db 100644
--- a/alib2algo/src/determinize/common/NFACommon.h
+++ b/alib2algo/src/automaton/determinize/common/NFACommon.h
@@ -11,6 +11,8 @@
 #include <automaton/common/State.h>
 #include <set>
 
+namespace automaton {
+
 namespace determinize {
 
 /**
@@ -34,4 +36,6 @@ std::set<automaton::State> recreateNFAStates(const automaton::State& dfaState);
 
 } /* namespace determinize */
 
+} /* namespace automaton */
+
 #endif /* NFA_COMMON_H_ */
diff --git a/alib2algo/src/determinize/common/RHDPDACommon.cpp b/alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp
similarity index 99%
rename from alib2algo/src/determinize/common/RHDPDACommon.cpp
rename to alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp
index d309b75f55b89f66a83bba54d682f11ae41f90c9..e8c29d07032e22f5e19aa6411c25b4ca85ed7e3b 100644
--- a/alib2algo/src/determinize/common/RHDPDACommon.cpp
+++ b/alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp
@@ -10,6 +10,8 @@
 #include "automaton/PDA/RealTimeHeightDeterministicDPDA.h"
 #include "automaton/PDA/RealTimeHeightDeterministicNPDA.h"
 
+namespace automaton {
+
 namespace determinize {
 
 label::Label packToStateLabel(std::set<std::pair<label::Label, label::Label>>&& data) {
@@ -221,4 +223,6 @@ std::set<label::Label> retrieveLabels(const std::set<automaton::State>& states)
 	return labels;
 }
 
+} /* namespace automaton */
+
 } /* namespace determinize */
diff --git a/alib2algo/src/determinize/common/RHDPDACommon.h b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
similarity index 97%
rename from alib2algo/src/determinize/common/RHDPDACommon.h
rename to alib2algo/src/automaton/determinize/common/RHDPDACommon.h
index 26fff9071ec8806e4ad8340cb4b3abbdfac6fb3e..787037bd81b438b6fb3f7557db9d8404b482c95e 100644
--- a/alib2algo/src/determinize/common/RHDPDACommon.h
+++ b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h
@@ -9,6 +9,8 @@
 #include <set>
 #include <map>
 
+namespace automaton {
+
 namespace determinize {
 
 label::Label packToStateLabel(std::set<std::pair<label::Label, label::Label>>&& data);
@@ -40,4 +42,6 @@ std::set<label::Label> retrieveLabels(const std::set<automaton::State>& states);
 
 } /* namespace determinize */
 
+} /* namespace automaton */
+
 #endif /* RHDPDA_VPA_COMMON_H_ */
diff --git a/alib2algo/src/generator/RandomAutomatonFactory.cpp b/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp
similarity index 97%
rename from alib2algo/src/generator/RandomAutomatonFactory.cpp
rename to alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp
index 3bed804ba9ce1cdbb3b91a41367baf1b0d24a656..6aacce65f39fc38f350fe42da960413777057e1e 100644
--- a/alib2algo/src/generator/RandomAutomatonFactory.cpp
+++ b/alib2algo/src/automaton/generate/RandomAutomatonFactory.cpp
@@ -10,7 +10,9 @@
 
 #include <algorithm>
 
-namespace generator {
+namespace automaton {
+
+namespace generate {
 
 automaton::NFA RandomAutomatonFactory::generateNFA( size_t statesCount, std::set<alphabet::Symbol> alphabet, double density ) {
 	std::deque<alphabet::Symbol> alphabet2;
@@ -150,4 +152,6 @@ automaton::NFA RandomAutomatonFactory::LeslieConnectedNFA( size_t n, const std::
 	return automaton;
 }
 
-}
+} /* namespace generate */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/generator/RandomAutomatonFactory.h b/alib2algo/src/automaton/generate/RandomAutomatonFactory.h
similarity index 87%
rename from alib2algo/src/generator/RandomAutomatonFactory.h
rename to alib2algo/src/automaton/generate/RandomAutomatonFactory.h
index 3501e45b780c4fb39ddd2e26ce1d6220c50f8678..0f2881e34ac187fd9d26f16969dd93e2a6789d46 100644
--- a/alib2algo/src/generator/RandomAutomatonFactory.h
+++ b/alib2algo/src/automaton/generate/RandomAutomatonFactory.h
@@ -14,7 +14,9 @@
 #include <exception/AlibException.h>
 #include <automaton/FSM/NFA.h>
 
-namespace generator {
+namespace automaton {
+
+namespace generate {
 
 class RandomAutomatonFactory {
 public:
@@ -25,6 +27,8 @@ private:
     static automaton::NFA LeslieConnectedNFA( size_t n, const std::deque<alphabet::Symbol> & alphabet, double density );
 };
 
-}
+} /* namespace generate */
+
+} /* namespace automaton */
 
 #endif /* RANDOM_AUTOMATON_FACTORY_H_ */
diff --git a/alib2algo/src/automaton/EpsilonClosure.cpp b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
similarity index 96%
rename from alib2algo/src/automaton/EpsilonClosure.cpp
rename to alib2algo/src/automaton/properties/EpsilonClosure.cpp
index 854df6f1c01af8008f155095ac3c1cef0e2cd6ee..b91b08d470cf3b64a12d9acc6b2334f9a435ef98 100644
--- a/alib2algo/src/automaton/EpsilonClosure.cpp
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.cpp
@@ -19,10 +19,12 @@
 #include <map>
 #include <queue>
 
-#include "../regexp/RegExpEpsilon.h"
+#include "../../regexp/properties/RegExpEpsilon.h"
 
 namespace automaton {
 
+namespace properties {
+
 std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::EpsilonNFA & fsm, const automaton::State & q ) {
 	if(! fsm.getStates().count(q) ) throw exception::AlibException("State is not in the automaton");
 
@@ -94,7 +96,7 @@ std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::Exte
 		closure.insert( p );
 
 		for( const auto & transition : fsm.getTransitions( ) )
-			if( transition.first.first == p && regexp::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
+			if( transition.first.first == p && regexp::properties::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
 				for (const auto & to : transition.second )
 					if( visited [ to ] == false )
 						queue.push( to );
@@ -209,5 +211,7 @@ void EpsilonClosure::Visit(void*, const OneTapeDTM&) const {
 
 const EpsilonClosure EpsilonClosure::EPSILON_CLOSURE;
 
-}
+} /* namespace properties */
+
+} /* namespace automaton */
 
diff --git a/alib2algo/src/automaton/EpsilonClosure.h b/alib2algo/src/automaton/properties/EpsilonClosure.h
similarity index 96%
rename from alib2algo/src/automaton/EpsilonClosure.h
rename to alib2algo/src/automaton/properties/EpsilonClosure.h
index 2d98d57a6b7389067ec88c7fb1c0b632779033c3..eb768f772a770a47cb9a4547c72255c476ae121c 100644
--- a/alib2algo/src/automaton/EpsilonClosure.h
+++ b/alib2algo/src/automaton/properties/EpsilonClosure.h
@@ -17,6 +17,8 @@
 
 namespace automaton {
 
+namespace properties {
+
 class EpsilonClosure : public VisitableAutomatonBase::const_visitor_type {
 public:
 	static std::set<automaton::State> epsilonClosure( const automaton::Automaton & automaton, const automaton::State & state );
@@ -52,6 +54,8 @@ private:
 	static const EpsilonClosure EPSILON_CLOSURE;
 };
 
-}
+} /* namespace properties */
+
+} /* namespace automaton */
 
 #endif /* EPSILON_CLOSURE_H_ */
diff --git a/alib2algo/src/automaton/UnreachableStates.cpp b/alib2algo/src/automaton/properties/UnreachableStates.cpp
similarity index 98%
rename from alib2algo/src/automaton/UnreachableStates.cpp
rename to alib2algo/src/automaton/properties/UnreachableStates.cpp
index 9e868c8fcd624b0e5ee543779fa56738ddd922c2..fd730f3edc02d1a39921aa28d7dbad8737db6012 100644
--- a/alib2algo/src/automaton/UnreachableStates.cpp
+++ b/alib2algo/src/automaton/properties/UnreachableStates.cpp
@@ -20,6 +20,8 @@
 
 namespace automaton {
 
+namespace properties {
+
 std::set<automaton::State> UnreachableStates::unreachableStates(const Automaton& automaton) {
 	std::set<automaton::State> out;
 	automaton.getData().Accept((void*) &out, UnreachableStates::UNREACHABLE_STATES);
@@ -181,5 +183,7 @@ void UnreachableStates::Visit(void*, const OneTapeDTM&) const {
 
 const UnreachableStates UnreachableStates::UNREACHABLE_STATES;
 
-}
+} /* namespace properties */
+
+} /* namespace automaton */
 
diff --git a/alib2algo/src/automaton/UnreachableStates.h b/alib2algo/src/automaton/properties/UnreachableStates.h
similarity index 95%
rename from alib2algo/src/automaton/UnreachableStates.h
rename to alib2algo/src/automaton/properties/UnreachableStates.h
index e18f17aa9d6343a255cc82cbc0a98e54d7264aa4..d50644c4b792f54b71d30572f0cfb82dceb1cdd6 100644
--- a/alib2algo/src/automaton/UnreachableStates.h
+++ b/alib2algo/src/automaton/properties/UnreachableStates.h
@@ -17,6 +17,8 @@
 
 namespace automaton {
 
+namespace properties {
+
 class UnreachableStates : public VisitableAutomatonBase::const_visitor_type {
 public:
 	static std::set<automaton::State> unreachableStates( const automaton::Automaton & automaton );
@@ -48,6 +50,8 @@ private:
 	static const UnreachableStates UNREACHABLE_STATES;
 };
 
-}
+} /* namespace properties */
+
+} /* namespace automaton */
 
 #endif /* UNREACHABLE_STATES_H_ */
diff --git a/alib2algo/src/automaton/UsefullStates.cpp b/alib2algo/src/automaton/properties/UsefullStates.cpp
similarity index 98%
rename from alib2algo/src/automaton/UsefullStates.cpp
rename to alib2algo/src/automaton/properties/UsefullStates.cpp
index 68e4837dcad9afc9d4d67a98132ce0a9b076f7c9..83a53781ae67b769a84e42fa7b9b14bc8c294994 100644
--- a/alib2algo/src/automaton/UsefullStates.cpp
+++ b/alib2algo/src/automaton/properties/UsefullStates.cpp
@@ -20,6 +20,8 @@
 
 namespace automaton {
 
+namespace properties {
+
 std::set<automaton::State> UsefullStates::usefullStates(const Automaton& automaton) {
 	std::set<automaton::State> out;
 	automaton.getData().Accept((void*) &out, UsefullStates::USEFULL_STATES);
@@ -151,5 +153,7 @@ void UsefullStates::Visit(void*, const OneTapeDTM&) const {
 
 const UsefullStates UsefullStates::USEFULL_STATES;
 
-}
+} /* namespace properties */
+
+} /* namespace automaton */
 
diff --git a/alib2algo/src/automaton/UsefullStates.h b/alib2algo/src/automaton/properties/UsefullStates.h
similarity index 95%
rename from alib2algo/src/automaton/UsefullStates.h
rename to alib2algo/src/automaton/properties/UsefullStates.h
index db9a641cb2ca1c0ec1f886d0a1d21570b5597bfa..81a11580298976eeaa14056bce2b453a1dfa1fba 100644
--- a/alib2algo/src/automaton/UsefullStates.h
+++ b/alib2algo/src/automaton/properties/UsefullStates.h
@@ -17,6 +17,8 @@
 
 namespace automaton {
 
+namespace properties {
+
 class UsefullStates : public VisitableAutomatonBase::const_visitor_type {
 public:
 	static std::set<automaton::State> usefullStates( const automaton::Automaton & automaton );
@@ -48,6 +50,8 @@ private:
 	static const UsefullStates USEFULL_STATES;
 };
 
-}
+} /* namespace properties */
+
+} /* namespace automaton */
 
 #endif /* USEFULL_STATES_H_ */
diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp b/alib2algo/src/automaton/simplify/EpsilonRemover.cpp
similarity index 56%
rename from alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp
rename to alib2algo/src/automaton/simplify/EpsilonRemover.cpp
index 76153a08d7f6daf613676991d7074af7a9dce821..7435740493845871c3028ad4c788b368305d52ed 100644
--- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp
+++ b/alib2algo/src/automaton/simplify/EpsilonRemover.cpp
@@ -1,32 +1,34 @@
 /*
- * FSMEpsilonRemover.cpp
+ * EpsilonRemover.cpp
  *
  *  Created on: 16. 1. 2014
  *	  Author: Tomas Pecka
  */
 
-#include "FSMEpsilonRemover.h"
+#include "EpsilonRemover.h"
 
-#include "../../automaton/EpsilonClosure.h"
+#include "../properties/EpsilonClosure.h"
 
-namespace epsilon {
+namespace automaton {
 
-automaton::DFA FSMEpsilonRemover::remove(const automaton::DFA& origFSM)
+namespace simplify {
+
+automaton::DFA EpsilonRemover::remove(const automaton::DFA& origFSM)
 {
     return origFSM;
 }
 
-automaton::MultiInitialStateNFA FSMEpsilonRemover::remove(const automaton::MultiInitialStateNFA& origFSM)
+automaton::MultiInitialStateNFA EpsilonRemover::remove(const automaton::MultiInitialStateNFA& origFSM)
 {
     return origFSM;
 }
 
-automaton::NFA FSMEpsilonRemover::remove(const automaton::NFA& origFSM)
+automaton::NFA EpsilonRemover::remove(const automaton::NFA& origFSM)
 {
     return origFSM;
 }
 
-automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) {
+automaton::NFA EpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) {
 	automaton::NFA fsm(origFSM.getInitialState());
 
 	for( const auto & state : origFSM.getStates() )
@@ -39,7 +41,7 @@ automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM
 	 * Step 1 from Melichar 2.41
 	 */
 	for( const auto & from : origFSM.getStates( ) )
-		for( const auto & fromClosure : automaton::EpsilonClosure::epsilonClosure( origFSM, from ) )
+		for( const auto & fromClosure : automaton::properties::EpsilonClosure::epsilonClosure( origFSM, from ) )
 			for( const auto & transition : origFSM.getTransitions( ) )
 				if (transition.first.first == fromClosure && transition.first.second.is<alphabet::Symbol>())
 					for( const auto & to : transition.second )
@@ -52,7 +54,7 @@ automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM
 
 	for( const auto & q : fsm.getStates( ) )
 	{
-		const std::set<automaton::State> & cl = automaton::EpsilonClosure::epsilonClosure( origFSM, q );
+		const std::set<automaton::State> & cl = automaton::properties::EpsilonClosure::epsilonClosure( origFSM, q );
 		const std::set<automaton::State> & F = origFSM.getFinalStates( );
 		std::set<automaton::State> intersect;
 
@@ -67,82 +69,84 @@ automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM
 	return fsm;
 }
 
-automaton::Automaton FSMEpsilonRemover::remove(const automaton::Automaton& automaton) {
+automaton::Automaton EpsilonRemover::remove(const automaton::Automaton& automaton) {
 	automaton::Automaton* out = NULL;
-	automaton.getData().Accept((void*) &out, FSMEpsilonRemover::FSM_EPSILON_REMOVER);
+	automaton.getData().Accept((void*) &out, EpsilonRemover::EPSILON_REMOVER);
 	automaton::Automaton res = std::move(*out);
 	delete out;
 	return res;
 }
 
-void FSMEpsilonRemover::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
+void EpsilonRemover::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
 	automaton::Automaton* & out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->remove(automaton));
 }
 
-void FSMEpsilonRemover::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
+void EpsilonRemover::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
 	automaton::Automaton* & out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->remove(automaton));
 }
 
-void FSMEpsilonRemover::Visit(void* data, const automaton::NFA& automaton) const {
+void EpsilonRemover::Visit(void* data, const automaton::NFA& automaton) const {
 	automaton::Automaton* & out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->remove(automaton));
 }
 
-void FSMEpsilonRemover::Visit(void* data, const automaton::DFA& automaton) const {
+void EpsilonRemover::Visit(void* data, const automaton::DFA& automaton) const {
 	automaton::Automaton* & out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->remove(automaton));
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::ExtendedNFA& ) const {
+void EpsilonRemover::Visit(void*, const automaton::ExtendedNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::CompactNFA& ) const {
+void EpsilonRemover::Visit(void*, const automaton::CompactNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type CompactNFA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::DPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::DPDA&) const {
 	throw exception::AlibException("Unsupported automaton type DPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopDPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::SinglePopDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::InputDrivenNPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::InputDrivenNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::VisiblyPushdownDPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::VisiblyPushdownDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::NPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::NPDA&) const {
 	throw exception::AlibException("Unsupported automaton type NPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopNPDA&) const {
+void EpsilonRemover::Visit(void*, const automaton::SinglePopNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
 }
 
-void FSMEpsilonRemover::Visit(void*, const automaton::OneTapeDTM&) const {
+void EpsilonRemover::Visit(void*, const automaton::OneTapeDTM&) const {
 	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
 }
 
-const FSMEpsilonRemover FSMEpsilonRemover::FSM_EPSILON_REMOVER;
+const EpsilonRemover EpsilonRemover::EPSILON_REMOVER;
+
+} /* namespace simplify */
 
-} /* namespace epsilon */
+} /* namespace automaton */
diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h b/alib2algo/src/automaton/simplify/EpsilonRemover.h
similarity index 84%
rename from alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h
rename to alib2algo/src/automaton/simplify/EpsilonRemover.h
index 380deb2c814487e2476088e71d774aed3fdec8cd..38aa69f2e356ef0011ae618a8ffaa621a250b325 100644
--- a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h
+++ b/alib2algo/src/automaton/simplify/EpsilonRemover.h
@@ -1,12 +1,12 @@
 /*
- * FSMEpsilonRemover.h
+ * EpsilonRemover.h
  *
  *  Created on: 16. 1. 2014
  *      Author: Tomas Pecka
  */
 
-#ifndef FMS_EPSILON_REMOVER_H_
-#define FMS_EPSILON_REMOVER_H_
+#ifndef EPSILON_REMOVER_H_
+#define EPSILON_REMOVER_H_
 
 #include <map>
 #include <algorithm>
@@ -19,9 +19,11 @@
 #include <automaton/FSM/DFA.h>
 #include <exception/AlibException.h>
 
-namespace epsilon {
+namespace automaton {
 
-class FSMEpsilonRemover : public automaton::VisitableAutomatonBase::const_visitor_type {
+namespace simplify {
+
+class EpsilonRemover : public automaton::VisitableAutomatonBase::const_visitor_type {
 public:
 	static automaton::Automaton remove( const automaton::Automaton & automaton );
 
@@ -51,9 +53,11 @@ private:
 	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
 	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
 
-	static const FSMEpsilonRemover FSM_EPSILON_REMOVER;
+	static const EpsilonRemover EPSILON_REMOVER;
 };
 
-} /* namespace epsilon */
+} /* namespace simplify */
+
+} /* namespace automaton */
 
-#endif /* FMS_EPSILON_REMOVER_H_ */
+#endif /* EPSILON_REMOVER_H_ */
diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp b/alib2algo/src/automaton/simplify/Minimize.cpp
similarity index 82%
rename from alib2algo/src/minimize/dfa/MinimizeDFA.cpp
rename to alib2algo/src/automaton/simplify/Minimize.cpp
index 4f60e53c71c74fafd0b9a1fe8d323e21b0bd0d17..548354a3d65b95256027b3cf0e37ed4ba0e8d084 100644
--- a/alib2algo/src/minimize/dfa/MinimizeDFA.cpp
+++ b/alib2algo/src/automaton/simplify/Minimize.cpp
@@ -1,11 +1,11 @@
 /*
- * MinimizeDFA.cpp
+ * Minimize.cpp
  *
  *  Created on: Dec 9, 2013
  *      Author: honza
  */
 
-#include "MinimizeDFA.h"
+#include "Minimize.h"
 
 #include <map>
 #include <set>
@@ -18,17 +18,19 @@
 
 #include <automaton/Automaton.h>
 
-namespace minimize {
+namespace automaton {
 
-automaton::Automaton MinimizeDFA::minimize(const automaton::Automaton& automaton) {
+namespace simplify {
+
+automaton::Automaton Minimize::minimize(const automaton::Automaton& automaton) {
 	automaton::Automaton* out = NULL;
-	automaton.getData().Accept((void*) &out, MinimizeDFA::MINIMIZE_DFA);
+	automaton.getData().Accept((void*) &out, Minimize::MINIMIZE);
 	automaton::Automaton res = std::move(*out);
 	delete out;
 	return res;
 }
 
-automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) {
+automaton::DFA Minimize::minimize(const automaton::DFA& dfa) {
 	if(dfa.getFinalStates().size() == 0) {
 		automaton::DFA result(automaton::State(0));
 		result.setInputSymbols(dfa.getInputAlphabet());
@@ -140,71 +142,73 @@ automaton::DFA MinimizeDFA::minimize(const automaton::DFA& dfa) {
 	return result;
 }
 
-void MinimizeDFA::Visit(void*, const automaton::EpsilonNFA&) const {
+void Minimize::Visit(void*, const automaton::EpsilonNFA&) const {
 	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
 }
 
-void MinimizeDFA::Visit(void* data, const automaton::DFA& automaton) const {
+void Minimize::Visit(void* data, const automaton::DFA& automaton) const {
 	automaton::Automaton* & out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->minimize(automaton));
 }
 
-void MinimizeDFA::Visit(void*, const automaton::MultiInitialStateNFA&) const {
+void Minimize::Visit(void*, const automaton::MultiInitialStateNFA&) const {
 	throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::NFA&) const {
+void Minimize::Visit(void*, const automaton::NFA&) const {
 	throw exception::AlibException("Unsupported automaton type DFA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::ExtendedNFA& ) const {
+void Minimize::Visit(void*, const automaton::ExtendedNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::CompactNFA& ) const {
+void Minimize::Visit(void*, const automaton::CompactNFA& ) const {
 	throw exception::AlibException("Unsupported automaton type CompactNFA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::DPDA&) const {
+void Minimize::Visit(void*, const automaton::DPDA&) const {
 	throw exception::AlibException("Unsupported automaton type DPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::SinglePopDPDA&) const {
+void Minimize::Visit(void*, const automaton::SinglePopDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::InputDrivenNPDA&) const {
+void Minimize::Visit(void*, const automaton::InputDrivenNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::VisiblyPushdownDPDA&) const {
+void Minimize::Visit(void*, const automaton::VisiblyPushdownDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
+void Minimize::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const {
+void Minimize::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const {
+void Minimize::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::NPDA&) const {
+void Minimize::Visit(void*, const automaton::NPDA&) const {
 	throw exception::AlibException("Unsupported automaton type NPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::SinglePopNPDA&) const {
+void Minimize::Visit(void*, const automaton::SinglePopNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
 }
 
-void MinimizeDFA::Visit(void*, const automaton::OneTapeDTM&) const {
+void Minimize::Visit(void*, const automaton::OneTapeDTM&) const {
 	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
 }
 
-const MinimizeDFA MinimizeDFA::MINIMIZE_DFA;
+const Minimize Minimize::MINIMIZE;
+
+} /* namespace simplify */
 
-} /* namespace minimize */
+} /* namespace automaton */
diff --git a/alib2algo/src/minimize/dfa/MinimizeDFA.h b/alib2algo/src/automaton/simplify/Minimize.h
similarity index 84%
rename from alib2algo/src/minimize/dfa/MinimizeDFA.h
rename to alib2algo/src/automaton/simplify/Minimize.h
index 01e2d9d8033ac3083c0b73fcbbf29333874bec82..cc16d9f6200d94fcae80febf1c920f11afe201ab 100644
--- a/alib2algo/src/minimize/dfa/MinimizeDFA.h
+++ b/alib2algo/src/automaton/simplify/Minimize.h
@@ -5,15 +5,17 @@
  *      Author: Jan Travnicek
  */
 
-#ifndef MINIMIZE_DFA_H_
-#define MINIMIZE_DFA_H_
+#ifndef MINIMIZE_H_
+#define MINIMIZE_H_
 
 #include <automaton/Automaton.h>
 #include <automaton/FSM/DFA.h>
 
-namespace minimize {
+namespace automaton {
 
-class MinimizeDFA : public automaton::VisitableAutomatonBase::const_visitor_type {
+namespace simplify {
+
+class Minimize : public automaton::VisitableAutomatonBase::const_visitor_type {
 public:
 	/**
 	 * @param dfa automaton to minimize
@@ -40,9 +42,11 @@ protected:
 	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
 	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
 
-	static const MinimizeDFA MINIMIZE_DFA;
+	static const Minimize MINIMIZE;
 };
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
-#endif /* MINIMIZE_DFA_H_ */
+#endif /* MINIMIZE_H_ */
diff --git a/alib2algo/src/normalize/dfa/NormalizeDFA.cpp b/alib2algo/src/automaton/simplify/Normalize.cpp
similarity index 90%
rename from alib2algo/src/normalize/dfa/NormalizeDFA.cpp
rename to alib2algo/src/automaton/simplify/Normalize.cpp
index d7b11ef6a5e55f2a45c0beb3d751d7ec70e02b62..1780efd4503954c258aee59cd8b885a7fc39b574 100644
--- a/alib2algo/src/normalize/dfa/NormalizeDFA.cpp
+++ b/alib2algo/src/automaton/simplify/Normalize.cpp
@@ -1,10 +1,11 @@
 /*
- * NormalizeDFA.cpp
+ * Normalize.cpp
  *
  *  Created on: Dec 9, 2013
- *      Author: JanTravnicek */
+ *	Author: Jan Travnicek
+ */
 
-#include "NormalizeDFA.h"
+#include "Normalize.h"
 
 #include <map>
 #include <deque>
@@ -19,9 +20,11 @@
 
 #include "automaton/Automaton.h"
 
-namespace normalize {
+namespace automaton {
 
-automaton::DFA NormalizeDFA::normalize(automaton::DFA& fsm) {
+namespace simplify {
+
+automaton::DFA Normalize::normalize(automaton::DFA& fsm) {
 	int counter = 0;
 	std::map<automaton::State, int > normalizationData;
 	std::deque<automaton::State > processingData;
@@ -67,4 +70,6 @@ automaton::DFA NormalizeDFA::normalize(automaton::DFA& fsm) {
 	return result;
 }
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/simplify/Normalize.h b/alib2algo/src/automaton/simplify/Normalize.h
new file mode 100644
index 0000000000000000000000000000000000000000..48a6df5a2ee60880daf391cc33fa86ed069ac8ef
--- /dev/null
+++ b/alib2algo/src/automaton/simplify/Normalize.h
@@ -0,0 +1,27 @@
+/*
+ * Normalize.h
+ *
+ *  Created on: Dec 9, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef NORMALIZE_H_
+#define NORMALIZE_H_
+
+#include "automaton/FSM/DFA.h"
+
+namespace automaton {
+
+namespace simplify {
+
+class Normalize {
+public:
+	static automaton::DFA normalize(automaton::DFA& dfa);
+
+};
+
+} /* namespace simplify */
+
+} /* namespace automaton */
+
+#endif /* NORMALIZE_H_ */
diff --git a/alib2algo/src/automaton/FSMSingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
similarity index 60%
rename from alib2algo/src/automaton/FSMSingleInitialState.cpp
rename to alib2algo/src/automaton/simplify/SingleInitialState.cpp
index b76387d69771b78b60e6732746c8bb3587add580..372b09d47ba5383a649c5852c0edd66e5bc947e6 100644
--- a/alib2algo/src/automaton/FSMSingleInitialState.cpp
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp
@@ -1,11 +1,11 @@
 /*
- * FSMSingleInitialState.cpp
+ * SingleInitialState.cpp
  *
  *  Created on: 20. 9. 2014
  *	  Author: Tomas Pecka
  */
 
-#include "FSMSingleInitialState.h"
+#include "SingleInitialState.h"
 
 #include <algorithm>
 #include <set>
@@ -20,15 +20,17 @@
 
 namespace automaton {
 
-automaton::Automaton FSMSingleInitialState::convert(const Automaton& automaton) {
+namespace simplify {
+
+automaton::Automaton SingleInitialState::convert(const Automaton& automaton) {
 	automaton::Automaton* out = NULL;
-	automaton.getData().Accept((void*) &out, FSMSingleInitialState::FSM_SINGLE_INITIAL_STATE);
+	automaton.getData().Accept((void*) &out, SingleInitialState::SINGLE_INITIAL_STATE);
 	automaton::Automaton res = std::move(*out);
 	delete out;
 	return res;
 }
 
-automaton::NFA FSMSingleInitialState::convert(const automaton::MultiInitialStateNFA& automaton) {
+automaton::NFA SingleInitialState::convert(const automaton::MultiInitialStateNFA& automaton) {
 	// step 3
 	automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), automaton.getStates());
 	automaton::NFA res(q0);
@@ -61,97 +63,98 @@ automaton::NFA FSMSingleInitialState::convert(const automaton::MultiInitialState
 	return res;
 }
 
-automaton::DFA FSMSingleInitialState::convert(const automaton::DFA& automaton) {
+automaton::DFA SingleInitialState::convert(const automaton::DFA& automaton) {
 	return automaton;
 }
 
-automaton::EpsilonNFA FSMSingleInitialState::convert(const automaton::EpsilonNFA& automaton) {
+automaton::EpsilonNFA SingleInitialState::convert(const automaton::EpsilonNFA& automaton) {
 	return automaton;
 }
 
-automaton::NFA FSMSingleInitialState::convert(const automaton::NFA& automaton) {
+automaton::NFA SingleInitialState::convert(const automaton::NFA& automaton) {
 	return automaton;
 }
 
-automaton::CompactNFA FSMSingleInitialState::convert(const automaton::CompactNFA& automaton) {
+automaton::CompactNFA SingleInitialState::convert(const automaton::CompactNFA& automaton) {
 	return automaton;
 }
 
-automaton::ExtendedNFA FSMSingleInitialState::convert(const automaton::ExtendedNFA& automaton) {
+automaton::ExtendedNFA SingleInitialState::convert(const automaton::ExtendedNFA& automaton) {
 	return automaton;
 }
 
-void FSMSingleInitialState::Visit(void* data, const EpsilonNFA& automaton) const {
+void SingleInitialState::Visit(void* data, const EpsilonNFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->convert(automaton));
 }
 
-void FSMSingleInitialState::Visit(void* data, const MultiInitialStateNFA& automaton) const {
+void SingleInitialState::Visit(void* data, const MultiInitialStateNFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->convert(automaton));
 }
 
-void FSMSingleInitialState::Visit(void* data, const NFA& automaton) const {
+void SingleInitialState::Visit(void* data, const NFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->convert(automaton));
 }
 
-void FSMSingleInitialState::Visit(void* data, const DFA& automaton) const {
+void SingleInitialState::Visit(void* data, const DFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->convert(automaton));
 }
 
-void FSMSingleInitialState::Visit(void* data, const ExtendedNFA& automaton) const {
+void SingleInitialState::Visit(void* data, const ExtendedNFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->convert(automaton));
 }
 
-void FSMSingleInitialState::Visit(void* data, const CompactNFA& automaton) const {
+void SingleInitialState::Visit(void* data, const CompactNFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->convert(automaton));
 }
 
-void FSMSingleInitialState::Visit(void*, const DPDA&) const {
+void SingleInitialState::Visit(void*, const DPDA&) const {
 	throw exception::AlibException("Unsupported automaton type DPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const SinglePopDPDA&) const {
+void SingleInitialState::Visit(void*, const SinglePopDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const InputDrivenNPDA&) const {
+void SingleInitialState::Visit(void*, const InputDrivenNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const VisiblyPushdownDPDA&) const {
+void SingleInitialState::Visit(void*, const VisiblyPushdownDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const VisiblyPushdownNPDA&) const {
+void SingleInitialState::Visit(void*, const VisiblyPushdownNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
+void SingleInitialState::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
 	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
+void SingleInitialState::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const NPDA&) const {
+void SingleInitialState::Visit(void*, const NPDA&) const {
 	throw exception::AlibException("Unsupported automaton type NPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const SinglePopNPDA&) const {
+void SingleInitialState::Visit(void*, const SinglePopNPDA&) const {
 	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
 }
 
-void FSMSingleInitialState::Visit(void*, const OneTapeDTM&) const {
+void SingleInitialState::Visit(void*, const OneTapeDTM&) const {
 	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
 }
 
-const FSMSingleInitialState FSMSingleInitialState::FSM_SINGLE_INITIAL_STATE;
+const SingleInitialState SingleInitialState::SINGLE_INITIAL_STATE;
 
-}
+} /* namespace simplify */
 
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/FSMSingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h
similarity index 84%
rename from alib2algo/src/automaton/FSMSingleInitialState.h
rename to alib2algo/src/automaton/simplify/SingleInitialState.h
index ef69e4f093f3f0cd291728876fa7931b0bbc7255..e5b1f6085c2530196514dfc7b907429540eccedf 100644
--- a/alib2algo/src/automaton/FSMSingleInitialState.h
+++ b/alib2algo/src/automaton/simplify/SingleInitialState.h
@@ -1,23 +1,25 @@
 /*
- * FSMSingleInitialState.h
+ * SingleInitialState.h
  *
  *  Created on: 20. 9. 2014
  *	  Author: Tomas Pecka
  */
 
-#ifndef FSM_SINGLE_INITIAL_STATE_H
-#define FSM_SINGLE_INITIAL_STATE_H
+#ifndef _SINGLE_INITIAL_STATE_H_
+#define _SINGLE_INITIAL_STATE_H_
 
 #include <automaton/Automaton.h>
 #include <automaton/common/State.h>
 
 namespace automaton {
 
+namespace simplify {
+
 /**
  * Makes finite automaton's transition function convert.
  * Source: Melichar: Algorithm 2.22
  */
-class FSMSingleInitialState : public VisitableAutomatonBase::const_visitor_type {
+class SingleInitialState : public VisitableAutomatonBase::const_visitor_type {
 public:
 	/**
 	 * Computes epsilon closure of a state in epsilon nonfree automaton
@@ -50,9 +52,11 @@ private:
 	void Visit(void*, const SinglePopNPDA& automaton) const;
 	void Visit(void*, const OneTapeDTM& automaton) const;
 
-	static const FSMSingleInitialState FSM_SINGLE_INITIAL_STATE;
+	static const SingleInitialState SINGLE_INITIAL_STATE;
 };
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
-#endif /* FSM_SINGLE_INITIAL_STATE_H_ */
+#endif /* _SINGLE_INITIAL_STATE_H_ */
diff --git a/alib2algo/src/automaton/FSMTotal.cpp b/alib2algo/src/automaton/simplify/Total.cpp
similarity index 71%
rename from alib2algo/src/automaton/FSMTotal.cpp
rename to alib2algo/src/automaton/simplify/Total.cpp
index 74cc8ce3aee704291e7a4d1b70f3628cb3b69146..970caa05c824fddf926c731b96b437794e3b4c41 100644
--- a/alib2algo/src/automaton/FSMTotal.cpp
+++ b/alib2algo/src/automaton/simplify/Total.cpp
@@ -1,11 +1,11 @@
 /*
- * FSMTotal.cpp
+ * Total.cpp
  *
  *  Created on: 20. 9. 2014
  *	  Author: Tomas Pecka
  */
 
-#include "FSMTotal.h"
+#include "Total.h"
 
 #include <exception/AlibException.h>
 
@@ -14,15 +14,17 @@
 
 namespace automaton {
 
-automaton::Automaton FSMTotal::total(const Automaton& automaton) {
+namespace simplify {
+
+automaton::Automaton Total::total(const Automaton& automaton) {
 	automaton::Automaton* out = NULL;
-	automaton.getData().Accept((void*) &out, FSMTotal::FSM_TOTAL);
+	automaton.getData().Accept((void*) &out, Total::TOTAL);
 	automaton::Automaton res = std::move(*out);
 	delete out;
 	return res;
 }
 
-automaton::NFA FSMTotal::total(const automaton::NFA& automaton) {
+automaton::NFA Total::total(const automaton::NFA& automaton) {
 	if(! automaton.isDeterministic()) {
 		throw exception::AlibException("Automaton must be deterministic to make its transition function total");
 	}
@@ -42,7 +44,7 @@ automaton::NFA FSMTotal::total(const automaton::NFA& automaton) {
 	return res;
 }
 
-automaton::DFA FSMTotal::total(const automaton::DFA& automaton) {
+automaton::DFA Total::total(const automaton::DFA& automaton) {
 	automaton::DFA res(automaton);
 	automaton::State nullState = automaton::createUniqueState(automaton::State("q0"), automaton.getStates());
 	res.addState(nullState);
@@ -58,33 +60,35 @@ automaton::DFA FSMTotal::total(const automaton::DFA& automaton) {
 	return res;
 }
 
-void FSMTotal::Visit(void*, const EpsilonNFA&) const {
+void Total::Visit(void*, const EpsilonNFA&) const {
 	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
 }
 
-void FSMTotal::Visit(void*, const MultiInitialStateNFA&) const {
+void Total::Visit(void*, const MultiInitialStateNFA&) const {
 	throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA");
 }
 
-void FSMTotal::Visit(void* data, const NFA& automaton) const {
+void Total::Visit(void* data, const NFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->total(automaton));
 }
 
-void FSMTotal::Visit(void* data, const DFA& automaton) const {
+void Total::Visit(void* data, const DFA& automaton) const {
 	automaton::Automaton*& out = *((automaton::Automaton**) data);
 	out = new automaton::Automaton(this->total(automaton));
 }
 
-void FSMTotal::Visit(void*, const ExtendedNFA&) const {
+void Total::Visit(void*, const ExtendedNFA&) const {
 	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
 }
 
-void FSMTotal::Visit(void*, const CompactNFA&) const {
+void Total::Visit(void*, const CompactNFA&) const {
 	throw exception::AlibException("Unsupported automaton type CompactNFA");
 }
 
-const FSMTotal FSMTotal::FSM_TOTAL;
+const Total Total::TOTAL;
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
diff --git a/alib2algo/src/automaton/FSMTotal.h b/alib2algo/src/automaton/simplify/Total.h
similarity index 81%
rename from alib2algo/src/automaton/FSMTotal.h
rename to alib2algo/src/automaton/simplify/Total.h
index 604ddb74823dcd4111b0a11c652a7a946b1dec16..9730b0b96e28ad005665707d71f2d285695f75e1 100644
--- a/alib2algo/src/automaton/FSMTotal.h
+++ b/alib2algo/src/automaton/simplify/Total.h
@@ -1,12 +1,12 @@
 /*
- * FSMTotal.h
+ * Total.h
  *
  *  Created on: 20. 9. 2014
  *	  Author: Tomas Pecka
  */
 
-#ifndef FSM_TOTAL_H_
-#define FSM_TOTAL_H_
+#ifndef TOTAL_H_
+#define TOTAL_H_
 
 #include <algorithm>
 #include <deque>
@@ -17,11 +17,13 @@
 
 namespace automaton {
 
+namespace simplify {
+
 /**
  * Makes finite automaton's transition function total.
  * Source: Melichar: Algorithm 2.22
  */
-class FSMTotal : public VisitableConstFSMBase {
+class Total : public VisitableConstFSMBase {
 public:
 	/**
 	 * Computes epsilon closure of a state in epsilon nonfree automaton
@@ -39,9 +41,11 @@ private:
 	void Visit(void*, const ExtendedNFA& automaton) const;
 	void Visit(void*, const CompactNFA& automaton) const;
 
-	static const FSMTotal FSM_TOTAL;
+	static const Total TOTAL;
 };
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
-#endif /* FSM_TOTAL_H_ */
+#endif /* TOTAL_H_ */
diff --git a/alib2algo/src/trim/automaton/Trim.cpp b/alib2algo/src/automaton/simplify/Trim.cpp
similarity index 97%
rename from alib2algo/src/trim/automaton/Trim.cpp
rename to alib2algo/src/automaton/simplify/Trim.cpp
index e2bbcd20a1289041f725267615c488b8a15012ab..416378528dcca262c97a848fc653c92cb5a36f05 100644
--- a/alib2algo/src/trim/automaton/Trim.cpp
+++ b/alib2algo/src/automaton/simplify/Trim.cpp
@@ -16,13 +16,12 @@
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
 
-#include "../../automaton/UsefullStates.h"
-#include "../../automaton/UnreachableStates.h"
-
 #include "automaton/common/State.h"
 #include "automaton/Automaton.h"
 
-namespace trim {
+namespace automaton {
+
+namespace simplify {
 
 template<class T>
 T Trim::trim( const T & fsm ) {
@@ -116,5 +115,7 @@ void Trim::Visit(void*, const automaton::OneTapeDTM&) const {
 
 const Trim Trim::TRIM;
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
diff --git a/alib2algo/src/trim/automaton/Trim.h b/alib2algo/src/automaton/simplify/Trim.h
similarity index 89%
rename from alib2algo/src/trim/automaton/Trim.h
rename to alib2algo/src/automaton/simplify/Trim.h
index 1c88bae446df6df1846654b4d4d4894f6dea2c49..e5c085bd268d6640af6b9157515a836579fa5e64 100644
--- a/alib2algo/src/trim/automaton/Trim.h
+++ b/alib2algo/src/automaton/simplify/Trim.h
@@ -5,15 +5,17 @@
  *	  Author: Tomas Pecka
  */
 
-#ifndef TRIM_H_
-#define TRIM_H_
+#ifndef AUTOMATON_TRIM_H_
+#define AUTOMAONT_TRIM_H_
 
 #include <algorithm>
 #include <deque>
 #include <set>
 #include <automaton/Automaton.h>
 
-namespace trim {
+namespace automaton {
+
+namespace simplify {
 
 class Trim : public automaton::VisitableAutomatonBase::const_visitor_type {
 public:
@@ -46,6 +48,8 @@ private:
 	static const Trim TRIM;
 };
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
-#endif /* TRIM_H_ */
+#endif /* AUTOMATON_TRIM_H_ */
diff --git a/alib2algo/src/trim/automaton/UnreachableStatesRemover.cpp b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
similarity index 93%
rename from alib2algo/src/trim/automaton/UnreachableStatesRemover.cpp
rename to alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
index 370a121f5b9827a7862b91ba5c1bfff70faf57bd..cfab0b7c602f88b987b818f08f6759553b1f6776 100644
--- a/alib2algo/src/trim/automaton/UnreachableStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.cpp
@@ -15,17 +15,19 @@
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
 
-#include "../../automaton/UnreachableStates.h"
+#include "../properties/UnreachableStates.h"
 
 #include "automaton/common/State.h"
 #include "automaton/Automaton.h"
 
-namespace trim {
+namespace automaton {
+
+namespace simplify {
 
 template<class T>
 T UnreachableStatesRemover::remove( const T & fsm ) {
 	// 1a
-	std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm );
+	std::set<automaton::State> Qa = automaton::properties::UnreachableStates::unreachableStates( fsm );
 
 	// 2
 	T M(fsm.getInitialState());
@@ -57,7 +59,7 @@ template automaton::ExtendedNFA UnreachableStatesRemover::remove( const automato
 template<>
 automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) {
 	// 1a
-	std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm );
+	std::set<automaton::State> Qa = automaton::properties::UnreachableStates::unreachableStates( fsm );
 
 	// 2
 	automaton::DFA M(fsm.getInitialState() );
@@ -83,7 +85,7 @@ automaton::DFA UnreachableStatesRemover::remove( const automaton::DFA & fsm ) {
 template<>
 automaton::MultiInitialStateNFA UnreachableStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) {
 	// 1a
-	std::set<automaton::State> Qa = automaton::UnreachableStates::unreachableStates( fsm );
+	std::set<automaton::State> Qa = automaton::properties::UnreachableStates::unreachableStates( fsm );
 
 	// 2
 	automaton::MultiInitialStateNFA M;
@@ -189,5 +191,6 @@ void UnreachableStatesRemover::Visit(void*, const automaton::OneTapeDTM&) const
 
 const UnreachableStatesRemover UnreachableStatesRemover::UNREACHABLE_STATES_REMOVER;
 
-}
+} /* namespace simplify */
 
+} /* namespace automaton */
diff --git a/alib2algo/src/trim/automaton/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
similarity index 94%
rename from alib2algo/src/trim/automaton/UnreachableStatesRemover.h
rename to alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
index 2c3143d3a997423395937647d411f454813a728f..1422d99aa9e3d8c8555f0c8af678bc0bb0b291d9 100644
--- a/alib2algo/src/trim/automaton/UnreachableStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
@@ -13,7 +13,9 @@
 #include <set>
 #include <automaton/Automaton.h>
 
-namespace trim {
+namespace automaton {
+
+namespace simplify {
 
 class UnreachableStatesRemover : public automaton::VisitableAutomatonBase::const_visitor_type {
 public:
@@ -46,6 +48,8 @@ private:
 	static const UnreachableStatesRemover UNREACHABLE_STATES_REMOVER;
 };
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
 #endif /* UNREACHABLE_STATES_REMOVER_H_ */
diff --git a/alib2algo/src/trim/automaton/UselessStatesRemover.cpp b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
similarity index 93%
rename from alib2algo/src/trim/automaton/UselessStatesRemover.cpp
rename to alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
index d4b55f85270d27e7af434668627b1140e8c01c34..540d6723dfd8691e1f06e1fbc726f68783f2a017 100644
--- a/alib2algo/src/trim/automaton/UselessStatesRemover.cpp
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.cpp
@@ -15,17 +15,19 @@
 #include <automaton/FSM/NFA.h>
 #include <automaton/FSM/DFA.h>
 
-#include "../../automaton/UsefullStates.h"
+#include "../properties/UsefullStates.h"
 
 #include "automaton/common/State.h"
 #include "automaton/Automaton.h"
 
-namespace trim {
+namespace automaton {
+
+namespace simplify {
 
 template<class T>
 T UselessStatesRemover::remove( const T & fsm ) {
 	// 1.
-	std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm );
+	std::set<automaton::State> Qu = automaton::properties::UsefullStates::usefullStates( fsm );
 
 	// 2.
 	T M(fsm.getInitialState());
@@ -59,7 +61,7 @@ template automaton::ExtendedNFA UselessStatesRemover::remove( const automaton::E
 template<>
 automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) {
 	// 1.
-	std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm );
+	std::set<automaton::State> Qu = automaton::properties::UsefullStates::usefullStates( fsm );
 
 	// 2.
 	automaton::DFA M ( fsm.getInitialState () );
@@ -87,7 +89,7 @@ automaton::DFA UselessStatesRemover::remove( const automaton::DFA & fsm ) {
 template<>
 automaton::MultiInitialStateNFA UselessStatesRemover::remove( const automaton::MultiInitialStateNFA & fsm ) {
 	// 1.
-	std::set<automaton::State> Qu = automaton::UsefullStates::usefullStates( fsm );
+	std::set<automaton::State> Qu = automaton::properties::UsefullStates::usefullStates( fsm );
 
 	// 2.
 	automaton::MultiInitialStateNFA M;
@@ -198,5 +200,6 @@ void UselessStatesRemover::Visit(void*, const automaton::OneTapeDTM&) const {
 
 const UselessStatesRemover UselessStatesRemover::USELESS_STATES_REMOVER;
 
-}
+} /* namespace simplify */
 
+} /* namespace automaton */
diff --git a/alib2algo/src/trim/automaton/UselessStatesRemover.h b/alib2algo/src/automaton/simplify/UselessStatesRemover.h
similarity index 94%
rename from alib2algo/src/trim/automaton/UselessStatesRemover.h
rename to alib2algo/src/automaton/simplify/UselessStatesRemover.h
index 30df905885469fa05ed96de576316c1ea2c66307..dbf462579d108bb3d0eb3e0924c6d1f9a51b2e66 100644
--- a/alib2algo/src/trim/automaton/UselessStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UselessStatesRemover.h
@@ -13,7 +13,9 @@
 #include <set>
 #include <automaton/Automaton.h>
 
-namespace trim {
+namespace automaton {
+
+namespace simplify {
 
 class UselessStatesRemover : public automaton::VisitableAutomatonBase::const_visitor_type {
 public:
@@ -46,6 +48,8 @@ private:
 	static const UselessStatesRemover USELESS_STATES_REMOVER;
 };
 
-}
+} /* namespace simplify */
+
+} /* namespace automaton */
 
 #endif /* USELESS_STATES_REMOVER_H_ */
diff --git a/alib2algo/src/automaton/PDAToRHPDA.cpp b/alib2algo/src/automaton/transform/PDAToRHPDA.cpp
similarity index 100%
rename from alib2algo/src/automaton/PDAToRHPDA.cpp
rename to alib2algo/src/automaton/transform/PDAToRHPDA.cpp
diff --git a/alib2algo/src/automaton/PDAToRHPDA.h b/alib2algo/src/automaton/transform/PDAToRHPDA.h
similarity index 100%
rename from alib2algo/src/automaton/PDAToRHPDA.h
rename to alib2algo/src/automaton/transform/PDAToRHPDA.h
diff --git a/alib2algo/src/automaton/RHPDAToPDA.cpp b/alib2algo/src/automaton/transform/RHPDAToPDA.cpp
similarity index 100%
rename from alib2algo/src/automaton/RHPDAToPDA.cpp
rename to alib2algo/src/automaton/transform/RHPDAToPDA.cpp
diff --git a/alib2algo/src/automaton/RHPDAToPDA.h b/alib2algo/src/automaton/transform/RHPDAToPDA.h
similarity index 100%
rename from alib2algo/src/automaton/RHPDAToPDA.h
rename to alib2algo/src/automaton/transform/RHPDAToPDA.h
diff --git a/alib2algo/src/conversions/re2fa/GlushkovNFA.h b/alib2algo/src/conversions/re2fa/GlushkovNFA.h
deleted file mode 100644
index 1cb1c806b7aa9859135c1a9841ee8b22664fb6fe..0000000000000000000000000000000000000000
--- a/alib2algo/src/conversions/re2fa/GlushkovNFA.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * GlushkovNFA.h
- *
- *  Created on: 11. 1. 2014
- *      Author: Tomas Pecka
- */
-
-#ifndef FA2RE_GLUSHKOVNFA_H_
-#define FA2RE_GLUSHKOVNFA_H_
-
-#include <map>
-
-#include <automaton/FSM/NFA.h>
-#include <regexp/RegExp.h>
-#include <regexp/formal/FormalRegExp.h>
-#include <regexp/unbounded/UnboundedRegExp.h>
-
-namespace conversions {
-
-namespace re2fa {
-
-/**
- * Converts regular expression to finite automaton using Glushkov's NFA construction algorithm.
- * Source: Melichar 2.107
- */
-class GlushkovNFA : public regexp::VisitableRegExpBase::const_visitor_type
-{
-public:
-    /**
-     * Performs conversion.
-     * @param re Original regular expression.
-     * @return NFA equivalent to original regular expression.
-     */
-	static automaton::NFA convert(const regexp::RegExp& re);
-
-    static automaton::NFA convert(const regexp::UnboundedRegExp& re);
-    static automaton::NFA convert(const regexp::FormalRegExp& re);
-
-private:
-    void Visit(void*, const regexp::FormalRegExp& regexp) const;
-    void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
-
-	static const GlushkovNFA GLUSHKOV_NFA;
-};
-
-} /* namespace re2fa */
-
-} /* namespace conversions */
-
-#endif /* FA2RE_GLUSHKOV_H_ */
diff --git a/alib2algo/src/conversions/rg2fa/RGtoFA.cpp b/alib2algo/src/conversions/rg2fa/RGtoFA.cpp
deleted file mode 100644
index d18ffdada6efff06b9ad9acbe39cf27fbb07ca60..0000000000000000000000000000000000000000
--- a/alib2algo/src/conversions/rg2fa/RGtoFA.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * RGtoFA.cpp
- *
- * Created on: 1. 11. 2013
- * Author: Tomas Pecka
- */
-#include "RGtoFA.h"
-
-#include <alphabet/LabeledSymbol.h>
-#include <exception/AlibException.h>
-
-namespace conversions
-{
-
-namespace rg2fa
-{
-
-automaton::Automaton RGtoFA::convert(const grammar::Grammar& grammar)
-{
-     automaton::Automaton* out = NULL;
-     grammar.getData().Accept((void*) &out, RGtoFA::RG_TO_FA_CONVERSION);
-     automaton::Automaton res = std::move(*out);
-     delete out;
-     return res;
-}
-
-automaton::NFA RGtoFA::convert(const grammar::LeftRG& grammar)
-{
-    std::map<alphabet::Symbol, automaton::State> stateMap;
-    std::set<automaton::State> states;
-
-    // step 2
-    for(const auto& symbol : grammar.getNonterminalAlphabet())
-    {
-        automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
-        states.insert(state);
-        stateMap.insert(std::make_pair(symbol, state));
-    }
-
-    // step 1, 4
-    const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states);
-    states.insert(q0);
-    automaton::NFA automaton(q0);
-    automaton.setInputSymbols(grammar.getTerminalAlphabet());
-    automaton.setStates(states);
-
-    // step 3
-    for(const auto& rule : grammar.getRules())
-    {
-        const alphabet::Symbol& lhs = rule.first;
-        for(const auto& ruleRHS : rule.second)
-        {
-            if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B
-            {
-                const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
-                automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second);
-            }
-            else // if B->a => \delta(StartState,a)=B
-            {
-                const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
-                automaton.addTransition(q0, rhs, stateMap.find(lhs)->second);
-            }
-        }
-    }
-
-    // step 5
-    automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second);
-    if(grammar.getGeneratesEpsilon())
-        automaton.addFinalState(q0);
-
-    return automaton;
-}
-
-automaton::NFA RGtoFA::convert(const grammar::RightRG& grammar)
-{
-    std::map<alphabet::Symbol, automaton::State> stateMap;
-    std::set<automaton::State> states;
-
-    // step2
-    for(const auto& symbol : grammar.getNonterminalAlphabet())
-    {
-        automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
-        states.insert(state);
-        stateMap.insert(std::make_pair(symbol, state));
-    }
-
-    // step 1, 4
-    const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states);
-    states.insert(AState);
-    automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second);
-    automaton.setStates(states);
-
-    automaton.setInputSymbols(grammar.getTerminalAlphabet());
-
-    // step 3
-    for(const auto& rule : grammar.getRules())
-    {
-        const alphabet::Symbol& lhs = rule.first;
-        for(const auto& ruleRHS : rule.second)
-        {
-            if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C
-            {
-                const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
-                automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second);
-            }
-            else // if B->a => \delta(B,a)=AState
-            {
-                const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
-                automaton.addTransition(stateMap.find(lhs)->second, rhs, AState);
-            }
-        }
-    }
-
-    // step 5
-    automaton.addFinalState(AState);
-    if(grammar.getGeneratesEpsilon())
-        automaton.addFinalState(automaton.getInitialState());
-
-    return automaton;
-}
-
-void RGtoFA::Visit(void* userData, const grammar::RightRG& grammar) const
-{
-    automaton::Automaton* & out = *((automaton::Automaton**) userData);
-    out = new automaton::Automaton(this->convert(grammar));
-}
-
-void RGtoFA::Visit(void* userData, const grammar::LeftRG& grammar) const
-{
-    automaton::Automaton* & out = *((automaton::Automaton**) userData);
-    out = new automaton::Automaton(this->convert(grammar));
-}
-
-void RGtoFA::Visit(void*, const grammar::RightLG&) const
-{
-    throw exception::AlibException("Unsupported grammar type RightLG");
-}
-
-void RGtoFA::Visit(void*, const grammar::LeftLG&) const
-{
-    throw exception::AlibException("Unsupported grammar type LeftLG");
-}
-
-const RGtoFA RGtoFA::RG_TO_FA_CONVERSION;
-
-} /* namespace rg2fa */
-
-} /* namespace conversions */
diff --git a/alib2algo/src/conversions/rg2fa/RGtoFA.h b/alib2algo/src/conversions/rg2fa/RGtoFA.h
deleted file mode 100644
index d88359532b2862ca676e46e988f4aa43e9dab1dc..0000000000000000000000000000000000000000
--- a/alib2algo/src/conversions/rg2fa/RGtoFA.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * RGtoFA.h
- *
- * Created on: 1. 11. 2013
- * Author: Tomas Pecka
- */
-
-#ifndef __RGTOFA_H__
-#define __RGTOFA_H__
-
-#include <grammar/Grammar.h>
-#include <grammar/Regular/LeftRG.h>
-#include <grammar/Regular/RightRG.h>
-
-#include <automaton/Automaton.h>
-#include <automaton/FSM/NFA.h>
-
-namespace conversions
-{
-
-namespace rg2fa
-{
-
-/**
- * Converts regular grammar to nondeterministic finite automaton.
- * Sources: Melichar 2.98 (RightRG -> NFA) and 2.102 (LeftRG -> NFA).
- */
-class RGtoFA : public grammar::VisitableConstRGBase
-{
-public:
-    /**
-     * Performs conversion.
-     * @param grammar Regular grammar to convert.
-     * @return FSM equivalent to source grammar.
-     */
-    static automaton::Automaton convert(const grammar::Grammar& grammar);
-
-    static automaton::NFA convert(const grammar::LeftRG& grammar);
-    static automaton::NFA convert(const grammar::RightRG& grammar);
-
-private:
-    void Visit(void*, const grammar::RightRG& grammar) const;
-    void Visit(void*, const grammar::LeftRG& grammar) const;
-    void Visit(void*, const grammar::RightLG& grammar) const;
-    void Visit(void*, const grammar::LeftLG& grammar) const;
-
-    static const RGtoFA RG_TO_FA_CONVERSION;
-};
-
-} /* namespace rg2fa */
-
-} /* namespace conversions */
-
-#endif /* __RGTOFA_H__ */
diff --git a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.h b/alib2algo/src/determinize/hdpda/HDPDADeterminizer.h
deleted file mode 100644
index 2d867dcdd04578899e268dbda81b5afe9013f7ca..0000000000000000000000000000000000000000
--- a/alib2algo/src/determinize/hdpda/HDPDADeterminizer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef HDPDA_DETERMINIZER_H_
-#define HDPDA_DETERMINIZER_H_
-
-#include "automaton/PDA/RealTimeHeightDeterministicNPDA.h"
-#include "automaton/PDA/RealTimeHeightDeterministicDPDA.h"
-
-namespace determinize {
-
-/**
- * Class for running basic determinization algorithm on vpa.
- */
-class HDPDADeterminizer {
-public:
-	/**
-	 * Runs determinization algorithm on nondeterministic vpa given in constructor.
-	 *
-	 * @return deterministic visibly pushdown automaton
-	 */
-	static automaton::RealTimeHeightDeterministicDPDA determinize(const automaton::RealTimeHeightDeterministicNPDA& nondeterministic);
-
-};
-
-} /* namespace determinize */
-
-#endif /* HDPDA_DETERMINIZER_h_ */
diff --git a/alib2algo/src/determinize/idpda/IDPDADeterminizer.h b/alib2algo/src/determinize/idpda/IDPDADeterminizer.h
deleted file mode 100644
index 4009c23dd29245ccac294b86ce5a6f916f012789..0000000000000000000000000000000000000000
--- a/alib2algo/src/determinize/idpda/IDPDADeterminizer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * IDPDADeterminizer.h
- *
- *  Created on: 16. 1. 2014
- *	  Author: Jan Vesely
- */
-
-#ifndef IDPDA_DETERMINIZER_H_
-#define IDPDA_DETERMINIZER_H_
-
-#include <set>
-
-#include "automaton/common/State.h"
-#include "automaton/PDA/InputDrivenNPDA.h"
-#include "automaton/PDA/DPDA.h"
-
-namespace determinize {
-
-/**
- * Class for running determinization algorithm on fsm.
- */
-class IDPDADeterminizer {
-public:
-
-	/**
-	 * @param nfsm nondeterministic final-state machine given for determinization
-	 * Runs determinization algorithm on nondeterministic fsm given in constructor.
-	 */
-	static automaton::DPDA determinize(const automaton::InputDrivenNPDA& nfa);
-
-};
-
-} /* namespace determinize */
-
-#endif /* IDPDA_DETERMINIZER_H_ */
diff --git a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp b/alib2algo/src/determinize/nfa/NFADeterminizer.cpp
deleted file mode 100644
index 3e0925ea731914873154ec7e967d09c88a99f501..0000000000000000000000000000000000000000
--- a/alib2algo/src/determinize/nfa/NFADeterminizer.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * NFADeterminizer.cpp
- *
- *  Created on: 16. 1. 2014
- *	  Author: Jan Vesely
- */
-
-#include "NFADeterminizer.h"
-#include "../common/NFACommon.h"
-
-#include <deque>
-#include <algorithm>
-
-namespace determinize {
-
-automaton::Automaton NFADeterminizer::determinize(const automaton::Automaton& automaton) {
-	automaton::Automaton* out = NULL;
-	automaton.getData().Accept((void*) &out, NFADeterminizer::NFA_DETERMINIZER);
-	automaton::Automaton res = std::move(*out);
-	delete out;
-	return res;
-}
-
-automaton::DFA NFADeterminizer::determinize(const automaton::MultiInitialStateNFA& nfa) {
-	// 1, 4
-	automaton::State initialState(createDFAState(nfa.getInitialStates()));
-	automaton::DFA res(initialState);
-	res.setInputSymbols(nfa.getInputAlphabet());
-	
-	// 2
-	std::deque<automaton::State> todo;
-	todo.push_back(initialState);
-	
-	do {
-		// 3a, c
-		automaton::State state = todo.front();
-		todo.pop_front();
-
-		// 3b
-		for (const auto& input : nfa.getInputAlphabet()) {
-			std::set<automaton::State> targetNFAStates;
-			for(const auto& nfaState : recreateNFAStates(state)) {
-				auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input));
-				if(iter != nfa.getTransitions().end()) {
-					targetNFAStates.insert(iter->second.begin(), iter->second.end());
-				}
-			}
-			automaton::State dfaState = createDFAState(targetNFAStates);
-
-			// 4
-			bool existed = !res.addState(dfaState);
-
-			// 3b
-			res.addTransition(state, input, dfaState);
-
-			if(!existed) todo.push_back(dfaState);
-		}
-	} while(!todo.empty());
-	
-	// 5
-	for (const auto& dfaState : res.getStates()) {
-		std::set<automaton::State> nfaStates = recreateNFAStates(dfaState);
-		if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) {
-			res.addFinalState(dfaState);
-		}
-	}
-	
-	return res;
-}
-
-automaton::DFA NFADeterminizer::determinize(const automaton::NFA& nfa) {
-	// 1, 4
-	automaton::State initialState(createDFAState({nfa.getInitialState()}));
-	automaton::DFA res(initialState);
-	res.setInputSymbols(nfa.getInputAlphabet());
-	
-	// 2
-	std::deque<automaton::State> todo;
-	todo.push_back(initialState);
-	
-	do {
-		// 3a, c
-		automaton::State state = todo.front();
-		todo.pop_front();
-
-		// 3b
-		for (const auto& input : nfa.getInputAlphabet()) {
-			std::set<automaton::State> targetNFAStates;
-			for(const auto& nfaState : recreateNFAStates(state)) {
-				auto iter = nfa.getTransitions().find(std::make_pair(nfaState, input));
-				if(iter != nfa.getTransitions().end()) {
-					targetNFAStates.insert(iter->second.begin(), iter->second.end());
-				}
-			}
-			automaton::State dfaState = createDFAState(targetNFAStates);
-
-			// 4
-			bool existed = !res.addState(dfaState);
-
-			// 3b
-			res.addTransition(state, input, dfaState);
-
-			if(!existed) todo.push_back(dfaState);
-		}
-	} while(!todo.empty());
-	
-	// 5
-	for (const auto& dfaState : res.getStates()) {
-		std::set<automaton::State> nfaStates = recreateNFAStates(dfaState);
-		if(std::any_of(nfaStates.begin(), nfaStates.end(), [&](const automaton::State& nfaState) { return nfa.getFinalStates().count(nfaState); })) {
-			res.addFinalState(dfaState);
-		}
-	}
-	
-	return res;
-}
-
-void NFADeterminizer::Visit(void*, const automaton::EpsilonNFA&) const {
-	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
-}
-
-void NFADeterminizer::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
-
-void NFADeterminizer::Visit(void* data, const automaton::NFA& automaton) const {
-	automaton::Automaton* & out = *((automaton::Automaton**) data);
-	out = new automaton::Automaton(this->determinize(automaton));
-}
-
-void NFADeterminizer::Visit(void*, const automaton::DFA&) const {
-	throw exception::AlibException("Unsupported automaton type DFA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::ExtendedNFA& ) const {
-	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::CompactNFA& ) const {
-	throw exception::AlibException("Unsupported automaton type CompactNFA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::DPDA&) const {
-	throw exception::AlibException("Unsupported automaton type DPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::SinglePopDPDA&) const {
-	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::InputDrivenNPDA&) const {
-	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::VisiblyPushdownDPDA&) const {
-	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::VisiblyPushdownNPDA&) const {
-	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::RealTimeHeightDeterministicDPDA&) const {
-	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::RealTimeHeightDeterministicNPDA&) const {
-	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::NPDA&) const {
-	throw exception::AlibException("Unsupported automaton type NPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::SinglePopNPDA&) const {
-	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
-}
-
-void NFADeterminizer::Visit(void*, const automaton::OneTapeDTM&) const {
-	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
-}
-
-const NFADeterminizer NFADeterminizer::NFA_DETERMINIZER;
-
-}
diff --git a/alib2algo/src/determinize/vpa/VPADeterminizer.h b/alib2algo/src/determinize/vpa/VPADeterminizer.h
deleted file mode 100644
index 129a90f2a3bda42bb9b35007fc8cbd4234286d04..0000000000000000000000000000000000000000
--- a/alib2algo/src/determinize/vpa/VPADeterminizer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef VPADETERMINIZER_H_
-#define VPADETERMINIZER_H_
-
-#include "automaton/PDA/VisiblyPushdownNPDA.h"
-#include "automaton/PDA/VisiblyPushdownDPDA.h"
-
-namespace determinize {
-
-/**
- * Class for running basic determinization algorithm on vpa.
- */
-class VPADeterminizer {
-public:
-	/**
-	 * Runs determinization algorithm on nondeterministic vpa given in constructor.
-	 *
-	 * @return deterministic visibly pushdown automaton
-	 */
-	static automaton::VisiblyPushdownDPDA determinize(const automaton::VisiblyPushdownNPDA& nondeterministic);
-
-};
-
-} /* namespace determinize */
-
-#endif /* VPADETERMINIZER_H_ */
diff --git a/alib2algo/src/equations/LeftRegularEquationSolver.cpp b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
index 72351deeaad2ad5cb333a0b44bc62a15e684877a..59f2d51ab21432ce778de40714c1df5eb92c62d2 100644
--- a/alib2algo/src/equations/LeftRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/LeftRegularEquationSolver.cpp
@@ -8,13 +8,11 @@
 #include "LeftRegularEquationSolver.h"
 #include "regexp/unbounded/UnboundedRegExpElements.h"
 
-#include "../regexp/RegExpOptimize.h"
+#include "../regexp/simplify/RegExpOptimize.h"
 
 namespace equations {
 
 regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
-	regexp::RegExpOptimize opt;
-
 	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); itA ++) {
 		const alphabet::Symbol& a = * itA;
 
@@ -24,7 +22,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 		 * => A = 10*B + 20*C
 		 */
 		regexp::UnboundedRegExpIteration loop(std::move(equationTransition.find(std::make_pair(a, a))->second));
-		regexp::RegExpOptimize::optimize(loop);
+		regexp::simplify::RegExpOptimize::optimize(loop);
 
 		// for all transitions from A apply Arden's Lemma
 		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); itB ++) {
@@ -35,7 +33,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 			regexp::UnboundedRegExpAlternation alt;
 			alt.appendElement(std::move(concat));
 			equationTransition.find(std::make_pair(a, b))->second = std::move(alt);
-			regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second);
+			regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second);
 		}
 		regexp::UnboundedRegExpConcatenation concat;
 		concat.appendElement(std::move(equationFinal.find(a)->second));
@@ -43,7 +41,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 		regexp::UnboundedRegExpAlternation alt;
 		alt.appendElement(std::move(concat));
 		equationFinal.find(a)->second = std::move(alt);
-		regexp::RegExpOptimize::optimize(equationFinal.find(a)->second);
+		regexp::simplify::RegExpOptimize::optimize(equationFinal.find(a)->second);
 
 		/*
 		 * eliminate A from rest of the equations using this pattern:
@@ -62,7 +60,7 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 				alt.appendElement(std::move(equationTransition.find(std::make_pair(b, c))->second));
 				alt.appendElement(std::move(concat));
 				equationTransition.find(std::make_pair(b, c))->second = std::move(alt);
-				regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second);
+				regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second);
 			}
 
 			regexp::UnboundedRegExpConcatenation concat;
@@ -72,11 +70,11 @@ regexp::UnboundedRegExp LeftRegularEquationSolver::eliminate(void) {
 			alt.appendElement(std::move(equationFinal.find(b)->second));
 			alt.appendElement(std::move(concat));
 			equationFinal.find(b)->second = std::move(alt);
-			regexp::RegExpOptimize::optimize(equationFinal.find(b)->second);
+			regexp::simplify::RegExpOptimize::optimize(equationFinal.find(b)->second);
 		}
 	}
 
-	return regexp::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second)));
+	return regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second)));
 }
 
 } /* namespace equations */
diff --git a/alib2algo/src/equations/RightRegularEquationSolver.cpp b/alib2algo/src/equations/RightRegularEquationSolver.cpp
index 08cf2fb03d8ba55b7f2eaff2c734be5856e11471..8403237f907543ea2699ae540206529335fcbf3e 100644
--- a/alib2algo/src/equations/RightRegularEquationSolver.cpp
+++ b/alib2algo/src/equations/RightRegularEquationSolver.cpp
@@ -8,13 +8,11 @@
 #include "RightRegularEquationSolver.h"
 #include "regexp/unbounded/UnboundedRegExpElements.h"
 
-#include "../regexp/RegExpOptimize.h"
+#include "../regexp/simplify/RegExpOptimize.h"
 
 namespace equations {
 
 regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
-	regexp::RegExpOptimize opt;
-
 	for(auto itA = nonterminalSymbolsByDepth.rbegin(); itA != nonterminalSymbolsByDepth.rend(); itA ++) {
 		const alphabet::Symbol& a = * itA;
 
@@ -24,7 +22,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 		 * => A = 0*1B + 0*2C
 		 */
 		regexp::UnboundedRegExpIteration loop(std::move(equationTransition.find(std::make_pair(a, a))->second));
-		regexp::RegExpOptimize::optimize(loop);
+		regexp::simplify::RegExpOptimize::optimize(loop);
 
 		// for all transitions from A apply Arden's Lemma
 		for(auto itB = std::next(itA) ; itB != nonterminalSymbolsByDepth.rend(); itB ++) {
@@ -35,7 +33,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 			regexp::UnboundedRegExpAlternation alt;
 			alt.appendElement(std::move(concat));
 			equationTransition.find(std::make_pair(a, b))->second = std::move(alt);
-			regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second);
+			regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(a, b))->second);
 		}
 		regexp::UnboundedRegExpConcatenation concat;
 		concat.appendElement(std::move(loop));
@@ -43,7 +41,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 		regexp::UnboundedRegExpAlternation alt;
 		alt.appendElement(std::move(concat));
 		equationFinal.find(a)->second = std::move(alt);
-		regexp::RegExpOptimize::optimize(equationFinal.find(a)->second);
+		regexp::simplify::RegExpOptimize::optimize(equationFinal.find(a)->second);
 
 		/*
 		 * eliminate A from rest of the equations using this pattern:
@@ -62,7 +60,7 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 				alt.appendElement(std::move(equationTransition.find(std::make_pair(b, c))->second));
 				alt.appendElement(std::move(concat));
 				equationTransition.find(std::make_pair(b, c))->second = std::move(alt);
-				regexp::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second);
+				regexp::simplify::RegExpOptimize::optimize(equationTransition.find(std::make_pair(b, c))->second);
 			}
 
 			regexp::UnboundedRegExpConcatenation concat;
@@ -72,11 +70,11 @@ regexp::UnboundedRegExp RightRegularEquationSolver::eliminate(void) {
 			alt.appendElement(std::move(equationFinal.find(b)->second));
 			alt.appendElement(std::move(concat));
 			equationFinal.find(b)->second = std::move(alt);
-			regexp::RegExpOptimize::optimize(equationFinal.find(b)->second);
+			regexp::simplify::RegExpOptimize::optimize(equationFinal.find(b)->second);
 		}
 	}
 
-	return regexp::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second)));
+	return regexp::simplify::RegExpOptimize::optimize(regexp::UnboundedRegExp(std::move( equationFinal.find(*nonterminalSymbolsByDepth.begin())->second)));
 }
 
 } /* namespace equations */
diff --git a/alib2algo/src/grammar/GrammarPropertiesCFG.cpp b/alib2algo/src/grammar/GrammarPropertiesCFG.cpp
deleted file mode 100644
index e72f1cb33e65ebe5bfd382b40bb131b2330fd955..0000000000000000000000000000000000000000
--- a/alib2algo/src/grammar/GrammarPropertiesCFG.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * GrammarPropertiesCFG.cpp
- *
- *  Created on: 22. 3. 2014
- *	  Author: Tomas Pecka
- */
-
-#include "GrammarPropertiesCFG.h"
-
-#include <grammar/ContextFree/CFG.h>
-#include <grammar/ContextFree/EpsilonFreeCFG.h>
-#include <grammar/ContextFree/GNF.h>
-#include <grammar/ContextFree/CNF.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 <std/set.hpp>
-
-namespace grammar {
-
-template<class T>
-std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const T & grammar ) {
-	// 1.
-	std::deque<std::set<alphabet::Symbol>> Ni;
-	Ni.push_back( std::set<alphabet::Symbol>( ) );
-
-	int i = 1;
-
-	// 2.
-	while( true ) {
-		Ni.push_back( Ni.at( i - 1 ) );
-
-		for( const auto & rule : grammar.getRawRules( ) ) {
-			for( const auto & rhs : rule.second ) {
-				if( std::all_of( rhs.begin( ), rhs.end( ), [ i, Ni, grammar ]( const alphabet::Symbol & symbol ) -> bool {
-					return Ni.at( i - 1 ) . count( symbol ) || grammar.getTerminalAlphabet( ). count( symbol );
-				} ) )
-					Ni.at( i ).insert( rule.first );
-			}
-		}
-
-		if( Ni.at( i ) == Ni.at( i - 1 ) )
-			break;
-
-		i = i + 1;
-	}
-
-	// 3.
-	return Ni.at( i );
-}
-
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::CFG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::EpsilonFreeCFG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::GNF & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::CNF & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::LG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::LeftLG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::LeftRG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::RightLG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getProductiveNonterminals( const grammar::RightRG & grammar );
-
-template<class T>
-std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const T & grammar ) {
-	// 1
-	std::deque<std::set<alphabet::Symbol>> Vi;
-	Vi.push_back( std::set<alphabet::Symbol>( ) );
-	Vi.at( 0 ).insert( grammar.getInitialSymbol( ) );
-
-	int i = 1;
-
-	// 2.
-	while( true ) {
-		Vi.push_back( Vi.at( i - 1 ) );
-
-		for( const auto & rule : grammar.getRawRules( ) ) {
-			if( Vi.at( i - 1 ).count( rule.first ) ) {
-				for( const auto & rhs : rule.second ) {
-					Vi.at( i ).insert( rhs.begin( ), rhs.end( ) );
-				}
-			}
-		}
-
-
-		if( Vi.at( i ) == Vi.at( i - 1 ) )
-			break;
-
-		i = i + 1;
-	}
-
-	// 3.
-	return Vi.at( i );
-}
-
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::CFG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::GNF & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::CNF & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::LG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::LeftLG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::LeftRG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::RightLG & grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getUnreachableSymbols( const grammar::RightRG & grammar );
-
-template<class T>
-std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals(const T& grammar) {
-	std::deque<std::set<alphabet::Symbol>> Ni;
-
-	Ni.push_back(std::set<alphabet::Symbol>{ });
-	int i = 1;
-
-	while(true) {
-		Ni.push_back(std::set<alphabet::Symbol>{ });
-		for(const auto& rule : grammar.getRawRules()) {
-			for(const auto& rhs : rule.second) {
-				if(rhs.size() == 0 || std::all_of(rhs.begin(), rhs.end(), [Ni, i](const alphabet::Symbol& symb){return Ni.at(i-1).count(symb);})) {
-					Ni.at(i).insert(rule.first);
-				}
-			}
-		}
-
-		if(Ni.at(i) == Ni.at(i-1))
-			break;
-
-		i += 1;
-	}
-
-	return Ni.at(i);
-}
-
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::CFG& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::EpsilonFreeCFG& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::GNF& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::CNF& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LG& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LeftLG& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::LeftRG& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::RightLG& grammar );
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNullableNonterminals( const grammar::RightRG& grammar );
-
-template<class T>
-std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal) {
-	if(grammar.getNonterminalAlphabet().count(nonterminal) == 0) {
-		throw exception::AlibException("Nonterminal symbol \"" + (std::string) nonterminal + "\" is not present in grammar.");
-	}
-
-	std::deque<std::set<alphabet::Symbol>> Ni;
-	Ni.push_back(std::set<alphabet::Symbol>{nonterminal});
-	int i = 1;
-
-	while(true) {
-		Ni.push_back(Ni.at(i-1));
-		for(const auto&rule : grammar.getRawRules()) {
-			const alphabet::Symbol& lhs = rule.first;
-
-			for(const auto& rhs : rule.second) {
-				if(Ni.at(i-1).count(lhs) && rhs.size() == 1 && grammar.getNonterminalAlphabet().count(rhs.front())) {
-					Ni.at(i).insert(rhs.front());
-				}
-			}
-		}
-
-		if(Ni.at(i) == Ni.at(i-1))
-			break;
-		
-		i += 1;
-	}
-
-	return Ni.at(i);
-}
-
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::CFG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::EpsilonFreeCFG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::GNF& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::CNF& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LeftLG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::LeftRG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::RightLG& grammar, const alphabet::Symbol& nonterminal);
-template std::set<alphabet::Symbol> GrammarPropertiesCFG::getNonterminalUnitRuleCycle(const grammar::RightRG& grammar, const alphabet::Symbol& nonterminal);
-
-} /* namespace grammar */
diff --git a/alib2algo/src/grammar/GrammarPropertiesCFG.h b/alib2algo/src/grammar/GrammarPropertiesCFG.h
deleted file mode 100644
index 4cf05c9cce7e2373c36b3b66836f887c67904e4d..0000000000000000000000000000000000000000
--- a/alib2algo/src/grammar/GrammarPropertiesCFG.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * GrammarPropertiesCFG.h
- *
- *  Created on: 22. 3. 2014
- *	  Author: Tomas Pecka
- */
-
-#ifndef GRAMMAR_PROPERTIES_CFG_H_
-#define GRAMMAR_PROPERTIES_CFG_H_
-
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <exception/AlibException.h>
-
-#include <alphabet/Symbol.h>
-
-namespace grammar {
-
-/**
- * Implements algorithms from Melichar, chapter 3.3
- */
-class GrammarPropertiesCFG {
-public:
-	/**
-	 * Implements steps 1 through 3 in Melichar 3.6
-	 */
-	template<class T>
-	static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar );
-
-	/**
-	 * Implements
-	 */
-	template<class T>
-	static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar );
-
-	/**
-	 * Retrieve all nullable nonterminals from grammar
-	 * Nullable nonterminal is such nonterminal A for which holds that A ->^* \eps
-	 *
-	 * Source: Melichar, algorithm 2.4, step 1
-	 *
-	 * @param grammar grammar
-	 * @return set of nullable nonterminals from grammar
-	 */
-	template<class T>
-	static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar);
-
-	/**
-	 * Retrieves set N = {B : A->^* B} for given grammar and nonterminal
-	 *
-	 * Source: Melichar, algorithm 2.6, step 1
-	 *
-	 * @param grammar grammar
-	 * @param nonterminal nonterminal
-	 * @return set of nonterminals for which we can be derived from giveUnitRuleCyclen nonterminals in finite number of steps
-	 */
-	template<class T>
-	static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal);
-};
-
-} /* namespace grammar */
-
-#endif /* GRAMMAR_PROPERTIES_CFG_H_ */
diff --git a/alib2algo/src/grammar/convert/ToAutomaton.cpp b/alib2algo/src/grammar/convert/ToAutomaton.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68a1e5ca4721c510c9928adbbd2f66827f8e6ce6
--- /dev/null
+++ b/alib2algo/src/grammar/convert/ToAutomaton.cpp
@@ -0,0 +1,182 @@
+/*
+ * ToAutomaton.cpp
+ *
+ * Created on: 1. 11. 2013
+ * Author: Tomas Pecka
+ */
+#include "ToAutomaton.h"
+
+#include <alphabet/LabeledSymbol.h>
+#include <exception/AlibException.h>
+
+namespace grammar {
+
+namespace convert {
+
+automaton::Automaton ToAutomaton::convert(const grammar::Grammar& grammar)
+{
+	 automaton::Automaton* out = NULL;
+	 grammar.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON);
+	 automaton::Automaton res = std::move(*out);
+	 delete out;
+	 return res;
+}
+
+automaton::NFA ToAutomaton::convert(const grammar::LeftRG& grammar)
+{
+	std::map<alphabet::Symbol, automaton::State> stateMap;
+	std::set<automaton::State> states;
+
+	// step 2
+	for(const auto& symbol : grammar.getNonterminalAlphabet())
+	{
+		automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
+		states.insert(state);
+		stateMap.insert(std::make_pair(symbol, state));
+	}
+
+	// step 1, 4
+	const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states);
+	states.insert(q0);
+	automaton::NFA automaton(q0);
+	automaton.setInputSymbols(grammar.getTerminalAlphabet());
+	automaton.setStates(states);
+
+	// step 3
+	for(const auto& rule : grammar.getRules())
+	{
+		const alphabet::Symbol& lhs = rule.first;
+		for(const auto& ruleRHS : rule.second)
+		{
+			if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B
+			{
+				const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
+				automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second);
+			}
+			else // if B->a => \delta(StartState,a)=B
+			{
+				const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
+				automaton.addTransition(q0, rhs, stateMap.find(lhs)->second);
+			}
+		}
+	}
+
+	// step 5
+	automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second);
+	if(grammar.getGeneratesEpsilon())
+		automaton.addFinalState(q0);
+
+	return automaton;
+}
+
+automaton::NFA ToAutomaton::convert(const grammar::RightRG& grammar)
+{
+	std::map<alphabet::Symbol, automaton::State> stateMap;
+	std::set<automaton::State> states;
+
+	// step2
+	for(const auto& symbol : grammar.getNonterminalAlphabet())
+	{
+		automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
+		states.insert(state);
+		stateMap.insert(std::make_pair(symbol, state));
+	}
+
+	// step 1, 4
+	const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states);
+	states.insert(AState);
+	automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second);
+	automaton.setStates(states);
+
+	automaton.setInputSymbols(grammar.getTerminalAlphabet());
+
+	// step 3
+	for(const auto& rule : grammar.getRules())
+	{
+		const alphabet::Symbol& lhs = rule.first;
+		for(const auto& ruleRHS : rule.second)
+		{
+			if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C
+			{
+				const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
+				automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second);
+			}
+			else // if B->a => \delta(B,a)=AState
+			{
+				const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
+				automaton.addTransition(stateMap.find(lhs)->second, rhs, AState);
+			}
+		}
+	}
+
+	// step 5
+	automaton.addFinalState(AState);
+	if(grammar.getGeneratesEpsilon())
+		automaton.addFinalState(automaton.getInitialState());
+
+	return automaton;
+}
+
+void ToAutomaton::Visit(void* userData, const grammar::RightRG& grammar) const
+{
+	automaton::Automaton* & out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(grammar));
+}
+
+void ToAutomaton::Visit(void* userData, const grammar::LeftRG& grammar) const
+{
+	automaton::Automaton* & out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(grammar));
+}
+
+void ToAutomaton::Visit(void*, const grammar::RightLG&) const
+{
+	throw exception::AlibException("Unsupported grammar type RightLG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::LeftLG&) const
+{
+	throw exception::AlibException("Unsupported grammar type LeftLG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::LG& ) const {
+	throw exception::AlibException("Unsupported grammar type LG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::CFG& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::EpsilonFreeCFG& ) const {
+	throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::CNF& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::GNF& ) const {
+	throw exception::AlibException("Unsupported grammar type GNF");
+}
+
+void ToAutomaton::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void ToAutomaton::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void ToAutomaton::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const ToAutomaton ToAutomaton::TO_AUTOMATON;
+
+} /* namespace convert */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/convert/ToAutomaton.h b/alib2algo/src/grammar/convert/ToAutomaton.h
new file mode 100644
index 0000000000000000000000000000000000000000..aeea0edfbc22db86bffd7dabf90e228e9088455c
--- /dev/null
+++ b/alib2algo/src/grammar/convert/ToAutomaton.h
@@ -0,0 +1,60 @@
+/*
+ * ToAutomaton.h
+ *
+ * Created on: 1. 11. 2013
+ * Author: Tomas Pecka
+ */
+
+#ifndef _GRAMMAR_TO_AUTOMATON_H_
+#define _GRAMMAR_TO_AUTOMATON_H_
+
+#include <grammar/Grammar.h>
+#include <grammar/Regular/LeftRG.h>
+#include <grammar/Regular/RightRG.h>
+
+#include <automaton/Automaton.h>
+#include <automaton/FSM/NFA.h>
+
+namespace grammar {
+
+namespace convert {
+
+/**
+ * Converts regular grammar to nondeterministic finite automaton.
+ * Sources: Melichar 2.98 (RightRG -> NFA) and 2.102 (LeftRG -> NFA).
+ */
+class ToAutomaton : public grammar::VisitableGrammarBase::const_visitor_type {
+public:
+	/**
+	 * Performs conversion.
+	 * @param grammar Regular grammar to convert.
+	 * @return FSM equivalent to source grammar.
+	 */
+	static automaton::Automaton convert(const grammar::Grammar& grammar);
+
+	static automaton::NFA convert(const grammar::LeftRG& grammar);
+	static automaton::NFA convert(const grammar::RightRG& grammar);
+
+private:
+	void Visit(void*, const grammar::RightRG& grammar) const;
+	void Visit(void*, const grammar::LeftRG& grammar) const;
+	void Visit(void*, const grammar::RightLG& grammar) const;
+	void Visit(void*, const grammar::LeftLG& 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 ToAutomaton TO_AUTOMATON;
+};
+
+} /* namespace convert */
+
+} /* namespace grammar */
+
+#endif /* _GRAMMAR_TO_AUTOMATON_H_ */
diff --git a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.cpp b/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp
similarity index 72%
rename from alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.cpp
rename to alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp
index 71bbf621fc4a4eed164601a6e0303c0b38db0645..e0eaa76cc0562710eb82fc113ee8680d30d336c3 100644
--- a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.cpp
+++ b/alib2algo/src/grammar/convert/ToGrammarLeftRG.cpp
@@ -1,30 +1,28 @@
 /*
- * RightToLeftRegularGrammar.cpp
+ * ToGrammarLeftRG.cpp
  *
  *  Created on: 8. 3. 2014
  *      Author: Tomas Pecka
  */
 
-#include "RightToLeftRegularGrammar.h"
+#include "ToGrammarLeftRG.h"
 
 #include <exception/AlibException.h>
 
-namespace conversions
-{
+namespace grammar {
 
-namespace rg2rg
-{
+namespace convert {
 
-grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::Grammar& grammar)
+grammar::LeftRG ToGrammarLeftRG::convert(const grammar::Grammar& grammar)
 {
 	grammar::LeftRG* out = NULL;
-	grammar.getData().Accept((void*) &out, RightToLeftRegularGrammar::RIGHT_TO_LEFT_REGULAR_GRAMMAR);
+	grammar.getData().Accept((void*) &out, ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG);
 	grammar::LeftRG res = std::move(*out);
 	delete out;
 	return res;
 }
 
-grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::RightRG& grammar)
+grammar::LeftRG ToGrammarLeftRG::convert(const grammar::RightRG& grammar)
 {
 	// 1.
 	alphabet::Symbol s = alphabet::createUniqueSymbol( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() );
@@ -73,30 +71,30 @@ grammar::LeftRG RightToLeftRegularGrammar::convert(const grammar::RightRG& gramm
 	return lrg;
 }
 
-void RightToLeftRegularGrammar::Visit(void* userData, const grammar::RightRG& grammar) const
+void ToGrammarLeftRG::Visit(void* userData, const grammar::RightRG& grammar) const
 {
 	grammar::LeftRG* & out = *((grammar::LeftRG**) userData);
 	out = new grammar::LeftRG(this->convert(grammar));
 }
 
-void RightToLeftRegularGrammar::Visit(void*, const grammar::LeftRG&) const
+void ToGrammarLeftRG::Visit(void*, const grammar::LeftRG&) const
 {
 	throw exception::AlibException("Unsupported grammar type RightRG");
 }
 
-void RightToLeftRegularGrammar::Visit(void*, const grammar::RightLG&) const
+void ToGrammarLeftRG::Visit(void*, const grammar::RightLG&) const
 {
 	throw exception::AlibException("Unsupported grammar type RightLG");
 }
 
-void RightToLeftRegularGrammar::Visit(void*, const grammar::LeftLG&) const
+void ToGrammarLeftRG::Visit(void*, const grammar::LeftLG&) const
 {
 	throw exception::AlibException("Unsupported grammar type LeftLG");
 }
 
-const RightToLeftRegularGrammar RightToLeftRegularGrammar::RIGHT_TO_LEFT_REGULAR_GRAMMAR;
+const ToGrammarLeftRG ToGrammarLeftRG::TO_GRAMMAR_LEFT_RG;
 
 
-} /* namespace rg2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace grammar */
diff --git a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.h b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h
similarity index 67%
rename from alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.h
rename to alib2algo/src/grammar/convert/ToGrammarLeftRG.h
index a965dc3926751e910b2a6efe2749e59512b254fe..58648f091a7eb5a12177d5a430586a270cc6a96b 100644
--- a/alib2algo/src/conversions/rg2rg/RightToLeftRegularGrammar.h
+++ b/alib2algo/src/grammar/convert/ToGrammarLeftRG.h
@@ -1,27 +1,25 @@
 /*
- * RightToLeftRegularGrammar.h
+ * ToGrammarLeftRG.h
  *
  *  Created on: 8. 3. 2014
  *      Author: Tomas Pecka
  */
 
-#ifndef RIGHT_TO_LEFT_REGULAR_GRAMMAR_H_
-#define RIGHT_TO_LEFT_REGULAR_GRAMMAR_H_
+#ifndef TO_GRAMMAR_LEFT_RG_H_
+#define TO_GRAMMAR_LEFT_RG_H_
 
 #include <grammar/Grammar.h>
 #include <grammar/Regular/LeftRG.h>
 #include <grammar/Regular/RightRG.h>
 
-namespace conversions
-{
+namespace grammar {
 
-namespace rg2rg
-{
+namespace convert {
 
 /**
  * Converts right regular grammar to left regular grammar.
  */
-class RightToLeftRegularGrammar : public grammar::VisitableConstRGBase
+class ToGrammarLeftRG : public grammar::VisitableConstRGBase
 {
 public:
     /**
@@ -38,11 +36,11 @@ private:
     void Visit(void*, const grammar::RightLG& grammar) const;
     void Visit(void*, const grammar::LeftLG& grammar) const;
 
-    static const RightToLeftRegularGrammar RIGHT_TO_LEFT_REGULAR_GRAMMAR;
+    static const ToGrammarLeftRG TO_GRAMMAR_LEFT_RG;
 };
 
-} /* namespace rg2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace grammar */
 
-#endif /* RIGHT_TO_LEFT_REGULAR_GRAMMAR_H_ */
+#endif /* TO_GRAMMAR_LEFT_RG_H_ */
diff --git a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.cpp b/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp
similarity index 72%
rename from alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.cpp
rename to alib2algo/src/grammar/convert/ToGrammarRightRG.cpp
index b784f0e5c03890be0b380aa067aeda5303706257..ae81d66fb1c4aa033c50964d9ecd8414199d9a24 100644
--- a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.cpp
+++ b/alib2algo/src/grammar/convert/ToGrammarRightRG.cpp
@@ -1,28 +1,28 @@
 /*
- * LeftToRightRegularGrammar.cpp
+ * ToGrammarRightRG.cpp
  *
  *  Created on: 8. 3. 2014
  *      Author: Tomas Pecka
  */
 
-#include "LeftToRightRegularGrammar.h"
+#include "ToGrammarRightRG.h"
 
 #include <exception/AlibException.h>
 
-namespace conversions {
+namespace grammar {
 
-namespace rg2rg {
+namespace convert {
 
-grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::Grammar& grammar)
+grammar::RightRG ToGrammarRightRG::convert(const grammar::Grammar& grammar)
 {
 	grammar::RightRG* out = NULL;
-	grammar.getData().Accept((void*) &out, LeftToRightRegularGrammar::LEFT_TO_RIGHT_REGULAR_GRAMMAR);
+	grammar.getData().Accept((void*) &out, ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG);
 	grammar::RightRG res = std::move(*out);
 	delete out;
 	return res;
 }
 
-grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::LeftRG& grammar)
+grammar::RightRG ToGrammarRightRG::convert(const grammar::LeftRG& grammar)
 {
 	// 1.
 	alphabet::Symbol s = alphabet::createUniqueSymbol( grammar.getInitialSymbol( ), grammar.getNonterminalAlphabet(), grammar.getTerminalAlphabet() );
@@ -71,29 +71,29 @@ grammar::RightRG LeftToRightRegularGrammar::convert(const grammar::LeftRG& gramm
 	return rrg;
 }
 
-void LeftToRightRegularGrammar::Visit(void*, const grammar::RightRG&) const
+void ToGrammarRightRG::Visit(void*, const grammar::RightRG&) const
 {
 	throw exception::AlibException("Unsupported grammar type RightRG");
 }
 
-void LeftToRightRegularGrammar::Visit(void* userData, const grammar::LeftRG& grammar) const
+void ToGrammarRightRG::Visit(void* userData, const grammar::LeftRG& grammar) const
 {
 	grammar::RightRG* & out = *((grammar::RightRG**) userData);
 	out = new grammar::RightRG(this->convert(grammar));
 }
 
-void LeftToRightRegularGrammar::Visit(void*, const grammar::RightLG&) const
+void ToGrammarRightRG::Visit(void*, const grammar::RightLG&) const
 {
 	throw exception::AlibException("Unsupported grammar type RightLG");
 }
 
-void LeftToRightRegularGrammar::Visit(void*, const grammar::LeftLG&) const
+void ToGrammarRightRG::Visit(void*, const grammar::LeftLG&) const
 {
 	throw exception::AlibException("Unsupported grammar type LeftLG");
 }
 
-const LeftToRightRegularGrammar LeftToRightRegularGrammar::LEFT_TO_RIGHT_REGULAR_GRAMMAR;
+const ToGrammarRightRG ToGrammarRightRG::TO_GRAMMAR_RIGHT_RG;
 
-} /* namespace rg2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace grammar */
diff --git a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.h b/alib2algo/src/grammar/convert/ToGrammarRightRG.h
similarity index 67%
rename from alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.h
rename to alib2algo/src/grammar/convert/ToGrammarRightRG.h
index 350eef77aa296b3291b26245aed3e4399bd156c9..468b72aa3a8fac45598d0d68ce16fafce45ab5af 100644
--- a/alib2algo/src/conversions/rg2rg/LeftToRightRegularGrammar.h
+++ b/alib2algo/src/grammar/convert/ToGrammarRightRG.h
@@ -1,26 +1,25 @@
 /*
- * LeftToRightRegularGrammar.h
+ * ToGrammarRightRG.h
  *
  *  Created on: 8. 3. 2014
  *      Author: Tomas Pecka
  */
 
-#ifndef LEFT_TORIGHT_REGULAR_GRAMMAR_H_
-#define LEFT_TORIGHT_REGULAR_GRAMMAR_H_
+#ifndef TO_GRAMMAR_RIGHT_RG_H_
+#define TO_GRAMMAR_RIGHT_RG_H_
 
 #include <grammar/Grammar.h>
 #include <grammar/Regular/LeftRG.h>
 #include <grammar/Regular/RightRG.h>
 
-namespace conversions{
+namespace grammar {
 
-namespace rg2rg
-{
+namespace convert {
 
 /**
  * Converts left regular grammar to right regular grammar.
  */
-class LeftToRightRegularGrammar : public grammar::VisitableConstRGBase
+class ToGrammarRightRG : public grammar::VisitableConstRGBase
 {
 public:
    /**
@@ -37,11 +36,11 @@ private:
     void Visit(void*, const grammar::RightLG& grammar) const;
     void Visit(void*, const grammar::LeftLG& grammar) const;
 
-    static const LeftToRightRegularGrammar LEFT_TO_RIGHT_REGULAR_GRAMMAR;
+    static const ToGrammarRightRG TO_GRAMMAR_RIGHT_RG;
 };
 
-} /* namespace rg2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace grammar */
 
-#endif /* LEFT_TO_RIGHT_REGULAR_GRAMMAR_H_ */
+#endif /* TO_GRAMMAR_RIGHT_RG_H_ */
diff --git a/alib2algo/src/grammar/convert/ToRegExp.cpp b/alib2algo/src/grammar/convert/ToRegExp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fe2696f7f470e2e5c5dd274ab6bd0b2e437d3339
--- /dev/null
+++ b/alib2algo/src/grammar/convert/ToRegExp.cpp
@@ -0,0 +1,87 @@
+/*
+ * ToRegExp.cpp
+ *
+ *  Created on: 4. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "ToRegExp.h"
+#include "ToRegExpAlgebraic.h"
+#include <exception/AlibException.h>
+
+namespace grammar {
+
+namespace convert {
+
+regexp::RegExp ToRegExp::convert(const grammar::Grammar& grammar)
+{
+	regexp::RegExp* out = NULL;
+	grammar.getData().Accept((void*) &out, ToRegExp::TO_REG_EXP);
+	regexp::RegExp res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToRegExp::Visit(void* userData, const grammar::RightRG& grammar) const
+{
+	regexp::RegExp* & out = *((regexp::RegExp**) userData);
+	out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar));
+}
+
+void ToRegExp::Visit(void* userData, const grammar::LeftRG& grammar) const
+{
+	regexp::RegExp* & out = *((regexp::RegExp**) userData);
+	out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar));
+}
+
+void ToRegExp::Visit(void*, const grammar::RightLG&) const
+{
+	throw exception::AlibException("Unsupported grammar type RightLG");
+}
+
+void ToRegExp::Visit(void*, const grammar::LeftLG&) const
+{
+	throw exception::AlibException("Unsupported grammar type LeftLG");
+}
+
+void ToRegExp::Visit(void*, const grammar::LG& ) const {
+	throw exception::AlibException("Unsupported grammar type LG");
+}
+
+void ToRegExp::Visit(void*, const grammar::CFG& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToRegExp::Visit(void*, const grammar::EpsilonFreeCFG& ) const {
+	throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG");
+}
+
+void ToRegExp::Visit(void*, const grammar::CNF& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToRegExp::Visit(void*, const grammar::GNF& ) const {
+	throw exception::AlibException("Unsupported grammar type GNF");
+}
+
+void ToRegExp::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void ToRegExp::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void ToRegExp::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void ToRegExp::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const ToRegExp ToRegExp::TO_REG_EXP;
+
+} /* namespace convert */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/convert/ToRegExp.h b/alib2algo/src/grammar/convert/ToRegExp.h
new file mode 100644
index 0000000000000000000000000000000000000000..aace07b45d5fbccc3876959de1977eed6b8900ba
--- /dev/null
+++ b/alib2algo/src/grammar/convert/ToRegExp.h
@@ -0,0 +1,52 @@
+/*
+ * ToRegExp.h
+ *
+ *  Created on: 4. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef GRAMMAR_TO_REG_EXP_H_
+#define GRAMMAR_TO_REG_EXP_H_
+
+#include <grammar/Grammar.h>
+#include <grammar/Regular/RightRG.h>
+#include <grammar/Regular/LeftRG.h>
+
+#include <regexp/RegExp.h>
+
+namespace grammar {
+
+namespace convert {
+
+class ToRegExp : public grammar::VisitableConstRGBase
+{
+public:
+	/**
+	 * @return regexp equivalent to source right regular grammar.
+	 * @param grammar Grammar to convert
+	 */
+	static regexp::RegExp convert(const grammar::Grammar& grammar);
+
+protected:
+	void Visit(void*, const grammar::RightRG& grammar) const;
+	void Visit(void*, const grammar::LeftRG& grammar) const;
+	void Visit(void*, const grammar::RightLG& grammar) const;
+	void Visit(void*, const grammar::LeftLG& 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 ToRegExp TO_REG_EXP;
+};
+
+} /* namespace covert */
+
+} /* namespace grammar */
+
+#endif /* GRAMMAR_TO_REG_EXP_H_ */
diff --git a/alib2algo/src/conversions/rg2re/Algebraic.cpp b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp
similarity index 77%
rename from alib2algo/src/conversions/rg2re/Algebraic.cpp
rename to alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp
index cdef84a2159881e4153bc58198207787efdb4982..5deb9296f085beec26595d62bf97aa986aac94c4 100644
--- a/alib2algo/src/conversions/rg2re/Algebraic.cpp
+++ b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.cpp
@@ -1,11 +1,11 @@
 /*
- * Algebraic.cpp
+ * ToRegExpAlgebraic.cpp
  *
  *  Created on: 4. 3. 2014
  *      Author: Tomas Pecka
  */
 
-#include "Algebraic.h"
+#include "ToRegExpAlgebraic.h"
 
 #include "../../equations/LeftRegularEquationSolver.h"
 #include "../../equations/RightRegularEquationSolver.h"
@@ -13,22 +13,20 @@
 #include <exception/AlibException.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
 
-namespace conversions
-{
+namespace grammar {
 
-namespace rg2re
-{
+namespace convert {
 
-regexp::RegExp Algebraic::convert(const grammar::Grammar& grammar)
+regexp::RegExp ToRegExpAlgebraic::convert(const grammar::Grammar& grammar)
 {
     regexp::RegExp* out = NULL;
-    grammar.getData().Accept((void*) &out, Algebraic::RG_TO_RE_ALGEBRAIC);
+    grammar.getData().Accept((void*) &out, ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC);
     regexp::RegExp res = std::move(*out);
     delete out;
     return res;
 }
 
-regexp::RegExp Algebraic::convert(const grammar::LeftRG& grammar)
+regexp::RegExp ToRegExpAlgebraic::convert(const grammar::LeftRG& grammar)
 {
     equations::LeftRegularEquationSolver solver;
 
@@ -58,7 +56,7 @@ regexp::RegExp Algebraic::convert(const grammar::LeftRG& grammar)
 
     return regexp::RegExp{solver.solve(grammar.getInitialSymbol())};
 }
-regexp::RegExp Algebraic::convert(const grammar::RightRG& grammar)
+regexp::RegExp ToRegExpAlgebraic::convert(const grammar::RightRG& grammar)
 {
     equations::RightRegularEquationSolver solver;
 
@@ -89,30 +87,30 @@ regexp::RegExp Algebraic::convert(const grammar::RightRG& grammar)
     return regexp::RegExp{solver.solve(grammar.getInitialSymbol())};
 }
 
-void Algebraic::Visit(void* userData, const grammar::RightRG& grammar) const
+void ToRegExpAlgebraic::Visit(void* userData, const grammar::RightRG& grammar) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) userData);
     out = new regexp::RegExp(this->convert(grammar));
 }
 
-void Algebraic::Visit(void* userData, const grammar::LeftRG& grammar) const
+void ToRegExpAlgebraic::Visit(void* userData, const grammar::LeftRG& grammar) const
 {
     regexp::RegExp* & out = *((regexp::RegExp**) userData);
     out = new regexp::RegExp(this->convert(grammar));
 }
 
-void Algebraic::Visit(void*, const grammar::RightLG&) const
+void ToRegExpAlgebraic::Visit(void*, const grammar::RightLG&) const
 {
     throw exception::AlibException("Unsupported grammar type RightLG");
 }
 
-void Algebraic::Visit(void*, const grammar::LeftLG&) const
+void ToRegExpAlgebraic::Visit(void*, const grammar::LeftLG&) const
 {
     throw exception::AlibException("Unsupported grammar type LeftLG");
 }
 
-const Algebraic Algebraic::RG_TO_RE_ALGEBRAIC;
+const ToRegExpAlgebraic ToRegExpAlgebraic::TO_REG_EXP_ALGEBRAIC;
 
-} /* namespace rg2re */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace grammar */
diff --git a/alib2algo/src/conversions/rg2re/Algebraic.h b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.h
similarity index 69%
rename from alib2algo/src/conversions/rg2re/Algebraic.h
rename to alib2algo/src/grammar/convert/ToRegExpAlgebraic.h
index bd4741d891fc06927fcda73a3a6b229978bc165f..3370fc3dfd51c874edf9cefb109710e21294ab74 100644
--- a/alib2algo/src/conversions/rg2re/Algebraic.h
+++ b/alib2algo/src/grammar/convert/ToRegExpAlgebraic.h
@@ -1,12 +1,12 @@
 /*
- * Algebraic.h
+ * ToRegExpAlgebraic.h
  *
  *  Created on: 4. 3. 2014
  *      Author: Tomas Pecka
  */
 
-#ifndef RG2RE_ALGEBRAIC_H_
-#define RG2RE_ALGEBRAIC_H_
+#ifndef GRAMMAR_TO_REG_EXP_ALGEBRAIC_H_
+#define GRAMMAR_TO_REG_EXP_ALGEBRAIC_H_
 
 #include <grammar/Grammar.h>
 #include <grammar/Regular/RightRG.h>
@@ -14,13 +14,11 @@
 
 #include <regexp/RegExp.h>
 
-namespace conversions
-{
+namespace grammar {
 
-namespace rg2re
-{
+namespace convert {
 
-class Algebraic : public grammar::VisitableConstRGBase
+class ToRegExpAlgebraic : public grammar::VisitableConstRGBase
 {
 public:
     /**
@@ -38,11 +36,11 @@ protected:
     void Visit(void*, const grammar::RightLG& grammar) const;
     void Visit(void*, const grammar::LeftLG& grammar) const;
 
-    static const Algebraic RG_TO_RE_ALGEBRAIC;
+    static const ToRegExpAlgebraic TO_REG_EXP_ALGEBRAIC;
 };
 
-} /* namespace rg2re */
+} /* namespace covert */
 
-} /* namespace conversions */
+} /* namespace grammar */
 
-#endif /* RG2RE_ALGEBRAIC_H_ */
+#endif /* GRAMMAR_TO_REG_EXP_ALGEBRAIC_H_ */
diff --git a/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05d5808b08149ce611ada0968a2e3cd19622057b
--- /dev/null
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.cpp
@@ -0,0 +1,46 @@
+/*
+ * IsLanguageEmpty.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "IsLanguageEmpty.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+#include "../properties/ProductiveNonterminals.h"
+
+namespace grammar {
+
+namespace properties {
+
+template<class T>
+bool IsLanguageEmpty::isLanguageEmpty( const T & grammar ) {
+	return grammar::properties::ProductiveNonterminals::getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
+}
+
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CFG & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::EpsilonFreeCFG & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::GNF & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::CNF & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LG & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftLG & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::LeftRG & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightLG & grammar );
+template bool IsLanguageEmpty::isLanguageEmpty( const grammar::RightRG & grammar );
+
+} /* namespace properties */
+
+} /* namespace grammar */
+
diff --git a/alib2algo/src/language/grammar/LanguagePropertiesCFG.h b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
similarity index 68%
rename from alib2algo/src/language/grammar/LanguagePropertiesCFG.h
rename to alib2algo/src/grammar/properties/IsLanguageEmpty.h
index 5029d5be546d403d6382d25f6b89512955ed1075..8aa3a2e13571e57acb11635b84c3ef7760539d5e 100644
--- a/alib2algo/src/language/grammar/LanguagePropertiesCFG.h
+++ b/alib2algo/src/grammar/properties/IsLanguageEmpty.h
@@ -1,12 +1,12 @@
 /*
- * LanguagePropertiesCFG.h
+ * IsLanguageEmpty.h
  *
  *  Created on: 22. 3. 2014
  *	  Author: Tomas Pecka
  */
 
-#ifndef LANGUAGE_PROPERTIED_CFG_H_
-#define LANGUAGE_PROPERTIED_CFG_H_
+#ifndef IS_LANGUAGE_EMPTY_H_
+#define IS_LANGUAGE_EMPTY_H_
 
 #include <algorithm>
 #include <deque>
@@ -16,12 +16,14 @@
 
 #include <alphabet/Symbol.h>
 
-namespace language {
+namespace grammar {
+
+namespace properties {
 
 /**
  * Implements algorithms from Melichar, chapter 3.3
  */
-class LanguagePropertiesCFG {
+class IsLanguageEmpty {
 public:
 	/*
 	 * Melichar 3.6 - decides whether L( grammar ) = \0
@@ -33,6 +35,8 @@ public:
 	static bool isLanguageEmpty( const T & grammar );
 };
 
-}
+} /* namespace properties */
+
+} /* namespace grammar */
 
-#endif /* LANGUAGE_PROPERTIED_CFG_H_ */
+#endif /* IS_LANGUAGE_EMPTY_H_ */
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2a4fbdd79ae93ac25e67a69d80638b49bb8cb4a7
--- /dev/null
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.cpp
@@ -0,0 +1,69 @@
+/*
+ * NonterminalUnitRuleCycle.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "NonterminalUnitRuleCycle.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+namespace grammar {
+
+namespace properties {
+
+template<class T>
+std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal) {
+	if(grammar.getNonterminalAlphabet().count(nonterminal) == 0) {
+		throw exception::AlibException("Nonterminal symbol \"" + (std::string) nonterminal + "\" is not present in grammar.");
+	}
+
+	std::deque<std::set<alphabet::Symbol>> Ni;
+	Ni.push_back(std::set<alphabet::Symbol>{nonterminal});
+	int i = 1;
+
+	while(true) {
+		Ni.push_back(Ni.at(i-1));
+		for(const auto&rule : grammar.getRawRules()) {
+			const alphabet::Symbol& lhs = rule.first;
+
+			for(const auto& rhs : rule.second) {
+				if(Ni.at(i-1).count(lhs) && rhs.size() == 1 && grammar.getNonterminalAlphabet().count(rhs.front())) {
+					Ni.at(i).insert(rhs.front());
+				}
+			}
+		}
+
+		if(Ni.at(i) == Ni.at(i-1))
+			break;
+		
+		i += 1;
+	}
+
+	return Ni.at(i);
+}
+
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CFG& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::EpsilonFreeCFG& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::GNF& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::CNF& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LG& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftLG& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::LeftRG& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightLG& grammar, const alphabet::Symbol& nonterminal);
+template std::set<alphabet::Symbol> NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(const grammar::RightRG& grammar, const alphabet::Symbol& nonterminal);
+
+} /* namespace properties */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
new file mode 100644
index 0000000000000000000000000000000000000000..2bfd991526c5a8844ff84ce607e69e3aac43f4e4
--- /dev/null
+++ b/alib2algo/src/grammar/properties/NonterminalUnitRuleCycle.h
@@ -0,0 +1,45 @@
+/*
+ * NonterminalUnitRuleCycle.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef NONTERMINAL_UNIT_RULE_CYCLE_H_
+#define NONTERMINAL_UNIT_RULE_CYCLE_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+
+#include <alphabet/Symbol.h>
+
+namespace grammar {
+
+namespace properties {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class NonterminalUnitRuleCycle {
+public:
+	/**
+	 * Retrieves set N = {B : A->^* B} for given grammar and nonterminal
+	 *
+	 * Source: Melichar, algorithm 2.6, step 1
+	 *
+	 * @param grammar grammar
+	 * @param nonterminal nonterminal
+	 * @return set of nonterminals for which we can be derived from giveUnitRuleCyclen nonterminals in finite number of steps
+	 */
+	template<class T>
+	static std::set<alphabet::Symbol> getNonterminalUnitRuleCycle(const T& grammar, const alphabet::Symbol& nonterminal);
+};
+
+} /* namespace properties */
+
+} /* namespace grammar */
+
+#endif /* NONTERMINAL_UNIT_RULE_CYCLE_H_ */
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.cpp b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f61bf0b691d641f468f5861ca8199e85089be365
--- /dev/null
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.cpp
@@ -0,0 +1,64 @@
+/*
+ * NullableNonterminals.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "NullableNonterminals.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+namespace grammar {
+
+namespace properties {
+
+template<class T>
+std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals(const T& grammar) {
+	std::deque<std::set<alphabet::Symbol>> Ni;
+
+	Ni.push_back(std::set<alphabet::Symbol>{ });
+	int i = 1;
+
+	while(true) {
+		Ni.push_back(std::set<alphabet::Symbol>{ });
+		for(const auto& rule : grammar.getRawRules()) {
+			for(const auto& rhs : rule.second) {
+				if(rhs.size() == 0 || std::all_of(rhs.begin(), rhs.end(), [Ni, i](const alphabet::Symbol& symb){return Ni.at(i-1).count(symb);})) {
+					Ni.at(i).insert(rule.first);
+				}
+			}
+		}
+
+		if(Ni.at(i) == Ni.at(i-1))
+			break;
+
+		i += 1;
+	}
+
+	return Ni.at(i);
+}
+
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CFG& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::EpsilonFreeCFG& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::GNF& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::CNF& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LG& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftLG& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::LeftRG& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightLG& grammar );
+template std::set<alphabet::Symbol> NullableNonterminals::getNullableNonterminals( const grammar::RightRG& grammar );
+
+} /* namespace properties */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/NullableNonterminals.h b/alib2algo/src/grammar/properties/NullableNonterminals.h
new file mode 100644
index 0000000000000000000000000000000000000000..c80c3b9bf83f4b43dd8db91c5cdd6759dd71d623
--- /dev/null
+++ b/alib2algo/src/grammar/properties/NullableNonterminals.h
@@ -0,0 +1,45 @@
+/*
+ * NullableNonterminals.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef NULLABLE_NONTERMINALS_H_
+#define NULLABLE_NONTERMINALS_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+
+#include <alphabet/Symbol.h>
+
+namespace grammar {
+
+namespace properties {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class NullableNonterminals {
+public:
+	/**
+	 * Retrieve all nullable nonterminals from grammar
+	 * Nullable nonterminal is such nonterminal A for which holds that A ->^* \eps
+	 *
+	 * Source: Melichar, algorithm 2.4, step 1
+	 *
+	 * @param grammar grammar
+	 * @return set of nullable nonterminals from grammar
+	 */
+	template<class T>
+	static std::set<alphabet::Symbol> getNullableNonterminals(const T& grammar);
+};
+
+} /* namespace properties */
+
+} /* namespace grammar */
+
+#endif /* NULLABLE_NONTERMINALS_H_ */
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63e33cdb9ef352382d9daf3cb97737565d2c28c9
--- /dev/null
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.cpp
@@ -0,0 +1,69 @@
+/*
+ * ProductiveNonterminals.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "ProductiveNonterminals.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+namespace grammar {
+
+namespace properties {
+
+template<class T>
+std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const T & grammar ) {
+	// 1.
+	std::deque<std::set<alphabet::Symbol>> Ni;
+	Ni.push_back( std::set<alphabet::Symbol>( ) );
+
+	int i = 1;
+
+	// 2.
+	while( true ) {
+		Ni.push_back( Ni.at( i - 1 ) );
+
+		for( const auto & rule : grammar.getRawRules( ) ) {
+			for( const auto & rhs : rule.second ) {
+				if( std::all_of( rhs.begin( ), rhs.end( ), [ i, Ni, grammar ]( const alphabet::Symbol & symbol ) -> bool {
+					return Ni.at( i - 1 ) . count( symbol ) || grammar.getTerminalAlphabet( ). count( symbol );
+				} ) )
+					Ni.at( i ).insert( rule.first );
+			}
+		}
+
+		if( Ni.at( i ) == Ni.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	// 3.
+	return Ni.at( i );
+}
+
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CFG & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::EpsilonFreeCFG & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::GNF & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::CNF & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LG & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftLG & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::LeftRG & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightLG & grammar );
+template std::set<alphabet::Symbol> ProductiveNonterminals::getProductiveNonterminals( const grammar::RightRG & grammar );
+
+} /* namespace properties */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/ProductiveNonterminals.h b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
new file mode 100644
index 0000000000000000000000000000000000000000..6139ad94085beb92027ab12dc8d84c4c4c1cca0a
--- /dev/null
+++ b/alib2algo/src/grammar/properties/ProductiveNonterminals.h
@@ -0,0 +1,40 @@
+/*
+ * GrammarPropertiesCFG.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef PRODUCTIVE_NONTERMINALS_H_
+#define PRODUCTIVE_NONTERMINALS_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+
+#include <alphabet/Symbol.h>
+
+namespace grammar {
+
+namespace properties {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class ProductiveNonterminals {
+public:
+	/**
+	 * Implements steps 1 through 3 in Melichar 3.6
+	 */
+	template<class T>
+	static std::set<alphabet::Symbol> getProductiveNonterminals( const T & grammar );
+
+};
+
+} /* namespace properties */
+
+} /* namespace grammar */
+
+#endif /* PRODUCTIVE_NONTERMINALS_H_ */
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.cpp b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2347f08ac4a42a3ce987b98d41fb20139fc18da6
--- /dev/null
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.cpp
@@ -0,0 +1,70 @@
+/*
+ * UnreachableSymbols.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "UnreachableSymbols.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+namespace grammar {
+
+namespace properties {
+
+template<class T>
+std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const T & grammar ) {
+	// 1
+	std::deque<std::set<alphabet::Symbol>> Vi;
+	Vi.push_back( std::set<alphabet::Symbol>( ) );
+	Vi.at( 0 ).insert( grammar.getInitialSymbol( ) );
+
+	int i = 1;
+
+	// 2.
+	while( true ) {
+		Vi.push_back( Vi.at( i - 1 ) );
+
+		for( const auto & rule : grammar.getRawRules( ) ) {
+			if( Vi.at( i - 1 ).count( rule.first ) ) {
+				for( const auto & rhs : rule.second ) {
+					Vi.at( i ).insert( rhs.begin( ), rhs.end( ) );
+				}
+			}
+		}
+
+
+		if( Vi.at( i ) == Vi.at( i - 1 ) )
+			break;
+
+		i = i + 1;
+	}
+
+	// 3.
+	return Vi.at( i );
+}
+
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CFG & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::GNF & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::CNF & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LG & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftLG & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::LeftRG & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightLG & grammar );
+template std::set<alphabet::Symbol> UnreachableSymbols::getUnreachableSymbols( const grammar::RightRG & grammar );
+
+} /* namespace properties */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/properties/UnreachableSymbols.h b/alib2algo/src/grammar/properties/UnreachableSymbols.h
new file mode 100644
index 0000000000000000000000000000000000000000..d64351b858799a05f10ae70a546559be5572f87f
--- /dev/null
+++ b/alib2algo/src/grammar/properties/UnreachableSymbols.h
@@ -0,0 +1,40 @@
+/*
+ * UnreachableSymbols.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef UNREACHABLE_SYMBOLS_H_
+#define UNREACHABLE_SYMBOLS_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+
+#include <alphabet/Symbol.h>
+
+namespace grammar {
+
+namespace properties {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class UnreachableSymbols {
+public:
+	/**
+	 * Implements
+	 */
+	template<class T>
+	static std::set<alphabet::Symbol> getUnreachableSymbols( const T & grammar );
+
+};
+
+} /* namespace properties */
+
+} /* namespace grammar */
+
+#endif /* UNREACHABLE_SYMBOLS_H_ */
diff --git a/alib2algo/src/grammar/simplify/Trim.cpp b/alib2algo/src/grammar/simplify/Trim.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..862cbbc62179fa8943660673286d621937386974
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/Trim.cpp
@@ -0,0 +1,118 @@
+/*
+ * Trim.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "Trim.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+#include "UnreachableSymbolsRemover.h"
+#include "UnproductiveSymbolsRemover.h"
+
+namespace grammar {
+
+namespace simplify {
+
+template<class T>
+T Trim::trim( const T & grammar ) {
+	return grammar::simplify::UnreachableSymbolsRemover::remove( grammar::simplify::UnproductiveSymbolsRemover::remove( grammar ) );
+}
+
+template grammar::CFG Trim::trim( const grammar::CFG & grammar );
+template grammar::EpsilonFreeCFG Trim::trim( const grammar::EpsilonFreeCFG & grammar );
+template grammar::GNF Trim::trim( const grammar::GNF & grammar );
+template grammar::CNF Trim::trim( const grammar::CNF & grammar );
+template grammar::LG Trim::trim( const grammar::LG & grammar );
+template grammar::LeftLG Trim::trim( const grammar::LeftLG & grammar );
+template grammar::LeftRG Trim::trim( const grammar::LeftRG & grammar );
+template grammar::RightLG Trim::trim( const grammar::RightLG & grammar );
+template grammar::RightRG Trim::trim( const grammar::RightRG & grammar );
+
+grammar::Grammar Trim::trim(const grammar::Grammar& grammar) {
+	grammar::Grammar* out = NULL;
+	grammar.getData().Accept((void*) &out, Trim::TRIM);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void Trim::Visit(void* data, const grammar::LeftLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::LeftRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::RightLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::RightRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::LG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::CFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::CNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void* data, const grammar::GNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->trim(grammar));
+}
+
+void Trim::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void Trim::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void Trim::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void Trim::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const Trim Trim::TRIM;
+
+} /* namespace simplify */
+
+} /* namespace grammar */
+
diff --git a/alib2algo/src/grammar/simplify/Trim.h b/alib2algo/src/grammar/simplify/Trim.h
new file mode 100644
index 0000000000000000000000000000000000000000..30b78b8365f733ffdcb377c162789ec2b34c2078
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/Trim.h
@@ -0,0 +1,58 @@
+/*
+ * Trim.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef GRAMMAR_TRIM_H_
+#define GRAMMAR_TRIM_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+#include <grammar/Grammar.h>
+#include <alphabet/Symbol.h>
+
+namespace grammar {
+
+namespace simplify {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class Trim : public grammar::VisitableGrammarBase::const_visitor_type {
+public:
+	static grammar::Grammar trim( const grammar::Grammar & automaton );
+
+	/**
+	 * Removes unproductive and useless symbols - Melichar 3.12
+	 */
+	template<class T>
+	static T trim( const T & 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 Trim TRIM;
+};
+
+} /* namespace simplify */
+
+} /* namespace grammar */
+
+#endif /* GRAMMAR_TRIM_H_ */
diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..43d2044ab0db60b6d023888d18b7be9bbeb21233
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.cpp
@@ -0,0 +1,145 @@
+/*
+ * UnproductiveSymbolsRemover.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "UnproductiveSymbolsRemover.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+#include "../properties/ProductiveNonterminals.h"
+
+namespace grammar {
+
+namespace simplify {
+
+template<class T>
+T UnproductiveSymbolsRemover::remove( const T & grammar ) {
+	// 1.
+	std::set<alphabet::Symbol> Nt = grammar::properties::ProductiveNonterminals::getProductiveNonterminals( grammar );
+
+	T ret(grammar.getInitialSymbol( ) );
+
+	for( const auto & symbol : Nt )
+		ret.addNonterminalSymbol( symbol );
+
+	for( const auto & symbol : grammar.getTerminalAlphabet( ) )
+		ret.addTerminalSymbol( symbol );
+
+	const std::set<alphabet::Symbol> & terminals = ret.getTerminalAlphabet( );
+	for( const auto & rule : grammar.getRawRules( ) ) {
+		if( Nt.count( rule.first ) ) {
+			for( const auto & rhs : rule.second ) {
+				if( all_of( rhs.begin( ), rhs.end( ), [ Nt, terminals ]( const alphabet::Symbol & symbol ) {
+						return Nt.count( symbol ) || terminals.count( symbol );
+				} ) )
+					ret.addRawRule( rule.first, rhs );
+			}
+		}
+	}
+
+
+	/* if( ! G1.getNonTerminalSymbols( ) . count( grammar.getInitialSymbol( ) ) )
+		throw AlibException( "Starting symbol of grammar was marked as unproductive and therefore it was removed." ); */
+
+	// 2.
+	return ret;
+}
+
+template grammar::CFG UnproductiveSymbolsRemover::remove( const grammar::CFG & grammar );
+template grammar::EpsilonFreeCFG UnproductiveSymbolsRemover::remove( const grammar::EpsilonFreeCFG & grammar );
+template grammar::GNF UnproductiveSymbolsRemover::remove( const grammar::GNF & grammar );
+template grammar::CNF UnproductiveSymbolsRemover::remove( const grammar::CNF & grammar );
+template grammar::LG UnproductiveSymbolsRemover::remove( const grammar::LG & grammar );
+template grammar::LeftLG UnproductiveSymbolsRemover::remove( const grammar::LeftLG & grammar );
+template grammar::LeftRG UnproductiveSymbolsRemover::remove( const grammar::LeftRG & grammar );
+template grammar::RightLG UnproductiveSymbolsRemover::remove( const grammar::RightLG & grammar );
+template grammar::RightRG UnproductiveSymbolsRemover::remove( const grammar::RightRG & grammar );
+
+grammar::Grammar UnproductiveSymbolsRemover::remove(const grammar::Grammar& grammar) {
+	grammar::Grammar* out = NULL;
+	grammar.getData().Accept((void*) &out, UnproductiveSymbolsRemover::UNPRODUCTIVE_SYMBOLS_REMOVER);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::LeftLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::LeftRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::RightLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::RightRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::LG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::CFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::CNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void* data, const grammar::GNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnproductiveSymbolsRemover::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void UnproductiveSymbolsRemover::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void UnproductiveSymbolsRemover::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void UnproductiveSymbolsRemover::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const UnproductiveSymbolsRemover UnproductiveSymbolsRemover::UNPRODUCTIVE_SYMBOLS_REMOVER;
+
+} /* namespace simplify */
+
+} /* namespace grammar */
+
diff --git a/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h
new file mode 100644
index 0000000000000000000000000000000000000000..de8a17830edf1f3a94a4910f9247c3bfc978ebcf
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/UnproductiveSymbolsRemover.h
@@ -0,0 +1,58 @@
+/*
+ * UnproductiveSymbolsRemover.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef UNPRODUCTIVE_SYMBOLS_REMOVER_H_
+#define UNPRODUCTIVE_SYMBOLS_REMOVER_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+#include <grammar/Grammar.h>
+#include <alphabet/Symbol.h>
+
+namespace grammar {
+
+namespace simplify {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class UnproductiveSymbolsRemover : public grammar::VisitableGrammarBase::const_visitor_type {
+public:
+	static grammar::Grammar remove( const grammar::Grammar & automaton );
+
+	/**
+	 * Removes unproductive (or useless - terminology) symbols - Melichar 3.12
+	 */
+	template<class T>
+	static T remove( const T & 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 UnproductiveSymbolsRemover UNPRODUCTIVE_SYMBOLS_REMOVER;
+};
+
+} /* namespace simplify */
+
+} /* namespace grammar */
+
+#endif /* UNPRODUCTIVE_SYMBOLS_REMOVER_H_ */
diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..627d6d469f2d2f2d3173175fcfd041584234929d
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.cpp
@@ -0,0 +1,145 @@
+/*
+ * UnreachableSymbolsRemover.cpp
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "UnreachableSymbolsRemover.h"
+
+#include <grammar/ContextFree/CFG.h>
+#include <grammar/ContextFree/EpsilonFreeCFG.h>
+#include <grammar/ContextFree/GNF.h>
+#include <grammar/ContextFree/CNF.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 <std/set.hpp>
+
+#include "../properties/UnreachableSymbols.h"
+
+namespace grammar {
+
+namespace simplify {
+
+template<class T>
+T UnreachableSymbolsRemover::remove( const T & grammar) {
+	// 1.
+	std::set<alphabet::Symbol> Vt = grammar::properties::UnreachableSymbols::getUnreachableSymbols( grammar );
+
+	T ret(grammar.getInitialSymbol( ) );
+
+	std::set<alphabet::Symbol> newNonTerminals, newTerminals;
+
+	set_intersection( Vt.begin( ), Vt.end( ), grammar.getNonterminalAlphabet( ).begin( ), grammar.getNonterminalAlphabet( ).end( ), std::inserter( newNonTerminals, newNonTerminals.begin( ) ) );
+	for( const auto & symbol : newNonTerminals )
+		ret.addNonterminalSymbol( symbol );
+
+	set_intersection( Vt.begin( ), Vt.end( ), grammar.getTerminalAlphabet( ).begin( ), grammar.getTerminalAlphabet( ).end( ), std::inserter( newTerminals, newTerminals.begin( ) ) );
+	for( const auto & symbol : newTerminals )
+		ret.addTerminalSymbol( symbol );
+
+	// A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P
+	for( const auto & rule : grammar.getRawRules( ) ) {
+		if( newNonTerminals.count( rule.first ) ) {
+			for( const auto& rhs : rule.second ) {
+				if( all_of( rhs.begin( ), rhs.end( ), [ Vt ]( alphabet::Symbol const& symb ) -> bool {
+					return Vt.count( symb );
+				} ) )
+					ret.addRawRule( rule.first, rhs );
+			}
+	}	
+	}
+
+	// 2.
+	return ret;
+}
+
+template grammar::CFG UnreachableSymbolsRemover::remove( const grammar::CFG & grammar );
+template grammar::EpsilonFreeCFG UnreachableSymbolsRemover::remove( const grammar::EpsilonFreeCFG & grammar );
+template grammar::GNF UnreachableSymbolsRemover::remove( const grammar::GNF & grammar );
+template grammar::CNF UnreachableSymbolsRemover::remove( const grammar::CNF & grammar );
+template grammar::LG UnreachableSymbolsRemover::remove( const grammar::LG & grammar );
+template grammar::LeftLG UnreachableSymbolsRemover::remove( const grammar::LeftLG & grammar );
+template grammar::LeftRG UnreachableSymbolsRemover::remove( const grammar::LeftRG & grammar );
+template grammar::RightLG UnreachableSymbolsRemover::remove( const grammar::RightLG & grammar );
+template grammar::RightRG UnreachableSymbolsRemover::remove( const grammar::RightRG & grammar );
+
+grammar::Grammar UnreachableSymbolsRemover::remove(const grammar::Grammar& grammar) {
+	grammar::Grammar* out = NULL;
+	grammar.getData().Accept((void*) &out, UnreachableSymbolsRemover::UNREACHABLE_SYMBOLS_REMOVER);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::LeftLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::LeftRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::RightLG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::RightRG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::LG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::CFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::EpsilonFreeCFG& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::CNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void* data, const grammar::GNF& grammar) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->remove(grammar));
+}
+
+void UnreachableSymbolsRemover::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void UnreachableSymbolsRemover::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void UnreachableSymbolsRemover::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void UnreachableSymbolsRemover::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const UnreachableSymbolsRemover UnreachableSymbolsRemover::UNREACHABLE_SYMBOLS_REMOVER;
+
+} /* namespace simplify */
+
+} /* namespace grammar */
+
diff --git a/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
new file mode 100644
index 0000000000000000000000000000000000000000..1144d510cc1d3c5f7bd30364e921bd8d45f15926
--- /dev/null
+++ b/alib2algo/src/grammar/simplify/UnreachableSymbolsRemover.h
@@ -0,0 +1,58 @@
+/*
+ * UnreachableSymbolsRemover.h
+ *
+ *  Created on: 22. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef UNREACHABLE_SYMBOLS_REMOVER_H_
+#define UNREACHABLE_SYMBOLS_REMOVER_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include <exception/AlibException.h>
+#include <grammar/Grammar.h>
+#include <alphabet/Symbol.h>
+
+namespace grammar {
+
+namespace simplify {
+
+/**
+ * Implements algorithms from Melichar, chapter 3.3
+ */
+class UnreachableSymbolsRemover : public grammar::VisitableGrammarBase::const_visitor_type {
+public:
+	static grammar::Grammar remove( const grammar::Grammar & automaton );
+
+	/*
+	 * Removes unreachable symbols - Melichar 3.9
+	 */
+	template<class T>
+	static T remove( const T & 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 UnreachableSymbolsRemover UNREACHABLE_SYMBOLS_REMOVER;
+};
+
+} /* namespace simplify */
+
+} /* namespace grammar */
+
+#endif /* UNREACHABLE_SYMBOLS_REMOVER_H_ */
diff --git a/alib2algo/src/language/grammar/LanguagePropertiesCFG.cpp b/alib2algo/src/language/grammar/LanguagePropertiesCFG.cpp
deleted file mode 100644
index 23070a8688d488286b684b16e81759c446341be5..0000000000000000000000000000000000000000
--- a/alib2algo/src/language/grammar/LanguagePropertiesCFG.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * LanguagePropertiesCFG.cpp
- *
- *  Created on: 22. 3. 2014
- *	  Author: Tomas Pecka
- */
-
-#include "LanguagePropertiesCFG.h"
-
-#include <grammar/ContextFree/CFG.h>
-#include <grammar/ContextFree/EpsilonFreeCFG.h>
-#include <grammar/ContextFree/GNF.h>
-#include <grammar/ContextFree/CNF.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 <std/set.hpp>
-
-#include "../../grammar/GrammarPropertiesCFG.h"
-
-namespace language {
-
-template<class T>
-bool LanguagePropertiesCFG::isLanguageEmpty( const T & grammar ) {
-	return grammar::GrammarPropertiesCFG::getProductiveNonterminals( grammar ).count( grammar.getInitialSymbol( ) );
-}
-
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::CFG & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::EpsilonFreeCFG & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::GNF & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::CNF & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::LG & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::LeftLG & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::LeftRG & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::RightLG & grammar );
-template bool LanguagePropertiesCFG::isLanguageEmpty( const grammar::RightRG & grammar );
-
-}
-
diff --git a/alib2algo/src/normalize/dfa/NormalizeDFA.h b/alib2algo/src/normalize/dfa/NormalizeDFA.h
deleted file mode 100644
index 9980cbad5bc957de97a94e19e2fbc6ac946e8f72..0000000000000000000000000000000000000000
--- a/alib2algo/src/normalize/dfa/NormalizeDFA.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * NormalizeDFA.h
- *
- *  Created on: Dec 9, 2013
- *      Author: Jan Travnicek
- */
-
-#ifndef NORMALIZE_DFA_H_
-#define NORMALIZE_DFA_H_
-
-#include "automaton/FSM/DFA.h"
-
-namespace normalize {
-
-class NormalizeDFA {
-public:
-	static automaton::DFA normalize(automaton::DFA& dfa);
-
-};
-
-}
-
-#endif /* NORMALIZE_DFA_H_ */
diff --git a/alib2algo/src/regexp/GlushkovTraversal.cpp b/alib2algo/src/regexp/GlushkovTraversal.cpp
index 0069f0bf75313d1a4e60f1cd90423f3c122ff5de..b622ed1a01b315c4cd03eac7e3ade2fd37d101bb 100644
--- a/alib2algo/src/regexp/GlushkovTraversal.cpp
+++ b/alib2algo/src/regexp/GlushkovTraversal.cpp
@@ -7,7 +7,7 @@
 
 #include "GlushkovTraversal.h"
 
-#include "RegExpEpsilon.h"
+#include "properties/RegExpEpsilon.h"
 
 using namespace alib;
 using namespace regexp;
@@ -112,7 +112,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::first( regexp::Unb
         tmp = first( element );
         ret.insert( tmp.begin( ), tmp.end( ) );
 
-        if(! regexp::RegExpEpsilon::languageContainsEpsilon(*element)) // If regexp of this subtree can match epsilon, then we need to add next subtree
+        if(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(*element)) // If regexp of this subtree can match epsilon, then we need to add next subtree
             break;
     }
 
@@ -188,7 +188,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::last( regexp::Unbo
         tmp = last( *it );
         ret.insert( tmp.begin( ), tmp.end( ) );
 
-        if( ! regexp::RegExpEpsilon::languageContainsEpsilon(**it) )
+        if( ! regexp::properties::RegExpEpsilon::languageContainsEpsilon(**it) )
             break;
     }
 
@@ -276,7 +276,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::follow( regexp::Un
                 tmp = first( *f );
                 ret.insert( tmp.begin( ), tmp.end( ) );
 
-                if( ! regexp::RegExpEpsilon::languageContainsEpsilon( **f ) )
+                if( ! regexp::properties::RegExpEpsilon::languageContainsEpsilon( **f ) )
                     break;
             }
         }
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.cpp b/alib2algo/src/regexp/convert/ToAutomaton.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..781ecccc3f25eb9e53b5d00c0116e2ec24d2fd28
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToAutomaton.cpp
@@ -0,0 +1,40 @@
+/*
+ * ToAutomaton.cpp
+ *
+ *  Created on: 11. 1. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "ToAutomaton.h"
+#include "ToAutomatonGlushkov.h"
+#include <exception/AlibException.h>
+
+namespace regexp {
+
+namespace convert {
+
+automaton::Automaton ToAutomaton::convert(const regexp::RegExp& regexp)
+{
+	automaton::Automaton* out = NULL;
+	regexp.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON);
+	automaton::Automaton res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToAutomaton::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+{
+	automaton::Automaton* &out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
+}
+void ToAutomaton::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+{
+	automaton::Automaton* &out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
+}
+
+const ToAutomaton ToAutomaton::TO_AUTOMATON;
+
+} /* namespace convert */
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.h b/alib2algo/src/regexp/convert/ToAutomaton.h
new file mode 100644
index 0000000000000000000000000000000000000000..9894aff99762f91750c1da349f7353fea6b0e4e0
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToAutomaton.h
@@ -0,0 +1,42 @@
+/*
+ * RegExpToAutomaton.h
+ *
+ *  Created on: 11. 1. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef REG_EXP_TO_AUTOMATON_H_
+#define REG_EXP_TO_AUTOMATON_H_
+
+#include <regexp/RegExp.h>
+#include <regexp/formal/FormalRegExp.h>
+#include <regexp/unbounded/UnboundedRegExp.h>
+
+#include <automaton/Automaton.h>
+#include <automaton/FSM/NFA.h>
+
+namespace regexp {
+
+namespace convert {
+
+class ToAutomaton : public regexp::VisitableRegExpBase::const_visitor_type
+{
+public:
+	/**
+	 * Performs conversion.
+	 * @return FSM equivalent to original regular expression.
+	 */
+	static automaton::Automaton convert(const regexp::RegExp& regexp);
+
+private:
+	void Visit(void*, const regexp::FormalRegExp& regexp) const;
+	void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
+
+	static const ToAutomaton TO_AUTOMATON;
+};
+
+} /* namespace convert */
+
+} /* namespace regexp */
+
+#endif /* REG_EXP_TO_AUTOMATON_H_ */
diff --git a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
similarity index 64%
rename from alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp
rename to alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
index 4916c8e363c1e150ae8c3401d588ea1f8e5e00fa..b6fe2135bd87a144d4b0bad8c806c7ce8382111c 100644
--- a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonDerivation.cpp
@@ -1,11 +1,11 @@
 /*
- * BrzozowskiDerivation.cpp
+ * ToAutomatonDerivation.cpp
  *
  *  Created on: 11. 1. 2014
  *	  Author: Tomas Pecka
  */
 
-#include "BrzozowskiDerivation.h"
+#include "ToAutomatonDerivation.h"
 
 #include <set>
 #include <deque>
@@ -15,31 +15,28 @@
 #include <string/LinearString.h>
 #include <std/hexavigesimal.h>
 
-#include "../../regexp/RegExpDerivation.h"
-#include "../../regexp/RegExpOptimize.h"
-#include "../../regexp/RegExpEpsilon.h"
+#include "../transform/RegExpDerivation.h"
+#include "../simplify/RegExpOptimize.h"
+#include "../properties/RegExpEpsilon.h"
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2fa
-{
+namespace convert {
 
-automaton::Automaton BrzozowskiDerivation::convert(const regexp::RegExp& regexp)
+automaton::Automaton ToAutomatonDerivation::convert(const regexp::RegExp& regexp)
 {
 	automaton::Automaton* out = NULL;
-	regexp.getData().Accept((void*) &out, BrzozowskiDerivation::BRZOZOWSKI_DERIVATION);
+	regexp.getData().Accept((void*) &out, ToAutomatonDerivation::TO_AUTOMATON_DERIVATION);
 	automaton::Automaton res = std::move(*out);
 	delete out;
 	return res;
 }
 
 template<class T>
-automaton::NFA BrzozowskiDerivation::convert(const T& regexp)
+automaton::NFA ToAutomatonDerivation::convert(const T& regexp)
 {
 	// 1.
-	regexp::RegExpOptimize opt;
-	regexp::RegExp V = regexp::RegExp{regexp::RegExpOptimize::optimize(regexp)};
+	regexp::RegExp V = regexp::RegExp{regexp::simplify::RegExpOptimize::optimize(regexp)};
 
 	std::set<regexp::RegExp> Q = { V };
 	std::deque<std::set<regexp::RegExp>> Qi;
@@ -62,7 +59,7 @@ automaton::NFA BrzozowskiDerivation::convert(const T& regexp)
 			{
 				string::LinearString string(std::vector<alphabet::Symbol>{a});
 				regexp::RegExp derived = deriv.derivation(dregexp, string);
-				derived = regexp::RegExpOptimize::optimize(derived);
+				derived = regexp::simplify::RegExpOptimize::optimize(derived);
 
 				// this will also add \emptyset as a regexp (and as FA state)
 				if(Q.count(derived) == 0) // if this state has already been found, do not add
@@ -103,7 +100,7 @@ automaton::NFA BrzozowskiDerivation::convert(const T& regexp)
 		{
 			string::LinearString string(std::vector<alphabet::Symbol>{a});
 			regexp::RegExp derived = deriv.derivation(r, string);
-			derived = regexp::RegExpOptimize::optimize(derived);
+			derived = regexp::simplify::RegExpOptimize::optimize(derived);
 
 			automaton.addTransition(stateMap.find(r)->second, a, stateMap.find(derived)->second);
 		}
@@ -111,29 +108,29 @@ automaton::NFA BrzozowskiDerivation::convert(const T& regexp)
 
 	for(const auto& r : Q)
 	{
-		if(regexp::RegExpEpsilon::languageContainsEpsilon(r))
+		if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(r))
 			automaton.addFinalState(stateMap.find(r)->second);
 	}
 
 	return automaton;
 }
 
-template automaton::NFA BrzozowskiDerivation::convert(const regexp::FormalRegExp& regexp);
-template automaton::NFA BrzozowskiDerivation::convert(const regexp::UnboundedRegExp& regexp);
+template automaton::NFA ToAutomatonDerivation::convert(const regexp::FormalRegExp& regexp);
+template automaton::NFA ToAutomatonDerivation::convert(const regexp::UnboundedRegExp& regexp);
 
-void BrzozowskiDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+void ToAutomatonDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
 	automaton::Automaton* &out = *((automaton::Automaton**) userData);
 	out = new automaton::Automaton(this->convert(regexp));
 }
-void BrzozowskiDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+void ToAutomatonDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
 {
 	automaton::Automaton* &out = *((automaton::Automaton**) userData);
 	out = new automaton::Automaton(this->convert(regexp));
 }
 
-const BrzozowskiDerivation BrzozowskiDerivation::BRZOZOWSKI_DERIVATION;
+const ToAutomatonDerivation ToAutomatonDerivation::TO_AUTOMATON_DERIVATION;
 
-} /* namespace re2fa */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
diff --git a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h b/alib2algo/src/regexp/convert/ToAutomatonDerivation.h
similarity index 67%
rename from alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h
rename to alib2algo/src/regexp/convert/ToAutomatonDerivation.h
index a3c249dfe7ab5465b2547b4100af12c1139a50f6..7b26ff65f4d23332521b1e7e02b05748d756bf71 100644
--- a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonDerivation.h
@@ -1,12 +1,12 @@
 /*
- * BrzozowskiDerivation.h
+ * ToAutomatonDerivation.h
  *
  *  Created on: 11. 1. 2014
  *	  Author: Tomas Pecka
  */
 
-#ifndef RE2FA_BRZOZOWSKIDERIVATION_H_
-#define RE2FA_BRZOZOWSKIDERIVATION_H_
+#ifndef TO_AUTOMATON_DERIVATION_H_
+#define TO_AUTOMATON_DERIVATION_H_
 
 #include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
@@ -15,17 +15,15 @@
 #include <automaton/Automaton.h>
 #include <automaton/FSM/NFA.h>
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2fa
-{
+namespace convert {
 
 /**
  * Converts regular expression to finite automaton using BrzozowskiDerivation algorithm (derivations of regular expressions).
  * Source: Melichar 2.110
  */
-class BrzozowskiDerivation : public regexp::VisitableRegExpBase::const_visitor_type
+class ToAutomatonDerivation : public regexp::VisitableRegExpBase::const_visitor_type
 {
 public:
 	/**
@@ -41,11 +39,11 @@ private:
 	void Visit(void* , const regexp::FormalRegExp& regexp) const;
 	void Visit(void* , const regexp::UnboundedRegExp& regexp) const;
 
-	static const BrzozowskiDerivation BRZOZOWSKI_DERIVATION;
+	static const ToAutomatonDerivation TO_AUTOMATON_DERIVATION;
 };
 
-} /* namespace re2fa */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
 
-#endif /* RE2FA_BRZOZOWSKIDERIVATION_H_ */
+#endif /* TO_AUTOMATON_DERIVATION_H_ */
diff --git a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
similarity index 61%
rename from alib2algo/src/conversions/re2fa/GlushkovNFA.cpp
rename to alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
index 825eee70c8a475aec170c4e51a3c9f3d9bd4c503..fb75db1789ad7c80434a234dde542e92d8c36c1e 100644
--- a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
@@ -1,34 +1,34 @@
 /*
- * GlushkovNFA.cpp
+ * ToAutomatonGlushkov.cpp
  *
  *  Created on: 11. 1. 2014
  *	  Author: Tomas Pecka
  */
 
-#include "GlushkovNFA.h"
+#include "ToAutomatonGlushkov.h"
 
 #include "label/Label.h"
 #include "label/LabelPairLabel.h"
 
-#include "../../regexp/GlushkovTraversal.h"
-#include "../../regexp/GlushkovPair.h"
-#include "../../regexp/GlushkovSymbol.h"
+#include "../GlushkovTraversal.h"
+#include "../GlushkovPair.h"
+#include "../GlushkovSymbol.h"
 
-#include "../../regexp/RegExpEpsilon.h"
+#include "../properties/RegExpEpsilon.h"
 
-namespace conversions{
+namespace regexp {
 
-namespace re2fa {
+namespace convert {
 
-automaton::NFA GlushkovNFA::convert(const regexp::RegExp& regexp) {
+automaton::NFA ToAutomatonGlushkov::convert(const regexp::RegExp& regexp) {
 	automaton::NFA* out = nullptr;
-	regexp.getData().Accept((void*) &out, GlushkovNFA::GLUSHKOV_NFA);
+	regexp.getData().Accept((void*) &out, ToAutomatonGlushkov::TO_AUTOMATON_GLUSHKOV);
 	automaton::NFA res = std::move(*out);
 	delete out;
 	return res;
 }
 
-automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp)
+automaton::NFA ToAutomatonGlushkov::convert(const regexp::UnboundedRegExp& regexp)
 {
 	automaton::State q0( label::Label( label::LabelPairLabel( std::make_pair( label::labelFrom( 'q' ), label::labelFrom( 0 ) ) ) ) );
 	automaton::NFA automaton( q0 );
@@ -38,9 +38,9 @@ automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp)
 		automaton.addInputSymbol( symbol );
 
 	// steps 2, 3, 4
-    std::set<regexp::GlushkovPair> pairs;
-    const std::set<regexp::GlushkovSymbol> first = regexp::GlushkovTraversal::first(regexp);
-    const std::set<regexp::GlushkovSymbol> last = regexp::GlushkovTraversal::last(regexp);
+	std::set<regexp::GlushkovPair> pairs;
+	const std::set<regexp::GlushkovSymbol> first = regexp::GlushkovTraversal::first(regexp);
+	const std::set<regexp::GlushkovSymbol> last = regexp::GlushkovTraversal::last(regexp);
 	for( auto const& x : regexp::GlushkovTraversal::getSymbols( regexp ) )
 		for( auto const& f : regexp::GlushkovTraversal::follow( regexp, x ) ) {
 			pairs.insert( regexp::GlushkovPair( x, f ) );
@@ -48,7 +48,7 @@ automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp)
 	// \e in q0 check is in step 7
 
 	// step 5
-    std::map<regexp::GlushkovSymbol, automaton::State> stateMap;
+	std::map<regexp::GlushkovSymbol, automaton::State> stateMap;
 
 	for( auto const& symbol : regexp::GlushkovTraversal::getSymbols( regexp ) ) {
 		automaton::State q( label::Label( label::LabelPairLabel( std::make_pair( label::labelFrom( symbol.getInputSymbol( ) ), label::labelFrom( symbol.getId( ) ) ) ) ) );
@@ -77,13 +77,18 @@ automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp)
 		automaton.addFinalState( q );
 	}
 
-	if(regexp::RegExpEpsilon::languageContainsEpsilon(regexp))
+	if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(regexp))
 		automaton.addFinalState( q0 );
 
 	return automaton;
 }
 
-void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+automaton::NFA ToAutomatonGlushkov::convert(const regexp::FormalRegExp& regexp)
+{
+	throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO
+}
+
+void ToAutomatonGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
 	/*
 	automaton::NFA* & out = *((automaton::NFA**) userData);
@@ -92,14 +97,14 @@ void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) cons
 	throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO
 }
 
-void GlushkovNFA::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+void ToAutomatonGlushkov::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
 {
 	automaton::NFA* & out = *((automaton::NFA**) userData);
 	out = new automaton::NFA(this->convert(regexp));
 }
 
-const GlushkovNFA GlushkovNFA::GLUSHKOV_NFA;
+const ToAutomatonGlushkov ToAutomatonGlushkov::TO_AUTOMATON_GLUSHKOV;
 
-} /* namespace fa2re */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
new file mode 100644
index 0000000000000000000000000000000000000000..edf737ad00edd4ba0ca3f0793c44b56a6eb5cdf3
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.h
@@ -0,0 +1,50 @@
+/*
+ * ToAutomatonGlushkov.h
+ *
+ *  Created on: 11. 1. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef TO_AUTOMATON_GLUSHKOV_H_
+#define TO_AUTOMATON_GLUSHKOV_H_
+
+#include <map>
+
+#include <automaton/FSM/NFA.h>
+#include <regexp/RegExp.h>
+#include <regexp/formal/FormalRegExp.h>
+#include <regexp/unbounded/UnboundedRegExp.h>
+
+namespace regexp {
+
+namespace convert {
+
+/**
+ * Converts regular expression to finite automaton using Glushkov's NFA construction algorithm.
+ * Source: Melichar 2.107
+ */
+class ToAutomatonGlushkov : public regexp::VisitableRegExpBase::const_visitor_type
+{
+public:
+	/**
+	 * Performs conversion.
+	 * @param re Original regular expression.
+	 * @return NFA equivalent to original regular expression.
+	 */
+	static automaton::NFA convert(const regexp::RegExp& re);
+
+	static automaton::NFA convert(const regexp::UnboundedRegExp& re);
+	static automaton::NFA convert(const regexp::FormalRegExp& re);
+
+private:
+	void Visit(void*, const regexp::FormalRegExp& regexp) const;
+	void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
+
+	static const ToAutomatonGlushkov TO_AUTOMATON_GLUSHKOV;
+};
+
+} /* namespace convert */
+
+} /* namespace regexp */
+
+#endif /* TO_AUTOMATON_GLUSHKOV_H_ */
diff --git a/alib2algo/src/conversions/re2fa/Thompson.cpp b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
similarity index 84%
rename from alib2algo/src/conversions/re2fa/Thompson.cpp
rename to alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
index b3fe522f0f88b5101de8432cfa56b841dd040145..a2b2611735233efccf2102e05f220a63527a234e 100644
--- a/alib2algo/src/conversions/re2fa/Thompson.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp
@@ -1,36 +1,34 @@
 /*
- * Thompson.cpp
+ * ToAutomatonThompson.cpp
  *
  *  Created on: 11. 1. 2014
  *	  Author: Tomas Pecka
  */
-#include "Thompson.h"
+#include "ToAutomatonThompson.h"
 #include <tuple>
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2fa
-{
+namespace convert {
 
-automaton::Automaton Thompson::convert(const regexp::RegExp& regexp)
+automaton::Automaton ToAutomatonThompson::convert(const regexp::RegExp& regexp)
 {
 	automaton::Automaton* out = NULL;
-	regexp.getData().Accept((void*) &out, Thompson::THOMPSON);
+	regexp.getData().Accept((void*) &out, ToAutomatonThompson::TO_AUTOMATON_THOMPSON);
 	automaton::Automaton res = std::move(*out);
 	delete out;
 	return res;
 }
 
 template<class T>
-automaton::EpsilonNFA Thompson::convert(const T& regexp)
+automaton::EpsilonNFA ToAutomatonThompson::convert(const T& regexp)
 {	//FIXME use actual algorithms that implement product alternation and iteration of re over automata and remove terrible TERRIBLE hack with dummy initial state
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> out(automaton::EpsilonNFA(automaton::State(0)), 1, nullptr, nullptr);
 
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
 	automaton.setInputSymbols(regexp.getAlphabet());
 
-	regexp.getRegExp().Accept((void*) &out, Thompson::THOMPSON);
+	regexp.getRegExp().Accept((void*) &out, ToAutomatonThompson::TO_AUTOMATON_THOMPSON);
 
 	automaton.setInitialState(*std::get<2>(out));
 	automaton.setFinalStates(std::set<automaton::State>{*std::get<3>(out)});
@@ -42,13 +40,13 @@ automaton::EpsilonNFA Thompson::convert(const T& regexp)
 
 // ----------------------------------------------------------------------------
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
 	automaton::Automaton* & out = *((automaton::Automaton**) userData);
 	out = new automaton::Automaton(this->convert(regexp));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
 {
 	automaton::Automaton* & out = *((automaton::Automaton**) userData);
 	out = new automaton::Automaton(this->convert(regexp));
@@ -56,7 +54,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) cons
 
 // ----------------------------------------------------------------------------
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
@@ -78,7 +76,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alte
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
@@ -95,7 +93,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& co
 	// std::get<3>(out) = std::get<3>(out);
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
@@ -116,7 +114,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iterat
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
@@ -132,7 +130,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) c
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
@@ -148,7 +146,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
@@ -166,7 +164,7 @@ void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const
 
 // ----------------------------------------------------------------------------
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
@@ -187,7 +185,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& a
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
@@ -206,7 +204,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation&
 	std::get<3>(out) = tails[tails.size()-1].second;
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
@@ -226,7 +224,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& ite
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
@@ -241,7 +239,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
@@ -256,7 +254,7 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) cons
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const
+void ToAutomatonThompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const
 {
 	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 	automaton::EpsilonNFA& automaton = std::get<0>(out);
@@ -270,8 +268,8 @@ void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const
 	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-const Thompson Thompson::THOMPSON;
+const ToAutomatonThompson ToAutomatonThompson::TO_AUTOMATON_THOMPSON;
 
-} /* namespace re2fa */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
diff --git a/alib2algo/src/conversions/re2fa/Thompson.h b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
similarity index 81%
rename from alib2algo/src/conversions/re2fa/Thompson.h
rename to alib2algo/src/regexp/convert/ToAutomatonThompson.h
index e127f07f54e53f48e9691986e9f04e6d0af0f312..e2608c9b1c12adccb75c390ac621a93fe5aa92a3 100644
--- a/alib2algo/src/conversions/re2fa/Thompson.h
+++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.h
@@ -1,12 +1,12 @@
 /*
- * Thompson.h
+ * ToAutomatonThompson.h
  *
  *  Created on: 11. 1. 2014
  *	  Author: Tomas Pecka
  */
 
-#ifndef THOMPSON_H_
-#define THOMPSON_H_
+#ifndef TO_AUTOMATON_THOMPSON_H_
+#define TO_AUTOMATON_THOMPSON_H_
 
 #include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExpElements.h>
@@ -14,11 +14,9 @@
 #include <automaton/Automaton.h>
 #include <automaton/FSM/EpsilonNFA.h>
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2fa
-{
+namespace convert {
 
 /**
  * Converts regular expression to finite automaton using Thompson's Construction Algorithm (TCA).
@@ -28,7 +26,7 @@ namespace re2fa
  *  http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.21.7450&rep=rep1&type=ps
  *  Melichar 2.112
  */
-class Thompson : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type
+class ToAutomatonThompson : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type
 {
 public:
 	/**
@@ -59,11 +57,11 @@ private:
 	 void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
 	 void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
 
-	 static const Thompson THOMPSON;
+	 static const ToAutomatonThompson TO_AUTOMATON_THOMPSON;
 };
 
-} /* namespace re2fa */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
 
-#endif /* THOMPSON_H_ */
+#endif /* TO_AUTOMATON_THOMPSON_H_ */
diff --git a/alib2algo/src/regexp/convert/ToGrammar.cpp b/alib2algo/src/regexp/convert/ToGrammar.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0eb7d88c9b2f33ff5deb0bebca7adeaea7a0edec
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToGrammar.cpp
@@ -0,0 +1,41 @@
+/*
+ * ToGrammar.cpp
+ *
+ *  Created on: 6. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "ToGrammar.h"
+#include "ToGrammarRightRGGlushkov.h"
+#include <exception/AlibException.h>
+
+namespace regexp {
+
+namespace convert {
+
+grammar::Grammar ToGrammar::convert(const regexp::RegExp& regexp)
+{
+	grammar::Grammar* out = NULL;
+	regexp.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToGrammar::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+{
+	grammar::Grammar* &out = *((grammar::Grammar**) userData);
+	out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
+}
+
+void ToGrammar::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+{
+	grammar::Grammar* &out = *((grammar::Grammar**) userData);
+	out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
+}
+
+const ToGrammar ToGrammar::TO_GRAMMAR;
+
+} /* namespace convert */
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/convert/ToGrammar.h b/alib2algo/src/regexp/convert/ToGrammar.h
new file mode 100644
index 0000000000000000000000000000000000000000..de8438c541638213b0e98dbde6cfd691d0b6b784
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToGrammar.h
@@ -0,0 +1,38 @@
+/*
+ * ToGrammar.h
+ *
+ *  Created on: 6. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef REG_EXP_TO_GRAMMAR_H_
+#define REG_EXP_TO_GRAMMAR_H_
+
+#include <grammar/Grammar.h>
+#include <regexp/RegExp.h>
+
+namespace regexp {
+
+namespace convert {
+
+class ToGrammar : public regexp::VisitableRegExpBase::const_visitor_type
+{
+public:
+	/**
+	 * Performs conversion.
+	 * @return right regular grammar equivalent to source regexp.
+	 */
+	static grammar::Grammar convert(const regexp::RegExp& regexp);
+
+private:
+	void Visit(void*, const regexp::FormalRegExp& regexp) const;
+	void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
+
+	static const ToGrammar TO_GRAMMAR;
+};
+
+} /* namespace convert */
+
+} /* namespace regexp */
+
+#endif /* REG_EXP_TO_GRAMMAR_H_ */
diff --git a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
similarity index 68%
rename from alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp
rename to alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
index 27e75fcdf0a0881a8e38572c4da0969b75cf5243..1f9106c2a9624b82db2353ee8398f2c70341ff6f 100644
--- a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
@@ -1,11 +1,11 @@
 /*
- * BrzozowskiDerivation.cpp
+ * ToGrammarRightRGDerivation.cpp
  *
  *  Created on: 6. 3. 2014
- *	  Author: tomas
+ *	  Author: Tomas Pecka
  */
 
-#include "BrzozowskiDerivation.h"
+#include "ToGrammarRightRGDerivation.h"
 
 #include <set>
 #include <deque>
@@ -14,30 +14,28 @@
 
 #include <std/hexavigesimal.h>
 
-#include "../../../regexp/RegExpOptimize.h"
-#include "../../../regexp/RegExpDerivation.h"
-#include "../../../regexp/RegExpEpsilon.h"
+#include "../simplify/RegExpOptimize.h"
+#include "../transform/RegExpDerivation.h"
+#include "../properties/RegExpEpsilon.h"
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2rg
-{
+namespace convert {
 
-grammar::RightRG BrzozowskiDerivation::convert(const regexp::RegExp& regexp)
+grammar::RightRG ToGrammarRightRGDerivation::convert(const regexp::RegExp& regexp)
 {
 	grammar::RightRG* out = NULL;
-	regexp.getData().Accept((void*) &out, BrzozowskiDerivation::BRZOZOWSKI_DERIVATION);
+	regexp.getData().Accept((void*) &out, ToGrammarRightRGDerivation::TO_GRAMMAR_RIGHT_RG_DERIVATION);
 	grammar::RightRG res = std::move(*out);
 	delete out;
 	return res;
 }
 
 template<class T>
-grammar::RightRG BrzozowskiDerivation::convert(const T& regexp)
+grammar::RightRG ToGrammarRightRGDerivation::convert(const T& regexp)
 {
 	// 1.
-	regexp::RegExp V = regexp::RegExp{regexp::RegExpOptimize::optimize(regexp)};
+	regexp::RegExp V = regexp::RegExp{regexp::simplify::RegExpOptimize::optimize(regexp)};
 
 	std::set<regexp::RegExp> N = { V };
 	std::deque<std::set<regexp::RegExp>> Ni;
@@ -60,7 +58,7 @@ grammar::RightRG BrzozowskiDerivation::convert(const T& regexp)
 			{
 				string::LinearString string(std::vector<alphabet::Symbol>{a});
 				regexp::RegExp derived = deriv.derivation(dregexp, string);
-				derived = regexp::RegExpOptimize::optimize(derived);
+				derived = regexp::simplify::RegExpOptimize::optimize(derived);
 
 				// this will also add \emptyset as a regexp (and as FA state)
 				if(N.count(derived) == 0) // if this state has already been found, do not add
@@ -101,37 +99,37 @@ grammar::RightRG BrzozowskiDerivation::convert(const T& regexp)
 		{
 			string::LinearString string(std::vector<alphabet::Symbol>{a});
 			regexp::RegExp derived = deriv.derivation(r, string);
-			derived = regexp::RegExpOptimize::optimize(derived);
+			derived = regexp::simplify::RegExpOptimize::optimize(derived);
 
 			grammar.addRule(nonterminalMap.find(r)->second, std::make_pair(a, nonterminalMap.find(derived)->second));
 
-			if(regexp::RegExpEpsilon::languageContainsEpsilon(derived))
+			if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(derived))
 				grammar.addRule(nonterminalMap.find(r)->second, a);
 		}
 	}
 
 	grammar.setInitialSymbol(nonterminalMap.find(V)->second);
 
-	if(regexp::RegExpEpsilon::languageContainsEpsilon(V))
+	if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(V))
 		grammar.setGeneratesEpsilon(true); // okay, because of this feature we do not have to bother with extending the grammar with new rules and nonterminals. YAY!
 
 	return grammar;
 }
 
-void BrzozowskiDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+void ToGrammarRightRGDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
 	grammar::RightRG* &out = *((grammar::RightRG**) userData);
 	out = new grammar::RightRG(this->convert(regexp));
 }
 
-void BrzozowskiDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+void ToGrammarRightRGDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
 {
 	grammar::RightRG* &out = *((grammar::RightRG**) userData);
 	out = new grammar::RightRG(this->convert(regexp));
 }
 
-const BrzozowskiDerivation BrzozowskiDerivation::BRZOZOWSKI_DERIVATION;
+const ToGrammarRightRGDerivation ToGrammarRightRGDerivation::TO_GRAMMAR_RIGHT_RG_DERIVATION;
 
-} /* namespace re2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
diff --git a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.h b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.h
similarity index 63%
rename from alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.h
rename to alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.h
index 7a5814ad9ab02a7e4c166b5301f4582f6f676ad3..4027f7169173a6f70cfdfa406e9e8f70e2b14818 100644
--- a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.h
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.h
@@ -1,29 +1,27 @@
 /*
- * BrzozowskiDerivation.h
+ * ToGrammarRightRGDerivation.h
  *
  *  Created on: 6. 3. 2014
  *	  Author: Tomas Pecka
  */
 
-#ifndef RE2RG_BRZOZOWSKIDERIVATION_H_
-#define RE2RG_BRZOZOWSKIDERIVATION_H_
+#ifndef TO_GRAMMAR_RIGHT_RG_DERIVATION_H_
+#define TO_GRAMMAR_RIGHT_RG_DERIVATION_H_
 
 #include <grammar/Regular/RightRG.h>
 #include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2rg
-{
+namespace convert {
 
 /**
  * Converts reg. expression to right regular grammar using brzozowski derivation algorithm.
  * Source: Melichar 2.137
  */
-class BrzozowskiDerivation : public regexp::VisitableRegExpBase::const_visitor_type
+class ToGrammarRightRGDerivation : public regexp::VisitableRegExpBase::const_visitor_type
 {
 public:
 	/**
@@ -39,11 +37,11 @@ private:
 	void Visit(void*, const regexp::FormalRegExp& regexp) const;
 	void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
 
-	static const BrzozowskiDerivation BRZOZOWSKI_DERIVATION;
+	static const ToGrammarRightRGDerivation TO_GRAMMAR_RIGHT_RG_DERIVATION;
 };
 
-} /* namespace re2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
 
-#endif /* RE2RG_BRZOZOWSKIDERIVATION_H_ */
+#endif /* TO_GRAMMAR_RIGHT_RG_DERIVATION_H_ */
diff --git a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
similarity index 71%
rename from alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp
rename to alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
index a49c6d9aacc3547918bd05bdf831c9bc3c8df61d..cb1ba5388b18391895ef03502df76fa223757992 100644
--- a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
@@ -1,11 +1,11 @@
 /*
- * Glushkov.cpp
+ * ToGrammarRightRGGlushkov.cpp
  *
  *  Created on: 11. 1. 2014
  *      Author: Tomas Pecka
  */
 
-#include "GlushkovNFA.h"
+#include "ToGrammarRightRGGlushkov.h"
 
 #include <algorithm>
 
@@ -13,28 +13,26 @@
 
 #include <label/LabelPairLabel.h>
 
-#include "../../../regexp/GlushkovTraversal.h"
-#include "../../../regexp/GlushkovPair.h"
-#include "../../../regexp/GlushkovSymbol.h"
+#include "../GlushkovTraversal.h"
+#include "../GlushkovPair.h"
+#include "../GlushkovSymbol.h"
 
-#include "../../../regexp/RegExpEpsilon.h"
+#include "../properties/RegExpEpsilon.h"
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2rg
-{
+namespace convert {
 
-grammar::Grammar GlushkovNFA::convert(const regexp::RegExp& regexp)
+grammar::Grammar ToGrammarRightRGGlushkov::convert(const regexp::RegExp& regexp)
 {
     grammar::Grammar* out = NULL;
-    regexp.getData().Accept((void*) &out, GlushkovNFA::GLUSHKOV_NFA);
+    regexp.getData().Accept((void*) &out, ToGrammarRightRGGlushkov::TO_GRAMMAR_RIGHT_RG_GLUSHKOV);
     grammar::Grammar res = std::move(*out);
     delete out;
     return res;
 }
 
-grammar::RightRG GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp)
+grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::UnboundedRegExp& regexp)
 {
     alphabet::Symbol S = alphabet::symbolFrom("S");
     grammar::RightRG grammar(S);
@@ -89,14 +87,17 @@ grammar::RightRG GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp)
                     grammar.addRule(rule.first, rhs.at(0));
     }
 
-    if(regexp::RegExpEpsilon::languageContainsEpsilon(regexp))
+    if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(regexp))
         grammar.setGeneratesEpsilon(true);
 
     return grammar;
 }
 
+grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::FormalRegExp& regexp) {
+    throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO
+}
 
-void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+void ToGrammarRightRGGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
     /*
     grammar::Grammar* & out = *((grammar::Grammar**) userData);
@@ -105,14 +106,14 @@ void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) cons
     throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO
 }
 
-void GlushkovNFA::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+void ToGrammarRightRGGlushkov::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
 {
     grammar::Grammar* & out = *((grammar::Grammar**) userData);
     out = new grammar::Grammar(this->convert(regexp));
 }
 
-const GlushkovNFA GlushkovNFA::GLUSHKOV_NFA;
+const ToGrammarRightRGGlushkov ToGrammarRightRGGlushkov::TO_GRAMMAR_RIGHT_RG_GLUSHKOV;
 
-} /* namespace re2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
diff --git a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h
similarity index 68%
rename from alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h
rename to alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h
index 32de94e8b020907573114155fb9c1c8b33bea075..42a9cb9e82f76a6c94e63c5cd75a9763672e1957 100644
--- a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.h
@@ -1,12 +1,12 @@
 /*
- * Glushkov.h
+ * ToGrammarRightRGGlushkov.h
  *
  *  Created on: 11. 1. 2014
  *      Author: Tomas Pecka
  */
 
-#ifndef RE2RG_GLUSHKOVNFA_H_
-#define RE2RG_GLUSHKOVNFA_H_
+#ifndef TO_GRAMMAR_RIGHT_RG_GLUSHKOV_H_
+#define TO_GRAMMAR_RIGHT_RG_GLUSHKOV_H_
 
 #include <grammar/Grammar.h>
 #include <grammar/Regular/RightRG.h>
@@ -15,17 +15,15 @@
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
 
-namespace conversions
-{
+namespace regexp {
 
-namespace re2rg
-{
+namespace convert {
 
 /**
  * Converts regular expression to right regular grammar using Glushkov algorithm.
  * Source: None yet.
  */
-class GlushkovNFA : public regexp::VisitableRegExpBase::const_visitor_type
+class ToGrammarRightRGGlushkov : public regexp::VisitableRegExpBase::const_visitor_type
 {
 public:
     /**
@@ -42,11 +40,11 @@ private:
     void Visit(void*, const regexp::FormalRegExp& regexp) const;
     void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
 
-    static const GlushkovNFA GLUSHKOV_NFA;
+    static const ToGrammarRightRGGlushkov TO_GRAMMAR_RIGHT_RG_GLUSHKOV;
 };
 
-} /* namespace re2rg */
+} /* namespace convert */
 
-} /* namespace conversions */
+} /* namespace regexp */
 
-#endif /* RE2RG_GLUSHKOVNFA_H_ */
+#endif /* TO_GRAMMAR_RIGHT_RG_GLUSHKOV_H_ */
diff --git a/alib2algo/src/generator/RandomRegExpFactory.cpp b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
similarity index 97%
rename from alib2algo/src/generator/RandomRegExpFactory.cpp
rename to alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
index 7dfd8eca9ecdbbcf29aa6bab8ef28d4dece83278..196802377d61ebe9fc9e4d690c0756b4090d4837 100644
--- a/alib2algo/src/generator/RandomRegExpFactory.cpp
+++ b/alib2algo/src/regexp/generate/RandomRegExpFactory.cpp
@@ -9,7 +9,9 @@
 
 #include <algorithm>
 
-namespace generator {
+namespace regexp {
+
+namespace generate {
 
 regexp::UnboundedRegExp RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize ) {
 	srand( time( NULL ) );
@@ -142,4 +144,6 @@ const regexp::UnboundedRegExpElement* RandomRegExpFactory::SimpleUnboundedRegExp
 	}
 }
 
-}
+} /* namespace generate */
+
+} /* namespace regexp */
diff --git a/alib2algo/src/generator/RandomRegExpFactory.h b/alib2algo/src/regexp/generate/RandomRegExpFactory.h
similarity index 91%
rename from alib2algo/src/generator/RandomRegExpFactory.h
rename to alib2algo/src/regexp/generate/RandomRegExpFactory.h
index 0459faf3acffa1f6d7308dd508a4fe17b6f92179..eaee929c6c09017ebf1921415077a29dc98fe290 100644
--- a/alib2algo/src/generator/RandomRegExpFactory.h
+++ b/alib2algo/src/regexp/generate/RandomRegExpFactory.h
@@ -15,7 +15,9 @@
 #include <regexp/unbounded/UnboundedRegExp.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
 
-namespace generator {
+namespace regexp {
+
+namespace generate {
 
 class RandomRegExpFactory {
 public:
@@ -27,6 +29,8 @@ private:
 	static const regexp::UnboundedRegExpElement* SimpleUnboundedRegExpElement(size_t n, size_t h, const std::vector<const regexp::UnboundedRegExpElement*> & elems);
 };
 
-}
+} /* namespace generate */
+
+} /* namespace regexp */
 
 #endif /* RANDOM_REG_EXP_FACTORY_H_ */
diff --git a/alib2algo/src/regexp/RegExpEmpty.cpp b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
similarity index 98%
rename from alib2algo/src/regexp/RegExpEmpty.cpp
rename to alib2algo/src/regexp/properties/RegExpEmpty.cpp
index 16247f9328df4c77308a87236084275b3f58f622..eae0d1262feea3bd2b7c561eda283fede9a3af34 100644
--- a/alib2algo/src/regexp/RegExpEmpty.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.cpp
@@ -7,8 +7,9 @@
 
 #include "RegExpEmpty.h"
 
-namespace regexp
-{
+namespace regexp {
+
+namespace properties {
 
 bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp)
 {
@@ -157,4 +158,6 @@ void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExp& regexp) const
 
 const RegExpEmpty RegExpEmpty::REG_EXP_EMPTY;
 
+} /* namespace properties */
+
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/RegExpEmpty.h b/alib2algo/src/regexp/properties/RegExpEmpty.h
similarity index 96%
rename from alib2algo/src/regexp/RegExpEmpty.h
rename to alib2algo/src/regexp/properties/RegExpEmpty.h
index 8b2958e121a1cf60d0ee7035768d100262684711..d76fa5fac364d1b933b73f399832cf47fc14f20e 100644
--- a/alib2algo/src/regexp/RegExpEmpty.h
+++ b/alib2algo/src/regexp/properties/RegExpEmpty.h
@@ -12,8 +12,9 @@
 #include <regexp/formal/FormalRegExpElements.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
 
-namespace regexp
-{
+namespace regexp {
+
+namespace properties {
 
 /**
  * Determines whether regular expression is empty (regexp == \0)
@@ -48,6 +49,8 @@ private:
 	static const RegExpEmpty REG_EXP_EMPTY;
 };
 
+} /* namespace properties */
+
 } /* namespace regexp */
 
 #endif /* REG_EXP_EMPTY_H_ */
diff --git a/alib2algo/src/regexp/RegExpEpsilon.cpp b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
similarity index 98%
rename from alib2algo/src/regexp/RegExpEpsilon.cpp
rename to alib2algo/src/regexp/properties/RegExpEpsilon.cpp
index c697cbbdd16061eb579353d0eec35df5bbb9e96a..58c9ed6497bf7235d1c71695143cf1ab1004481f 100644
--- a/alib2algo/src/regexp/RegExpEpsilon.cpp
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp
@@ -7,8 +7,9 @@
 
 #include "RegExpEpsilon.h"
 
-namespace regexp
-{
+namespace regexp {
+
+namespace properties {
 
 bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp)
 {
@@ -174,4 +175,6 @@ void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExp& regexp) con
 
 const RegExpEpsilon RegExpEpsilon::REG_EXP_EPSILON;
 
+} /* namespace properties */
+
 } /* namespace regexp */
diff --git a/alib2algo/src/regexp/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h
similarity index 96%
rename from alib2algo/src/regexp/RegExpEpsilon.h
rename to alib2algo/src/regexp/properties/RegExpEpsilon.h
index 4472068c2c856e87ecb974eedb962b284915b797..58d2518919684da699a1d26048048ac3d0e72198 100644
--- a/alib2algo/src/regexp/RegExpEpsilon.h
+++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h
@@ -12,8 +12,9 @@
 #include <regexp/formal/FormalRegExpElements.h>
 #include <regexp/unbounded/UnboundedRegExpElements.h>
 
-namespace regexp
-{
+namespace regexp {
+
+namespace properties {
 
 /**
  * Checks, whether regexp (or its subtree) describes epsilon (empty string).
@@ -53,6 +54,8 @@ private:
     static const RegExpEpsilon REG_EXP_EPSILON;
 };
 
+} /* namespace properties */
+
 } /* namespace regexp */
 
 #endif /* REG_EXP_EPSILON_H_ */
diff --git a/alib2algo/src/regexp/RegExpOptimize.cpp b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
similarity index 97%
rename from alib2algo/src/regexp/RegExpOptimize.cpp
rename to alib2algo/src/regexp/simplify/RegExpOptimize.cpp
index 42573dc1e8e492d60fa8725e47fdfce805a2e0dd..e3c630f1a4863b676e1ce32f9d2235e4939ae32a 100644
--- a/alib2algo/src/regexp/RegExpOptimize.cpp
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.cpp
@@ -7,7 +7,7 @@
 
 #include "RegExpOptimize.h"
 
-#include "RegExpEpsilon.h"
+#include "../properties/RegExpEpsilon.h"
 
 #include <cassert>
 #include <iostream>
@@ -15,6 +15,8 @@
 
 namespace regexp {
 
+namespace simplify {
+
 regexp::RegExp RegExpOptimize::optimize(const regexp::RegExp& regexp)
 {
     regexp::RegExp * out = NULL;
@@ -157,7 +159,9 @@ void RegExpOptimize::optimize( UnboundedRegExpElement & element ) {
 
 const RegExpOptimize RegExpOptimize::REG_EXP_OPTIMIZE;
 
+} /* namespace regexp */
+
+} /* namespace simplify */
+
 #include "RegExpOptimizeUnboundedPart.cxx"
 #include "RegExpOptimizeFormalPart.cxx"
-
-}
diff --git a/alib2algo/src/regexp/RegExpOptimize.h b/alib2algo/src/regexp/simplify/RegExpOptimize.h
similarity index 98%
rename from alib2algo/src/regexp/RegExpOptimize.h
rename to alib2algo/src/regexp/simplify/RegExpOptimize.h
index 1cd12f7a686a47d3719e46feffaad8c78d8b00b6..f0d7ba78c0fb52a2045b8ac01daa2f1f07b95c5d 100644
--- a/alib2algo/src/regexp/RegExpOptimize.h
+++ b/alib2algo/src/regexp/simplify/RegExpOptimize.h
@@ -24,6 +24,8 @@
 
 namespace regexp {
 
+namespace simplify {
+
 /*
  * Optimizes RegExp (or its subtree) using axioms defined in Melichar 2.87
  * (A1 to A10) and Melichar 2.95(V1 through V6 and V8, V9, V10)
@@ -134,6 +136,8 @@ private:
     static const RegExpOptimize REG_EXP_OPTIMIZE;
 };
 
-}
+} /* namespace simplify */
+
+} /* namespace regexp */
 
 #endif /* REGEXPNORMALIZE_H_ */
diff --git a/alib2algo/src/regexp/RegExpOptimizeFormalPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
similarity index 98%
rename from alib2algo/src/regexp/RegExpOptimizeFormalPart.cxx
rename to alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
index 8a6793f16eb4c2ed513811918ff5bcb935edd104..d2ac3dd6313390a3e61cefdff287af821574d653 100644
--- a/alib2algo/src/regexp/RegExpOptimizeFormalPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeFormalPart.cxx
@@ -1,3 +1,14 @@
+/*
+ * RegExpOptimize.cpp
+ *
+ *  Created on: 20. 1. 2014
+ *	  Author: Jan Travnicek
+ */
+
+namespace regexp {
+
+namespace simplify {
+
 FormalRegExpElement* RegExpOptimize::optimize( FormalRegExpElement const * const & node ) const
 {
 	FormalRegExpElement* elem = node->clone();
@@ -567,4 +578,9 @@ bool RegExpOptimize::X1( FormalRegExpElement * & n ) const
 	}
 
 	return false;
+
 }
+
+} /* namespace simplify */
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/RegExpOptimizeUnboundedPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
similarity index 98%
rename from alib2algo/src/regexp/RegExpOptimizeUnboundedPart.cxx
rename to alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
index 95f668405c83e2e049b28433eabb50babf150b8a..9d3faf3058028244f8f590e68ee93c2d9fe712b7 100644
--- a/alib2algo/src/regexp/RegExpOptimizeUnboundedPart.cxx
+++ b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx
@@ -1,3 +1,14 @@
+/*
+ * RegExpOptimize.cpp
+ *
+ *  Created on: 20. 1. 2014
+ *	  Author: Tomas Pecka
+ */
+
+namespace regexp {
+
+namespace simplify {
+
 UnboundedRegExpElement* RegExpOptimize::optimize( UnboundedRegExpElement const * const & node ) const
 {
 	const UnboundedRegExpAlternation * alternation = dynamic_cast<const UnboundedRegExpAlternation*>( node );
@@ -999,7 +1010,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const
 			auto it2 = it;
 			advance( it2, - (int)concat->elements.size( ) );
 
-			if( regexp::RegExpEpsilon::languageContainsEpsilon(*concat) &&
+			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*concat) &&
 				distance( concat->elements.begin( ), concat->elements.end( )) == distance ( it2, node->elements.end( ) ) &&
 				equal( concat->elements.begin( ), concat->elements.end( ), it2, [] ( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a == *b; } ) )
 			{
@@ -1025,7 +1036,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const
 
 			auto prev = std::prev( it );
 
-			if( regexp::RegExpEpsilon::languageContainsEpsilon(*(iter->element)) && *( iter->element ) == **prev )
+			if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*(iter->element)) && *( iter->element ) == **prev )
 			{
 				delete * prev;
 				it = node->elements.erase( prev );
@@ -1160,3 +1171,7 @@ bool RegExpOptimize::X1( UnboundedRegExpAlternation * const & node ) const
 
 	return false;
 }
+
+} /* namespace simplify */
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/RegExpAlternate.cpp b/alib2algo/src/regexp/transform/RegExpAlternate.cpp
similarity index 100%
rename from alib2algo/src/regexp/RegExpAlternate.cpp
rename to alib2algo/src/regexp/transform/RegExpAlternate.cpp
diff --git a/alib2algo/src/regexp/RegExpAlternate.h b/alib2algo/src/regexp/transform/RegExpAlternate.h
similarity index 100%
rename from alib2algo/src/regexp/RegExpAlternate.h
rename to alib2algo/src/regexp/transform/RegExpAlternate.h
diff --git a/alib2algo/src/regexp/RegExpConcatenate.cpp b/alib2algo/src/regexp/transform/RegExpConcatenate.cpp
similarity index 100%
rename from alib2algo/src/regexp/RegExpConcatenate.cpp
rename to alib2algo/src/regexp/transform/RegExpConcatenate.cpp
diff --git a/alib2algo/src/regexp/RegExpConcatenate.h b/alib2algo/src/regexp/transform/RegExpConcatenate.h
similarity index 100%
rename from alib2algo/src/regexp/RegExpConcatenate.h
rename to alib2algo/src/regexp/transform/RegExpConcatenate.h
diff --git a/alib2algo/src/regexp/RegExpDerivation.cpp b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
similarity index 97%
rename from alib2algo/src/regexp/RegExpDerivation.cpp
rename to alib2algo/src/regexp/transform/RegExpDerivation.cpp
index ac198be43829e95377b16dc06b1f1c2eddb3f9a0..cbf0f3a744251b1c9541e9cdca6735b6ef92a87f 100644
--- a/alib2algo/src/regexp/RegExpDerivation.cpp
+++ b/alib2algo/src/regexp/transform/RegExpDerivation.cpp
@@ -7,7 +7,7 @@
 
 #include "RegExpDerivation.h"
 
-#include "RegExpEpsilon.h"
+#include "../properties/RegExpEpsilon.h"
 
 namespace regexp
 {
@@ -97,7 +97,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpConcatena
     delete leftDerivative;
     delete rightElement;
 
-    if(regexp::RegExpEpsilon::languageContainsEpsilon(concatenation.getLeftElement()))
+    if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(concatenation.getLeftElement()))
     {
         const regexp::FormalRegExpElement *alternation = out.second, *rightDerivative = nullptr;
         static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this);
@@ -186,7 +186,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcat
         ret->appendElement(std::move(*concat));
         delete concat;
 
-        if(regexp::RegExpEpsilon::languageContainsEpsilon(**child))
+        if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(**child))
             continue; // this IF construct is intentional "to match algorithm"
         break;
     }
diff --git a/alib2algo/src/regexp/RegExpDerivation.h b/alib2algo/src/regexp/transform/RegExpDerivation.h
similarity index 100%
rename from alib2algo/src/regexp/RegExpDerivation.h
rename to alib2algo/src/regexp/transform/RegExpDerivation.h
diff --git a/alib2algo/src/regexp/RegExpIntegral.cpp b/alib2algo/src/regexp/transform/RegExpIntegral.cpp
similarity index 100%
rename from alib2algo/src/regexp/RegExpIntegral.cpp
rename to alib2algo/src/regexp/transform/RegExpIntegral.cpp
diff --git a/alib2algo/src/regexp/RegExpIntegral.h b/alib2algo/src/regexp/transform/RegExpIntegral.h
similarity index 100%
rename from alib2algo/src/regexp/RegExpIntegral.h
rename to alib2algo/src/regexp/transform/RegExpIntegral.h
diff --git a/alib2algo/src/regexp/RegExpIterate.cpp b/alib2algo/src/regexp/transform/RegExpIterate.cpp
similarity index 100%
rename from alib2algo/src/regexp/RegExpIterate.cpp
rename to alib2algo/src/regexp/transform/RegExpIterate.cpp
diff --git a/alib2algo/src/regexp/RegExpIterate.h b/alib2algo/src/regexp/transform/RegExpIterate.h
similarity index 100%
rename from alib2algo/src/regexp/RegExpIterate.h
rename to alib2algo/src/regexp/transform/RegExpIterate.h
diff --git a/alib2algo/src/compare/string/CyclicStringCompare.cpp b/alib2algo/src/string/compare/CyclicStringCompare.cpp
similarity index 94%
rename from alib2algo/src/compare/string/CyclicStringCompare.cpp
rename to alib2algo/src/string/compare/CyclicStringCompare.cpp
index 0e8fc8b879a6c37df39f19602558af4bf8d20191..0e33dfbe2a59f8bc0255e2ee2d8f28346597dc13 100644
--- a/alib2algo/src/compare/string/CyclicStringCompare.cpp
+++ b/alib2algo/src/string/compare/CyclicStringCompare.cpp
@@ -6,8 +6,10 @@
 
 #include "CyclicStringCompare.h"
 
+namespace string {
+
 namespace compare {
-	
+
 bool CyclicStringCompare::equals(const string::LinearString& u, const string::LinearString& v) {
     int n = (int)u.getContent().size();
     int i = -1, j = -1, k;
@@ -39,4 +41,6 @@ int CyclicStringCompare::compare(const string::LinearString& u, const string::Li
     return last ? 1 : - 1;
 }
 
-}
+} /* namespace compare */
+
+} /* namespace string */
diff --git a/alib2algo/src/compare/string/CyclicStringCompare.h b/alib2algo/src/string/compare/CyclicStringCompare.h
similarity index 86%
rename from alib2algo/src/compare/string/CyclicStringCompare.h
rename to alib2algo/src/string/compare/CyclicStringCompare.h
index 18e062432185332ba40c38737496ee25aea62d60..267a791376918e9f287bb714706e58e1163ce2ca 100644
--- a/alib2algo/src/compare/string/CyclicStringCompare.h
+++ b/alib2algo/src/string/compare/CyclicStringCompare.h
@@ -10,6 +10,8 @@
 
 #include "string/LinearString.h" 
 
+namespace string {
+
 namespace compare {
 
 class CyclicStringCompare {
@@ -19,6 +21,8 @@ public:
 
 };
 
-}
+} /* namespace compare */
+
+} /* namespace string */
 
 #endif /* CYCLIC_STRING_COMPARE_H_ */
diff --git a/alib2algo/src/trim/grammar/TrimCFG.cpp b/alib2algo/src/trim/grammar/TrimCFG.cpp
deleted file mode 100644
index 0a5fe0f974df1edc42ae7b022db0b4622468a0d5..0000000000000000000000000000000000000000
--- a/alib2algo/src/trim/grammar/TrimCFG.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * TrimCFG.cpp
- *
- *  Created on: 22. 3. 2014
- *	  Author: Tomas Pecka
- */
-
-#include "TrimCFG.h"
-
-#include <grammar/ContextFree/CFG.h>
-#include <grammar/ContextFree/EpsilonFreeCFG.h>
-#include <grammar/ContextFree/GNF.h>
-#include <grammar/ContextFree/CNF.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 <std/set.hpp>
-
-#include "../../grammar/GrammarPropertiesCFG.h"
-
-namespace trim {
-
-template<class T>
-T TrimCFG::removeUnreachableSymbols( const T & grammar) {
-	// 1.
-	std::set<alphabet::Symbol> Vt = grammar::GrammarPropertiesCFG::getUnreachableSymbols( grammar );
-
-	T ret(grammar.getInitialSymbol( ) );
-
-	std::set<alphabet::Symbol> newNonTerminals, newTerminals;
-
-	set_intersection( Vt.begin( ), Vt.end( ), grammar.getNonterminalAlphabet( ).begin( ), grammar.getNonterminalAlphabet( ).end( ), std::inserter( newNonTerminals, newNonTerminals.begin( ) ) );
-	for( const auto & symbol : newNonTerminals )
-		ret.addNonterminalSymbol( symbol );
-
-	set_intersection( Vt.begin( ), Vt.end( ), grammar.getTerminalAlphabet( ).begin( ), grammar.getTerminalAlphabet( ).end( ), std::inserter( newTerminals, newTerminals.begin( ) ) );
-	for( const auto & symbol : newTerminals )
-		ret.addTerminalSymbol( symbol );
-
-	// A->\alpha: if A \in N' and \alpha in V_i*, then A->\alpha in P
-	for( const auto & rule : grammar.getRawRules( ) ) {
-		if( newNonTerminals.count( rule.first ) ) {
-			for( const auto& rhs : rule.second ) {
-				if( all_of( rhs.begin( ), rhs.end( ), [ Vt ]( alphabet::Symbol const& symb ) -> bool {
-					return Vt.count( symb );
-				} ) )
-					ret.addRawRule( rule.first, rhs );
-			}
-	}	
-	}
-
-	// 2.
-	return ret;
-}
-
-template grammar::CFG TrimCFG::removeUnreachableSymbols( const grammar::CFG & grammar );
-template grammar::EpsilonFreeCFG TrimCFG::removeUnreachableSymbols( const grammar::EpsilonFreeCFG & grammar );
-template grammar::GNF TrimCFG::removeUnreachableSymbols( const grammar::GNF & grammar );
-template grammar::CNF TrimCFG::removeUnreachableSymbols( const grammar::CNF & grammar );
-template grammar::LG TrimCFG::removeUnreachableSymbols( const grammar::LG & grammar );
-template grammar::LeftLG TrimCFG::removeUnreachableSymbols( const grammar::LeftLG & grammar );
-template grammar::LeftRG TrimCFG::removeUnreachableSymbols( const grammar::LeftRG & grammar );
-template grammar::RightLG TrimCFG::removeUnreachableSymbols( const grammar::RightLG & grammar );
-template grammar::RightRG TrimCFG::removeUnreachableSymbols( const grammar::RightRG & grammar );
-
-template<class T>
-T TrimCFG::removeUnproductiveSymbols( const T & grammar ) {
-	// 1.
-	std::set<alphabet::Symbol> Nt = grammar::GrammarPropertiesCFG::getProductiveNonterminals( grammar );
-
-	T ret(grammar.getInitialSymbol( ) );
-
-	for( const auto & symbol : Nt )
-		ret.addNonterminalSymbol( symbol );
-
-	for( const auto & symbol : grammar.getTerminalAlphabet( ) )
-		ret.addTerminalSymbol( symbol );
-
-	const std::set<alphabet::Symbol> & terminals = ret.getTerminalAlphabet( );
-	for( const auto & rule : grammar.getRawRules( ) ) {
-		if( Nt.count( rule.first ) ) {
-			for( const auto & rhs : rule.second ) {
-				if( all_of( rhs.begin( ), rhs.end( ), [ Nt, terminals ]( const alphabet::Symbol & symbol ) {
-						return Nt.count( symbol ) || terminals.count( symbol );
-				} ) )
-					ret.addRawRule( rule.first, rhs );
-			}
-		}
-	}
-
-
-	/* if( ! G1.getNonTerminalSymbols( ) . count( grammar.getInitialSymbol( ) ) )
-		throw AlibException( "Starting symbol of grammar was marked as unproductive and therefore it was removed." ); */
-
-	// 2.
-	return ret;
-}
-
-template grammar::CFG TrimCFG::removeUnproductiveSymbols( const grammar::CFG & grammar );
-template grammar::EpsilonFreeCFG TrimCFG::removeUnproductiveSymbols( const grammar::EpsilonFreeCFG & grammar );
-template grammar::GNF TrimCFG::removeUnproductiveSymbols( const grammar::GNF & grammar );
-template grammar::CNF TrimCFG::removeUnproductiveSymbols( const grammar::CNF & grammar );
-template grammar::LG TrimCFG::removeUnproductiveSymbols( const grammar::LG & grammar );
-template grammar::LeftLG TrimCFG::removeUnproductiveSymbols( const grammar::LeftLG & grammar );
-template grammar::LeftRG TrimCFG::removeUnproductiveSymbols( const grammar::LeftRG & grammar );
-template grammar::RightLG TrimCFG::removeUnproductiveSymbols( const grammar::RightLG & grammar );
-template grammar::RightRG TrimCFG::removeUnproductiveSymbols( const grammar::RightRG & grammar );
-
-template<class T>
-T TrimCFG::trim( const T & grammar ) {
-	return removeUnreachableSymbols( removeUnproductiveSymbols( grammar ) );
-}
-
-template grammar::CFG TrimCFG::trim( const grammar::CFG & grammar );
-template grammar::EpsilonFreeCFG TrimCFG::trim( const grammar::EpsilonFreeCFG & grammar );
-template grammar::GNF TrimCFG::trim( const grammar::GNF & grammar );
-template grammar::CNF TrimCFG::trim( const grammar::CNF & grammar );
-template grammar::LG TrimCFG::trim( const grammar::LG & grammar );
-template grammar::LeftLG TrimCFG::trim( const grammar::LeftLG & grammar );
-template grammar::LeftRG TrimCFG::trim( const grammar::LeftRG & grammar );
-template grammar::RightLG TrimCFG::trim( const grammar::RightLG & grammar );
-template grammar::RightRG TrimCFG::trim( const grammar::RightRG & grammar );
-
-}
-
diff --git a/alib2algo/src/trim/grammar/TrimCFG.h b/alib2algo/src/trim/grammar/TrimCFG.h
deleted file mode 100644
index 3b320cdcd81e328fec37f06feffbf998faa365d9..0000000000000000000000000000000000000000
--- a/alib2algo/src/trim/grammar/TrimCFG.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * TrimCFG.h
- *
- *  Created on: 22. 3. 2014
- *	  Author: Tomas Pecka
- */
-
-#ifndef TRIM_CFG_H_
-#define TRIM_CFG_H_
-
-#include <algorithm>
-#include <deque>
-#include <set>
-
-#include <exception/AlibException.h>
-
-#include <alphabet/Symbol.h>
-
-namespace trim {
-
-/**
- * Implements algorithms from Melichar, chapter 3.3
- */
-class TrimCFG {
-public:
-	/*
-	 * Removes unreachable symbols - Melichar 3.9
-	 */
-	template<class T>
-	static T removeUnreachableSymbols( const T & grammar );
-
-	/**
-	 * Removes unproductive (or useless - terminology) symbols - Melichar 3.12
-	 */
-	template<class T>
-	static T removeUnproductiveSymbols( const T & grammar );
-
-	/**
-	 * Removes unproductive and useless symbols - Melichar 3.12
-	 */
-	template<class T>
-	static T trim( const T & grammar );
-};
-
-}
-
-#endif /* TRIM_CFG_H_ */
diff --git a/alib2algo/test-src/determinize/determinizeTest.cpp b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
similarity index 94%
rename from alib2algo/test-src/determinize/determinizeTest.cpp
rename to alib2algo/test-src/automaton/determinize/determinizeTest.cpp
index fe1bf1fb1b60013fe6ad594a3a5ac49256f6ee68..f2408f344d5c7d37098c5298661be4d6ca3f7b7b 100644
--- a/alib2algo/test-src/determinize/determinizeTest.cpp
+++ b/alib2algo/test-src/automaton/determinize/determinizeTest.cpp
@@ -1,8 +1,7 @@
 #include <list>
 #include "determinizeTest.h"
 
-#include "determinize/nfa/NFADeterminizer.h"
-#include "determinize/idpda/IDPDADeterminizer.h"
+#include "automaton/determinize/Determinize.h"
 
 #include "factory/DataFactory.hpp"
 
@@ -30,7 +29,7 @@ void determinizeTest::testDeterminizeNFA() {
 
   automaton.addFinalState(automaton::State(3));
 
-  automaton::DFA determinized = determinize::NFADeterminizer::determinize(automaton);
+  automaton::DFA determinized = automaton::determinize::Determinize::determinize(automaton);
 
   CPPUNIT_ASSERT(determinized.getStates().size() == 3);
 
@@ -54,7 +53,7 @@ void determinizeTest::testDeterminizeIDPDA() {
   automaton.addInitialState(automaton::State(1));
   automaton.addFinalState(automaton::State(3));
 
-  automaton::DPDA determinized = determinize::IDPDADeterminizer::determinize(automaton);
+  automaton::DPDA determinized = automaton::determinize::Determinize::determinize(automaton);
 
   CPPUNIT_ASSERT(determinized.getStates().size() == 3);
 }
diff --git a/alib2algo/test-src/determinize/determinizeTest.h b/alib2algo/test-src/automaton/determinize/determinizeTest.h
similarity index 100%
rename from alib2algo/test-src/determinize/determinizeTest.h
rename to alib2algo/test-src/automaton/determinize/determinizeTest.h
diff --git a/alib2algo/test-src/automaton/FSMSingleInitialStateTest.cpp b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
similarity index 67%
rename from alib2algo/test-src/automaton/FSMSingleInitialStateTest.cpp
rename to alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
index 2b592081c33f62e8ee438c32f90909549bcfbb19..4a7ce40ba2436070e58dd19219c0bf2bd3e6a1a7 100644
--- a/alib2algo/test-src/automaton/FSMSingleInitialStateTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.cpp
@@ -1,8 +1,10 @@
 #include "FSMSingleInitialStateTest.h"
 
-#include "automaton/FSMSingleInitialState.h"
-#include "determinize/nfa/NFADeterminizer.h"
-#include "normalize/dfa/NormalizeDFA.h"
+#include "automaton/simplify/SingleInitialState.h"
+#include "automaton/determinize/Determinize.h"
+#include "automaton/simplify/Normalize.h"
+
+#include "automaton/FSM/MultiInitialStateNFA.h"
 
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
@@ -33,7 +35,7 @@ void FSMSingleInitialStateTest::testSingleInitialState() {
 	automaton1.addTransition(q1, b, q2);
 	automaton1.addTransition(q2, a, q3);
 
-	automaton::NFA automaton2 = automaton::FSMSingleInitialState::convert(automaton1);
+	automaton::NFA automaton2 = automaton::simplify::SingleInitialState::convert(automaton1);
 
 	automaton::NFA automaton3(q);
 	automaton3.setStates({q, q1, q2, q3});
@@ -45,8 +47,8 @@ void FSMSingleInitialStateTest::testSingleInitialState() {
 	automaton3.addTransition(q1, b, q2);
 	automaton3.addTransition(q2, a, q3);
 
-	automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(automaton2);
-	automaton::DFA dfa3 = determinize::NFADeterminizer::determinize(automaton3);
+	automaton::DFA dfa2 = automaton::determinize::Determinize::determinize(automaton2);
+	automaton::DFA dfa3 = automaton::determinize::Determinize::determinize(automaton3);
 
-	CPPUNIT_ASSERT(normalize::NormalizeDFA::normalize(dfa3) == normalize::NormalizeDFA::normalize(dfa3));
+	CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(dfa3) == automaton::simplify::Normalize::normalize(dfa3));
 }
diff --git a/alib2algo/test-src/automaton/FSMSingleInitialStateTest.h b/alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.h
similarity index 100%
rename from alib2algo/test-src/automaton/FSMSingleInitialStateTest.h
rename to alib2algo/test-src/automaton/simplify/FSMSingleInitialStateTest.h
diff --git a/alib2algo/test-src/automaton/FSMTotalTest.cpp b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp
similarity index 62%
rename from alib2algo/test-src/automaton/FSMTotalTest.cpp
rename to alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp
index c5ce5a4a1577636a6477d45f850d7e639ec7a934..7e6ba6ab2c652bf696f5b4e901da0882ba65cedc 100644
--- a/alib2algo/test-src/automaton/FSMTotalTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/FSMTotalTest.cpp
@@ -2,9 +2,9 @@
 
 #include <automaton/FSM/DFA.h>
 
-#include "automaton/FSMTotal.h"
-#include "normalize/dfa/NormalizeDFA.h"
-#include "trim/automaton/Trim.h"
+#include "automaton/simplify/Total.h"
+#include "automaton/simplify/Normalize.h"
+#include "automaton/simplify/Trim.h"
 
 CPPUNIT_TEST_SUITE_REGISTRATION( TotalTest );
 
@@ -35,11 +35,11 @@ void TotalTest::testTotal() {
 	automaton.addTransition(q1, c, q2);
 	automaton.addTransition(q2, c, q2);
 
-	automaton::DFA totalAutomaton = automaton::FSMTotal::total(automaton);
+	automaton::DFA totalAutomaton = automaton::simplify::Total::total(automaton);
 	CPPUNIT_ASSERT(totalAutomaton.isTotal());
 
-	automaton::DFA trimmedAutomaton = trim::Trim::trim(automaton);
-	automaton::DFA trimmedTotalAutomaton = trim::Trim::trim(totalAutomaton);
+	automaton::DFA trimmedAutomaton = automaton::simplify::Trim::trim(automaton);
+	automaton::DFA trimmedTotalAutomaton = automaton::simplify::Trim::trim(totalAutomaton);
 
-	CPPUNIT_ASSERT(normalize::NormalizeDFA::normalize(trimmedAutomaton) == normalize::NormalizeDFA::normalize(trimmedTotalAutomaton));
+	CPPUNIT_ASSERT(automaton::simplify::Normalize::normalize(trimmedAutomaton) == automaton::simplify::Normalize::normalize(trimmedTotalAutomaton));
 }
diff --git a/alib2algo/test-src/automaton/FSMTotalTest.h b/alib2algo/test-src/automaton/simplify/FSMTotalTest.h
similarity index 100%
rename from alib2algo/test-src/automaton/FSMTotalTest.h
rename to alib2algo/test-src/automaton/simplify/FSMTotalTest.h
diff --git a/alib2algo/test-src/minimize/minimizeTest.cpp b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
similarity index 87%
rename from alib2algo/test-src/minimize/minimizeTest.cpp
rename to alib2algo/test-src/automaton/simplify/minimizeTest.cpp
index 8351ca03e5d2039a8643b24b244f5cf5f2ad077b..f5153ba2896850a7642f3deab3567acd5b425f33 100644
--- a/alib2algo/test-src/minimize/minimizeTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/minimizeTest.cpp
@@ -1,7 +1,7 @@
 #include <list>
 #include "minimizeTest.h"
 
-#include "minimize/dfa/MinimizeDFA.h"
+#include "automaton/simplify/Minimize.h"
 
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
@@ -27,7 +27,7 @@ void minimizeTest::testMinimize() {
 
   automaton.addFinalState(automaton::State(3));
   
-  automaton::DFA minimized = minimize::MinimizeDFA::minimize(automaton);
+  automaton::DFA minimized = automaton::simplify::Minimize::minimize(automaton);
 
   CPPUNIT_ASSERT(minimized.getStates().size() == 3);
 
diff --git a/alib2algo/test-src/minimize/minimizeTest.h b/alib2algo/test-src/automaton/simplify/minimizeTest.h
similarity index 100%
rename from alib2algo/test-src/minimize/minimizeTest.h
rename to alib2algo/test-src/automaton/simplify/minimizeTest.h
diff --git a/alib2algo/test-src/normalize/normalizeTest.cpp b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp
similarity index 87%
rename from alib2algo/test-src/normalize/normalizeTest.cpp
rename to alib2algo/test-src/automaton/simplify/normalizeTest.cpp
index 6ffd51fbb4a46fa4db81076b89458f2677d28f81..e12bbec861366f3257b4d66c05883c1e0c1f99e4 100644
--- a/alib2algo/test-src/normalize/normalizeTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/normalizeTest.cpp
@@ -1,7 +1,7 @@
 #include <list>
 #include "normalizeTest.h"
 
-#include "normalize/dfa/NormalizeDFA.h"
+#include "automaton/simplify/Normalize.h"
 
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
@@ -27,7 +27,7 @@ void normalizeTest::testNormalize() {
 
   automaton.addFinalState(automaton::State(2));
   
-  automaton::DFA normalized = normalize::NormalizeDFA::normalize(automaton);
+  automaton::DFA normalized = automaton::simplify::Normalize::normalize(automaton);
 
   CPPUNIT_ASSERT(normalized.getStates().size() == 3);
 
diff --git a/alib2algo/test-src/normalize/normalizeTest.h b/alib2algo/test-src/automaton/simplify/normalizeTest.h
similarity index 100%
rename from alib2algo/test-src/normalize/normalizeTest.h
rename to alib2algo/test-src/automaton/simplify/normalizeTest.h
diff --git a/alib2algo/test-src/trim/trimTest.cpp b/alib2algo/test-src/automaton/simplify/trimTest.cpp
similarity index 91%
rename from alib2algo/test-src/trim/trimTest.cpp
rename to alib2algo/test-src/automaton/simplify/trimTest.cpp
index 2de4d81f8470561ae675f430f5dd53763ae9a858..a4b46abe0f2eff9d34ceb896442136f5519293c6 100644
--- a/alib2algo/test-src/trim/trimTest.cpp
+++ b/alib2algo/test-src/automaton/simplify/trimTest.cpp
@@ -1,8 +1,8 @@
 #include <list>
 #include "trimTest.h"
 
-#include "trim/automaton/Trim.h"
-#include "trim/grammar/TrimCFG.h"
+#include "automaton/simplify/Trim.h"
+#include "grammar/simplify/Trim.h"
 
 #include "automaton/FSM/DFA.h"
 #include "grammar/Regular/RightRG.h"
@@ -32,7 +32,7 @@ void trimTest::testTrimAutomaton() {
 
   automaton.addFinalState(automaton::State(1));
   
-  automaton::DFA trimed = trim::Trim::trim(automaton);
+  automaton::DFA trimed = automaton::simplify::Trim::trim(automaton);
 
   CPPUNIT_ASSERT(trimed.getStates().size() == 2);
 }
@@ -58,7 +58,7 @@ void trimTest::testTrimGrammar() {
   rrGrammar.addRule(alphabet::symbolFrom(5), std::make_pair(alphabet::symbolFrom("b"), alphabet::symbolFrom(2)));
   rrGrammar.addRule(alphabet::symbolFrom(6), std::make_pair(alphabet::symbolFrom("b"), alphabet::symbolFrom(6)));
 
-  grammar::RightRG trimed = trim::TrimCFG::trim(rrGrammar);
+  grammar::RightRG trimed = grammar::simplify::Trim::trim(rrGrammar);
 
   CPPUNIT_ASSERT(trimed.getNonterminalAlphabet().size() == 3);
 }
diff --git a/alib2algo/test-src/trim/trimTest.h b/alib2algo/test-src/automaton/simplify/trimTest.h
similarity index 100%
rename from alib2algo/test-src/trim/trimTest.h
rename to alib2algo/test-src/automaton/simplify/trimTest.h
diff --git a/alib2algo/test-src/compare/compareTest.cpp b/alib2algo/test-src/compare/compareTest.cpp
deleted file mode 100644
index 9ada8b24b774329e4cdd2df6d348854630fcb378..0000000000000000000000000000000000000000
--- a/alib2algo/test-src/compare/compareTest.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <list>
-#include "compareTest.h"
-
-#include "compare/string/CyclicStringCompare.h"
-#include "string/LinearString.h"
-
-#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
-
-CPPUNIT_TEST_SUITE_REGISTRATION( compareTest );
-
-void compareTest::setUp() {
-}
-
-void compareTest::tearDown() {
-}
-
-void compareTest::testCyclicStringCompareBoolean() {
-  string::LinearString str1("alfa");
-  string::LinearString str2("aalf");
-  str2.addSymbolsToAlphabet(str1.getAlphabet());
-  str1.addSymbolsToAlphabet(str2.getAlphabet());
-  
-  CPPUNIT_ASSERT(compare::CyclicStringCompare::equals(str1, str2));
-}
-
-void compareTest::testCyclicStringCompareInt() {
-  string::LinearString str1("alfa");
-  string::LinearString str2("aalf");
-  str2.addSymbolsToAlphabet(str1.getAlphabet());
-  str1.addSymbolsToAlphabet(str2.getAlphabet());
-  
-  CPPUNIT_ASSERT(compare::CyclicStringCompare::compare(str1, str2) == 0);
-}
diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
deleted file mode 100644
index 9adb79a4c57b375ed7e1360c009cec27ed8b8a02..0000000000000000000000000000000000000000
--- a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include <list>
-#include "re2faTest.h"
-
-#include "conversions/re2fa/BrzozowskiDerivation.h"
-#include "conversions/re2fa/GlushkovNFA.h"
-#include "conversions/re2fa/Thompson.h"
-#include "conversions/fa2re/Algebraic.h"
-#include "determinize/nfa/NFADeterminizer.h"
-#include "minimize/dfa/MinimizeDFA.h"
-#include "normalize/dfa/NormalizeDFA.h"
-#include "epsilon/fsm/FSMEpsilonRemover.h"
-
-#include "regexp/unbounded/UnboundedRegExp.h"
-#include "regexp/RegExpFromStringParser.h"
-
-#include "automaton/FSM/NFA.h"
-#include <factory/DataFactory.hpp>
-
-CPPUNIT_TEST_SUITE_REGISTRATION( re2faTest );
-
-void re2faTest::setUp() {
-}
-
-void re2faTest::tearDown() {
-}
-
-void re2faTest::testThompson() {
-	std::string input = "a+a* b*";
-	std::stringstream inputs(input);
-
-	regexp::RegExpFromStringParser parser(inputs);
-	regexp::RegExp regexp1( parser.parseValue() );
-
-	automaton::Automaton enfa1 = conversions::re2fa::Thompson::convert(regexp1);
-
-	regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(enfa1) );
-
-	automaton::Automaton enfa2 = conversions::re2fa::Thompson::convert(regexp2);
-
-	automaton::Automaton nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1);
-	automaton::Automaton nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2);
-
-	automaton::Automaton dfa1 = determinize::NFADeterminizer::determinize(nfa1);
-	automaton::Automaton dfa2 = determinize::NFADeterminizer::determinize(nfa2);
-
-	automaton::Automaton mdfa1 = minimize::MinimizeDFA::minimize(dfa1);
-	automaton::Automaton mdfa2 = minimize::MinimizeDFA::minimize(dfa2);
-
-	CPPUNIT_ASSERT( mdfa1 == mdfa2);
-}
-
-void re2faTest::testGlushkov() {
-	std::string input = "a+a* b*";
-	std::stringstream inputs(input);
-
-	regexp::RegExpFromStringParser parser(inputs);
-	regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) );
-
-    conversions::re2fa::GlushkovNFA glushkov1;
-	automaton::NFA nfa1 = glushkov1.convert(regexp1);
-
-	regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( conversions::fa2re::Algebraic::convert(nfa1) ) );
-
-	conversions::re2fa::GlushkovNFA glushkov2;
-	automaton::NFA nfa2 = glushkov2.convert(regexp2);
-
-	automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1);
-	automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2);
-
-	automaton::DFA mdfa1 = minimize::MinimizeDFA::minimize(dfa1);
-	automaton::DFA mdfa2 = minimize::MinimizeDFA::minimize(dfa2);
-
-	CPPUNIT_ASSERT( mdfa1 == mdfa2);
-}
-
-void re2faTest::testBrzozowski() {
-	std::string input = "a+a* b*";
-	std::stringstream inputs(input);
-
-	regexp::RegExpFromStringParser parser(inputs);
-	regexp::RegExp regexp1( parser.parseValue() );
-
-	automaton::Automaton nfa1 = conversions::re2fa::BrzozowskiDerivation::convert(regexp1);
-
-	regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(static_cast<const automaton::NFA&>(nfa1.getData())) );
-
-	automaton::Automaton nfa2 = conversions::re2fa::BrzozowskiDerivation::convert(regexp2);
-
-	automaton::DFA mdfa1_1 = determinize::NFADeterminizer::determinize(static_cast<const automaton::NFA&>(nfa1.getData()));
-	automaton::DFA mdfa1_2 = minimize::MinimizeDFA::minimize(mdfa1_1);
-	automaton::DFA mdfa1_3 = normalize::NormalizeDFA::normalize(mdfa1_2);
-
-	automaton::DFA mdfa2_1 = determinize::NFADeterminizer::determinize(static_cast<const automaton::NFA&>(nfa2.getData()));
-	automaton::DFA mdfa2_2 = minimize::MinimizeDFA::minimize(mdfa2_1);
-	automaton::DFA mdfa2_3 = normalize::NormalizeDFA::normalize(mdfa2_2);
-
-	CPPUNIT_ASSERT( mdfa1_3 == mdfa2_3);
-}
diff --git a/alib2algo/test-src/grammar/GrammarPropertiesTest.cpp b/alib2algo/test-src/grammar/properties/GrammarPropertiesTest.cpp
similarity index 78%
rename from alib2algo/test-src/grammar/GrammarPropertiesTest.cpp
rename to alib2algo/test-src/grammar/properties/GrammarPropertiesTest.cpp
index d3f8019d1bd33a7ddf3f4d824adc920517dd72c0..dcc23b4012cf396551bb9bdea178d5398cbafe9b 100644
--- a/alib2algo/test-src/grammar/GrammarPropertiesTest.cpp
+++ b/alib2algo/test-src/grammar/properties/GrammarPropertiesTest.cpp
@@ -5,7 +5,8 @@
 #include <alphabet/LabeledSymbol.h>
 #include <alphabet/Symbol.h>
 
-#include "grammar/GrammarPropertiesCFG.h"
+#include "grammar/properties/NullableNonterminals.h"
+#include "grammar/properties/NonterminalUnitRuleCycle.h"
 
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
@@ -36,7 +37,7 @@ void GrammarPropertiesTest::testNullable() {
 	grammar.addRule(Z, std::vector<alphabet::Symbol>{ X, Y, Z });
 
 	std::set<alphabet::Symbol> res = {X, Y};
-	CPPUNIT_ASSERT(res == grammar::GrammarPropertiesCFG::getNullableNonterminals(grammar));
+	CPPUNIT_ASSERT(res == grammar::properties::NullableNonterminals::getNullableNonterminals(grammar));
 }
 
 void GrammarPropertiesTest::testUnitRules() {
@@ -67,8 +68,8 @@ void GrammarPropertiesTest::testUnitRules() {
 	std::set<alphabet::Symbol> N_B = {B};
 	std::set<alphabet::Symbol> N_C = {C};
 
-	CPPUNIT_ASSERT(N_S == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, S));
-	CPPUNIT_ASSERT(N_A == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, A));
-	CPPUNIT_ASSERT(N_B == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, B));
-	CPPUNIT_ASSERT(N_C == grammar::GrammarPropertiesCFG::getNonterminalUnitRuleCycle(llg, C));
+	CPPUNIT_ASSERT(N_S == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, S));
+	CPPUNIT_ASSERT(N_A == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, A));
+	CPPUNIT_ASSERT(N_B == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, B));
+	CPPUNIT_ASSERT(N_C == grammar::properties::NonterminalUnitRuleCycle::getNonterminalUnitRuleCycle(llg, C));
 }
diff --git a/alib2algo/test-src/grammar/GrammarPropertiesTest.h b/alib2algo/test-src/grammar/properties/GrammarPropertiesTest.h
similarity index 100%
rename from alib2algo/test-src/grammar/GrammarPropertiesTest.h
rename to alib2algo/test-src/grammar/properties/GrammarPropertiesTest.h
diff --git a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp b/alib2algo/test-src/grammar/toGrammar/rg2rgTest.cpp
similarity index 91%
rename from alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp
rename to alib2algo/test-src/grammar/toGrammar/rg2rgTest.cpp
index 42bb8b4a644d69cae0feefcb14e4147e9ef81a35..ebf7a14df0cd2755058c0f973ce4c4e695c6cac5 100644
--- a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.cpp
+++ b/alib2algo/test-src/grammar/toGrammar/rg2rgTest.cpp
@@ -1,8 +1,8 @@
 #include <list>
 #include "rg2rgTest.h"
 
-#include "conversions/rg2rg/RightToLeftRegularGrammar.h"
-#include "conversions/rg2rg/LeftToRightRegularGrammar.h"
+#include "grammar/convert/ToGrammarLeftRG.h"
+#include "grammar/convert/ToGrammarRightRG.h"
 
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
@@ -27,7 +27,7 @@ void rg2rgTest::testConversion() {
   rrGrammar.addRule(alphabet::symbolFrom(2), std::make_pair(alphabet::symbolFrom("b"), alphabet::symbolFrom(3)));
   rrGrammar.addRule(alphabet::symbolFrom(3), alphabet::symbolFrom("a"));
 
-  grammar::LeftRG lrGrammar = conversions::rg2rg::RightToLeftRegularGrammar::convert(rrGrammar);
+  grammar::LeftRG lrGrammar = grammar::convert::ToGrammarLeftRG::convert(rrGrammar);
 
   grammar::LeftRG lrGrammarRef(alphabet::symbolFrom(4));
 
@@ -58,7 +58,7 @@ void rg2rgTest::testConversion2() {
   lrGrammar.addRule(alphabet::symbolFrom(3), std::make_pair(alphabet::symbolFrom(2), alphabet::symbolFrom("b")));
   lrGrammar.addRule(alphabet::symbolFrom(4), std::make_pair(alphabet::symbolFrom(3), alphabet::symbolFrom("a")));
 
-  grammar::RightRG rrGrammar = conversions::rg2rg::LeftToRightRegularGrammar::convert(lrGrammar);
+  grammar::RightRG rrGrammar = grammar::convert::ToGrammarRightRG::convert(lrGrammar);
 
   grammar::RightRG rrGrammarRef(alphabet::symbolFrom(5));
 
diff --git a/alib2algo/test-src/conversions/rg2rg/rg2rgTest.h b/alib2algo/test-src/grammar/toGrammar/rg2rgTest.h
similarity index 100%
rename from alib2algo/test-src/conversions/rg2rg/rg2rgTest.h
rename to alib2algo/test-src/grammar/toGrammar/rg2rgTest.h
diff --git a/alib2algo/test-src/conversions/playTest.cpp b/alib2algo/test-src/playTest.cpp
similarity index 71%
rename from alib2algo/test-src/conversions/playTest.cpp
rename to alib2algo/test-src/playTest.cpp
index 9931f8f8794d4241bc4db1e50e4212280fddc789..82c3c242baab48d1d7af6a09cd14b94ac0e26b27 100644
--- a/alib2algo/test-src/conversions/playTest.cpp
+++ b/alib2algo/test-src/playTest.cpp
@@ -4,14 +4,12 @@
 #include <cstdlib>
 #include <ctime>
 
-#include "determinize/nfa/NFADeterminizer.h"
-#include "minimize/dfa/MinimizeDFA.h"
-
-#include "generator/RandomAutomatonFactory.h"
-#include "normalize/dfa/NormalizeDFA.h"
-#include "trim/automaton/Trim.h"
-#include "epsilon/fsm/FSMEpsilonRemover.h"
-#include "minimize/dfa/MinimizeDFA.h"
+#include "automaton/determinize/Determinize.h"
+#include "automaton/generate/RandomAutomatonFactory.h"
+#include "automaton/simplify/Minimize.h"
+#include "automaton/simplify/Normalize.h"
+#include "automaton/simplify/Trim.h"
+#include "automaton/simplify/EpsilonRemover.h"
 
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
@@ -31,7 +29,7 @@ void playTest::tearDown(){}
 
 automaton::NFA playTest::randomNFA(void) const
 {
-    return generator::RandomAutomatonFactory::generateNFA(
+    return automaton::generate::RandomAutomatonFactory::generateNFA(
             rand() % TEST_AUTOMATON_STATES_MAX + 1,
             rand() % TEST_AUTOMATON_ALPHABET_MAX + 1,
             static_cast<double> (rand()) / (static_cast<double> (RAND_MAX/TEST_AUTOMATON_DENSITY_MAX))
@@ -40,12 +38,12 @@ automaton::NFA playTest::randomNFA(void) const
 
 automaton::DFA playTest::mDFA(const automaton::NFA& automaton) const
 {
-    automaton::NFA nfa = epsilon::FSMEpsilonRemover::remove(automaton);
-    nfa = trim::Trim::trim(nfa);
-    automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa);
-    dfa = trim::Trim::trim(dfa);
-    dfa = minimize::MinimizeDFA::minimize(dfa);
-    dfa = normalize::NormalizeDFA::normalize(dfa);
+    automaton::NFA nfa = automaton::simplify::EpsilonRemover::remove(automaton);
+    nfa = automaton::simplify::Trim::trim(nfa);
+    automaton::DFA dfa = automaton::determinize::Determinize::determinize(nfa);
+    dfa = automaton::simplify::Trim::trim(dfa);
+    dfa = automaton::simplify::Minimize::minimize(dfa);
+    dfa = automaton::simplify::Normalize::normalize(dfa);
     return dfa;
 }
 
diff --git a/alib2algo/test-src/conversions/playTest.h b/alib2algo/test-src/playTest.h
similarity index 100%
rename from alib2algo/test-src/conversions/playTest.h
rename to alib2algo/test-src/playTest.h
diff --git a/alib2algo/test-src/regexp/RegExpEmptyTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp
similarity index 78%
rename from alib2algo/test-src/regexp/RegExpEmptyTest.cpp
rename to alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp
index d451d65689f3eded0b6de2b67ecad26accad47de..bf5dfdb0d2eb2d29e33bed488af62e7c972d2633 100644
--- a/alib2algo/test-src/regexp/RegExpEmptyTest.cpp
+++ b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.cpp
@@ -1,6 +1,6 @@
 #include "RegExpEmptyTest.h"
 
-#include "regexp/RegExpEmpty.h"
+#include "regexp/properties/RegExpEmpty.h"
 
 #include <sstream>
 #include <regexp/RegExp.h>
@@ -21,7 +21,7 @@ void RegExpEmptyTest::testRegExpEmpty() {
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(regexp::RegExpEmpty::languageIsEmpty(re));
+		CPPUNIT_ASSERT(regexp::properties::RegExpEmpty::languageIsEmpty(re));
 	}
 	{
 		std::string input = "(#E + a ) + ( #0 a + (b ( #0 (a*) ) ) )";
@@ -29,6 +29,6 @@ void RegExpEmptyTest::testRegExpEmpty() {
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(! regexp::RegExpEmpty::languageIsEmpty(re));
+		CPPUNIT_ASSERT(! regexp::properties::RegExpEmpty::languageIsEmpty(re));
 	}
 }
diff --git a/alib2algo/test-src/regexp/RegExpEmptyTest.h b/alib2algo/test-src/regexp/properties/RegExpEmptyTest.h
similarity index 100%
rename from alib2algo/test-src/regexp/RegExpEmptyTest.h
rename to alib2algo/test-src/regexp/properties/RegExpEmptyTest.h
diff --git a/alib2algo/test-src/regexp/RegExpEpsilonTest.cpp b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp
similarity index 69%
rename from alib2algo/test-src/regexp/RegExpEpsilonTest.cpp
rename to alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp
index 86e177beb8af91690b5535d0f35e19bba1604bd3..05c2af2065968df9099cdaed0aa53ef92ca67c56 100644
--- a/alib2algo/test-src/regexp/RegExpEpsilonTest.cpp
+++ b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.cpp
@@ -1,6 +1,6 @@
 #include "RegExpEpsilonTest.h"
 
-#include "regexp/RegExpEpsilon.h"
+#include "regexp/properties/RegExpEpsilon.h"
 #include <sstream>
 #include <regexp/RegExpFromStringParser.h>
 
@@ -20,54 +20,54 @@ void RegExpEpsilonTest::testRegExpEpsilon() {
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
-	}	
+		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
+	}
 	{
 		std::string input = "( a* )( a* )";
 		std::stringstream inputs(input);
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
-	}	
+		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
+	}
 	{
 		std::string input = "a + #0";
 		std::stringstream inputs(input);
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re));
-	}	
+		CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
+	}
 	{
 		std::string input = "#E + a #E + a*";
 		std::stringstream inputs(input);
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
-	}	
+		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
+	}
 	{
 		std::string input = "a* a*";
 		std::stringstream inputs(input);
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
-	}	
+		CPPUNIT_ASSERT(regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
+	}
 	{
 		std::string input = "a s d #E + #E #0";
 		std::stringstream inputs(input);
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re));
-	}	
+		CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
+	}
 	{
 		std::string input = "a + #0";
 		std::stringstream inputs(input);
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::RegExp re = parser.parseValue();
 
-		CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re));
-	}	
+		CPPUNIT_ASSERT(! regexp::properties::RegExpEpsilon::languageContainsEpsilon(re));
+	}
 }
diff --git a/alib2algo/test-src/regexp/RegExpEpsilonTest.h b/alib2algo/test-src/regexp/properties/RegExpEpsilonTest.h
similarity index 100%
rename from alib2algo/test-src/regexp/RegExpEpsilonTest.h
rename to alib2algo/test-src/regexp/properties/RegExpEpsilonTest.h
diff --git a/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
similarity index 88%
rename from alib2algo/test-src/regexp/RegExpOptimizeTest.cpp
rename to alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
index bbe21afc1d430dbcc739efb3e810cc04ff34df0f..41c7be67a9006ea009c44b3576c81664d859832c 100644
--- a/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp
+++ b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.cpp
@@ -4,7 +4,7 @@
 #include "regexp/unbounded/UnboundedRegExp.h"
 #include "regexp/RegExpFromStringParser.h"
 
-#include "regexp/RegExpOptimize.h"
+#include "regexp/simplify/RegExpOptimize.h"
 
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 #define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y)))
@@ -25,8 +25,7 @@ void RegExpOptimizeTest::testOptimize() {
 		regexp::RegExpFromStringParser parser(inputs);
 		regexp::UnboundedRegExp regexp( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) );
 
-		regexp::RegExpOptimize opt;
-		regexp::UnboundedRegExp res = opt.optimize(regexp);
+		regexp::UnboundedRegExp res = regexp::simplify::RegExpOptimize::optimize(regexp);
 	}
 	{
 		std::string input = "a+a* (b+a)* c";
diff --git a/alib2algo/test-src/regexp/RegExpOptimizeTest.h b/alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.h
similarity index 100%
rename from alib2algo/test-src/regexp/RegExpOptimizeTest.h
rename to alib2algo/test-src/regexp/simplify/RegExpOptimizeTest.h
diff --git a/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d02597094105a569b0e960ce5d3ef3e6d190fa89
--- /dev/null
+++ b/alib2algo/test-src/regexp/toAutomaton/re2faTest.cpp
@@ -0,0 +1,96 @@
+#include <list>
+#include "re2faTest.h"
+
+#include "regexp/convert/ToAutomatonDerivation.h"
+#include "regexp/convert/ToAutomatonGlushkov.h"
+#include "regexp/convert/ToAutomatonThompson.h"
+#include "automaton/convert/ToRegExpAlgebraic.h"
+#include "automaton/determinize/Determinize.h"
+#include "automaton/simplify/Minimize.h"
+#include "automaton/simplify/Normalize.h"
+#include "automaton/simplify/EpsilonRemover.h"
+
+#include "regexp/unbounded/UnboundedRegExp.h"
+#include "regexp/RegExpFromStringParser.h"
+
+#include "automaton/FSM/NFA.h"
+#include <factory/DataFactory.hpp>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( re2faTest );
+
+void re2faTest::setUp() {
+}
+
+void re2faTest::tearDown() {
+}
+
+void re2faTest::testThompson() {
+	std::string input = "a+a* b*";
+	std::stringstream inputs(input);
+
+	regexp::RegExpFromStringParser parser(inputs);
+	regexp::RegExp regexp1( parser.parseValue() );
+
+	automaton::Automaton enfa1 = regexp::convert::ToAutomatonThompson::convert(regexp1);
+
+	regexp::RegExp regexp2( automaton::convert::ToRegExpAlgebraic::convert(enfa1) );
+
+	automaton::Automaton enfa2 = regexp::convert::ToAutomatonThompson::convert(regexp2);
+
+	automaton::Automaton nfa1 = automaton::simplify::EpsilonRemover::remove(enfa1);
+	automaton::Automaton nfa2 = automaton::simplify::EpsilonRemover::remove(enfa2);
+
+	automaton::Automaton dfa1 = automaton::determinize::Determinize::determinize(nfa1);
+	automaton::Automaton dfa2 = automaton::determinize::Determinize::determinize(nfa2);
+
+	automaton::Automaton mdfa1 = automaton::simplify::Minimize::minimize(dfa1);
+	automaton::Automaton mdfa2 = automaton::simplify::Minimize::minimize(dfa2);
+
+	CPPUNIT_ASSERT( mdfa1 == mdfa2);
+}
+
+void re2faTest::testGlushkov() {
+	std::string input = "a+a* b*";
+	std::stringstream inputs(input);
+
+	regexp::RegExpFromStringParser parser(inputs);
+	regexp::UnboundedRegExp regexp1( static_cast<const regexp::UnboundedRegExp &>( parser.parseValue().getData() ) );
+
+	automaton::NFA nfa1 = regexp::convert::ToAutomatonGlushkov::convert(regexp1);
+
+	regexp::UnboundedRegExp regexp2( static_cast<const regexp::UnboundedRegExp &>( automaton::convert::ToRegExpAlgebraic::convert(nfa1) ) );
+
+	automaton::NFA nfa2 = regexp::convert::ToAutomatonGlushkov::convert(regexp2);
+
+	automaton::DFA dfa1 = automaton::determinize::Determinize::determinize(nfa1);
+	automaton::DFA dfa2 = automaton::determinize::Determinize::determinize(nfa2);
+
+	automaton::DFA mdfa1 = automaton::simplify::Minimize::minimize(dfa1);
+	automaton::DFA mdfa2 = automaton::simplify::Minimize::minimize(dfa2);
+
+	CPPUNIT_ASSERT( mdfa1 == mdfa2);
+}
+
+void re2faTest::testBrzozowski() {
+	std::string input = "a+a* b*";
+	std::stringstream inputs(input);
+
+	regexp::RegExpFromStringParser parser(inputs);
+	regexp::RegExp regexp1( parser.parseValue() );
+
+	automaton::Automaton nfa1 = regexp::convert::ToAutomatonDerivation::convert(regexp1);
+
+	regexp::RegExp regexp2( automaton::convert::ToRegExpAlgebraic::convert(static_cast<const automaton::NFA&>(nfa1.getData())) );
+
+	automaton::Automaton nfa2 = regexp::convert::ToAutomatonDerivation::convert(regexp2);
+
+	automaton::DFA mdfa1_1 = automaton::determinize::Determinize::determinize(static_cast<const automaton::NFA&>(nfa1.getData()));
+	automaton::DFA mdfa1_2 = automaton::simplify::Minimize::minimize(mdfa1_1);
+	automaton::DFA mdfa1_3 = automaton::simplify::Normalize::normalize(mdfa1_2);
+
+	automaton::DFA mdfa2_1 = automaton::determinize::Determinize::determinize(static_cast<const automaton::NFA&>(nfa2.getData()));
+	automaton::DFA mdfa2_2 = automaton::simplify::Minimize::minimize(mdfa2_1);
+	automaton::DFA mdfa2_3 = automaton::simplify::Normalize::normalize(mdfa2_2);
+
+	CPPUNIT_ASSERT( mdfa1_3 == mdfa2_3);
+}
diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.h b/alib2algo/test-src/regexp/toAutomaton/re2faTest.h
similarity index 100%
rename from alib2algo/test-src/conversions/re2fa/re2faTest.h
rename to alib2algo/test-src/regexp/toAutomaton/re2faTest.h
diff --git a/alib2algo/test-src/regexp/RegExpConcatenateTest.cpp b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
similarity index 98%
rename from alib2algo/test-src/regexp/RegExpConcatenateTest.cpp
rename to alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
index 531302826131cf14140c72b09f20198dac631133..0f2441f469e218f41409a42723644f9ebfd5f69e 100644
--- a/alib2algo/test-src/regexp/RegExpConcatenateTest.cpp
+++ b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.cpp
@@ -1,6 +1,6 @@
 #include "RegExpConcatenateTest.h"
 
-#include "regexp/RegExpConcatenate.h"
+#include "regexp/transform/RegExpConcatenate.h"
 
 #include <sstream>
 #include <regexp/RegExp.h>
diff --git a/alib2algo/test-src/regexp/RegExpConcatenateTest.h b/alib2algo/test-src/regexp/transform/RegExpConcatenateTest.h
similarity index 100%
rename from alib2algo/test-src/regexp/RegExpConcatenateTest.h
rename to alib2algo/test-src/regexp/transform/RegExpConcatenateTest.h
diff --git a/alib2algo/test-src/regexp/RegExpDerivationTest.cpp b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp
similarity index 97%
rename from alib2algo/test-src/regexp/RegExpDerivationTest.cpp
rename to alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp
index cab3743a202371b31a429b810188b1f109f4170a..268a9e20f936b96374d06e57f72eb5c918997a5c 100644
--- a/alib2algo/test-src/regexp/RegExpDerivationTest.cpp
+++ b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.cpp
@@ -2,7 +2,7 @@
 
 #include "RegExpDerivationTest.h"
 
-#include "regexp/RegExpDerivation.h"
+#include "regexp/transform/RegExpDerivation.h"
 
 #include <regexp/RegExpFromStringParser.h>
 #include <regexp/RegExpToStringComposer.h>
diff --git a/alib2algo/test-src/regexp/RegExpDerivationTest.h b/alib2algo/test-src/regexp/transform/RegExpDerivationTest.h
similarity index 100%
rename from alib2algo/test-src/regexp/RegExpDerivationTest.h
rename to alib2algo/test-src/regexp/transform/RegExpDerivationTest.h
diff --git a/alib2algo/test-src/regexp/RegExpIntegralTest.cpp b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp
similarity index 96%
rename from alib2algo/test-src/regexp/RegExpIntegralTest.cpp
rename to alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp
index fa92bed0de55b13b21347a9361888c5a8a65896c..a4ec1514eebc58aa91f618f0aaa248d04fb38aef 100644
--- a/alib2algo/test-src/regexp/RegExpIntegralTest.cpp
+++ b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.cpp
@@ -2,7 +2,7 @@
 
 #include "RegExpIntegralTest.h"
 
-#include "regexp/RegExpIntegral.h"
+#include "regexp/transform/RegExpIntegral.h"
 
 #include <regexp/RegExpFromStringParser.h>
 #include <regexp/RegExpToStringComposer.h>
diff --git a/alib2algo/test-src/regexp/RegExpIntegralTest.h b/alib2algo/test-src/regexp/transform/RegExpIntegralTest.h
similarity index 100%
rename from alib2algo/test-src/regexp/RegExpIntegralTest.h
rename to alib2algo/test-src/regexp/transform/RegExpIntegralTest.h
diff --git a/alib2algo/test-src/string/compare/compareTest.cpp b/alib2algo/test-src/string/compare/compareTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d75ef51ca8a3414a4b7b5eea6e901d5e1c099851
--- /dev/null
+++ b/alib2algo/test-src/string/compare/compareTest.cpp
@@ -0,0 +1,33 @@
+#include <list>
+#include "compareTest.h"
+
+#include "string/compare/CyclicStringCompare.h"
+#include "string/LinearString.h"
+
+#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
+
+CPPUNIT_TEST_SUITE_REGISTRATION( compareTest );
+
+void compareTest::setUp() {
+}
+
+void compareTest::tearDown() {
+}
+
+void compareTest::testCyclicStringCompareBoolean() {
+	string::LinearString str1("alfa");
+	string::LinearString str2("aalf");
+	str2.addSymbolsToAlphabet(str1.getAlphabet());
+	str1.addSymbolsToAlphabet(str2.getAlphabet());
+
+	CPPUNIT_ASSERT(string::compare::CyclicStringCompare::equals(str1, str2));
+}
+
+void compareTest::testCyclicStringCompareInt() {
+	string::LinearString str1("alfa");
+	string::LinearString str2("aalf");
+	str2.addSymbolsToAlphabet(str1.getAlphabet());
+	str1.addSymbolsToAlphabet(str2.getAlphabet());
+	
+	CPPUNIT_ASSERT(string::compare::CyclicStringCompare::compare(str1, str2) == 0);
+}
diff --git a/alib2algo/test-src/compare/compareTest.h b/alib2algo/test-src/string/compare/compareTest.h
similarity index 100%
rename from alib2algo/test-src/compare/compareTest.h
rename to alib2algo/test-src/string/compare/compareTest.h
diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
index cb53ab3f2428175058505e687839b569e31bc2a2..0ff6327c5b07830da28a2b96e53d4eb5ee8f3bd7 100644
--- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h
@@ -13,6 +13,12 @@
 
 namespace regexp {
 
+namespace simplify {
+
+class RegExpOptimize;
+
+} /* namespace simplify */
+
 /**
  * Represents alternation operator in the regular expression. Contains list of FormalRegExpElement
  * as operands of the operator.
@@ -98,7 +104,7 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	friend class RegExpOptimize;
+	friend class simplify::RegExpOptimize;
 
 	virtual operator std::string() const;
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
index 1f539385db24877572a4c93f22fd7c20cc3a0ebd..b88af6b5898241739b62c8517685c9770fa80147 100644
--- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
+++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h
@@ -14,6 +14,12 @@
 
 namespace regexp {
 
+namespace simplify {
+
+class RegExpOptimize;
+
+} /* namespace simplify */
+
 /**
  * Represents concatenation operator in the regular expression. Contains list of FormalRegExpElement
  * as operands of the operator.
@@ -96,7 +102,7 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	friend class RegExpOptimize;
+	friend class simplify::RegExpOptimize;
 
 	virtual operator std::string() const;
 
diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h
index aa35c9b21c2ca029ad37d1c023825fd894c7367c..9d0629cd7679d693a3e3811dad0541705c8c4ac6 100644
--- a/alib2data/src/regexp/formal/FormalRegExpIteration.h
+++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h
@@ -13,6 +13,12 @@
 
 namespace regexp {
 
+namespace simplify {
+
+class RegExpOptimize;
+
+} /* namespace simplify */
+
 /**
  * Represents iteration operator in the regular expression. Contains one FormalRegExpElement
  * as operand.
@@ -91,7 +97,7 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	friend class RegExpOptimize;
+	friend class simplify::RegExpOptimize;
 
 	virtual operator std::string() const;
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
index 18b9dec3a776af697f014f46a41278c99ba06b39..ab78cbfdac74d2f6e2a7b8b4b349a22337c05ea1 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
@@ -13,8 +13,12 @@
 
 namespace regexp {
 
+namespace simplify {
+
 class RegExpOptimize;
 
+} /* namespace simplify */
+
 /**
  * Represents alternation operator in the regular expression. Contains list of UnboundedRegExpElement
  * as operands of the operator.
@@ -94,7 +98,7 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	friend class RegExpOptimize;
+	friend class simplify::RegExpOptimize;
 
 	virtual operator std::string() const;
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
index feb155a2eb9cbfdb123dc38b3e371552da260bea..04314dfad668306318fc7fbc8d5b2cc7452a1469 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
@@ -13,8 +13,12 @@
 
 namespace regexp {
 
+namespace simplify {
+
 class RegExpOptimize;
 
+} /* namespace simplify */
+
 /**
  * Represents concatenation operator in the regular expression. Contains list of UnboundedRegExpElement
  * as operands of the operator.
@@ -92,8 +96,8 @@ public:
 	 * @copydoc UnboundedRegExpElement::operator>>() const
 	 */
 	virtual void operator>>(std::ostream& out) const;
-	
-	friend class RegExpOptimize;
+
+	friend class simplify::RegExpOptimize;
 
 	virtual operator std::string() const;
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
index 55b53447b360e77d5e0debe9a0977ad8faee3547..26901d9629db18efcb720fa1a0a1f0c73886ddd5 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
@@ -13,8 +13,12 @@
 
 namespace regexp {
 
+namespace simplify {
+
 class RegExpOptimize;
 
+} /* namespace simplify */
+
 /**
  * Represents iteration operator in the regular expression. Contains one UnboundedRegExpElement
  * as operand.
@@ -92,7 +96,7 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	friend class RegExpOptimize;
+	friend class simplify::RegExpOptimize;
 
 	virtual operator std::string() const;
 
diff --git a/aminimize2/src/aminimize.cpp b/aminimize2/src/aminimize.cpp
index b2c963e5e4ba9d0055b2da791c8ed2b4b87a1719..db1764078fdefe2cf45788cb8c1610f1c282730b 100644
--- a/aminimize2/src/aminimize.cpp
+++ b/aminimize2/src/aminimize.cpp
@@ -8,7 +8,7 @@
 #include <exception/AlibException.h>
 #include <factory/DataFactory.hpp>
 
-#include "minimize/dfa/MinimizeDFA.h"
+#include "automaton/simplify/Minimize.h"
 
 int main(int argc, char** argv) {
 
@@ -17,9 +17,9 @@ int main(int argc, char** argv) {
 			std::cout << "Automaton minimize." << std::endl << "Usage: aminimize automaton.xml" << std::endl;
 			return -1;
 		} else if (argc == 1 || (argc == 2 && std::string("--").compare(argv[1]) == 0)) {
-			alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>()));
+			alib::DataFactory::toStdout(automaton::simplify::Minimize::minimize(alib::DataFactory::fromStdin<automaton::Automaton>()));
 		} else if (argc == 2) {
-			alib::DataFactory::toStdout(minimize::MinimizeDFA::minimize(alib::DataFactory::fromStdin<automaton::Automaton>()));
+			alib::DataFactory::toStdout(automaton::simplify::Minimize::minimize(alib::DataFactory::fromFile<automaton::Automaton>(argv[1])));
 		} else {
 			std::cout << "Automaton minimize require deterministic finite automaton" << std::endl;
 			return 1;
diff --git a/anormalize2/src/anormalize.cpp b/anormalize2/src/anormalize.cpp
index 0c76be0727c4378c6b59953a7e04254d5db3b60a..66763a09ae2a399e99dd394cd6db85c0ff135971 100644
--- a/anormalize2/src/anormalize.cpp
+++ b/anormalize2/src/anormalize.cpp
@@ -9,7 +9,7 @@
 
 #include "exception/AlibException.h"
 #include "factory/DataFactory.hpp"
-#include "normalize/dfa/NormalizeDFA.h"
+#include "automaton/simplify/Normalize.h"
 
 int main(int argc, char** argv) {
 
@@ -29,7 +29,7 @@ int main(int argc, char** argv) {
 			return 1;
 		}
 		
-		automaton::DFA res = normalize::NormalizeDFA::normalize(*automatonPointer);
+		automaton::DFA res = automaton::simplify::Normalize::normalize(*automatonPointer);
 		alib::DataFactory::toStdout(res);
 
 		delete automatonPointer;
diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp
index ca55037be601a3b3028cfb82f7fdd410e4c0ea13..316e99a031900f7404b8576b6f79940a6cfa2b56 100644
--- a/arand2/src/arand.cpp
+++ b/arand2/src/arand.cpp
@@ -15,8 +15,8 @@
 #include <automaton/FSM/NFA.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
 #include <factory/DataFactory.hpp>
-#include "generator/RandomAutomatonFactory.h"
-#include "generator/RandomRegExpFactory.h"
+#include "automaton/generate/RandomAutomatonFactory.h"
+#include "regexp/generate/RandomRegExpFactory.h"
 
 void help( void )
 {
@@ -116,7 +116,7 @@ int main(int argc, char* argv[])
 			return 1;
 		}
 
-		automaton::NFA res = generator::RandomAutomatonFactory::generateNFA( statesCount, alphabetSize, density );
+		automaton::NFA res = automaton::generate::RandomAutomatonFactory::generateNFA( statesCount, alphabetSize, density );
 		alib::DataFactory::toStdout(res);
 	} else if( type == "RE" ) {
 
@@ -139,7 +139,7 @@ int main(int argc, char* argv[])
 			return 1;
 		}
 
-		regexp::UnboundedRegExp res = generator::RandomRegExpFactory::generateUnboundedRegExp(leafNodes, height, alphabetSize );
+		regexp::UnboundedRegExp res = regexp::generate::RandomRegExpFactory::generateUnboundedRegExp(leafNodes, height, alphabetSize );
 		alib::DataFactory::toStdout(res);
 	}
 
diff --git a/atrim2/src/atrim.cpp b/atrim2/src/atrim.cpp
index cf10cfcc21da413d6ea63245fb3bf1891b2e6121..5c4c11f8a360c8a955476ccbc77c6b03446b965f 100644
--- a/atrim2/src/atrim.cpp
+++ b/atrim2/src/atrim.cpp
@@ -4,11 +4,13 @@
 #include <factory/DataFactory.hpp>
 #include <exception/AlibException.h>
 
-#include "trim/grammar/TrimCFG.h"
-#include "trim/automaton/Trim.h"
-#include "trim/automaton/UselessStatesRemover.h"
-#include "trim/automaton/UnreachableStatesRemover.h"
-#include "regexp/RegExpOptimize.h"
+#include "grammar/simplify/Trim.h"
+#include "grammar/simplify/UnproductiveSymbolsRemover.h"
+#include "grammar/simplify/UnreachableSymbolsRemover.h"
+#include "automaton/simplify/Trim.h"
+#include "automaton/simplify/UselessStatesRemover.h"
+#include "automaton/simplify/UnreachableStatesRemover.h"
+#include "regexp/simplify/RegExpOptimize.h"
 
 void help( void ) {
 	std::cout << "atrim 0.01" << std::endl;
@@ -23,64 +25,28 @@ void help( void ) {
 	std::cout << std::endl;
 }
 
-template<typename T>
-grammar::GrammarBase* dynamicTrim(const grammar::Grammar& g, bool del_unreachable, bool del_useless) {
-	const T* gp = dynamic_cast<const T*>(&g.getData());
-
-	if(gp) {
-		T res(*gp);
-		if( del_unreachable )
-			res = trim::TrimCFG::removeUnreachableSymbols( res );
-		if( del_useless )
-			res = trim::TrimCFG::removeUnproductiveSymbols( res );
-		return std::move(res).plunder();
-	} else {
-		return NULL;
-	}
-}
-
-grammar::Grammar trimGrammar(const grammar::Grammar& g, bool del_unreachable, bool del_useless) {
-	grammar::GrammarBase* res = NULL;
-
-	res = dynamicTrim<grammar::CFG>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	res = dynamicTrim<grammar::EpsilonFreeCFG>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	res = dynamicTrim<grammar::GNF>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	res = dynamicTrim<grammar::CNF>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	res = dynamicTrim<grammar::LeftLG>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	res = dynamicTrim<grammar::LeftRG>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	res = dynamicTrim<grammar::RightLG>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	res = dynamicTrim<grammar::RightRG>(g, del_unreachable, del_useless);
-	if(res) return grammar::Grammar(*res);
-
-	throw exception::AlibException("Unsupported grammar type");
+grammar::Grammar trimGrammar(const grammar::Grammar& g, bool del_unreachable, bool del_unproductive) {
+	if( del_unreachable && del_unproductive )
+		return grammar::simplify::Trim::trim( g );
+	if( del_unreachable )
+		return grammar::simplify::UnreachableSymbolsRemover::remove( g );
+	if( del_unproductive )
+		return grammar::simplify::UnproductiveSymbolsRemover::remove( g );
+	return g;
 }
 
 automaton::Automaton trimAutomaton(const automaton::Automaton& g, bool del_unreachable, bool del_useless) {
 	if( del_unreachable && del_useless )
-		return trim::Trim::trim( g );
+		return automaton::simplify::Trim::trim( g );
 	if( del_unreachable )
-		return trim::UnreachableStatesRemover::remove( g );
+		return automaton::simplify::UnreachableStatesRemover::remove( g );
 	if( del_useless )
-		return trim::UnreachableStatesRemover::remove( g );
+		return automaton::simplify::UselessStatesRemover::remove( g );
 	return g;
 }
 
 regexp::RegExp optimizeRegExp(const regexp::RegExp& r) {
-	return regexp::RegExpOptimize::optimize( r );
+	return regexp::simplify::RegExpOptimize::optimize( r );
 }
 
 int main(int argc, char* argv[]) {