diff --git a/aaccept/makefile b/aaccept/makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d4fe0b69359fe2244bddf3a4dd1c3c0f455035da
--- /dev/null
+++ b/aaccept/makefile
@@ -0,0 +1,20 @@
+CC=g++
+EXECUTABLE=aaccept
+CCFLAGS= -std=c++11 -O2 -g -c -Wall -I../alib/src -I/usr/include/libxml2/ 
+LDFLAGS= -L../alib/lib -lxml2 -lalib -Wl,-rpath,.
+
+SOURCES=$(shell find src/ -name *cpp)
+OBJECTS=$(patsubst src/%.cpp, obj/%.o, $(SOURCES))
+
+all: $(SOURCES) bin/$(EXECUTABLE)
+
+bin/$(EXECUTABLE): $(OBJECTS)
+	mkdir -p bin
+	$(CC) $(OBJECTS) -o $@ $(LDFLAGS)
+
+obj/%.o: src/%.cpp
+	mkdir -p $(dir $@)
+	$(CC) $(CCFLAGS) $< -o $@
+
+clean:
+	$(RM) -r *.o *.d bin obj
diff --git a/aaccept/src/NFARun.cpp b/aaccept/src/NFARun.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a4c695f2c7162d43ef63496865eb336afb160479
--- /dev/null
+++ b/aaccept/src/NFARun.cpp
@@ -0,0 +1,77 @@
+/*
+ * NFARun.cpp
+ *
+ *  Created on: 14. 2. 2014
+ *      Author: tomas
+ */
+
+#include "NFARun.h"
+#include <iostream>
+
+using namespace alib;
+using namespace automaton;
+using namespace std;
+
+NFARun::NFARun( const FSM & fsm ) : m_fsm( fsm )
+{
+
+}
+
+bool NFARun::simulate( const list<Symbol> & string ) const
+{
+    if( ! checkAlphabet( string ) )
+        throw AlibException( "String alphabet does not match automaton alphabet." );
+
+    for( const auto & state : m_fsm.getInitialStates( ) )
+        if( configuration( state, string ) )
+            return true;
+
+    return false;
+}
+
+bool NFARun::checkAlphabet( const list<Symbol> & string ) const
+{
+    const auto & alphabet = m_fsm.getInputAlphabet( );
+    for( const auto & symbol : string )
+        if( alphabet.find( symbol ) == alphabet.end( ) )
+            return false;
+
+    return true;
+}
+
+bool NFARun::configuration( const State & state, const list<Symbol> & string ) const
+{
+    if( string.empty( ) )
+        return m_fsm.getFinalStates( ).find( state ) != m_fsm.getFinalStates( ).end( );
+
+    const Symbol & inputSymbol = string.front( );
+
+    list<Symbol> newString = string;
+    newString.pop_front( );
+
+    for( const auto & transition : m_fsm.getTransitionsFromState( state ) )
+        if( transition.getInput( ) == inputSymbol && configuration( transition.getTo( ), newString ) )
+            return true;
+
+    return false;
+}
+
+State NFARun::createUniqueState( const string & desiredName ) const
+{
+    //TODO: No need for this method after utils from aconversions project is merged into alib
+
+    State s( desiredName );
+    if( m_fsm.getStates( ).find( s ) == m_fsm.getStates( ).end( ) )
+        return s;
+
+    int i = 0;
+    while( true )
+    {
+        State s( desiredName + to_string( i ++ ) );
+
+        // state not present in totalFSM
+        if( m_fsm.getStates( ).find( s ) == m_fsm.getStates( ).end( ) )
+            return s;
+    }
+    throw AlibException( "WordAcceptance - Unable to create trash state" );
+}
diff --git a/aaccept/src/NFARun.h b/aaccept/src/NFARun.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0ca42db08b95500912718be58928e56c92652db
--- /dev/null
+++ b/aaccept/src/NFARun.h
@@ -0,0 +1,62 @@
+/*
+ * NFARun.h
+ *
+ *  Created on: 14. 2. 2014
+ *      Author: tomas
+ */
+
+#ifndef NFARUN_H_
+#define NFARUN_H_
+
+#include <automaton/FSM/FSM.h>
+#include <alphabet/Symbol.h>
+#include <AlibException.h>
+
+#include <climits>
+#include <list>
+#include <map>
+#include <stdexcept>
+
+/**
+ * @brief Simulates NFA run
+ */
+class NFARun
+{
+public:
+    NFARun( const automaton::FSM & fsm );
+
+    /**
+     * Simulates run of FSM with input word
+     * @param word Input word
+     * @return bool boolean value whether word was accepted
+     */
+    bool simulate( const std::list<alphabet::Symbol> & string ) const;
+
+private:
+    /**
+     * Create unique state in automaton. If state with desired name is
+     *  already present, tries to create state with same name and integer suffix
+     * @param desiredName desired name of state
+     * @return new unique state
+     * @throws AutomatonException if was unable to create unique state (counter
+     *  reached INT_MAX)
+     */
+    automaton::State createUniqueState( const std::string & desiredName ) const;
+
+    /**
+     * @return true if all symbols are in the automata's input alphabet
+     */
+    bool checkAlphabet( const std::list<alphabet::Symbol> & string ) const;
+
+    /*
+     * Puts automaton into configuration Q x T* and checks if
+     * @param state state of automata
+     * @param string unreaded substring
+     * @return true if in configuration ( q, \eps ), q is accepting state
+     */
+    bool configuration( const automaton::State & state, const std::list<alphabet::Symbol> & string ) const;
+
+    automaton::FSM m_fsm;
+};
+
+#endif /* NFARUN_H_ */
diff --git a/aaccept/src/aaccept.cpp b/aaccept/src/aaccept.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01442e54ec194918dfd619e8b1f91b61ec743b09
--- /dev/null
+++ b/aaccept/src/aaccept.cpp
@@ -0,0 +1,58 @@
+#include <iostream>
+#include <string>
+#include <list>
+
+#include <AlibException.h>
+#include <automaton/AutomatonParser.h>
+#include <automaton/UnknownAutomaton.h>
+#include <AutomatonFactory.h>
+#include <sax/SaxInterface.h>
+
+#include "NFARun.h"
+
+using namespace alib;
+using namespace automaton;
+using namespace alphabet;
+using namespace std;
+using namespace sax;
+
+/*
+ * Usage:
+ *  aacept.fsm "a" "b" "cc" < fsm.xml (accepts FSM.xml word <a><b><cc> ?)
+ */
+
+int main(int argc, char** argv)
+{
+    try
+    {
+        list<Token> tokens;
+        string input(istreambuf_iterator<char>(cin), (istreambuf_iterator<char>()));
+        SaxInterface::parseMemory(input, tokens);
+
+        UnknownAutomaton unknownAutomaton = AutomatonParser::parse(tokens);
+        FSM fsm = AutomatonFactory::buildFSM( unknownAutomaton );
+        NFARun nfa( fsm );
+        list<Symbol> word;
+
+        for( int i = 1; i < argc ; i++ )
+            word.push_back( Symbol ( argv[ i ] ) );
+
+        if( nfa.simulate( word ) )
+        {
+            cout << "Automaton accepted word." << endl;
+            return 0;
+        }
+        else
+        {
+            cout << "Automaton did not accept word" << endl;
+            return 1;
+        }
+    }
+    catch( AlibException & e )
+    {
+        cout << e.what() << endl;
+        return 255;
+    }
+
+    return 0;
+}
diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index f7367ae9919207528e15ca9c66bab2f88454b5ed..dcb30cb7a7ecf3f8f1ff44f03f944afb04964e5a 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -174,7 +174,7 @@ void ConversionHandler::convertFSMtoRG( void )
 
 void ConversionHandler::convertFSMtoRRG( void )
 {
-	const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );
+	const automaton::Automaton fsm = alib::DataFactory::fromTokens<automaton::Automaton>( m_tokens );
 
 	switch( m_algorithm )
 	{
@@ -188,7 +188,7 @@ void ConversionHandler::convertFSMtoRRG( void )
 
 void ConversionHandler::convertFSMtoLRG( void )
 {
-	const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );
+	const automaton::Automaton fsm = alib::DataFactory::fromTokens<automaton::Automaton>( m_tokens );
 
 	switch( m_algorithm )
 	{
diff --git a/aconvert2/src/DotConverter.cpp b/aconvert2/src/DotConverter.cpp
index a8fb8fd21d4543fcebc403d33bc0e6807bebb9b1..04e8ff6dbd3da113ef1cd23d7d563eacb6a266a2 100644
--- a/aconvert2/src/DotConverter.cpp
+++ b/aconvert2/src/DotConverter.cpp
@@ -15,6 +15,8 @@
 #include <automaton/FSM/CompactNFA.h>
 #include <automaton/PDA/NPDA.h>
 #include <automaton/PDA/SinglePopNPDA.h>
+#include <automaton/PDA/DPDA.h>
+#include <automaton/PDA/SinglePopDPDA.h>
 #include <automaton/TM/OneTapeDTM.h>
 
 #include <exception/AlibException.h>
@@ -212,6 +214,72 @@ void DotConverter::convert(const automaton::CompactNFA& a, std::ostream& out) {
 	out << "}";
 }
 
+void DotConverter::convert(const automaton::DPDA& a, std::ostream& out) {
+	label::LabelToStringComposer composer;
+
+	out << "digraph automaton {\n";
+	out << "rankdir=LR;\n";
+	int cnt = 1;
+
+	//Map states to indices
+	std::map<automaton::State, int> states;
+	for (const automaton::State& state : a.getStates()) {
+		states.insert(std::make_pair(state, cnt++));
+	}
+
+	//Print final states
+	for (const automaton::State& state : a.getFinalStates()) {
+		out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n";
+	}
+
+	//Print nonfinal states
+	for (const auto& state : states) {
+		if (!a.getFinalStates().count(state.first)) {
+			out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n";
+		}
+	}
+
+	//Mark initial states
+	out << "node [shape = plaintext, label=\"start\"]; 0; \n";
+	out << "0 -> " << a.getInitialState() << ";\n";
+
+	transitions(a, states, out);
+	out << "}";
+}
+
+void DotConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) {
+	label::LabelToStringComposer composer;
+
+	out << "digraph automaton {\n";
+	out << "rankdir=LR;\n";
+	int cnt = 1;
+
+	//Map states to indices
+	std::map<automaton::State, int> states;
+	for (const automaton::State& state : a.getStates()) {
+		states.insert(std::make_pair(state, cnt++));
+	}
+
+	//Print final states
+	for (const automaton::State& state : a.getFinalStates()) {
+		out << "node [shape = doublecircle, label=\"" << composer.compose(state.getName()) << "\"]; " << states.find(state)->second << ";\n";
+	}
+
+	//Print nonfinal states
+	for (const auto& state : states) {
+		if (!a.getFinalStates().count(state.first)) {
+			out << "node [shape = circle, label=\"" << composer.compose(state.first.getName()) << "\" ]; " << state.second << ";\n";
+		}
+	}
+
+	//Mark initial states
+	out << "node [shape = plaintext, label=\"start\"]; 0; \n";
+	out << "0 -> " << a.getInitialState() << ";\n";
+
+	transitions(a, states, out);
+	out << "}";
+}
+
 void DotConverter::convert(const automaton::NPDA& a, std::ostream& out) {
 	label::LabelToStringComposer composer;
 
@@ -453,6 +521,115 @@ void DotConverter::transitions(const automaton::CompactNFA& fsm, const std::map<
 	}
 }
 
+void DotConverter::transitions(const automaton::DPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out) {
+	std::map<std::pair<int, int>, std::string> transitions;
+
+	for (const auto& transition : pda.getTransitions()) {
+		std::string symbol;
+
+		//input symbol
+		if (std::get<1>(transition.first).is<string::Epsilon>()) {
+			symbol = "&epsilon;";
+		} else {
+			alphabet::SymbolToStringComposer composer;
+			symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>());
+		}
+
+		symbol += " |";
+
+		//Pop part
+		if (std::get<2>(transition.first).size() == 0) {
+			symbol += " &epsilon;";
+		} else {
+			for (alphabet::Symbol symb : std::get<2>(transition.first)) {
+				alphabet::SymbolToStringComposer composer;
+				symbol += " " + composer.compose(symb);
+			}
+
+		}
+
+		symbol += " ->";
+
+		//Push part
+		if (transition.second.second.size() == 0) {
+			symbol += " &epsilon;";
+		} else {
+			for (alphabet::Symbol symb : transition.second.second) {
+				alphabet::SymbolToStringComposer composer;
+				symbol += " " + composer.compose(symb);
+			}
+
+		}
+
+		//Insert into map
+		std::pair<int, int> key(states.find(std::get<0>(transition.first))->second, states.find(transition.second.first)->second);
+		std::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key);
+
+		if (mapit == transitions.end()) {
+			transitions.insert(std::make_pair(key, symbol));
+		} else {
+			mapit->second += ", " + symbol;
+		}
+	}
+
+	//print the map
+	for (const std::pair<std::pair<int, int>, std::string> transition : transitions) {
+		out << transition.first.first << " -> " << transition.first.second;
+		out << "[label=\"" << transition.second << "\"]\n";
+	}
+}
+
+void DotConverter::transitions(const automaton::SinglePopDPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out) {
+	std::map<std::pair<int, int>, std::string> transitions;
+
+	for (const auto& transition : pda.getTransitions()) {
+		std::string symbol;
+
+		//input symbol
+		if (std::get<1>(transition.first).is<string::Epsilon>()) {
+			symbol = "&epsilon;";
+		} else {
+			alphabet::SymbolToStringComposer composer;
+			symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>());
+		}
+
+		symbol += " |";
+
+		//Pop part
+		alphabet::SymbolToStringComposer composer;
+		symbol += " " + composer.compose(std::get<2>(transition.first));
+
+		symbol += " ->";
+
+		//Push part
+		if (transition.second.second.size() == 0) {
+			symbol += " &epsilon;";
+		} else {
+			for (alphabet::Symbol symb : transition.second.second) {
+				alphabet::SymbolToStringComposer composer;
+				symbol += " " + composer.compose(symb);
+			}
+
+		}
+
+		//Insert into map
+		std::pair<int, int> key(states.find(std::get<0>(transition.first))->second, states.find(transition.second.first)->second);
+		std::map<std::pair<int, int>, std::string>::iterator mapit = transitions.find(key);
+
+		if (mapit == transitions.end()) {
+			transitions.insert(std::make_pair(key, symbol));
+		} else {
+			mapit->second += ", " + symbol;
+		}
+	}
+
+	//print the map
+	for (const std::pair<std::pair<int, int>, std::string> transition : transitions) {
+		out << transition.first.first << " -> " << transition.first.second;
+		out << "[label=\"" << transition.second << "\"]\n";
+	}
+}
+
 void DotConverter::transitions(const automaton::NPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out) {
 	std::map<std::pair<int, int>, std::string> transitions;
 
@@ -637,6 +814,14 @@ void DotConverter::Visit(void* data, const automaton::CompactNFA& automaton) con
 	DotConverter::convert(automaton, *((std::ostream*) data));
 }
 
+void DotConverter::Visit(void* data, const automaton::DPDA& automaton) const {
+	DotConverter::convert(automaton, *((std::ostream*) data));
+}
+
+void DotConverter::Visit(void* data, const automaton::SinglePopDPDA& automaton) const {
+	DotConverter::convert(automaton, *((std::ostream*) data));
+}
+
 void DotConverter::Visit(void* data, const automaton::NPDA& automaton) const {
 	DotConverter::convert(automaton, *((std::ostream*) data));
 }
diff --git a/aconvert2/src/DotConverter.h b/aconvert2/src/DotConverter.h
index 17a9463cd5b8c74e79bd6d55896a2f1d50adef35..8592b03f8c0c51f5d8d44847d48984c395506f1a 100644
--- a/aconvert2/src/DotConverter.h
+++ b/aconvert2/src/DotConverter.h
@@ -22,6 +22,8 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ
 	void Visit(void*, const automaton::DFA& automaton) const;
 	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
 	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
 	void Visit(void*, const automaton::NPDA& automaton) const;
 	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
 	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
@@ -32,6 +34,8 @@ class DotConverter : public automaton::VisitableAutomatonBase::const_visitor_typ
 	static void transitions(const automaton::DFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::ExtendedNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::CompactNFA& fsm, const std::map<automaton::State, int>& states, std::ostream& out);
+	static void transitions(const automaton::DPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out);
+	static void transitions(const automaton::SinglePopDPDA& tm, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::NPDA& pda, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::SinglePopNPDA& tm, const std::map<automaton::State, int>& states, std::ostream& out);
 	static void transitions(const automaton::OneTapeDTM& tm, const std::map<automaton::State, int>& states, std::ostream& out);
@@ -46,6 +50,8 @@ public:
 	static void convert(const automaton::DFA& a, std::ostream& out);
 	static void convert(const automaton::ExtendedNFA& a, std::ostream& out);
 	static void convert(const automaton::CompactNFA& a, std::ostream& out);
+	static void convert(const automaton::DPDA& a, std::ostream& out);
+	static void convert(const automaton::SinglePopDPDA& a, std::ostream& out);
 	static void convert(const automaton::NPDA& a, std::ostream& out);
 	static void convert(const automaton::SinglePopNPDA& a, std::ostream& out);
 	static void convert(const automaton::OneTapeDTM& a, std::ostream& out);
diff --git a/aconvert2/src/GasTexConverter.cpp b/aconvert2/src/GasTexConverter.cpp
index 69224ebacca95e3c1928c6f4dbbed164cf21f642..eb49c83135c14dad638912a72fea51121fbde333 100644
--- a/aconvert2/src/GasTexConverter.cpp
+++ b/aconvert2/src/GasTexConverter.cpp
@@ -12,10 +12,16 @@
 #include <automaton/FSM/DFA.h>
 #include <automaton/FSM/ExtendedNFA.h>
 #include <automaton/FSM/CompactNFA.h>
+#include <automaton/PDA/DPDA.h>
+#include <automaton/PDA/SinglePopDPDA.h>
 #include <automaton/PDA/NPDA.h>
 #include <automaton/PDA/SinglePopNPDA.h>
 #include <automaton/TM/OneTapeDTM.h>
 
+#include <alphabet/SymbolToStringComposer.h>
+#include <regexp/RegExpToStringComposer.h>
+#include <string/StringToStringComposer.h>
+
 #include <set>
 #include <map>
 #include <typeinfo>
@@ -25,8 +31,8 @@ void GasTexConverter::convert(const automaton::Automaton& a, std::ostream& out)
 	a.getData().Accept((void*) &out, GasTexConverter::instance);
 }
 
-void GasTexConverter::convert(const automaton::UnknownAutomaton& a, std::ostream& out) {
-	//TODO
+void GasTexConverter::convert(const automaton::UnknownAutomaton&, std::ostream&) {
+	throw exception::AlibException("Unable to convert unknown automata to gastex");
 }
 
 void GasTexConverter::convert(const automaton::EpsilonNFA& a, std::ostream& out) {
@@ -224,6 +230,84 @@ void GasTexConverter::convert(const automaton::CompactNFA& a, std::ostream& out)
 	out << "\\end{picture}\n";
 }
 
+void GasTexConverter::convert(const automaton::DPDA& a, std::ostream& out) {
+	out << "\\begin{center}\n";
+	out << "\\begin{picture}(,)(,)\n";
+
+	for (auto& state : a.getStates()) {
+		bool initial = false;
+		bool final = false;
+
+		if(a.getInitialState() == state) {
+			initial = true;
+		}
+		if(a.getFinalStates().count(state)) {
+			final = true;
+		}
+
+		if(initial || final) {
+			out << "\\node[Nmarks=";
+			if(initial){
+				out << "i";
+			}
+			if(final){
+				out << "r";
+			}
+			out<<"](";
+		} else {
+			out <<"\\node(";
+		}
+
+		out << state.getName();
+		out << ")(,){";
+		out << state.getName();
+		out << "}\n";
+	}
+
+	transitions(a, out);
+	out << "\\end{center}\n";
+	out << "\\end{picture}\n";
+}
+
+void GasTexConverter::convert(const automaton::SinglePopDPDA& a, std::ostream& out) {
+	out << "\\begin{center}\n";
+	out << "\\begin{picture}(,)(,)\n";
+
+	for (auto& state : a.getStates()) {
+		bool initial = false;
+		bool final = false;
+
+		if(a.getInitialState() == state) {
+			initial = true;
+		}
+		if(a.getFinalStates().count(state)){
+			final = true;
+		}
+
+		if(initial || final) {
+			out << "\\node[Nmarks=";
+			if(initial){
+				out << "i";
+			}
+			if(final){
+				out << "r";
+			}
+			out<<"](";
+		} else {
+			out <<"\\node(";
+		}
+
+		out << state.getName();
+		out << ")(,){";
+		out << state.getName();
+		out << "}\n";
+	}
+
+	transitions(a, out);
+	out << "\\end{center}\n";
+	out << "\\end{picture}\n";
+}
+
 void GasTexConverter::convert(const automaton::NPDA& a, std::ostream& out) {
 	out << "\\begin{center}\n";
 	out << "\\begin{picture}(,)(,)\n";
@@ -341,7 +425,7 @@ void GasTexConverter::convert(const automaton::OneTapeDTM& a, std::ostream& out)
 	out << "\\end{picture}\n";
 }
 
-std::string GasTexConverter::getStackSymbols(const std::list<alphabet::Symbol>& stackSymbols) {
+std::string GasTexConverter::getStackSymbols(const std::vector<alphabet::Symbol>& stackSymbols) {
 	if (stackSymbols.size() == 0) {
 		return "$\\varepsilon$";
 	}
@@ -442,69 +526,210 @@ void GasTexConverter::transitions(const automaton::DFA& fsm, std::ostream& out)
 	printTransitionMap(transitionMap, out);
 }
 
-void GasTexConverter::transitions(const automaton::ExtendedNFA& pda, std::ostream& out) {
-	//TODO
-}
+void GasTexConverter::transitions(const automaton::ExtendedNFA& fsm, std::ostream& out) {
+	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
+
+	regexp::RegExpToStringComposer composer;
+	for (const auto& transition : fsm.getTransitions()) {
+		for(const auto& to : transition.second) {
+			std::pair<std::string, std::string> key(transition.first.first.getName(), to.getName());
+
+			std::string symbol = composer.compose(transition.first.second);
 
-void GasTexConverter::transitions(const automaton::CompactNFA& pda, std::ostream& out) {
-	// TODO
+			auto mapIterator = transitionMap.find(key);
+			if (mapIterator == transitionMap.end()) {
+				transitionMap.insert(make_pair(key, symbol));
+			} else {
+				mapIterator->second += ", " + symbol;
+			}
+		}
+	}
+	printTransitionMap(transitionMap, out);
 }
 
-void GasTexConverter::transitions(const automaton::NPDA& pda, std::ostream& out) {
-	// TODO
-	/*map<pair<string, string>, string> transitionMap;
+void GasTexConverter::transitions(const automaton::CompactNFA& fsm, std::ostream& out) {
+	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
+
+	string::StringToStringComposer composer;
+	for (const auto& transition : fsm.getTransitions()) {
+		for(const auto& to : transition.second) {
+			std::pair<std::string, std::string> key(transition.first.first.getName(), to.getName());
 
-	for (auto& transition : pda.getTransitions()) {
+			std::string symbol = composer.compose(string::String(transition.first.second));
 
-		pair<string, string> key(transition.getFrom().getName(), transition.getTo().getName());
+			auto mapIterator = transitionMap.find(key);
+			if (mapIterator == transitionMap.end()) {
+				transitionMap.insert(make_pair(key, symbol));
+			} else {
+				mapIterator->second += ", " + symbol;
+			}
+		}
+	}
+	printTransitionMap(transitionMap, out);
+}
+
+void GasTexConverter::transitions(const automaton::DPDA& pda, std::ostream& out) {
+	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
+
+	alphabet::SymbolToStringComposer composer;
+	for (const auto& transition : pda.getTransitions()) {
+		std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) transition.second.first.getName());
 		auto mapIterator = transitionMap.find(key);
 
-		string symbol = checkEpsilon(transition.getInput().getSymbol());
+		std::string symbol;
+		if (std::get<1>(transition.first).is<string::Epsilon>()) {
+			symbol = "$\\varepsilon;$";
+		} else {
+			symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>());
+		}
 
-		symbol += ",";
+		symbol += "|";
 
+		symbol += getStackSymbols(std::get<2>(transition.first));
+		symbol += "\\rarrow";
+		symbol += getStackSymbols(transition.second.second);
 
-		symbol += getStackSymbols(transition.getPop());
-		symbol += "/";
-		symbol += getStackSymbols(transition.getPush());
+		if (mapIterator == transitionMap.end()) {
+			transitionMap.insert(std::make_pair(key, symbol));
+		} else {
+			mapIterator->second += "; " + symbol;
+		}
+	}
+
+	printTransitionMap(transitionMap, out);
+}
+
+void GasTexConverter::transitions(const automaton::SinglePopDPDA& pda, std::ostream& out) {
+	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
+
+	alphabet::SymbolToStringComposer composer;
+	for (const auto& transition : pda.getTransitions()) {
+		std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) transition.second.first.getName());
+		auto mapIterator = transitionMap.find(key);
+
+		std::string symbol;
+		if (std::get<1>(transition.first).is<string::Epsilon>()) {
+			symbol = "$\\varepsilon;$";
+		} else {
+			symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>());
+		}
+
+		symbol += "|";
+
+		symbol += composer.compose(std::get<2>(transition.first));
+		symbol += "\\rarrow";
+		symbol += getStackSymbols(transition.second.second);
 
 		if (mapIterator == transitionMap.end()) {
-			transitionMap.insert(pair<pair<string, string>, string>(key, symbol));
+			transitionMap.insert(std::make_pair(key, symbol));
 		} else {
 			mapIterator->second += "; " + symbol;
 		}
 	}
 
-	printTransitionMap(transitionMap, out);*/
+	printTransitionMap(transitionMap, out);
+}
+
+void GasTexConverter::transitions(const automaton::NPDA& pda, std::ostream& out) {
+	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
+
+	alphabet::SymbolToStringComposer composer;
+	for (const auto& transition : pda.getTransitions()) {
+		for(const auto& to : transition.second) {
+			std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) to.first.getName());
+			auto mapIterator = transitionMap.find(key);
+
+			std::string symbol;
+			if (std::get<1>(transition.first).is<string::Epsilon>()) {
+				symbol = "$\\varepsilon;$";
+			} else {
+				symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>());
+			}
+
+			symbol += "|";
+
+			symbol += getStackSymbols(std::get<2>(transition.first));
+			symbol += "\\rarrow";
+			symbol += getStackSymbols(to.second);
+
+			if (mapIterator == transitionMap.end()) {
+				transitionMap.insert(std::make_pair(key, symbol));
+			} else {
+				mapIterator->second += "; " + symbol;
+			}
+		}
+	}
+
+	printTransitionMap(transitionMap, out);
 }
 
-void GasTexConverter::transitions(const automaton::SinglePopNPDA& tm, std::ostream& out) {
-	// TODO
+void GasTexConverter::transitions(const automaton::SinglePopNPDA& pda, std::ostream& out) {
+	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
+
+	alphabet::SymbolToStringComposer composer;
+	for (const auto& transition : pda.getTransitions()) {
+		for(const auto& to : transition.second) {
+			std::pair<std::string, std::string> key((std::string) std::get<0>(transition.first).getName(), (std::string) to.first.getName());
+			auto mapIterator = transitionMap.find(key);
+
+			std::string symbol;
+			if (std::get<1>(transition.first).is<string::Epsilon>()) {
+				symbol = "$\\varepsilon;$";
+			} else {
+				symbol = composer.compose(std::get<1>(transition.first).get<alphabet::Symbol>());
+			}
+
+			symbol += "|";
+
+			symbol += composer.compose(std::get<2>(transition.first));
+			symbol += "\\rarrow";
+			symbol += getStackSymbols(to.second);
+
+			if (mapIterator == transitionMap.end()) {
+				transitionMap.insert(std::make_pair(key, symbol));
+			} else {
+				mapIterator->second += "; " + symbol;
+			}
+		}
+	}
+
+	printTransitionMap(transitionMap, out);
 }
 
 void GasTexConverter::transitions(const automaton::OneTapeDTM& tm, std::ostream& out) {
-	// TODO
-	/*map<pair<string, string>, string> transitionMap;
+	std::map<std::pair<std::string, std::string>, std::string> transitionMap;
 
+	alphabet::SymbolToStringComposer composer;
 	for (auto& transition : tm.getTransitions()) {
-
-		pair<string, string> key(transition.getFrom().getName(), transition.getTo().getName());
+		std::pair<std::string, std::string> key((std::string) transition.first.first.getName(), (std::string) std::get<0>(transition.second).getName());
 		auto mapIterator = transitionMap.find(key);
 
-		string symbol = checkEpsilon(transition.getInput().getSymbol());
+		std::string symbol = composer.compose(transition.first.second);
 		symbol += "/";
-		symbol += checkEpsilon(transition.getOutput().getSymbol());
+		symbol += composer.compose(std::get<1>(transition.second));
 		symbol += ",";
-		symbol += (std::string[] ) { "$\\leftarrow$", "$\\rightarrow$", "$\\times$" } [transition.getShift()];
+		switch(std::get<2>(transition.second)) {
+		case automaton::Shift::LEFT:
+			symbol += "$\\leftarrow$";
+			break;
+		case automaton::Shift::RIGHT:
+			symbol += "$\\rightarrow$";
+			break;
+		case automaton::Shift::NONE:
+			symbol += "$\\times$";
+			break;
+		default:
+			throw exception::AlibException("Unexpected shift direction");
+		}
 
 		if (mapIterator == transitionMap.end()) {
-			transitionMap.insert(pair<pair<string, string>, string>(key, symbol));
+			transitionMap.insert(std::make_pair(key, symbol));
 		} else {
 			mapIterator->second += "; " + symbol;
 		}
 	}
 
-	printTransitionMap(transitionMap, out);*/
+	printTransitionMap(transitionMap, out);
 }
 
 const GasTexConverter GasTexConverter::instance;
@@ -533,6 +758,14 @@ void GasTexConverter::Visit(void* data, const automaton::CompactNFA& automaton)
 	GasTexConverter::convert(automaton, *((std::ostream*) data));
 }
 
+void GasTexConverter::Visit(void* data, const automaton::DPDA& automaton) const {
+	GasTexConverter::convert(automaton, *((std::ostream*) data));
+}
+
+void GasTexConverter::Visit(void* data, const automaton::SinglePopDPDA& automaton) const {
+	GasTexConverter::convert(automaton, *((std::ostream*) data));
+}
+
 void GasTexConverter::Visit(void* data, const automaton::NPDA& automaton) const {
 	GasTexConverter::convert(automaton, *((std::ostream*) data));
 }
diff --git a/aconvert2/src/GasTexConverter.h b/aconvert2/src/GasTexConverter.h
index 8ddff8716de039e9fafcd59c6eb7742f365837ea..84f821bc1eef21f2626755c9be5aaabd7ac95aa0 100644
--- a/aconvert2/src/GasTexConverter.h
+++ b/aconvert2/src/GasTexConverter.h
@@ -11,7 +11,7 @@
 #include <ostream>
 #include <map>
 #include <utility>
-#include <list>
+#include <vector>
 #include "automaton/Automaton.h"
 #include "alphabet/Symbol.h"
 
@@ -22,12 +22,14 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_
 	void Visit(void*, const automaton::DFA& automaton) const;
 	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
 	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
 	void Visit(void*, const automaton::NPDA& automaton) const;
 	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
 	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
 
 	static void printTransitionMap( const std::map<std::pair<std::string, std::string>, std::string> transitionMap, std::ostream& out);
-	static std::string getStackSymbols(const std::list<alphabet::Symbol>& stackSymbols);
+	static std::string getStackSymbols(const std::vector<alphabet::Symbol>& stackSymbols);
 
 	static void transitions(const automaton::UnknownAutomaton& fsm, std::ostream& out);
 	static void transitions(const automaton::EpsilonNFA& fsm, std::ostream& out);
@@ -35,6 +37,8 @@ class GasTexConverter : public automaton::VisitableAutomatonBase::const_visitor_
 	static void transitions(const automaton::DFA& fsm, std::ostream& out);
 	static void transitions(const automaton::ExtendedNFA& fsm, std::ostream& out);
 	static void transitions(const automaton::CompactNFA& fsm, std::ostream& out);
+	static void transitions(const automaton::DPDA& pda, std::ostream& out);
+	static void transitions(const automaton::SinglePopDPDA& tm, std::ostream& out);
 	static void transitions(const automaton::NPDA& pda, std::ostream& out);
 	static void transitions(const automaton::SinglePopNPDA& tm, std::ostream& out);
 	static void transitions(const automaton::OneTapeDTM& tm, std::ostream& out);
@@ -49,6 +53,8 @@ public:
 	static void convert(const automaton::DFA& a, std::ostream& out);
 	static void convert(const automaton::ExtendedNFA& a, std::ostream& out);
 	static void convert(const automaton::CompactNFA& a, std::ostream& out);
+	static void convert(const automaton::DPDA& a, std::ostream& out);
+	static void convert(const automaton::SinglePopDPDA& a, std::ostream& out);
 	static void convert(const automaton::NPDA& a, std::ostream& out);
 	static void convert(const automaton::SinglePopNPDA& a, std::ostream& out);
 	static void convert(const automaton::OneTapeDTM& a, std::ostream& out);
diff --git a/aepsilon2/src/aepsilon.cpp b/aepsilon2/src/aepsilon.cpp
index 0c2ac5def5cbc57dd03902a53857ee47c0f64aaa..3c8cf8f8c712958a522135bf9a4377c7f1875c3d 100644
--- a/aepsilon2/src/aepsilon.cpp
+++ b/aepsilon2/src/aepsilon.cpp
@@ -9,7 +9,7 @@
 #include <factory/DataFactory.hpp>
 #include <exception/AlibException.h>
 
-#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h"
+#include "epsilon/fsm/FSMEpsilonRemover.h"
 
 int main(int argc, char** argv) {
 	int fileParameterIndex = -1;
@@ -45,21 +45,9 @@ int main(int argc, char** argv) {
 
 		if(alib::FromXMLParsers::automatonParser.first(tokens)) {
 			std::string xmlMark = tokens.front( ).getData( );
-			if(xmlMark == "EpsilonNFA") {
-				automaton::EpsilonNFA automaton = alib::DataFactory::fromTokens<automaton::EpsilonNFA>(tokens);
-				automaton::NFA res = epsilon::EpsilonNFAEpsilonRemover::remove( automaton );
-				alib::DataFactory::toStdout(res);
-			} else if(xmlMark == "NFA") {
-				automaton::NFA automaton = alib::DataFactory::fromTokens<automaton::NFA>(tokens);
-				alib::DataFactory::toStdout(automaton);
-			} else if(xmlMark == "DFA") {
-				automaton::DFA automaton = alib::DataFactory::fromTokens<automaton::DFA>(tokens);
-				alib::DataFactory::toStdout(automaton);
-			} else {
-				automaton::EpsilonNFA automaton = alib::DataFactory::fromTokens<automaton::EpsilonNFA>(tokens);
-				automaton::NFA res = epsilon::EpsilonNFAEpsilonRemover::remove( automaton );
-				alib::DataFactory::toStdout(res);
-			}
+			automaton::Automaton automaton = alib::DataFactory::fromTokens<automaton::Automaton>(tokens);
+			automaton::Automaton res = epsilon::FSMEpsilonRemover::remove( automaton );
+			alib::DataFactory::toStdout(res);
 		} else {
 			throw exception::AlibException("Invalid argument expected Epsilon NFA.");
 		}
diff --git a/alib2algo/src/automaton/AutomatonPropertiesFSM.cpp b/alib2algo/src/automaton/AutomatonPropertiesFSM.cpp
index 9a526297758d1ca5f47a925a4417a74f20df480b..618d3dca0b60d1cb48bdee2063c56f1ee4d918e4 100644
--- a/alib2algo/src/automaton/AutomatonPropertiesFSM.cpp
+++ b/alib2algo/src/automaton/AutomatonPropertiesFSM.cpp
@@ -130,30 +130,5 @@ std::set<automaton::State> AutomatonPropertiesFSM::getUnreachableStates( const a
 	return Qi.at( i );
 }
 
-std::set<automaton::State> AutomatonPropertiesFSM::epsilonClosure( automaton::EpsilonNFA const& fsm, automaton::State const& q ) {
-	std::set<automaton::State> closure;
-	std::queue<automaton::State> queue;
-	std::map<automaton::State, bool> visited;
-
-	for( const auto & p : fsm.getStates( ) )
-		visited[ p ] = false;
-
-	queue.push( q );
-	while( ! queue.empty( ) )
-	{
-		automaton::State p = queue.front( );
-		queue.pop( );
-		visited[ p ] = true;
-		closure.insert( p );
-
-		for( const auto & transition : fsm.getEpsilonTransitionsFromState( p ) )
-			for (const auto & to : transition.second )
-				if( visited [ to ] == false )
-					queue.push( to );
-	}
-
-	return closure;
-}
-
 }
 
diff --git a/alib2algo/src/automaton/AutomatonPropertiesFSM.h b/alib2algo/src/automaton/AutomatonPropertiesFSM.h
index 00682825ad09dbc761a8c5aaacad76e5b822d83c..64f94e888ffc97f69cc583181c7eba1f09e6ef03 100644
--- a/alib2algo/src/automaton/AutomatonPropertiesFSM.h
+++ b/alib2algo/src/automaton/AutomatonPropertiesFSM.h
@@ -29,11 +29,6 @@ public:
 	 */
 	template<class T>
 	static std::set<automaton::State> getUnreachableStates( const T & fsm );
-
-	/**
-	 * Computes epsilon closure of a state in epsilon nonfree automaton
-	 */
-	static std::set<automaton::State> epsilonClosure( const automaton::EpsilonNFA & fsm, const automaton::State & state );
 };
 
 }
diff --git a/alib2algo/src/automaton/EpsilonClosure.cpp b/alib2algo/src/automaton/EpsilonClosure.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..99f4577e545fa030dfe775f593ae3c8fe5ad5941
--- /dev/null
+++ b/alib2algo/src/automaton/EpsilonClosure.cpp
@@ -0,0 +1,182 @@
+/*
+ * EpsilonClosure.cpp
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "EpsilonClosure.h"
+
+#include <exception/AlibException.h>
+#include <automaton/FSM/ExtendedNFA.h>
+#include <automaton/FSM/CompactNFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <set>
+#include <map>
+#include <queue>
+
+#include "../regexp/RegExpEpsilon.h"
+
+namespace automaton {
+
+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");
+
+	std::set<automaton::State> closure;
+	std::queue<automaton::State> queue;
+	std::map<automaton::State, bool> visited;
+
+	for( const auto & p : fsm.getStates( ) )
+		visited[ p ] = false;
+
+	queue.push( q );
+	while( ! queue.empty( ) )
+	{
+		automaton::State p = queue.front( );
+		queue.pop( );
+		visited[ p ] = true;
+		closure.insert( p );
+
+		for( const auto & transition : fsm.getEpsilonTransitionsFromState( p ) )
+			for (const auto & to : transition.second )
+				if( visited [ to ] == false )
+					queue.push( to );
+	}
+
+	return closure;
+}
+
+std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::NFA & fsm, const automaton::State & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::AlibException("State is not in the automaton");
+
+	std::set<automaton::State> closure;
+	closure.insert(q);
+	return closure;
+}
+
+std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::DFA & fsm, const automaton::State & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::AlibException("State is not in the automaton");
+
+	std::set<automaton::State> closure;
+	closure.insert(q);
+	return closure;
+}
+
+std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::ExtendedNFA & fsm, const automaton::State & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::AlibException("State is not in the automaton");
+
+	std::set<automaton::State> closure;
+	std::queue<automaton::State> queue;
+	std::map<automaton::State, bool> visited;
+
+	for( const auto & p : fsm.getStates( ) )
+		visited[ p ] = false;
+
+	queue.push( q );
+	while( ! queue.empty( ) )
+	{
+		automaton::State p = queue.front( );
+		queue.pop( );
+		visited[ p ] = true;
+		closure.insert( p );
+
+		for( const auto & transition : fsm.getTransitionsFromState( p ) )
+			if( regexp::RegExpEpsilon::languageContainsEpsilon( transition.first.second ) )
+				for (const auto & to : transition.second )
+					if( visited [ to ] == false )
+						queue.push( to );
+	}
+
+	return closure;
+}
+
+std::set<automaton::State> EpsilonClosure::epsilonClosure( const automaton::CompactNFA & fsm, const automaton::State & q ) {
+	if(! fsm.getStates().count(q) ) throw exception::AlibException("State is not in the automaton");
+
+	std::set<automaton::State> closure;
+	std::queue<automaton::State> queue;
+	std::map<automaton::State, bool> visited;
+
+	for( const auto & p : fsm.getStates( ) )
+		visited[ p ] = false;
+
+	queue.push( q );
+	while( ! queue.empty( ) )
+	{
+		automaton::State p = queue.front( );
+		queue.pop( );
+		visited[ p ] = true;
+		closure.insert( p );
+
+		for( const auto & transition : fsm.getTransitionsFromState( p ) )
+			if( transition.first.second.getContent().size() != 0 )
+				for (const auto & to : transition.second )
+					if( visited [ to ] == false )
+						queue.push( to );
+	}
+
+	return closure;
+}
+
+std::set<automaton::State> EpsilonClosure::epsilonClosure(const Automaton& automaton, const automaton::State& q) {
+	std::pair<automaton::State, std::set<automaton::State>> out = std::make_pair(q, std::set<automaton::State> {});
+	automaton.getData().Accept((void*) &out, EpsilonClosure::EPSILON_CLOSURE);
+	return out.second;
+}
+
+void EpsilonClosure::Visit(void*, const UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void EpsilonClosure::Visit(void* data, const EpsilonNFA& automaton) const {
+	std::pair<automaton::State, std::set<automaton::State>> & out = *((std::pair<automaton::State, std::set<automaton::State>>*) data);
+	out.second = this->epsilonClosure(automaton, out.first);
+}
+
+void EpsilonClosure::Visit(void* data, const NFA& automaton) const {
+	std::pair<automaton::State, std::set<automaton::State>> & out = *((std::pair<automaton::State, std::set<automaton::State>>*) data);
+	out.second = this->epsilonClosure(automaton, out.first);
+}
+
+void EpsilonClosure::Visit(void* data, const DFA& automaton) const {
+	std::pair<automaton::State, std::set<automaton::State>> & out = *((std::pair<automaton::State, std::set<automaton::State>>*) data);
+	out.second = this->epsilonClosure(automaton, out.first);
+}
+
+void EpsilonClosure::Visit(void* data, const ExtendedNFA& automaton) const {
+	std::pair<automaton::State, std::set<automaton::State>> & out = *((std::pair<automaton::State, std::set<automaton::State>>*) data);
+	out.second = this->epsilonClosure(automaton, out.first);
+}
+
+void EpsilonClosure::Visit(void* data, const CompactNFA& automaton) const {
+	std::pair<automaton::State, std::set<automaton::State>> & out = *((std::pair<automaton::State, std::set<automaton::State>>*) data);
+	out.second = this->epsilonClosure(automaton, out.first);
+}
+
+void EpsilonClosure::Visit(void*, const DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void EpsilonClosure::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void EpsilonClosure::Visit(void*, const NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void EpsilonClosure::Visit(void*, const SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void EpsilonClosure::Visit(void*, const OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+const EpsilonClosure EpsilonClosure::EPSILON_CLOSURE;
+
+}
+
diff --git a/alib2algo/src/automaton/EpsilonClosure.h b/alib2algo/src/automaton/EpsilonClosure.h
new file mode 100644
index 0000000000000000000000000000000000000000..515c88f23de748391377187caf2e6b30f14edb7d
--- /dev/null
+++ b/alib2algo/src/automaton/EpsilonClosure.h
@@ -0,0 +1,51 @@
+/*
+ * EpsilonClosure.h
+ *
+ *  Created on: 23. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef EPSILON_CLOSURE_H_
+#define EPSILON_CLOSURE_H_
+
+#include <algorithm>
+#include <deque>
+#include <set>
+
+#include "automaton/Automaton.h"
+#include <automaton/common/State.h>
+
+namespace automaton {
+
+class EpsilonClosure : public VisitableAutomatonBase::const_visitor_type {
+public:
+	static std::set<automaton::State> epsilonClosure( const automaton::Automaton & automaton, const automaton::State & state );
+
+	/**
+	 * Computes epsilon closure of a state in epsilon nonfree automaton
+	 */
+	static std::set<automaton::State> epsilonClosure( const automaton::EpsilonNFA & fsm, const automaton::State & state );
+	static std::set<automaton::State> epsilonClosure( const automaton::NFA & fsm, const automaton::State & state );
+	static std::set<automaton::State> epsilonClosure( const automaton::DFA & fsm, const automaton::State & state );
+	static std::set<automaton::State> epsilonClosure( const automaton::ExtendedNFA & fsm, const automaton::State & state );
+	static std::set<automaton::State> epsilonClosure( const automaton::CompactNFA & fsm, const automaton::State & state );
+
+private:
+	void Visit(void*, const UnknownAutomaton& automaton) const;
+	void Visit(void*, const EpsilonNFA& 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 NPDA& automaton) const;
+	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
+
+	static const EpsilonClosure EPSILON_CLOSURE;
+};
+
+}
+
+#endif /* EPSILON_CLOSURE_H_ */
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
index aa02f307715808e587806dcc4c8b2026161a5e5a..da56c262a88154e533f833a112a9fc10869e9fe6 100644
--- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
+++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
@@ -4,55 +4,161 @@
 #include <label/StringLabel.h>
 #include <alphabet/LabeledSymbol.h>
 
+#include <exception/AlibException.h>
+
 namespace fa2rg
 {
 
 grammar::LeftRG FAtoLRGConverter::convert(const automaton::NFA& automaton)
 {
-    std::map<automaton::State, alphabet::Symbol> nonterminalMap;
-    // step 2
-    grammar::LeftRG grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+	// step 2
+	grammar::LeftRG grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+
+	// step 1
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& state : automaton.getStates())
+	{
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::pair<automaton::State, alphabet::Symbol>(state, nt));
+	}
+
+
+	// step 3 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+
+		for(const auto& to : transition.second)
+		{
+			// 3a
+			grammar.addRule(nonterminalMap.find(to)->second, std::make_pair(nonterminalMap.find(from)->second, input));
+
+			if(automaton.getFinalStates().count(to) > 0)
+				grammar.addRule(grammar.getInitialSymbol(), std::make_pair(nonterminalMap.find(from)->second, input));
+
+
+			if(automaton.getInitialStates().count(from) > 0)
+			{
+				grammar.addRule(nonterminalMap.find(to)->second, input);
+
+				if(automaton.getFinalStates().count(to) > 0)
+					grammar.addRule(grammar.getInitialSymbol(), input);
+			}
+		}
+	}
+
+	for(const auto & initial : automaton.getInitialStates()) {
+		if(automaton.getFinalStates().count(initial) > 0)
+			grammar.setGeneratesEpsilon(true);
+	}
+
+	return grammar;
+}
+
+grammar::LeftRG FAtoLRGConverter::convert(const automaton::DFA& automaton)
+{
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+	// step 2
+	grammar::LeftRG grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+
+	// step 1
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& state : automaton.getStates())
+	{
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::pair<automaton::State, alphabet::Symbol>(state, nt));
+	}
+
+
+	// step 3 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+		const automaton::State& to = transition.second;
+
+		// 3a
+		grammar.addRule(nonterminalMap.find(to)->second, std::make_pair(nonterminalMap.find(from)->second, input));
 
-    // step 1
-    grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+		if(automaton.getFinalStates().count(to) > 0)
+			grammar.addRule(grammar.getInitialSymbol(), std::make_pair(nonterminalMap.find(from)->second, input));
 
-    for(const auto& state : automaton.getStates())
-    {
-        alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
-        grammar.addNonterminalSymbol(nt);
-        nonterminalMap.insert(std::pair<automaton::State, alphabet::Symbol>(state, nt));
-    }
 
+		if(automaton.getInitialState() == from)
+		{
+			grammar.addRule(nonterminalMap.find(to)->second, input);
 
-    // step 3 - create set of P in G
-    for(const auto& transition : automaton.getTransitions())
-    {
-        const automaton::State& from = transition.first.first;
-        const alphabet::Symbol& input = transition.first.second;
+			if(automaton.getFinalStates().count(to) > 0)
+				grammar.addRule(grammar.getInitialSymbol(), input);
+		}
+	}
 
-        for(const auto& to : transition.second)
-        {
-            // 3a
-            grammar.addRule(nonterminalMap.find(to)->second, std::make_pair(nonterminalMap.find(from)->second, input));
+	if(automaton.getFinalStates().count(automaton.getInitialState()) > 0)
+		grammar.setGeneratesEpsilon(true);
 
-            if(automaton.getFinalStates().count(to) > 0)
-                grammar.addRule(grammar.getInitialSymbol(), std::make_pair(nonterminalMap.find(from)->second, input));
+	return grammar;
+}
+
+grammar::Grammar FAtoLRGConverter::convert(const automaton::Automaton& automaton) {
+	grammar::Grammar* out = NULL;
+	automaton.getData().Accept((void*) &out, FAtoLRGConverter::FA_TO_LRG_CONVERTER);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoLRGConverter::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 {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->convert(automaton));
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoLRGConverter::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
 
+void FAtoLRGConverter::Visit(void*, const automaton::DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
 
-            if(automaton.getInitialStates().count(from) > 0)
-            {
-                grammar.addRule(nonterminalMap.find(to)->second, input);
+void FAtoLRGConverter::Visit(void*, const automaton::SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
 
-                if(automaton.getFinalStates().count(to) > 0)
-                    grammar.addRule(grammar.getInitialSymbol(), input);
-            }
-        }
-    }
+void FAtoLRGConverter::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
 
-    if(automaton.getFinalStates().count(*automaton.getInitialStates().begin()) > 0)
-        grammar.setGeneratesEpsilon(true);
+void FAtoLRGConverter::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
 
-    return grammar;
+void FAtoLRGConverter::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
 }
 
+const FAtoLRGConverter FAtoLRGConverter::FA_TO_LRG_CONVERTER;
+
 } /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
index ef2f0a32ac70af252448548b085a74bb8c6d7fe9..e7558af5a7cdefe5838d1e8ed00107888872771f 100644
--- a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
+++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
@@ -1,10 +1,12 @@
 #ifndef __FATOLRGCONVERTER_H__
 #define __FATOLRGCONVERTER_H__
 
-#include <map>
-
 #include <grammar/Regular/LeftRG.h>
 #include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <grammar/Grammar.h>
+#include <automaton/Automaton.h>
 
 namespace fa2rg
 {
@@ -13,14 +15,32 @@ namespace fa2rg
  * Finite automaton to right regular grammar converter.
  * Source: My own :)
  */
-class FAtoLRGConverter
+class FAtoLRGConverter : public automaton::VisitableAutomatonBase::const_visitor_type
 {
 public:
-    /**
-     * Performs conversion.
-     * @return left regular grammar equivalent to source automaton.
-     */
-    grammar::LeftRG convert(const automaton::NFA& automaton);
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static grammar::Grammar convert(const automaton::Automaton& automaton);
+
+	static grammar::LeftRG convert(const automaton::NFA& automaton);
+	static grammar::LeftRG convert(const automaton::DFA& automaton);
+
+private:
+	void Visit(void*, const automaton::UnknownAutomaton& automaton) const;
+	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
+	void Visit(void*, const automaton::NFA& automaton) const;
+	void Visit(void*, const automaton::DFA& automaton) const;
+	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
+	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::NPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
+	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
+
+	static const FAtoLRGConverter FA_TO_LRG_CONVERTER;
 };
 
 } /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
index 4cf3d3cf79d2084d3a3d0e3a9f4719ee2bb8455f..e1fb2bd497c38eb0efb08bf0e2349f2b7ab15bc7 100644
--- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
+++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
@@ -1,53 +1,158 @@
 #include "FAtoRRGConverter.h"
 
+#include <label/StringLabel.h>
 #include <alphabet/LabeledSymbol.h>
 
+#include <exception/AlibException.h>
+
 namespace fa2rg
 {
 
 grammar::RightRG FAtoRRGConverter::convert(const automaton::NFA& automaton)
 {
-    std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+
+	const automaton::State& initState = *automaton.getInitialStates().begin(); //FIXME what about other initial states
+	const alphabet::Symbol initSymbol(alphabet::LabeledSymbol(initState.getName()));
+
+	grammar::RightRG grammar(initSymbol);
+	nonterminalMap.insert(std::make_pair(initState, initSymbol));
+
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+	for(const auto& state : automaton.getStates())
+	{
+		if(state == initState)
+			continue;
+
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::make_pair(state, nt));
+	}
+
+	// step 2 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+		for(const auto& to : transition.second)
+		{
+			grammar.addRule(nonterminalMap.find(from)->second, std::make_pair(input, nonterminalMap.find(to)->second)); // 2a
+			if(automaton.getFinalStates().count(to)) // 2b
+				grammar.addRule(nonterminalMap.find(from)->second, input);
+		}
+	}
+
+	// step 3 - set start symbol of G
+	grammar.setInitialSymbol(nonterminalMap.find(*automaton.getInitialStates().begin())->second);
+
+	// step 4
+	for(const auto & initial : automaton.getInitialStates()) {
+		if(automaton.getFinalStates().count(initial) > 0)
+			grammar.setGeneratesEpsilon(true); // okay this feature makes algorithm mismatch mathematical but simplifies the code actually :))
+	}
+
+	return grammar;
+}
+
+grammar::RightRG FAtoRRGConverter::convert(const automaton::DFA& automaton)
+{
+	std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+
+	const automaton::State& initState = automaton.getInitialState();
+	const alphabet::Symbol initSymbol(alphabet::LabeledSymbol(initState.getName()));
+
+	grammar::RightRG grammar(initSymbol);
+	nonterminalMap.insert(std::make_pair(initState, initSymbol));
 
-    const automaton::State& initState = *automaton.getInitialStates().begin();
-    const alphabet::Symbol initSymbol(alphabet::LabeledSymbol(initState.getName()));
+	grammar.setTerminalAlphabet(automaton.getInputAlphabet());
 
-    grammar::RightRG grammar(initSymbol);
-    nonterminalMap.insert(std::make_pair(initState, initSymbol));
+	for(const auto& state : automaton.getStates())
+	{
+		if(state == initState)
+			continue;
 
-    grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+		alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+		grammar.addNonterminalSymbol(nt);
+		nonterminalMap.insert(std::make_pair(state, nt));
+	}
 
-    for(const auto& state : automaton.getStates())
-    {
-        if(state == initState)
-            continue;
+	// step 2 - create set of P in G
+	for(const auto& transition : automaton.getTransitions())
+	{
+		const automaton::State& from = transition.first.first;
+		const alphabet::Symbol& input = transition.first.second;
+		const automaton::State& to = transition.second;
 
-        alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
-        grammar.addNonterminalSymbol(nt);
-        nonterminalMap.insert(std::make_pair(state, nt));
-    }
+		grammar.addRule(nonterminalMap.find(from)->second, std::make_pair(input, nonterminalMap.find(to)->second)); // 2a
+		if(automaton.getFinalStates().count(to)) // 2b
+			grammar.addRule(nonterminalMap.find(from)->second, input);
+	}
 
-    // step 2 - create set of P in G
-    for(const auto& transition : automaton.getTransitions())
-    {
-        const automaton::State& from = transition.first.first;
-        const alphabet::Symbol& input = transition.first.second;
-        for(const auto& to : transition.second)
-        {
-            grammar.addRule(nonterminalMap.find(from)->second, std::make_pair(input, nonterminalMap.find(to)->second)); // 2a
-            if(automaton.getFinalStates().count(to)) // 2b
-                grammar.addRule(nonterminalMap.find(from)->second, input);
-        }
-    }
+	// step 3 - set start symbol of G
+	grammar.setInitialSymbol(nonterminalMap.find(automaton.getInitialState())->second);
 
-    // step 3 - set start symbol of G
-    grammar.setInitialSymbol(nonterminalMap.find(*automaton.getInitialStates().begin())->second);
+	// step 4
+	if(automaton.getFinalStates().count(automaton.getInitialState()))
+		grammar.setGeneratesEpsilon(true); // okay this feature breaks algorithm but simplifies the code actually :))
 
-    // step 4
-    if(automaton.getFinalStates().count(*automaton.getInitialStates().begin()))
-        grammar.setGeneratesEpsilon(true); // okay this feature breaks algorithm but simplifies the code actually :))
+	return grammar;
+}
+
+grammar::Grammar FAtoRRGConverter::convert(const automaton::Automaton& automaton) {
+	grammar::Grammar* out = NULL;
+	automaton.getData().Accept((void*) &out, FAtoRRGConverter::FA_TO_RRG_CONVERTER);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
 
-    return grammar;
+void FAtoRRGConverter::Visit(void*, const automaton::EpsilonNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
 }
 
+void FAtoRRGConverter::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 {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(this->convert(automaton));
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FAtoRRGConverter::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+const FAtoRRGConverter FAtoRRGConverter::FA_TO_RRG_CONVERTER;
+
 } /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
index 79132db83956f40ff4c36bb88336d36ff7238121..97e8909d15d3b6f9806f79a99c4de62a78a8f95f 100644
--- a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
+++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
@@ -3,6 +3,10 @@
 
 #include <grammar/Regular/RightRG.h>
 #include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <grammar/Grammar.h>
+#include <automaton/Automaton.h>
 
 namespace fa2rg
 {
@@ -11,17 +15,32 @@ namespace fa2rg
  * Finite automaton to right regular grammar converter.
  * Source: Melichar 2.104
  */
-class FAtoRRGConverter
+class FAtoRRGConverter : public automaton::VisitableAutomatonBase::const_visitor_type
 {
 public:
-    /**
-     * Performs conversion.
-     * @return left regular grammar equivalent to source automaton.
-     */
-    grammar::RightRG convert(const automaton::NFA& automaton);
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static grammar::Grammar convert(const automaton::Automaton& automaton);
+
+	static grammar::RightRG convert(const automaton::NFA& automaton);
+	static grammar::RightRG convert(const automaton::DFA& automaton);
 
 private:
-    bool isSymbolOnAnyRightHandSide(const alphabet::Symbol& symbol, const grammar::RightRG& grammar) const;
+	void Visit(void*, const automaton::UnknownAutomaton& automaton) const;
+	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
+	void Visit(void*, const automaton::NFA& automaton) const;
+	void Visit(void*, const automaton::DFA& automaton) const;
+	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
+	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::NPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
+	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
+
+	static const FAtoRRGConverter FA_TO_RRG_CONVERTER;
 };
 
 } /* namespace fa2rg */
diff --git a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp
deleted file mode 100644
index 584bd8809981fe686fb89a3313e3db1a1b64a92b..0000000000000000000000000000000000000000
--- a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * EpsilonNFAEpsilonRemover.cpp
- *
- *  Created on: 16. 1. 2014
- *	  Author: Tomas Pecka
- */
-
-#include "EpsilonNFAEpsilonRemover.h"
-
-#include "../../automaton/AutomatonPropertiesFSM.h"
-
-namespace epsilon {
-
-automaton::NFA EpsilonNFAEpsilonRemover::remove(const automaton::NFA& origFSM)
-{
-    return origFSM;
-}
-
-automaton::NFA EpsilonNFAEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) {
-	automaton::NFA fsm;
-
-	for( const auto & state : origFSM.getStates() )
-		fsm.addState( state );
-
-	for( const auto & state : origFSM.getInitialStates() )
-		fsm.addInitialState( state );
-
-	for( const auto & symbol : origFSM.getInputAlphabet() )
-		fsm.addInputSymbol( symbol );
-
-	/**
-	 * Step 1 from Melichar 2.41
-	 */
-	for( const auto & from : origFSM.getStates( ) )
-		for( const auto & fromClosure : automaton::AutomatonPropertiesFSM::epsilonClosure( origFSM, from ) )
-			for( const auto & transition : origFSM.getSymbolTransitionsFromState( fromClosure ) )
-				for( const auto & to : transition.second )
-					fsm.addTransition( from, transition.first.second, to );
-
-	/**
-	 * Step 2 from Melichar 2.41
-	 */
-	std::set<automaton::State> finalStates;
-
-	for( const auto & q : fsm.getStates( ) )
-	{
-		const std::set<automaton::State> & cl = automaton::AutomatonPropertiesFSM::epsilonClosure( origFSM, q );
-		const std::set<automaton::State> & F = origFSM.getFinalStates( );
-		std::set<automaton::State> intersect;
-
-		set_intersection( cl.begin(), cl.end(), F.begin(), F.end(), std::inserter( intersect, intersect.begin() ) );
-		if( intersect.size( ) != 0 )
-			finalStates.insert( q );
-	}
-
-	for( const auto & q : finalStates )
-		fsm.addFinalState( q );
-
-	return fsm;
-}
-
-} /* namespace epsilon */
diff --git a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h b/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h
deleted file mode 100644
index c65beebcc4197cbe78ed70ed3e2316aefdb7420d..0000000000000000000000000000000000000000
--- a/alib2algo/src/epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * EpsilonNFAEpsilonRemover.h
- *
- *  Created on: 16. 1. 2014
- *      Author: Tomas Pecka
- */
-
-#ifndef EPSILON_NFA_EPSILON_REMOVER_H_
-#define EPSILON_NFA_EPSILON_REMOVER_H_
-
-#include <map>
-#include <algorithm>
-
-#include <automaton/FSM/EpsilonNFA.h>
-#include <automaton/FSM/NFA.h>
-#include <exception/AlibException.h>
-
-namespace epsilon {
-
-class EpsilonNFAEpsilonRemover {
-public:
-    static automaton::NFA remove(const automaton::EpsilonNFA &);
-    static automaton::NFA remove(const automaton::NFA &);
-};
-
-} /* namespace epsilon */
-
-#endif /* EPSILON_NFA_EPSILON_REMOVER_H_ */
diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b07bc9d1fb17c347c454e0ed2c4c36c95615aab
--- /dev/null
+++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.cpp
@@ -0,0 +1,124 @@
+/*
+ * FSMEpsilonRemover.cpp
+ *
+ *  Created on: 16. 1. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "FSMEpsilonRemover.h"
+
+#include "../../automaton/EpsilonClosure.h"
+
+namespace epsilon {
+
+automaton::DFA FSMEpsilonRemover::remove(const automaton::DFA& origFSM)
+{
+    return origFSM;
+}
+
+automaton::NFA FSMEpsilonRemover::remove(const automaton::NFA& origFSM)
+{
+    return origFSM;
+}
+
+automaton::NFA FSMEpsilonRemover::remove( const automaton::EpsilonNFA & origFSM ) {
+	automaton::NFA fsm;
+
+	for( const auto & state : origFSM.getStates() )
+		fsm.addState( state );
+
+	for( const auto & state : origFSM.getInitialStates() )
+		fsm.addInitialState( state );
+
+	for( const auto & symbol : origFSM.getInputAlphabet() )
+		fsm.addInputSymbol( symbol );
+
+	/**
+	 * Step 1 from Melichar 2.41
+	 */
+	for( const auto & from : origFSM.getStates( ) )
+		for( const auto & fromClosure : automaton::EpsilonClosure::epsilonClosure( origFSM, from ) )
+			for( const auto & transition : origFSM.getSymbolTransitionsFromState( fromClosure ) )
+				for( const auto & to : transition.second )
+					fsm.addTransition( from, transition.first.second, to );
+
+	/**
+	 * Step 2 from Melichar 2.41
+	 */
+	std::set<automaton::State> finalStates;
+
+	for( const auto & q : fsm.getStates( ) )
+	{
+		const std::set<automaton::State> & cl = automaton::EpsilonClosure::epsilonClosure( origFSM, q );
+		const std::set<automaton::State> & F = origFSM.getFinalStates( );
+		std::set<automaton::State> intersect;
+
+		set_intersection( cl.begin(), cl.end(), F.begin(), F.end(), std::inserter( intersect, intersect.begin() ) );
+		if( intersect.size( ) != 0 )
+			finalStates.insert( q );
+	}
+
+	for( const auto & q : finalStates )
+		fsm.addFinalState( q );
+
+	return fsm;
+}
+
+automaton::Automaton FSMEpsilonRemover::remove(const automaton::Automaton& automaton) {
+	automaton::Automaton* out = NULL;
+	automaton.getData().Accept((void*) &out, FSMEpsilonRemover::FSM_EPSILON_REMOVER);
+	automaton::Automaton res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::UnknownAutomaton&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FSMEpsilonRemover::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::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 {
+	automaton::Automaton* & out = *((automaton::Automaton**) data);
+	out = new automaton::Automaton(this->remove(automaton));
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+void FSMEpsilonRemover::Visit(void*, const automaton::OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type UnknownAutomaton");
+}
+
+const FSMEpsilonRemover FSMEpsilonRemover::FSM_EPSILON_REMOVER;
+
+} /* namespace epsilon */
diff --git a/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h
new file mode 100644
index 0000000000000000000000000000000000000000..e31662e2dcfd71f6c59db6e44e3478b283726f5a
--- /dev/null
+++ b/alib2algo/src/epsilon/fsm/FSMEpsilonRemover.h
@@ -0,0 +1,52 @@
+/*
+ * FSMEpsilonRemover.h
+ *
+ *  Created on: 16. 1. 2014
+ *      Author: Tomas Pecka
+ */
+
+#ifndef FMS_EPSILON_REMOVER_H_
+#define FMS_EPSILON_REMOVER_H_
+
+#include <map>
+#include <algorithm>
+
+#include <automaton/Automaton.h>
+
+#include <automaton/FSM/EpsilonNFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+#include <exception/AlibException.h>
+
+namespace epsilon {
+
+class FSMEpsilonRemover : public automaton::VisitableAutomatonBase::const_visitor_type {
+public:
+	static automaton::Automaton remove( const automaton::Automaton & automaton );
+
+	/**
+	 * Computes epsilon closure of a state in epsilon nonfree automaton
+	 */
+	static automaton::NFA remove( const automaton::EpsilonNFA & fsm );
+	static automaton::NFA remove( const automaton::NFA & fsm );
+	static automaton::DFA remove( const automaton::DFA & fsm );
+
+private:
+	void Visit(void*, const automaton::UnknownAutomaton& automaton) const;
+	void Visit(void*, const automaton::EpsilonNFA& automaton) const;
+	void Visit(void*, const automaton::NFA& automaton) const;
+	void Visit(void*, const automaton::DFA& automaton) const;
+	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
+	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
+	void Visit(void*, const automaton::NPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
+	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
+
+	static const FSMEpsilonRemover FSM_EPSILON_REMOVER;
+};
+
+} /* namespace epsilon */
+
+#endif /* FMS_EPSILON_REMOVER_H_ */
diff --git a/alib2algo/src/generator/RandomAutomatonFactory.cpp b/alib2algo/src/generator/RandomAutomatonFactory.cpp
index 9dfccb80386e08893a22f75678bfc7b7ab752b02..9960ee03cb3b3c89cf063b96c116e1c321214487 100644
--- a/alib2algo/src/generator/RandomAutomatonFactory.cpp
+++ b/alib2algo/src/generator/RandomAutomatonFactory.cpp
@@ -6,11 +6,12 @@
  */
 
 #include "RandomAutomatonFactory.h"
-#include "label/StringLabel.h"
-#include "label/IntegerLabel.h"
-#include "alphabet/LabeledSymbol.h"
+#include <label/StringLabel.h>
+#include <label/IntegerLabel.h>
+#include <alphabet/LabeledSymbol.h>
+#include <automaton/Automaton.h>
 
-#include "automaton/Automaton.h"
+#include <algorithm>
 
 namespace generator {
 
diff --git a/alib2algo/src/generator/RandomAutomatonFactory.h b/alib2algo/src/generator/RandomAutomatonFactory.h
index 2f36ce16c22db4ee8cfc6517d4094a1bb290c3a3..3501e45b780c4fb39ddd2e26ce1d6220c50f8678 100644
--- a/alib2algo/src/generator/RandomAutomatonFactory.h
+++ b/alib2algo/src/generator/RandomAutomatonFactory.h
@@ -9,9 +9,7 @@
 #define RANDOM_AUTOMATON_FACTORY_H_
 
 #include <deque>
-#include <map>
 #include <set>
-#include <algorithm>
 
 #include <exception/AlibException.h>
 #include <automaton/FSM/NFA.h>
diff --git a/alib2algo/src/regexp/RegExpEpsilon.cpp b/alib2algo/src/regexp/RegExpEpsilon.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..74a832881bc9239c4746c9a55126d86435876429
--- /dev/null
+++ b/alib2algo/src/regexp/RegExpEpsilon.cpp
@@ -0,0 +1,44 @@
+/*
+ * RegExpEpsilon.cpp
+ *
+ *  Created on: 19. 1. 2014
+ *      Author: Tomas Pecka
+ */
+
+#include "RegExpEpsilon.h"
+
+namespace regexp
+{
+
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp)
+{
+    bool out;
+    regexp.getData().Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON);
+    return out;
+}
+
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp& regexp)
+{
+	return regexp.containsEmptyString();
+}
+
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExp& regexp)
+{
+	return regexp.containsEmptyString();
+}
+
+void RegExpEpsilon::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+{
+    bool &ret = *(bool*) userData;
+    ret = RegExpEpsilon::REG_EXP_EPSILON.languageContainsEpsilon(regexp);
+}
+
+void RegExpEpsilon::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+{
+    bool &ret = *(bool*) userData;
+    ret = RegExpEpsilon::REG_EXP_EPSILON.languageContainsEpsilon(regexp);
+}
+
+const RegExpEpsilon RegExpEpsilon::REG_EXP_EPSILON;
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/RegExpEpsilon.h b/alib2algo/src/regexp/RegExpEpsilon.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f2642add7d360290552e8bb0eb3a8fd6e0f5bdd
--- /dev/null
+++ b/alib2algo/src/regexp/RegExpEpsilon.h
@@ -0,0 +1,39 @@
+/*
+ * RegExpEpsilon.h
+ *
+ *  Created on: 19. 1. 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef REG_EXP_EPSILON_H_
+#define REG_EXP_EPSILON_H_
+
+#include <regexp/RegExp.h>
+#include <regexp/formal/FormalRegExpElements.h>
+#include <regexp/unbounded/UnboundedRegExpElements.h>
+
+namespace regexp
+{
+
+/**
+ * Calculates languageContainsEpsilon of regular expression.
+ *
+ */
+class RegExpEpsilon : public regexp::VisitableRegExpBase::const_visitor_type
+{
+public:
+    static bool languageContainsEpsilon(const regexp::RegExp& regexp);
+
+    static bool languageContainsEpsilon(const regexp::FormalRegExp& regexp);
+    static bool languageContainsEpsilon(const regexp::UnboundedRegExp& regexp);
+
+private:
+    void Visit(void* data, const regexp::UnboundedRegExp& regexp) const;
+    void Visit(void* data, const regexp::FormalRegExp& regexp) const;
+
+    static const RegExpEpsilon REG_EXP_EPSILON;
+};
+
+} /* namespace regexp */
+
+#endif /* REG_EXP_EPSILON_H_ */
diff --git a/alib2algo/test-src/conversions/playTest.cpp b/alib2algo/test-src/conversions/playTest.cpp
index 03a7af3387c5ee02b60d63767a15f99e83ba8932..ee74dc2a748395cc747988e15936c36b49b2267a 100644
--- a/alib2algo/test-src/conversions/playTest.cpp
+++ b/alib2algo/test-src/conversions/playTest.cpp
@@ -10,7 +10,7 @@
 #include "generator/RandomAutomatonFactory.h"
 #include "normalize/dfa/NormalizeDFA.h"
 #include "trim/automaton/TrimFSM.h"
-#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h"
+#include "epsilon/fsm/FSMEpsilonRemover.h"
 #include "minimize/dfa/MinimizeDFA.h"
 
 //#include "conversions/fa2re/StateElimination.h"
@@ -57,7 +57,7 @@ automaton::NFA playTest::randomNFA(void) const
 
 automaton::DFA playTest::mDFA(const automaton::NFA& automaton) const
 {
-    automaton::NFA nfa = epsilon::EpsilonNFAEpsilonRemover::remove(automaton);
+    automaton::NFA nfa = epsilon::FSMEpsilonRemover::remove(automaton);
     nfa = trim::TrimFSM::trim(nfa);
     automaton::DFA dfa = determinize::NFADeterminizer::determinize(nfa);
     dfa = trim::TrimFSM::trim(dfa);
diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
index 23f3376fe3c24dd5b9f74d1c04e0a1539fa52718..0d0d507550e7fb53051897ccf10760b69bc88d4b 100644
--- a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
+++ b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
@@ -7,7 +7,7 @@
 #include "conversions/fa2re/BrzozowskiAlgebraic.h"
 #include "determinize/nfa/NFADeterminizer.h"
 #include "minimize/dfa/MinimizeDFA.h"
-#include "epsilon/epsilonNfa/EpsilonNFAEpsilonRemover.h"
+#include "epsilon/fsm/FSMEpsilonRemover.h"
 
 #include "regexp/unbounded/UnboundedRegExp.h"
 #include "regexp/RegExpFromStringParser.h"
@@ -37,8 +37,8 @@ void re2faTest::testThompson() {
 	re2fa::Thompson thompson2;
 	automaton::EpsilonNFA enfa2 = thompson2.convert(regexp2);
 
-	automaton::NFA nfa1 = epsilon::EpsilonNFAEpsilonRemover::remove(enfa1);
-	automaton::NFA nfa2 = epsilon::EpsilonNFAEpsilonRemover::remove(enfa2);
+	automaton::NFA nfa1 = epsilon::FSMEpsilonRemover::remove(enfa1);
+	automaton::NFA nfa2 = epsilon::FSMEpsilonRemover::remove(enfa2);
 
 	automaton::DFA dfa1 = determinize::NFADeterminizer::determinize(nfa1);
 	automaton::DFA dfa2 = determinize::NFADeterminizer::determinize(nfa2);
diff --git a/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp b/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp
index 13896b5189e5c381cdf695f58991bd26c8c18f58..bbe21afc1d430dbcc739efb3e810cc04ff34df0f 100644
--- a/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp
+++ b/alib2algo/test-src/regexp/RegExpOptimizeTest.cpp
@@ -27,7 +27,6 @@ void RegExpOptimizeTest::testOptimize() {
 
 		regexp::RegExpOptimize opt;
 		regexp::UnboundedRegExp res = opt.optimize(regexp);
-		std::cout << res << std::endl;
 	}
 	{
 		std::string input = "a+a* (b+a)* c";
diff --git a/alib2data/src/Api.cpp b/alib2data/src/Api.cpp
index 001a533c6d2a065d74e8518c0fb70bca60fc21e7..e5a60b8b3585d42b0f948473a108fa710360c386 100644
--- a/alib2data/src/Api.cpp
+++ b/alib2data/src/Api.cpp
@@ -160,6 +160,22 @@ std::list<sax::Token> api<automaton::CompactNFA>::compose(const automaton::Compa
 	return ToXMLComposers::automatonComposer.compose(data);
 }
 
+automaton::DPDA api<automaton::DPDA>::parse(std::list<sax::Token>& input) {
+	return FromXMLParsers::automatonParser.parseDPDA(input);
+}
+
+std::list<sax::Token> api<automaton::DPDA>::compose(const automaton::DPDA& data) {
+	return ToXMLComposers::automatonComposer.compose(data);
+}
+
+automaton::SinglePopDPDA api<automaton::SinglePopDPDA>::parse(std::list<sax::Token>& input) {
+	return FromXMLParsers::automatonParser.parseSinglePopDPDA(input);
+}
+
+std::list<sax::Token> api<automaton::SinglePopDPDA>::compose(const automaton::SinglePopDPDA& data) {
+	return ToXMLComposers::automatonComposer.compose(data);
+}
+
 automaton::NPDA api<automaton::NPDA>::parse(std::list<sax::Token>& input) {
 	return FromXMLParsers::automatonParser.parseNPDA(input);
 }
@@ -460,6 +476,14 @@ void ToXMLComposers::Visit(void* data, const automaton::CompactNFA& automaton) c
 	*((std::list<sax::Token>*) data) = std::move(api<automaton::CompactNFA>::compose(automaton));
 }
 
+void ToXMLComposers::Visit(void* data, const automaton::DPDA& automaton) const {
+	*((std::list<sax::Token>*) data) = std::move(api<automaton::DPDA>::compose(automaton));
+}
+
+void ToXMLComposers::Visit(void* data, const automaton::SinglePopDPDA& automaton) const {
+	*((std::list<sax::Token>*) data) = std::move(api<automaton::SinglePopDPDA>::compose(automaton));
+}
+
 void ToXMLComposers::Visit(void* data, const automaton::NPDA& automaton) const {
 	*((std::list<sax::Token>*) data) = std::move(api<automaton::NPDA>::compose(automaton));
 }
diff --git a/alib2data/src/Api.hpp b/alib2data/src/Api.hpp
index 3161b494ad66f839024358a441899c3dd5ff1d15..675b892f73de43c530437e0bc61b040be0ed34a8 100644
--- a/alib2data/src/Api.hpp
+++ b/alib2data/src/Api.hpp
@@ -136,6 +136,18 @@ struct api<automaton::CompactNFA> {
 	static std::list<sax::Token> compose(const automaton::CompactNFA& data);
 };
 
+template<>
+struct api<automaton::DPDA> {
+	static automaton::DPDA parse(std::list<sax::Token>& input);
+	static std::list<sax::Token> compose(const automaton::DPDA& data);
+};
+
+template<>
+struct api<automaton::SinglePopDPDA> {
+	static automaton::SinglePopDPDA parse(std::list<sax::Token>& input);
+	static std::list<sax::Token> compose(const automaton::SinglePopDPDA& data);
+};
+
 template<>
 struct api<automaton::NPDA> {
 	static automaton::NPDA parse(std::list<sax::Token>& input);
@@ -372,6 +384,8 @@ class ToXMLComposers : public VisitableObjectBase::const_visitor_type {
 	void Visit(void*, const automaton::DFA& automaton) const;
 	void Visit(void*, const automaton::ExtendedNFA& automaton) const;
 	void Visit(void*, const automaton::CompactNFA& automaton) const;
+	void Visit(void*, const automaton::DPDA& automaton) const;
+	void Visit(void*, const automaton::SinglePopDPDA& automaton) const;
 	void Visit(void*, const automaton::NPDA& automaton) const;
 	void Visit(void*, const automaton::SinglePopNPDA& automaton) const;
 	void Visit(void*, const automaton::OneTapeDTM& automaton) const;
diff --git a/alib2data/src/automaton/AutomatonBase.h b/alib2data/src/automaton/AutomatonBase.h
index 07ff350f0127675a872f2cb57dde5fc2bbcf8d9a..40e639a22c005fcca0c131ca5341a71691fd6aee 100644
--- a/alib2data/src/automaton/AutomatonBase.h
+++ b/alib2data/src/automaton/AutomatonBase.h
@@ -14,7 +14,7 @@
 namespace automaton {
 
 typedef std::acceptor_base<
-			automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM
+			automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM
 	> VisitableAutomatonBase;
 
 /**
diff --git a/alib2data/src/automaton/AutomatonFeatures.h b/alib2data/src/automaton/AutomatonFeatures.h
index cc71a8a1a5e16c931f7492663c4198f85a41eaf1..5677a8ba0a0ce1946188c0d3dc7b833e379e6d04 100644
--- a/alib2data/src/automaton/AutomatonFeatures.h
+++ b/alib2data/src/automaton/AutomatonFeatures.h
@@ -17,6 +17,8 @@ enum class FEATURES {
 	DFA,
 	COMPACT_NFA,
 	EXTENDED_NFA,
+	DPDA,
+	SINGLE_POP_DPDA,
 	NPDA,
 	SINGLE_POP_NPDA,
 	ONE_TAPE_DTM
diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.cpp b/alib2data/src/automaton/AutomatonFromXMLParser.cpp
index 4d04ffa462aab673e4601e7fb1dfa43a228c4339..bda25b15d253723c3c0a7fda63e379bb4ac268e6 100644
--- a/alib2data/src/automaton/AutomatonFromXMLParser.cpp
+++ b/alib2data/src/automaton/AutomatonFromXMLParser.cpp
@@ -18,7 +18,7 @@
 namespace automaton {
 
 Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token> &input) const {
-	return parseAutomaton(input, std::set<FEATURES>({FEATURES::AUTOMATON, FEATURES::EPSILON_NFA, FEATURES::NFA, FEATURES::DFA, FEATURES::COMPACT_NFA, FEATURES::EXTENDED_NFA, FEATURES::NPDA, FEATURES::SINGLE_POP_NPDA, FEATURES::ONE_TAPE_DTM}));
+	return parseAutomaton(input, std::set<FEATURES>({FEATURES::AUTOMATON, FEATURES::EPSILON_NFA, FEATURES::NFA, FEATURES::DFA, FEATURES::COMPACT_NFA, FEATURES::EXTENDED_NFA, FEATURES::DPDA, FEATURES::SINGLE_POP_DPDA, FEATURES::NPDA, FEATURES::SINGLE_POP_NPDA, FEATURES::ONE_TAPE_DTM}));
 }
 
 Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token>& input, const std::set<FEATURES>& features) const {
@@ -40,6 +40,12 @@ Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token>& input, c
 	} else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "ExtendedNFA")) {
 		if(!features.count(FEATURES::EXTENDED_NFA)) throw exception::AlibException();
 		return Automaton(parseExtendedNFA(input));
+	} else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "DPDA")) {
+		if(!features.count(FEATURES::DPDA)) throw exception::AlibException();
+		return Automaton(parseDPDA(input));
+	} else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopDPDA")) {
+		if(!features.count(FEATURES::SINGLE_POP_DPDA)) throw exception::AlibException();
+		return Automaton(parseSinglePopDPDA(input));
 	} else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA")) {
 		if(!features.count(FEATURES::NPDA)) throw exception::AlibException();
 		return Automaton(parseNPDA(input));
@@ -50,11 +56,11 @@ Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token>& input, c
 		if(!features.count(FEATURES::ONE_TAPE_DTM)) throw exception::AlibException();
 		return Automaton(parseOneTapeDTM(input));
 	} else
-		throw sax::ParserException(sax::Token("Automaton / EpsilonNFA / NFA / DFA", sax::Token::TokenType::START_ELEMENT), input.front());
+		throw sax::ParserException(sax::Token("Automaton / EpsilonNFA / NFA / DFA / CompactNFA / ExtendedNFA / DPDA / SinglePopDPDA / NPDA / SinglePopNPDA / OneTapeDTM", sax::Token::TokenType::START_ELEMENT), input.front());
 }
 
 bool AutomatonFromXMLParser::first(std::list<sax::Token>& input) const {
-	if(isToken(input, sax::Token::TokenType::START_ELEMENT, "automaton") || isToken(input, sax::Token::TokenType::START_ELEMENT, "EpsilonNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DFA")) {
+	if(isToken(input, sax::Token::TokenType::START_ELEMENT, "automaton") || isToken(input, sax::Token::TokenType::START_ELEMENT, "EpsilonNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "CompactNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "ExtendedNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopDPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "OneTapeDTM")) {
 		return true;
 	} else {
 		return false;
@@ -193,6 +199,52 @@ ExtendedNFA AutomatonFromXMLParser::parseExtendedNFA(std::list<sax::Token>& inpu
 	return automaton;
 }
 
+DPDA AutomatonFromXMLParser::parseDPDA(std::list<sax::Token>& input) const {
+	popToken(input, sax::Token::TokenType::START_ELEMENT, "DPDA");
+
+	std::set<State> states = parseStates(input);
+	std::set<alphabet::Symbol> inputSymbols = parseInputAlphabet(input);
+	std::set<alphabet::Symbol> stackSymbols = parseStackAlphabet(input);
+	State initialState = parseInitialState(input);
+	alphabet::Symbol initialStackSymbol = parseInitialStackSymbol(input);
+	std::set<State> finalStates = parseFinalStates(input);
+
+	DPDA automaton(initialState, initialStackSymbol);
+	automaton.setStates(states);
+	automaton.setInputSymbols(inputSymbols);
+	automaton.setStackSymbols(stackSymbols);
+	automaton.setFinalStates(finalStates);
+
+	parseTransitions<DPDA>(input, automaton);
+
+	popToken(input, sax::Token::TokenType::END_ELEMENT, "DPDA");
+
+	return automaton;
+}
+
+SinglePopDPDA AutomatonFromXMLParser::parseSinglePopDPDA(std::list<sax::Token>& input) const {
+	popToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopDPDA");
+
+	std::set<State> states = parseStates(input);
+	std::set<alphabet::Symbol> inputSymbols = parseInputAlphabet(input);
+	std::set<alphabet::Symbol> stackSymbols = parseStackAlphabet(input);
+	State initialState = parseInitialState(input);
+	alphabet::Symbol initialStackSymbol = parseInitialStackSymbol(input);
+	std::set<State> finalStates = parseFinalStates(input);
+
+	SinglePopDPDA automaton(initialState, initialStackSymbol);
+	automaton.setStates(states);
+	automaton.setInputSymbols(inputSymbols);
+	automaton.setStackSymbols(stackSymbols);
+	automaton.setFinalStates(finalStates);
+
+	parseTransitions<SinglePopDPDA>(input, automaton);
+
+	popToken(input, sax::Token::TokenType::END_ELEMENT, "SinglePopDPDA");
+
+	return automaton;
+}
+
 NPDA AutomatonFromXMLParser::parseNPDA(std::list<sax::Token>& input) const {
 	popToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA");
 
@@ -408,6 +460,26 @@ void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, Exten
 	automaton.addTransition(from, inputRegexp, to);
 }
 
+void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, DPDA& automaton) const {
+	State from = parseTransitionFrom(input);
+	std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input);
+	State to = parseTransitionFrom(input);
+	std::vector<alphabet::Symbol> pop = parseTransitionPop(input);
+	std::vector<alphabet::Symbol> push = parseTransitionPush(input);
+
+	automaton.addTransition(from, inputSymbol, pop, to, push);
+}
+
+void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, SinglePopDPDA& automaton) const {
+	State from = parseTransitionFrom(input);
+	std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input);
+	State to = parseTransitionFrom(input);
+	alphabet::Symbol pop = parseTransitionSinglePop(input);
+	std::vector<alphabet::Symbol> push = parseTransitionPush(input);
+
+	automaton.addTransition(from, inputSymbol, pop, to, push);
+}
+
 void AutomatonFromXMLParser::parseTransition(std::list<sax::Token>& input, NPDA& automaton) const {
 	State from = parseTransitionFrom(input);
 	std::variant<string::Epsilon, alphabet::Symbol> inputSymbol = parseTransitionInputEpsilonSymbol(input);
diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.h b/alib2data/src/automaton/AutomatonFromXMLParser.h
index ef49696ae5ffe33302ff8d1639b2b4476de175a1..360a7315ae591dd707989898ebbffe5260ae734b 100644
--- a/alib2data/src/automaton/AutomatonFromXMLParser.h
+++ b/alib2data/src/automaton/AutomatonFromXMLParser.h
@@ -17,6 +17,8 @@
 #include "FSM/DFA.h"
 #include "FSM/CompactNFA.h"
 #include "FSM/ExtendedNFA.h"
+#include "PDA/DPDA.h"
+#include "PDA/SinglePopDPDA.h"
 #include "PDA/NPDA.h"
 #include "PDA/SinglePopNPDA.h"
 #include "TM/OneTapeDTM.h"
@@ -65,6 +67,8 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper {
 	void parseTransition(std::list<sax::Token>& input, DFA& automaton) const;
 	void parseTransition(std::list<sax::Token>& input, CompactNFA& automaton) const;
 	void parseTransition(std::list<sax::Token>& input, ExtendedNFA& automaton) const;
+	void parseTransition(std::list<sax::Token>& input, DPDA& automaton) const;
+	void parseTransition(std::list<sax::Token>& input, SinglePopDPDA& automaton) const;
 	void parseTransition(std::list<sax::Token>& input, NPDA& automaton) const;
 	void parseTransition(std::list<sax::Token>& input, SinglePopNPDA& automaton) const;
 	void parseTransition(std::list<sax::Token>& input, OneTapeDTM& automaton) const;
@@ -91,6 +95,8 @@ class AutomatonFromXMLParser : public sax::FromXMLParserHelper {
 	DFA parseDFA(std::list<sax::Token>& input) const;
 	CompactNFA parseCompactNFA(std::list<sax::Token>& input) const;
 	ExtendedNFA parseExtendedNFA(std::list<sax::Token>& input) const;
+	DPDA parseDPDA(std::list<sax::Token>& input) const;
+	SinglePopDPDA parseSinglePopDPDA(std::list<sax::Token>& input) const;
 	NPDA parseNPDA(std::list<sax::Token>& input) const;
 	SinglePopNPDA parseSinglePopNPDA(std::list<sax::Token>& input) const;
 	OneTapeDTM parseOneTapeDTM(std::list<sax::Token>& input) const;
diff --git a/alib2data/src/automaton/AutomatonToXMLComposer.cpp b/alib2data/src/automaton/AutomatonToXMLComposer.cpp
index 6c8537d5d84de8ab36373ce5e0e2ca8e3927e51b..834d646130b24228e1a667457b17cdc2385d0a41 100644
--- a/alib2data/src/automaton/AutomatonToXMLComposer.cpp
+++ b/alib2data/src/automaton/AutomatonToXMLComposer.cpp
@@ -202,6 +202,40 @@ void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, cons
 	out.push_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT));
 }
 
+void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, const DPDA& automaton) const {
+	out.push_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT));
+	for(const auto& transition : automaton.getTransitions()) {
+		out.push_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT));
+
+		composeTransitionFrom(out, std::get<0>(transition.first));
+		composeTransitionInputEpsilonSymbol(out, std::get<1>(transition.first));
+		composeTransitionPop(out, std::get<2>(transition.first));
+		composeTransitionTo(out, transition.second.first);
+		composeTransitionPush(out, transition.second.second);
+
+		out.push_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT));
+	}
+
+	out.push_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT));
+}
+
+void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, const SinglePopDPDA& automaton) const {
+	out.push_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT));
+	for(const auto& transition : automaton.getTransitions()) {
+		out.push_back(sax::Token("transition", sax::Token::TokenType::START_ELEMENT));
+
+		composeTransitionFrom(out, std::get<0>(transition.first));
+		composeTransitionInputEpsilonSymbol(out, std::get<1>(transition.first));
+		composeTransitionSinglePop(out, std::get<2>(transition.first));
+		composeTransitionTo(out, transition.second.first);
+		composeTransitionPush(out, transition.second.second);
+
+		out.push_back(sax::Token("transition", sax::Token::TokenType::END_ELEMENT));
+	}
+
+	out.push_back(sax::Token("transitions", sax::Token::TokenType::END_ELEMENT));
+}
+
 void AutomatonToXMLComposer::composeTransitions(std::list<sax::Token>& out, const NPDA& automaton) const {
 	out.push_back(sax::Token("transitions", sax::Token::TokenType::START_ELEMENT));
 	for(const auto& transition : automaton.getTransitions()) {
@@ -460,6 +494,38 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const CompactNFA& automato
 	return out;
 }
 
+std::list<sax::Token> AutomatonToXMLComposer::compose(const DPDA& automaton) const {
+	std::list<sax::Token> out;
+	out.push_back(sax::Token("DPDA", sax::Token::TokenType::START_ELEMENT));
+
+	composeStates(out, automaton.getStates());
+	composeInputAlphabet(out, automaton.getInputAlphabet());
+	composeStackAlphabet(out, automaton.getStackAlphabet());
+	composeInitialState(out, automaton.getInitialState());
+	composeFinalStates(out, automaton.getFinalStates());
+	composeInitialStackSymbol(out, automaton.getInitialSymbol());
+	composeTransitions(out, automaton);
+
+	out.push_back(sax::Token("DPDA", sax::Token::TokenType::END_ELEMENT));
+	return out;
+}
+
+std::list<sax::Token> AutomatonToXMLComposer::compose(const SinglePopDPDA& automaton) const {
+	std::list<sax::Token> out;
+	out.push_back(sax::Token("SinglePopDPDA", sax::Token::TokenType::START_ELEMENT));
+
+	composeStates(out, automaton.getStates());
+	composeInputAlphabet(out, automaton.getInputAlphabet());
+	composeStackAlphabet(out, automaton.getStackAlphabet());
+	composeInitialState(out, automaton.getInitialState());
+	composeFinalStates(out, automaton.getFinalStates());
+	composeInitialStackSymbol(out, automaton.getInitialSymbol());
+	composeTransitions(out, automaton);
+
+	out.push_back(sax::Token("SinglePopDPDA", sax::Token::TokenType::END_ELEMENT));
+	return out;
+}
+
 std::list<sax::Token> AutomatonToXMLComposer::compose(const NPDA& automaton) const {
 	std::list<sax::Token> out;
 	out.push_back(sax::Token("NPDA", sax::Token::TokenType::START_ELEMENT));
diff --git a/alib2data/src/automaton/AutomatonToXMLComposer.h b/alib2data/src/automaton/AutomatonToXMLComposer.h
index 729b97dcaa3e39f05eb57426fcaa69dab6297415..50f3e1f8d49fd47833264a7477816a977e6b9bd6 100644
--- a/alib2data/src/automaton/AutomatonToXMLComposer.h
+++ b/alib2data/src/automaton/AutomatonToXMLComposer.h
@@ -52,6 +52,8 @@ class AutomatonToXMLComposer {
 	void composeTransitions(std::list<sax::Token>&, const ExtendedNFA& automaton) const;
 	void composeTransitions(std::list<sax::Token>&, const NFA& automaton) const;
 	void composeTransitions(std::list<sax::Token>&, const DFA& automaton) const;
+	void composeTransitions(std::list<sax::Token>&, const DPDA& automaton) const;
+	void composeTransitions(std::list<sax::Token>&, const SinglePopDPDA& automaton) const;
 	void composeTransitions(std::list<sax::Token>&, const NPDA& automaton) const;
 	void composeTransitions(std::list<sax::Token>&, const SinglePopNPDA& automaton) const;
 	void composeTransitions(std::list<sax::Token>&, const OneTapeDTM& automaton) const;
@@ -84,6 +86,8 @@ class AutomatonToXMLComposer {
 	std::list<sax::Token> compose(const EpsilonNFA& automaton) const;
 	std::list<sax::Token> compose(const ExtendedNFA& automaton) const;
 	std::list<sax::Token> compose(const CompactNFA& automaton) const;
+	std::list<sax::Token> compose(const DPDA& automaton) const;
+	std::list<sax::Token> compose(const SinglePopDPDA& automaton) const;
 	std::list<sax::Token> compose(const NPDA& automaton) const;
 	std::list<sax::Token> compose(const SinglePopNPDA& automaton) const;
 	std::list<sax::Token> compose(const OneTapeDTM& automaton) const;
diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
index 8a6eab24581c8607752174fd6032b1e091f85508..69e337f6ed01b3faaa7d433e9247cd789e272e21 100644
--- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
+++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.cpp
@@ -186,6 +186,14 @@ void FiniteAutomatonToStringComposer::Visit(void*, const CompactNFA&) const {
 	throw exception::AlibException();
 }
 
+void FiniteAutomatonToStringComposer::Visit(void*, const DPDA&) const {
+	throw exception::AlibException();
+}
+
+void FiniteAutomatonToStringComposer::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException();
+}
+
 void FiniteAutomatonToStringComposer::Visit(void*, const NPDA&) const {
 	throw exception::AlibException();
 }
diff --git a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h
index 7998f253b154f1dc0b8153189e95b9370a95cda7..3b6c906f845dadaa8dd33c1e8fa8fca616327868 100644
--- a/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h
+++ b/alib2data/src/automaton/FSM/FiniteAutomatonToStringComposer.h
@@ -18,6 +18,8 @@ class FiniteAutomatonToStringComposer : public VisitableAutomatonBase::const_vis
 	void Visit(void*, const CompactNFA& automaton) const;
 	void Visit(void*, const NPDA& automaton) const;
 	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const DPDA& automaton) const;
+	void Visit(void*, const SinglePopDPDA& automaton) const;
 	void Visit(void*, const OneTapeDTM& automaton) const;
 
 	void composeTransitionsFromState(std::stringstream& out, const DFA& automaton, const State& from) const;
diff --git a/alib2data/src/automaton/PDA/DPDA.cpp b/alib2data/src/automaton/PDA/DPDA.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b557b37e0fa15d9c9a72ef83ee82817168a3d1ef
--- /dev/null
+++ b/alib2data/src/automaton/PDA/DPDA.cpp
@@ -0,0 +1,235 @@
+/*
+ * DPDA.cpp
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Martin Zak
+ */
+
+#include "DPDA.h"
+#include "../../std/map.hpp"
+#include "../AutomatonException.h"
+#include <algorithm>
+#include <sstream>
+
+namespace automaton {
+
+DPDA::DPDA(const State& initialState, const alphabet::Symbol& initialPushdownSymbol) : SingleInitialSymbolPushdownStoreAlphabet(initialPushdownSymbol), SingleInitialState(initialState) {
+
+}
+
+AutomatonBase* DPDA::clone() const {
+	return new DPDA(*this);
+}
+
+AutomatonBase* DPDA::plunder() && {
+	return new DPDA(std::move(*this));
+}
+
+bool DPDA::removeState(const State& state) {
+	if (initialState == state) {
+		throw AutomatonException("State \"" + (std::string) state.getName() + "\" is initial state.");
+	}
+
+	if (finalStates.find(state) != finalStates.end()) {
+		throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state.");
+	}
+
+	for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
+		if (state == std::get<0>(transition->first))
+			throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
+		if( transition->second.first == state)
+			throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
+	}
+
+	return states.erase(state);
+}
+
+bool DPDA::removeInputSymbol(const alphabet::Symbol& symbol) {
+	for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
+		if (std::get<1>(transition->first).is<alphabet::Symbol>() && symbol == std::get<1>(transition->first).get<alphabet::Symbol>())
+			throw AutomatonException("Symbol \"" + (std::string) symbol + "\" is used in transition.");
+	}
+
+	return inputAlphabet.erase(symbol);
+}
+
+bool DPDA::removeStackSymbol(const alphabet::Symbol& symbol) {
+	for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
+		for (std::vector<alphabet::Symbol>::const_iterator popSymbol = std::get<2>(transition->first).begin(); popSymbol != std::get<2>(transition->first).end();
+				popSymbol++) {
+			if (symbol == *popSymbol)
+				throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
+		}
+		if (std::find(transition->second.second.begin(), transition->second.second.end(), symbol) != transition->second.second.end())
+			throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
+	}
+
+	if(initialSymbol == symbol) {
+		throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is start symbol.");
+	}
+
+	return stackAlphabet.erase(symbol);
+}
+
+bool DPDA::addTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	if (states.find(from) == states.end()) {
+		throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist.");
+	}
+
+	if (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end()) {
+		throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" doesn't exist.");
+	}
+
+	if (states.find(to) == states.end()) {
+		throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist.");
+	}
+
+	for(std::vector<alphabet::Symbol>::const_iterator popSymbol = pop.begin(); popSymbol != pop.end(); popSymbol++) {
+		if (stackAlphabet.find(*popSymbol) == stackAlphabet.end()) {
+			throw AutomatonException("Stack symbol \"" + (std::string) *popSymbol + "\" doesn't exist.");
+		}
+	}
+
+	for(std::vector<alphabet::Symbol>::const_iterator pushSymbol = push.begin(); pushSymbol != push.end(); pushSymbol++) {
+		if (stackAlphabet.find(*pushSymbol) == stackAlphabet.end()) {
+			throw AutomatonException("Stack symbol \"" + (std::string) *pushSymbol + "\" doesn't exist.");
+		}
+	}
+
+	std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> > key(from, input, pop);
+	std::pair<automaton::State, std::vector<alphabet::Symbol> > value = std::make_pair(to, push);
+	
+	if (transitions.find(key) != transitions.end()) {
+		if(transitions.find(key)->second == value)
+			return false;
+		else if (input.is<alphabet::Symbol>())
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<alphabet::Symbol>() + "\", \"pop\") -> ?? already exists.");
+		else
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<string::Epsilon>() + "\", \"pop\") -> ?? already exists.");
+	}
+
+	if(input.is<string::Epsilon>()) {
+		if(std::any_of(transitions.begin(), transitions.end(), [&](const std::pair<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<automaton::State, std::vector<alphabet::Symbol> > > & transition) {
+				if(std::get<0>(transition.first) == from) {
+					const std::vector<alphabet::Symbol>& alpha = std::get<2>(transition.first);
+					const std::vector<alphabet::Symbol>& beta = pop;
+
+					const std::vector<alphabet::Symbol>& shorter = (alpha.size() < beta.size()) ? alpha : beta;
+					const std::vector<alphabet::Symbol>& longer = (alpha.size() < beta.size()) ? beta : alpha;
+
+					for(auto itS = shorter.begin(), itL = longer.begin(); itS != shorter.end(); itS++, itL++) {
+						if(*itS != *itL) return false;
+					}
+					return true;
+				}
+				return false;
+			}))
+				throw exception::AlibException("Conflicting transition");
+	} else {
+		if(std::any_of(transitions.begin(), transitions.end(), [&](const std::pair<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<automaton::State, std::vector<alphabet::Symbol> > > & transition) {
+				if(std::get<0>(transition.first) == from && ( std::get<1>(transition.first) == input || std::get<1>(transition.first).is<string::Epsilon>() )) {
+					const std::vector<alphabet::Symbol>& alpha = std::get<2>(transition.first);
+					const std::vector<alphabet::Symbol>& beta = pop;
+
+					const std::vector<alphabet::Symbol>& shorter = (alpha.size() < beta.size()) ? alpha : beta;
+					const std::vector<alphabet::Symbol>& longer = (alpha.size() < beta.size()) ? beta : alpha;
+
+					for(auto itS = shorter.begin(), itL = longer.begin(); itS != shorter.end(); itS++, itL++) {
+						if(*itS != *itL) return false;
+					}
+					return true;
+				}
+				return false;
+			}))
+				throw exception::AlibException("Conflicting transition");
+	}
+
+	transitions.insert(std::make_pair(key, value) );
+	return true;
+}
+
+bool DPDA::addTransition(const State& from, const alphabet::Symbol& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input);
+	return addTransition(from, inputVariant, pop, to, push);
+}
+
+bool DPDA::addTransition(const State& from, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON);
+	return addTransition(from, inputVariant, pop, to, push);
+}
+
+bool DPDA::removeTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> > key(from, input, pop);
+	std::pair<automaton::State, std::vector<alphabet::Symbol> > value = std::make_pair(to, push);
+
+	if (transitions.find(key) == transitions.end())
+		return false;
+
+	if(transitions.find(key)->second != value) {
+		if (input.is<alphabet::Symbol>())
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<alphabet::Symbol>() + "\") -> \"to\" doesn't exist.");
+		else
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<string::Epsilon>() + "\") -> \"to\" doesn't exist.");
+	}
+
+	transitions.erase(key);
+	return true;
+}
+
+bool DPDA::removeTransition(const State& from, const alphabet::Symbol& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input);
+	return removeTransition(from, inputVariant, pop, to, push);
+}
+
+bool DPDA::removeTransition(const State& from, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON);
+	return removeTransition(from, inputVariant, pop, to, push);
+}
+
+const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >& DPDA::getTransitions() const {
+	return transitions;
+}
+
+bool DPDA::operator==(const ObjectBase& other) const {
+	return other == *this;
+}
+
+bool DPDA::operator<(const ObjectBase& other) const {
+	return other > *this;
+}
+
+bool DPDA::operator>(const ObjectBase& other) const {
+	return other < *this;
+}
+
+bool DPDA::operator==(const DPDA& other) const {
+	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbol == other.initialSymbol && this->transitions == other.transitions;
+}
+
+bool DPDA::operator<(const DPDA& other) const {
+	return std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, initialSymbol, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.initialSymbol, other.transitions);
+}
+
+void DPDA::operator>>(std::ostream& out) const {
+	out << "(DPDA"
+		<< "states = " << states
+		<< "inputAlphabet = " << inputAlphabet
+		<< "initialState = " << initialState
+		<< "finalStates = " << finalStates
+		<< "stackAlphabet = " << stackAlphabet
+		<< "initialSymbol = " << initialSymbol
+		<< "transitions = " << transitions
+		<< ")";
+}
+
+DPDA::operator std::string () const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
+} /* namespace automaton */
diff --git a/alib2data/src/automaton/PDA/DPDA.h b/alib2data/src/automaton/PDA/DPDA.h
new file mode 100644
index 0000000000000000000000000000000000000000..2fedc19a03a07d66baa0e91d736f92b7bfbb9b83
--- /dev/null
+++ b/alib2data/src/automaton/PDA/DPDA.h
@@ -0,0 +1,103 @@
+/*
+ * DPDA.h
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Martin Zak
+ */
+
+#ifndef DPDA_H_
+#define DPDA_H_
+
+#include <set>
+#include <map>
+#include <vector>
+#include "../../std/variant.hpp"
+#include "../AutomatonBase.h"
+#include "../common/SingleInitialState.h"
+#include "../common/SingleInitialSymbolPushdownStoreAlphabet.h"
+#include "../common/InputAlphabet.h"
+#include "../../alphabet/Symbol.h"
+#include "../../string/Epsilon.h"
+
+namespace automaton {
+
+/**
+ * Push Down Automaton
+ *
+ * $|\delta (q, a, \gamma)| \leq 1$, $\forall q, a, \gamma, q \in Q, a \in (T \cup \{\varepsilon\}), \gamma \in G^*.$
+ * if $\delta (q, a, \alpha) \neq \emptyset$, $\delta (q, a, \beta) \neq \emptyset$ and $\alpha \neq \beta$, then $\alpha$ is not suffix of $\beta$ and $\beta$ is not suffix of $\alpha$ (formally $\gamma \alpha \neq \beta and \alpha \neq \gamma \beta$).
+ * if $\delta(q, a, \alpha) \neq \emptyset$, $\delta (q, \varepsilon, \beta) \neq \emptyset$, then $\alpha$ is not suffix of $\beta$ and $\beta$ is not suffix of $\alpha$ (fornally $\gamma \alpha \neq \beta and \alpha \neq \gamma \beta$).
+ */
+class DPDA : public std::acceptor<DPDA, VisitableAutomatonBase, std::acceptor<DPDA, alib::VisitableObjectBase, AutomatonBase> >, public SingleInitialSymbolPushdownStoreAlphabet, public SingleInitialState, public InputAlphabet {
+protected:
+	std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > > transitions;
+public:
+	DPDA(const State& initialState, const alphabet::Symbol& initialPushdownSymbol);
+
+	virtual AutomatonBase* clone() const;
+	
+	virtual AutomatonBase* plunder() &&;
+
+	/**
+	 * @copydoc Automaton::removeState(const State&)
+	 */
+	virtual bool removeState(const State& state);
+
+	/**
+	 * @copydoc Automaton::removeInputSymbol(const Symbol&)
+	 */
+	virtual bool removeInputSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * @copydoc Automaton::removeStackSymbol(const Symbol&)
+	 */
+	virtual bool removeStackSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * Adds transition to the DPDA.
+	 * @param transition transition to add
+	 * @throws AutomatonException when some part of the transition is not present
+	 * in the DPDA (state, input symbol, stack symbol) or when transition already exists
+	 */
+	bool addTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	bool addTransition(const State& from, const alphabet::Symbol& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	bool addTransition(const State& from, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	/**
+	 * Removes the transition from the DPDA.
+	 * @param transition transition to remove
+	 * @throws AutomatonException when transition is not present in the DPDA
+	 */
+	bool removeTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	bool removeTransition(const State& from, const alphabet::Symbol& input, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	bool removeTransition(const State& from, const std::vector<alphabet::Symbol>& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	/**
+	 * @return DPDA transitions
+	 */
+	const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::pair<State, std::vector<alphabet::Symbol> > >& getTransitions() const;
+
+	virtual bool operator<(const alib::ObjectBase& other) const;
+	virtual bool operator==(const alib::ObjectBase& other) const;
+	virtual bool operator>(const alib::ObjectBase& other) const;
+
+	virtual bool operator==(const DPDA& other) const;
+
+	virtual bool operator<(const DPDA& other) const;
+
+	virtual void operator>>(std::ostream& os) const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
+};
+
+} /* namespace automaton */
+
+#endif /* DPDA_H_ */
diff --git a/alib2data/src/automaton/PDA/SinglePopDPDA.cpp b/alib2data/src/automaton/PDA/SinglePopDPDA.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e188c1c79b8f866ab9f3a46bbb3918bc37aa8635
--- /dev/null
+++ b/alib2data/src/automaton/PDA/SinglePopDPDA.cpp
@@ -0,0 +1,209 @@
+/*
+ * SinglePopDPDA.cpp
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Martin Zak
+ */
+
+#include "SinglePopDPDA.h"
+#include "../../std/map.hpp"
+#include "../AutomatonException.h"
+#include <algorithm>
+#include <sstream>
+#include <ostream>
+
+namespace automaton {
+
+SinglePopDPDA::SinglePopDPDA(const State& initialState, const alphabet::Symbol& initialPushdownSymbol) : SingleInitialSymbolPushdownStoreAlphabet(initialPushdownSymbol), SingleInitialState(initialState) {
+
+}
+
+AutomatonBase* SinglePopDPDA::clone() const {
+	return new SinglePopDPDA(*this);
+}
+
+AutomatonBase* SinglePopDPDA::plunder() && {
+	return new SinglePopDPDA(std::move(*this));
+}
+
+bool SinglePopDPDA::removeState(const State& state) {
+	if (initialState == state) {
+		throw AutomatonException("State \"" + (std::string) state.getName() + "\" is initial state.");
+	}
+
+	if (finalStates.find(state) != finalStates.end()) {
+		throw AutomatonException("State \"" + (std::string) state.getName() + "\" is final state.");
+	}
+
+	for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
+		if (state == std::get<0>(transition->first))
+			throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
+		if(transition->second.first == state)
+			throw AutomatonException("State \"" + (std::string) state.getName() + "\" is used in transition.");
+		
+	}
+
+	return states.erase(state);
+}
+
+bool SinglePopDPDA::removeInputSymbol(const alphabet::Symbol& symbol) {
+	for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
+		if (std::get<1>(transition->first).is<alphabet::Symbol>() && symbol == std::get<1>(transition->first).get<alphabet::Symbol>())
+			throw AutomatonException("Symbol \"" + (std::string) symbol + "\" is used in transition.");
+	}
+
+	return inputAlphabet.erase(symbol);
+}
+
+bool SinglePopDPDA::removeStackSymbol(const alphabet::Symbol& symbol) {
+	for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
+		if (symbol == std::get<2>(transition->first))
+			throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
+
+		if (std::find(transition->second.second.begin(), transition->second.second.end(), symbol) != transition->second.second.end())
+			throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
+	}
+
+	if(initialSymbol == symbol) {
+		throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is start symbol.");
+	}
+
+	return stackAlphabet.erase(symbol);
+}
+
+bool SinglePopDPDA::addTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	if (states.find(from) == states.end()) {
+		throw AutomatonException("State \"" + (std::string) from.getName() + "\" doesn't exist.");
+	}
+
+	if (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end()) {
+		throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" doesn't exist.");
+	}
+
+	if (states.find(to) == states.end()) {
+		throw AutomatonException("State \"" + (std::string) to.getName() + "\" doesn't exist.");
+	}
+
+	if (stackAlphabet.find(pop) == stackAlphabet.end()) {
+		throw AutomatonException("Stack symbol \"" + (std::string) pop + "\" doesn't exist.");
+	}
+
+	for(std::vector<alphabet::Symbol>::const_iterator pushSymbol = push.begin(); pushSymbol != push.end(); pushSymbol++) {
+		if (stackAlphabet.find(*pushSymbol) == stackAlphabet.end()) {
+			throw AutomatonException("Stack symbol \"" + (std::string) *pushSymbol + "\" doesn't exist.");
+		}
+	}
+
+	std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol> key(from, input, pop);
+	std::pair<automaton::State, std::vector<alphabet::Symbol> > value = std::make_pair(to, push);
+
+	if (transitions.find(key) != transitions.end()) {
+		if(transitions.find(key)->second == value)
+			return false;
+		else if (input.is<alphabet::Symbol>())
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<alphabet::Symbol>() + "\", \"" + (std::string) pop + "\") -> ?? already exists.");
+		else
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<string::Epsilon>() + "\", \"" + (std::string) pop + "\") -> ?? already exists.");
+	}
+
+	if(input.is<string::Epsilon>()) {
+		if(std::any_of(transitions.begin(), transitions.end(), [&](const std::pair<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<automaton::State, std::vector<alphabet::Symbol> > > & transition) {
+				if(std::get<0>(transition.first) == from && std::get<2>(transition.first) == pop) return true;
+				return false;
+			}))
+				throw exception::AlibException("Conflicting transition");
+	} else {
+		std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol> key(from, std::variant<string::Epsilon, alphabet::Symbol>{ string::Epsilon { } }, pop);
+		if(transitions.find(key) != transitions.end())
+			throw exception::AlibException("Conflicting transition");
+	}
+
+	transitions.insert(std::make_pair(key, value) );
+	return true;
+}
+
+bool SinglePopDPDA::addTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input);
+	return addTransition(from, inputVariant, pop, to, push);
+}
+
+bool SinglePopDPDA::addTransition(const State& from, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON);
+	return addTransition(from, inputVariant, pop, to, push);
+}
+
+bool SinglePopDPDA::removeTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol> key(from, input, pop);
+	std::pair<automaton::State, std::vector<alphabet::Symbol> > value = std::make_pair(to, push);
+	
+	if (transitions.find(key) == transitions.end())
+		return false;
+
+	if(transitions.find(key)->second != value) {
+		if (input.is<alphabet::Symbol>())
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<alphabet::Symbol>() + "\") -> \"" + (std::string) to.getName() + "\" doesn't exist.");
+		else
+			throw AutomatonException(
+				"Transition (\"" + (std::string) from.getName() + "\", \"" + (std::string) input.get<string::Epsilon>() + "\") -> \"" + (std::string) to.getName() + "\" doesn't exist.");
+	}
+
+	transitions.erase(key);
+	return true;
+}
+
+bool SinglePopDPDA::removeTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(input);
+	return removeTransition(from, inputVariant, pop, to, push);
+}
+
+bool SinglePopDPDA::removeTransition(const State& from, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push) {
+	std::variant<string::Epsilon, alphabet::Symbol> inputVariant(string::Epsilon::EPSILON);
+	return removeTransition(from, inputVariant, pop, to, push);
+}
+
+const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<State, std::vector<alphabet::Symbol> > >& SinglePopDPDA::getTransitions() const {
+	return transitions;
+}
+
+bool SinglePopDPDA::operator==(const ObjectBase& other) const {
+	return other == *this;
+}
+
+bool SinglePopDPDA::operator<(const ObjectBase& other) const {
+	return other > *this;
+}
+
+bool SinglePopDPDA::operator>(const ObjectBase& other) const {
+	return other < *this;
+}
+
+bool SinglePopDPDA::operator==(const SinglePopDPDA& other) const {
+	return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbol == other.initialSymbol && this->transitions == other.transitions;
+}
+
+bool SinglePopDPDA::operator<(const SinglePopDPDA& other) const {
+	return std::tie(states, inputAlphabet, initialState, finalStates, stackAlphabet, initialSymbol, transitions) < std::tie(other.states, other.inputAlphabet, other.initialState, other.finalStates, other.stackAlphabet, other.initialSymbol, other.transitions);
+}
+
+void SinglePopDPDA::operator>>(std::ostream& out) const {
+	out << "(SinglePopDPDA"
+		<< "states = " << states
+		<< "inputAlphabet = " << inputAlphabet
+		<< "initialState = " << initialState
+		<< "finalStates = " << finalStates
+		<< "stackAlphabet = " << stackAlphabet
+		<< "initialSymbol = " << initialSymbol
+		<< "transitions = " << transitions
+		<< ")";
+}
+
+SinglePopDPDA::operator std::string () const {
+	std::stringstream ss;
+	ss << *this;
+	return ss.str();
+}
+
+} /* namespace automaton */
diff --git a/alib2data/src/automaton/PDA/SinglePopDPDA.h b/alib2data/src/automaton/PDA/SinglePopDPDA.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6f663dc1148cdf23fedf4d039062968a665a221
--- /dev/null
+++ b/alib2data/src/automaton/PDA/SinglePopDPDA.h
@@ -0,0 +1,102 @@
+/*
+ * SinglePopDPDA.h
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef SINGLE_POP_DPDA_H_
+#define SINGLE_POP_DPDA_H_
+
+#include <set>
+#include <map>
+#include <vector>
+#include "../../std/variant.hpp"
+#include "../AutomatonBase.h"
+#include "../common/SingleInitialState.h"
+#include "../common/SingleInitialSymbolPushdownStoreAlphabet.h"
+#include "../common/InputAlphabet.h"
+#include "../../alphabet/Symbol.h"
+#include "../../string/Epsilon.h"
+
+namespace automaton {
+
+/**
+ * Push Down Automaton
+ *
+ * $|\delta (q, a, \gamma)| \leq 1$, $\forall q, a, \gamma, q \in Q, a \in (T \cup \{\varepsilon\}), \gamma \in G^*.$
+ * if $\delta (q, a, r) \neq \emptyset$, $\delta (q, a, s) \neq \emptyset$ then $r \neq s$.
+ * if $\delta(q, a, r) \neq \emptyset$, $\delta (q, \varepsilon, s) \neq \emptyset$, then $r \neq s$.
+ */
+class SinglePopDPDA: public std::acceptor<SinglePopDPDA, VisitableAutomatonBase, std::acceptor<SinglePopDPDA, alib::VisitableObjectBase, AutomatonBase> >, public SingleInitialSymbolPushdownStoreAlphabet, public SingleInitialState, public InputAlphabet {
+protected:
+	std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<State, std::vector<alphabet::Symbol> > > transitions;
+public:
+	SinglePopDPDA(const State& initialState, const alphabet::Symbol& initialPushdownSymbol);
+
+	virtual AutomatonBase* clone() const;
+	
+	virtual AutomatonBase* plunder() &&;
+
+	/**
+	 * @copydoc Automaton::removeState(const State&)
+	 */
+	virtual bool removeState(const State& state);
+
+	/**
+	 * @copydoc Automaton::removeInputSymbol(const Symbol&)
+	 */
+	virtual bool removeInputSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * @copydoc Automaton::removeStackSymbol(const Symbol&)
+	 */
+	virtual bool removeStackSymbol(const alphabet::Symbol& symbol);
+
+	/**
+	 * Adds transition to the SinglePopDPDA.
+	 * @param transition transition to add
+	 * @throws AutomatonException when some part of the transition is not present
+	 * in the SinglePopDPDA (state, input symbol, stack symbol) or when transition already exists
+	 */
+	bool addTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	bool addTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+	
+	bool addTransition(const State& from, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	/**
+	 * Removes the transition from the SinglePopDPDA.
+	 * @param transition transition to remove
+	 * @throws AutomatonException when transition is not present in the SinglePopDPDA
+	 */
+	bool removeTransition(const State& from, const std::variant<string::Epsilon, alphabet::Symbol>& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	bool removeTransition(const State& from, const alphabet::Symbol& input, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+	
+	bool removeTransition(const State& from, const alphabet::Symbol& pop, const State& to, const std::vector<alphabet::Symbol>& push);
+
+	/**
+	 * @return SinglePopDPDA transitions
+	 */
+	const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, alphabet::Symbol>, std::pair<State, std::vector<alphabet::Symbol> > >& getTransitions() const;
+
+	virtual bool operator<(const alib::ObjectBase& other) const;
+	virtual bool operator==(const alib::ObjectBase& other) const;
+	virtual bool operator>(const alib::ObjectBase& other) const;
+
+	virtual bool operator==(const SinglePopDPDA& other) const;
+	virtual bool operator<(const SinglePopDPDA& other) const;
+
+	virtual void operator>>(std::ostream& os) const;
+
+	virtual operator std::string() const;
+
+	virtual int selfTypeId() const {
+		return typeId(*this);
+	}
+};
+
+} /* namespace automaton */
+
+#endif /* SINGLE_POP_DPDA_H_ */
diff --git a/alib2data/src/automaton/UnknownAutomaton.h b/alib2data/src/automaton/UnknownAutomaton.h
index aeea1d2bcfcf7916dc022c4be9e370795f6066c6..716f78fc3c4b9e478a265f00021ea31d83d36732 100644
--- a/alib2data/src/automaton/UnknownAutomaton.h
+++ b/alib2data/src/automaton/UnknownAutomaton.h
@@ -35,6 +35,7 @@ protected:
 	std::set<UnknownTransition> transitions;
 public:
 	UnknownAutomaton();
+	//TODO destructor and operator= and copy constructor
 	~UnknownAutomaton() noexcept;
 
 	virtual AutomatonBase* clone() const;
diff --git a/alib2data/src/exception/AlibException.cpp b/alib2data/src/exception/AlibException.cpp
index c2106dd6dce1089dcf7f3346fa214d5d110619d0..fd8645fd9043ac039f8722e1066e144d075635d8 100644
--- a/alib2data/src/exception/AlibException.cpp
+++ b/alib2data/src/exception/AlibException.cpp
@@ -13,12 +13,12 @@
 #include <sstream>
 
 #include <execinfo.h>
-#include "../std/simpleStacktrace.h"
+#include "../std/bfdStacktrace.h"
 
 namespace exception {
 
 AlibException::AlibException ( ) {
-	this->backtrace = std::simpleStacktrace();
+	this->backtrace = std::bfdStacktrace();
 
 	this->whatMessage += this->backtrace;
 }
diff --git a/alib2data/src/grammar/UnknownGrammar.h b/alib2data/src/grammar/UnknownGrammar.h
index 6b33248dfae7278e88acf035ce2b3cceef035ef3..f52cd43bdf093dac0e691f5950a5f512af71a203 100644
--- a/alib2data/src/grammar/UnknownGrammar.h
+++ b/alib2data/src/grammar/UnknownGrammar.h
@@ -24,7 +24,8 @@ class UnknownGrammar : public std::acceptor<UnknownGrammar, VisitableGrammarBase
 	alphabet::Symbol* initialSymbol;
 public:
 	UnknownGrammar();
-	
+	//TODO destructor and operator= and copy constructor
+
 	virtual GrammarBase* clone() const;
 	
 	virtual GrammarBase* plunder() &&;
diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h
index 140edebb7a17c39d104cfbe043f75387b1b6dc62..cec271d494f2e7fcdf156133d91d5696366414c0 100644
--- a/alib2data/src/object/ObjectBase.h
+++ b/alib2data/src/object/ObjectBase.h
@@ -25,6 +25,8 @@ class NFA;
 class EpsilonNFA;
 class CompactNFA;
 class ExtendedNFA;
+class DPDA;
+class SinglePopDPDA;
 class NPDA;
 class SinglePopNPDA;
 class OneTapeDTM;
@@ -94,7 +96,7 @@ namespace alib {
 
 typedef std::acceptor_base<
 			exception::AlibException,
-			automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM,
+			automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM,
 			grammar::UnknownGrammar, grammar::LeftLG, grammar::LeftRG, grammar::RightLG, grammar::RightRG, grammar::LG, grammar::CFG, grammar::EpsilonFreeCFG, grammar::CNF, grammar::GNF, grammar::CSG, grammar::NonContractingGrammar, grammar::ContextPreservingUnrestrictedGrammar, grammar::UnrestrictedGrammar,
 			label::StringLabel, label::IntegerLabel, label::CharacterLabel, label::LabelSetLabel, label::LabelPairLabel,
 			regexp::UnboundedRegExp, regexp::FormalRegExp,
@@ -107,7 +109,7 @@ class ObjectBase :
 	public alib::base<
 			ObjectBase,
 			exception::AlibException,
-			automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM,
+			automaton::UnknownAutomaton, automaton::DFA, automaton::NFA, automaton::EpsilonNFA, automaton::CompactNFA, automaton::ExtendedNFA, automaton::DPDA, automaton::SinglePopDPDA, automaton::NPDA, automaton::SinglePopNPDA, automaton::OneTapeDTM,
 			grammar::UnknownGrammar, grammar::LeftLG, grammar::LeftRG, grammar::RightLG, grammar::RightRG, grammar::LG, grammar::CFG, grammar::EpsilonFreeCFG, grammar::CNF, grammar::GNF, grammar::CSG, grammar::NonContractingGrammar, grammar::ContextPreservingUnrestrictedGrammar, grammar::UnrestrictedGrammar,
 			label::StringLabel, label::IntegerLabel, label::CharacterLabel, label::LabelSetLabel, label::LabelPairLabel,
 			regexp::UnboundedRegExp, regexp::FormalRegExp,
diff --git a/alib2data/src/std/variant.hpp b/alib2data/src/std/variant.hpp
index cc6d293d8b14bcf631d3bab7ba4546300420d740..d551bd66e8509935c4cf24396a23e5cb2eaf12dc 100644
--- a/alib2data/src/std/variant.hpp
+++ b/alib2data/src/std/variant.hpp
@@ -52,7 +52,15 @@ struct variant_helper<F, Ts...> {
 		else
 			return variant_helper<Ts...>::copy(old_t, old_v, new_v);
 	}
-	
+
+	inline static void move(size_t old_t, void * old_v, void * new_v)
+	{
+		if (old_t == typeid(F).hash_code())
+			new (new_v) F(std::move(*reinterpret_cast<F*>(old_v)));
+		else
+			variant_helper<Ts...>::move(old_t, old_v, new_v);
+	}
+
 	inline static bool compareEq(size_t this_t, const void * this_v, size_t other_t, const void * other_v)
 	{
 		if (this_t == typeid(F).hash_code())
@@ -85,6 +93,7 @@ struct variant_helper<F, Ts...> {
 template<> struct variant_helper<>  {
 inline static void destroy(size_t, void *) { }
 inline static void copy(size_t, const void *, void *) { }
+inline static void move(size_t, void *, void *) { }
 inline static bool compareEq(size_t, const void *, size_t, const void *) { return true; }
 inline static void print(ostream&, const size_t, const void *) {}
 inline static bool compareLess(size_t, const void *, size_t, const void *) { return false; }
@@ -135,8 +144,8 @@ public:
 	//move constructor
 	variant(variant<F, Ts...>&& old) : variant_base<static_max<sizeof(F), sizeof(Ts)...>, static_max<alignof(F), alignof(Ts)...>, F, Ts...>()
 	{
-		std::swap(this->type_id, old.type_id);
-		std::swap(this->data, old.data);
+		this->type_id = old.type_id;
+		helper_t::move(old.type_id, &old.data, &this->data);
 	}
 
 	//assignment operator
diff --git a/alib2data/src/string/Epsilon.cpp b/alib2data/src/string/Epsilon.cpp
index 45b5fb8885b85bfcad8b6fd8f5c8334fcc0cc7b9..7950335b849f37ec30d98fcef5996ca186d5101f 100644
--- a/alib2data/src/string/Epsilon.cpp
+++ b/alib2data/src/string/Epsilon.cpp
@@ -14,10 +14,6 @@
 
 namespace string {
 
-Epsilon::Epsilon() {
-
-}
-
 StringBase* Epsilon::clone() const {
 	return new Epsilon(*this);
 }
@@ -65,7 +61,7 @@ bool Epsilon::operator<(const CyclicString& other) const {
 }
 
 bool Epsilon::operator==(const Epsilon& other) const {
-	return alphabet == other.getAlphabet();
+	return alphabet == other.alphabet;
 }
 
 bool Epsilon::operator==(const LinearString& other) const {
diff --git a/alib2data/src/string/Epsilon.h b/alib2data/src/string/Epsilon.h
index 10d2395eddb8f7f4a6b107ce0ace4c4c4a655de1..3d478256f79a5aedb5f225bc7b05c19997861e8e 100644
--- a/alib2data/src/string/Epsilon.h
+++ b/alib2data/src/string/Epsilon.h
@@ -25,8 +25,6 @@ namespace string {
  */
 class Epsilon : public std::acceptor<Epsilon, VisitableStringBase, std::acceptor<Epsilon, alib::VisitableObjectBase, StringBase> >, public StringAlphabet {
 public:
-	Epsilon();
-
 	virtual StringBase* clone() const;
 	virtual StringBase* plunder() &&;
 
diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp
index d7d63c7fb45cfab9d266087719342e8d40de5378..8e9024a7f196d10fba7cb000a0499346eeb84c76 100644
--- a/alib2data/test-src/automaton/AutomatonTest.cpp
+++ b/alib2data/test-src/automaton/AutomatonTest.cpp
@@ -7,6 +7,8 @@
 #include "automaton/UnknownAutomaton.h"
 
 #include "automaton/FSM/DFA.h"
+#include "automaton/PDA/SinglePopDPDA.h"
+#include "automaton/PDA/DPDA.h"
 #include "automaton/AutomatonFromXMLParser.h"
 #include "automaton/AutomatonToXMLComposer.h"
 
@@ -158,3 +160,96 @@ void AutomatonTest::FSMStringParserTest() {
 		CPPUNIT_ASSERT( automaton == automaton2 );
 	}
 }
+
+void AutomatonTest::SinglePopDPDATransitions() {
+  automaton::SinglePopDPDA automaton(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(1))));
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(2))));
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(3))));
+
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))));
+
+  automaton.addStackSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+  automaton.addStackSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))));
+  automaton.addStackSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))));
+
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), /* eps, */ alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } );
+  
+  CPPUNIT_ASSERT(!automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), /* eps, */ alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } ) );
+  
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))), automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } );
+
+  CPPUNIT_ASSERT_THROW(
+	automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } ),
+	exception::AlibException
+  );
+
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), /* eps, */ alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))), automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(2))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } );
+  CPPUNIT_ASSERT_THROW(
+	automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(2))), /* eps, */ alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } ),
+	exception::AlibException
+  );
+  
+  automaton.addFinalState(automaton::State(label::Label(label::IntegerLabel(3))));
+
+}
+
+void AutomatonTest::DPDATransitions() {
+  automaton::DPDA automaton(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(1))));
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(2))));
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(3))));
+  automaton.addState(automaton::State(label::Label(label::IntegerLabel(4))));
+
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))));
+
+  automaton.addStackSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+  automaton.addStackSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))));
+  automaton.addStackSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))));
+
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), /* eps, */ { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } );
+  
+  CPPUNIT_ASSERT(!automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), /* eps, */ { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } ) );
+  
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) }, automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } );
+
+  CPPUNIT_ASSERT_THROW(
+	automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(3))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } ),
+	exception::AlibException
+  );
+
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(1))), /* eps, */ { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(2))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } );
+  CPPUNIT_ASSERT_THROW(
+	automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(2))), /* eps, */ { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(1))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) } ),
+	exception::AlibException
+  );
+
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(4))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(4))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(4))), /* eps, */ { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  CPPUNIT_ASSERT(!automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(4))), /* eps, */ { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } ));
+  CPPUNIT_ASSERT_THROW(
+  	automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(4))), /* eps, */ { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } ),
+	exception::AlibException
+  );
+  automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(4))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } );
+  CPPUNIT_ASSERT_THROW(
+  	automaton.addTransition(automaton::State(label::Label(label::IntegerLabel(4))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("X")))) }, automaton::State(label::Label(label::IntegerLabel(2))), { alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("Y")))) } ),
+	exception::AlibException
+  );
+  
+  automaton.addFinalState(automaton::State(label::Label(label::IntegerLabel(3))));
+
+}
diff --git a/alib2data/test-src/automaton/AutomatonTest.h b/alib2data/test-src/automaton/AutomatonTest.h
index 3984de6d8cb8cf36c8a501fc88b1559093255384..65db52d914286e6eb89427877c9a877ed2bcc985 100644
--- a/alib2data/test-src/automaton/AutomatonTest.h
+++ b/alib2data/test-src/automaton/AutomatonTest.h
@@ -9,6 +9,8 @@ class AutomatonTest : public CppUnit::TestFixture
   CPPUNIT_TEST( testXMLParser );
   CPPUNIT_TEST( testDFAParser );
   CPPUNIT_TEST( FSMStringParserTest );
+  CPPUNIT_TEST( SinglePopDPDATransitions );
+  CPPUNIT_TEST( DPDATransitions );
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -18,6 +20,8 @@ public:
   void testXMLParser();
   void testDFAParser();
   void FSMStringParserTest();
+  void SinglePopDPDATransitions();
+  void DPDATransitions();
 };
 
 #endif  // AUTOMATON_TEST_H_
diff --git a/alib2data/test-src/std/StdTest.cpp b/alib2data/test-src/std/StdTest.cpp
index 4abf600248012914c5271f62053ef189e8209b12..0371ce18cedc111284a45bbfac20f49313a4751a 100644
--- a/alib2data/test-src/std/StdTest.cpp
+++ b/alib2data/test-src/std/StdTest.cpp
@@ -89,4 +89,17 @@ void StdTest::testVariantSet() {
 	
 	std::variant<StdTest::test2, std::string, StdTest::test> h("aa");
 	CPPUNIT_ASSERT( h.is<std::string>() );
+
+	std::map<std::variant<std::string, int>, int> testMap;
+	testMap.insert(std::make_pair(std::variant<std::string, int> {"aa"}, 10));
+
+	CPPUNIT_ASSERT( testMap.size() == 1 );
+	CPPUNIT_ASSERT( testMap.find(std::variant<std::string, int> {"aa"}) != testMap.end() );
+	CPPUNIT_ASSERT( testMap.find(std::variant<std::string, int> {10}) == testMap.end() );
+
+	testMap.insert(std::make_pair(std::variant<std::string, int> {"ab"}, 11));
+	testMap.insert(std::make_pair(std::variant<std::string, int> {3}, 13));
+
+	CPPUNIT_ASSERT( testMap.find(std::variant<std::string, int> {"aa"}) != testMap.end() );
+	CPPUNIT_ASSERT( testMap.find(std::variant<std::string, int> {10}) == testMap.end() );
 }
diff --git a/alib2data/test-src/string/StringTest.cpp b/alib2data/test-src/string/StringTest.cpp
index a5086e5376a074aeec1390a9b372068a44bb6f07..47489599778010408e874115cd340c1194c8096a 100644
--- a/alib2data/test-src/string/StringTest.cpp
+++ b/alib2data/test-src/string/StringTest.cpp
@@ -17,6 +17,7 @@
 
 #include "alphabet/Symbol.h"
 #include "alphabet/LabeledSymbol.h"
+#include "alphabet/BlankSymbol.h"
 
 #include "label/StringLabel.h"
 #include "label/IntegerLabel.h"
@@ -163,4 +164,24 @@ void StringTest::testCompareCyclic() {
   CPPUNIT_ASSERT(cyclic4 != cyclic1);
   CPPUNIT_ASSERT(cyclic4 != cyclic2);
   CPPUNIT_ASSERT(cyclic4 != cyclic3);
+
+  CPPUNIT_ASSERT(!(string::Epsilon::EPSILON < string::Epsilon::EPSILON));
+
+  std::map<std::variant<string::Epsilon, int>, int> testMap;
+  std::variant<string::Epsilon, int> epsVar { string::Epsilon { } };
+  CPPUNIT_ASSERT( string::Epsilon::EPSILON == epsVar.get<string::Epsilon>() );
+  CPPUNIT_ASSERT( epsVar.get<string::Epsilon>() == string::Epsilon::EPSILON );
+
+  std::pair<std::variant<string::Epsilon, int>, int> epsVarPair = std::make_pair(epsVar, 10 );
+  CPPUNIT_ASSERT( string::Epsilon::EPSILON == epsVarPair.first.get<string::Epsilon>() );
+  CPPUNIT_ASSERT( epsVarPair.first.get<string::Epsilon>() == string::Epsilon::EPSILON );
+
+  testMap.insert(std::make_pair(std::variant<string::Epsilon, int> { string::Epsilon { } }, 10));
+  CPPUNIT_ASSERT( testMap.find(std::variant<string::Epsilon, int> { string::Epsilon { } } ) != testMap.end() );
+  for( const auto & entry : testMap) {
+    CPPUNIT_ASSERT( entry.first.is<string::Epsilon>());
+    if(entry.first.is<string::Epsilon>())
+      CPPUNIT_ASSERT( string::Epsilon::EPSILON == entry.first.get<string::Epsilon>() );
+      CPPUNIT_ASSERT( entry.first.get<string::Epsilon>() == string::Epsilon::EPSILON );
+  }
 }