diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index 2b6e790d95c42b086d7b39d514083fb461bead2a..d523dced31a63f879d3d30bba48e806c072fdb71 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -204,8 +204,7 @@ void ConversionHandler::convertREtoFSM( void )
 	switch( m_algorithm )
 	{
 	case BRZOZOWSKI_DERIVATION: {
-			conversions::re2fa::BrzozowskiDerivation conv;
-			alib::DataFactory::toStdout(conv.convert(regexp));
+			alib::DataFactory::toStdout(conversions::re2fa::BrzozowskiDerivation::convert(regexp));
 			break;
 		}
 	case THOMPSON_NFA: {
diff --git a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp b/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp
index 961418bfa92dab8af8a87d107a6aaf4549cba7e0..93032524fd1c279cecd82980a4f96d035dace9ac 100644
--- a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp
+++ b/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.cpp
@@ -2,7 +2,7 @@
  * BrzozowskiDerivation.cpp
  *
  *  Created on: 11. 1. 2014
- *      Author: Tomas Pecka
+ *	  Author: Tomas Pecka
  */
 
 #include "BrzozowskiDerivation.h"
@@ -14,10 +14,10 @@
 
 #include <string/LinearString.h>
 #include <std/hexavigesimal.h>
-#include <label/StringLabel.h>
 
 #include "../../regexp/RegExpDerivation.h"
 #include "../../regexp/RegExpOptimize.h"
+#include "../../regexp/RegExpEpsilon.h"
 
 namespace conversions
 {
@@ -25,110 +25,116 @@ namespace conversions
 namespace re2fa
 {
 
-BrzozowskiDerivation::BrzozowskiDerivation(void){}
-BrzozowskiDerivation::~BrzozowskiDerivation(void){}
-
-
-void BrzozowskiDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp)
+automaton::Automaton BrzozowskiDerivation::convert(const regexp::RegExp& regexp)
 {
-    std::pair<std::set<alphabet::Symbol>, bool>& out = *(std::pair<std::set<alphabet::Symbol>, bool>*) userData;
-    out.first = regexp.getAlphabet();
-    out.second = regexp.containsEmptyString();
+	automaton::Automaton* out = NULL;
+	regexp.getData().Accept((void*) &out, BrzozowskiDerivation::BRZOZOWSKI_DERIVATION);
+	automaton::Automaton res = std::move(*out);
+	delete out;
+	return res;
 }
-void BrzozowskiDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp)
+
+template<class T>
+automaton::NFA BrzozowskiDerivation::convert(const T& regexp)
 {
-    std::pair<std::set<alphabet::Symbol>, bool>& out = *(std::pair<std::set<alphabet::Symbol>, bool>*) userData;
-    out.first = regexp.getAlphabet();
-    out.second = regexp.containsEmptyString();
+	// 1.
+	regexp::RegExpOptimize opt;
+	regexp::RegExp V = regexp::RegExp{opt.optimize(regexp)};
+
+	std::set<regexp::RegExp> Q = { V };
+	std::deque<std::set<regexp::RegExp>> Qi;
+
+	Qi.push_back(std::set<regexp::RegExp>());
+	Qi.at(0).insert(V);
+
+	int i = 1;
+
+	// 2.
+	while(! Qi.at(i - 1).empty())
+	{
+		Qi.push_back(std::set<regexp::RegExp>()); // initialize set Q_i
+
+		for(const auto& dregexp : Qi.at(i - 1))
+		{
+			regexp::RegExpDerivation deriv;
+
+			for(const auto& a : regexp.getAlphabet())
+			{
+				string::LinearString string(std::vector<alphabet::Symbol>{a});
+				regexp::RegExp derived = deriv.derivation(dregexp, string);
+				derived = opt.optimize(derived);
+
+				// this will also add \emptyset as a regexp (and as FA state)
+				if(Q.count(derived) == 0) // if this state has already been found, do not add
+					Qi.at(i).insert(derived);
+			}
+		}
+
+		Q.insert(Qi.at(i).begin(), Qi.at(i).end());
+		i += 1;
+	}
+
+	std::map<regexp::RegExp, automaton::State> stateMap;
+	int stateId = 0;
+
+	for(const auto& r : Q)
+	{
+		automaton::State q(std::toBase26(stateId++));
+		stateMap.insert(std::make_pair(r, q));
+	}
+
+	// ------------------------------------------------------------------------
+	// 3.
+
+	automaton::NFA automaton;
+
+	for(const auto& r : stateMap)
+	{
+		automaton.addState(r.second);
+	}
+
+	automaton.addInitialState(stateMap.find(V)->second);
+
+	automaton.setInputSymbols(regexp.getAlphabet());
+
+	for(const auto& r : Q)
+	{
+		regexp::RegExpDerivation deriv;
+
+		for(const auto& a: regexp.getAlphabet())
+		{
+			string::LinearString string(std::vector<alphabet::Symbol>{a});
+			regexp::RegExp derived = deriv.derivation(r, string);
+			derived = opt.optimize(derived);
+
+			automaton.addTransition(stateMap.find(r)->second, a, stateMap.find(derived)->second);
+		}
+	}
+
+	for(const auto& r : Q)
+	{
+		if(regexp::RegExpEpsilon::languageContainsEpsilon(r))
+			automaton.addFinalState(stateMap.find(r)->second);
+	}
+
+	return automaton;
 }
 
-automaton::DFA BrzozowskiDerivation::convert(const regexp::RegExp& regexp)
+template automaton::NFA BrzozowskiDerivation::convert(const regexp::FormalRegExp& regexp);
+template automaton::NFA BrzozowskiDerivation::convert(const regexp::UnboundedRegExp& regexp);
+
+void BrzozowskiDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
-    // 1.
-    regexp::RegExpOptimize opt;
-    regexp::RegExp V = opt.optimize(regexp);
-
-    std::pair<std::set<alphabet::Symbol>, bool> out({}, false);
-    regexp.getData().Accept((void*) &out, *this);
-    const std::set<alphabet::Symbol>& alphabet = out.first;
-
-    std::set<regexp::RegExp> Q = { V };
-    std::deque<std::set<regexp::RegExp>> Qi;
-
-    Qi.push_back(std::set<regexp::RegExp>());
-    Qi.at(0).insert(V);
-
-    int i = 1;
-
-    // 2.
-    while(! Qi.at(i - 1).empty())
-    {
-        Qi.push_back(std::set<regexp::RegExp>()); // initialize set Q_i
-
-        for(const auto& dregexp : Qi.at(i - 1))
-        {
-            regexp::RegExpDerivation deriv;
-
-            for(const auto& a : alphabet)
-            {
-                string::LinearString string(std::vector<alphabet::Symbol>{a});
-                regexp::RegExp derived = deriv.derivation(dregexp, string);
-                derived = opt.optimize(derived);
-
-                // this will also add \emptyset as a regexp (and as FA state)
-                if(Q.count(derived) == 0) // if this state has already been found, do not add
-                    Qi.at(i).insert(derived);
-            }
-        }
-
-        Q.insert(Qi.at(i).begin(), Qi.at(i).end());
-        i += 1;
-    }
-
-    std::map<regexp::RegExp, automaton::State> stateMap;
-    int stateId = 0;
-
-    for(const auto& r : Q)
-    {
-        automaton::State q(label::Label(label::StringLabel(std::toBase26(stateId++))));
-        stateMap.insert(std::make_pair(r, q));
-    }
-
-    // ------------------------------------------------------------------------
-    // 3.
-
-    automaton::DFA automaton(stateMap.find(V)->second);
-
-    for(const auto& r : stateMap)
-    {
-        automaton.addState(r.second);
-    }
-
-    automaton.setInputSymbols(alphabet);
-
-    for(const auto& r : Q)
-    {
-        regexp::RegExpDerivation deriv;
-
-        for(const auto& a: alphabet)
-        {
-            string::LinearString string(std::vector<alphabet::Symbol>{a});
-            regexp::RegExp derived = deriv.derivation(r, string);
-            derived = opt.optimize(derived);
-
-            automaton.addTransition(stateMap.find(r)->second, a, stateMap.find(derived)->second);
-        }
-    }
-
-    for(const auto& r : Q)
-    {
-        r.getData().Accept((void*) &out, *this);
-        if(out.second) // if(r.containsEmptyString())
-            automaton.addFinalState(stateMap.find(r)->second);
-    }
-
-    return automaton;
+	automaton::Automaton* &out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(regexp));
 }
+void BrzozowskiDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+{
+	automaton::Automaton* &out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(regexp));
+}
+
+const BrzozowskiDerivation BrzozowskiDerivation::BRZOZOWSKI_DERIVATION;
 
 } /* namespace re2fa */
 
diff --git a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h b/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h
index 4344d295786b96448ea5729ef890f2a79dc17e52..a3c249dfe7ab5465b2547b4100af12c1139a50f6 100644
--- a/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h
+++ b/alib2algo/src/conversions/re2fa/BrzozowskiDerivation.h
@@ -2,7 +2,7 @@
  * BrzozowskiDerivation.h
  *
  *  Created on: 11. 1. 2014
- *      Author: Tomas Pecka
+ *	  Author: Tomas Pecka
  */
 
 #ifndef RE2FA_BRZOZOWSKIDERIVATION_H_
@@ -11,7 +11,9 @@
 #include <regexp/RegExp.h>
 #include <regexp/formal/FormalRegExp.h>
 #include <regexp/unbounded/UnboundedRegExp.h>
-#include <automaton/FSM/DFA.h>
+
+#include <automaton/Automaton.h>
+#include <automaton/FSM/NFA.h>
 
 namespace conversions
 {
@@ -23,21 +25,23 @@ namespace re2fa
  * Converts regular expression to finite automaton using BrzozowskiDerivation algorithm (derivations of regular expressions).
  * Source: Melichar 2.110
  */
-class BrzozowskiDerivation : public regexp::VisitableRegExpBase::visitor_type
+class BrzozowskiDerivation : public regexp::VisitableRegExpBase::const_visitor_type
 {
 public:
-    BrzozowskiDerivation(void);
-    ~BrzozowskiDerivation(void);
+	/**
+	 * Performs conversion.
+	 * @return FSM equivalent to original regular expression.
+	 */
+	static automaton::Automaton convert(const regexp::RegExp& regexp);
 
-    /**
-     * Performs conversion.
-     * @return FSM equivalent to original regular expression.
-     */
-    automaton::DFA convert(const regexp::RegExp& regexp);
+	template<class T>
+	static automaton::NFA convert(const T& regexp);
 
 private:
-    void Visit(void* , const regexp::FormalRegExp& regexp);
-    void Visit(void* , const regexp::UnboundedRegExp& regexp);
+	void Visit(void* , const regexp::FormalRegExp& regexp) const;
+	void Visit(void* , const regexp::UnboundedRegExp& regexp) const;
+
+	static const BrzozowskiDerivation BRZOZOWSKI_DERIVATION;
 };
 
 } /* namespace re2fa */
diff --git a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp b/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp
index 076a7fa30560eb66e3d7f545f591376df8a5625f..ad614b9a75cb07dfc7fd57db87f1901140c45f9d 100644
--- a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp
+++ b/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp
@@ -12,6 +12,8 @@
 #include "label/IntegerLabel.h"
 #include "label/LabelPairLabel.h"
 
+#include "../../regexp/RegExpEpsilon.h"
+
 namespace conversions{
 
 namespace re2fa {
@@ -80,7 +82,7 @@ automaton::NFA GlushkovNFA::convert( const regexp::UnboundedRegExp & re ) {
 		automaton.addFinalState( q );
 	}
 
-	if( re.containsEmptyString( ) )
+	if(regexp::RegExpEpsilon::languageContainsEpsilon(re))
 		automaton.addFinalState( q0 );
 
 	return automaton;
diff --git a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp b/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp
index ac979b534a4a742fc8e3bcc159ffa595dd03bc51..9520a2a1f81f8ace45326ab8704068c688afb952 100644
--- a/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp
+++ b/alib2algo/src/conversions/re2rg/re2rrg/BrzozowskiDerivation.cpp
@@ -17,6 +17,7 @@
 
 #include "../../../regexp/RegExpOptimize.h"
 #include "../../../regexp/RegExpDerivation.h"
+#include "../../../regexp/RegExpEpsilon.h"
 
 namespace conversions
 {
@@ -32,13 +33,13 @@ void BrzozowskiDerivation::Visit(void* userData, const regexp::FormalRegExp& reg
 {
     std::pair<std::set<alphabet::Symbol>, bool>& out = *(std::pair<std::set<alphabet::Symbol>, bool>*) userData;
     out.first = regexp.getAlphabet();
-    out.second = regexp.containsEmptyString();
+	out.second = regexp::RegExpEpsilon::languageContainsEpsilon(regexp);
 }
 void BrzozowskiDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp)
 {
     std::pair<std::set<alphabet::Symbol>, bool>& out = *(std::pair<std::set<alphabet::Symbol>, bool>*) userData;
     out.first = regexp.getAlphabet();
-    out.second = regexp.containsEmptyString();
+	out.second = regexp::RegExpEpsilon::languageContainsEpsilon(regexp);
 }
 
 grammar::RightRG BrzozowskiDerivation::convert(const regexp::RegExp& regexp)
diff --git a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp b/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp
index 7fa60cb6369cb98d084cb58956409308659ca709..c8dad374dd5dcbf78b6438a384e7fce5deffe3f2 100644
--- a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp
+++ b/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp
@@ -20,6 +20,8 @@
 #include "../../../regexp/GlushkovPair.h"
 #include "../../../regexp/GlushkovSymbol.h"
 
+#include "../../../regexp/RegExpEpsilon.h"
+
 namespace conversions
 {
 
@@ -89,7 +91,7 @@ grammar::RightRG GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp)
                     grammar.addRule(rule.first, rhs.at(0));
     }
 
-    if(regexp.containsEmptyString( ) )
+    if(regexp::RegExpEpsilon::languageContainsEpsilon(regexp))
         grammar.setGeneratesEpsilon(true);
 
     return grammar;
diff --git a/alib2algo/src/regexp/GlushkovTraversal.cpp b/alib2algo/src/regexp/GlushkovTraversal.cpp
index 525d8ce9c5722f21a9bde242680c30b9159df91c..0069f0bf75313d1a4e60f1cd90423f3c122ff5de 100644
--- a/alib2algo/src/regexp/GlushkovTraversal.cpp
+++ b/alib2algo/src/regexp/GlushkovTraversal.cpp
@@ -7,6 +7,8 @@
 
 #include "GlushkovTraversal.h"
 
+#include "RegExpEpsilon.h"
+
 using namespace alib;
 using namespace regexp;
 using namespace std;
@@ -110,7 +112,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::first( regexp::Unb
         tmp = first( element );
         ret.insert( tmp.begin( ), tmp.end( ) );
 
-        if( ! element->containsEmptyString( ) ) // If regexp of this subtree can match epsilon, then we need to add next subtree
+        if(! regexp::RegExpEpsilon::languageContainsEpsilon(*element)) // If regexp of this subtree can match epsilon, then we need to add next subtree
             break;
     }
 
@@ -186,7 +188,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::last( regexp::Unbo
         tmp = last( *it );
         ret.insert( tmp.begin( ), tmp.end( ) );
 
-        if( ! ( * it )->containsEmptyString( ) )
+        if( ! regexp::RegExpEpsilon::languageContainsEpsilon(**it) )
             break;
     }
 
@@ -274,7 +276,7 @@ set<regexp::UnboundedRegExpSymbol const *> GlushkovTraversal::follow( regexp::Un
                 tmp = first( *f );
                 ret.insert( tmp.begin( ), tmp.end( ) );
 
-                if( ! ( *f )->containsEmptyString( ) )
+                if( ! regexp::RegExpEpsilon::languageContainsEpsilon( **f ) )
                     break;
             }
         }
diff --git a/alib2algo/src/regexp/RegExpDerivation.cpp b/alib2algo/src/regexp/RegExpDerivation.cpp
index 3c168fcc51eb43e687077a83de539d378446dd7a..2d7c5f0aba710477e1347034f8a3ee5cd45cdf59 100644
--- a/alib2algo/src/regexp/RegExpDerivation.cpp
+++ b/alib2algo/src/regexp/RegExpDerivation.cpp
@@ -7,6 +7,8 @@
 
 #include "RegExpDerivation.h"
 
+#include "RegExpEpsilon.h"
+
 namespace regexp
 {
 
@@ -184,7 +186,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcat
         ret->appendElement(std::move(*concat));
         delete concat;
 
-        if((*child)->containsEmptyString())
+        if(regexp::RegExpEpsilon::languageContainsEpsilon(**child))
             continue; // this IF construct is intentional "to match algorithm"
         break;
     }
diff --git a/alib2algo/src/regexp/RegExpEmpty.cpp b/alib2algo/src/regexp/RegExpEmpty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..16247f9328df4c77308a87236084275b3f58f622
--- /dev/null
+++ b/alib2algo/src/regexp/RegExpEmpty.cpp
@@ -0,0 +1,160 @@
+/*
+ * RegExpEmpty.cpp
+ *
+ *  Created on: 19. 1. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "RegExpEmpty.h"
+
+namespace regexp
+{
+
+bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp)
+{
+	bool out;
+	regexp.getData().Accept((void*) &out, RegExpEmpty::REG_EXP_EMPTY);
+	return out;
+}
+
+bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExp& regexp)
+{
+	bool out;
+	regexp.getRegExp().Accept((void*) &out, RegExpEmpty::REG_EXP_EMPTY);
+	return out;
+}
+
+bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExp& regexp)
+{
+	bool out;
+	regexp.getRegExp().Accept((void*) &out, RegExpEmpty::REG_EXP_EMPTY);
+	return out;
+}
+
+// ----------------------------------------------------------------------------
+
+void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const
+{
+	bool &ret = *(bool*) data;
+
+	for(const auto& element : alternation.getElements())
+	{
+		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, *this);
+		if(! ret)
+		{
+			ret = false;
+			return;
+		}
+	}
+	ret = true;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const
+{
+	bool &ret = *(bool*) data;
+
+	for(const auto& element : concatenation.getElements())
+	{
+		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, *this);
+		if(ret)
+		{
+			ret = true;
+			return;
+		}
+	}
+	ret = false;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpIteration&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const
+{
+	bool &ret = *(bool*) data;
+	ret = true;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+// ----------------------------------------------------------------------------
+
+void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const
+{
+	bool &ret = *(bool*) data;
+
+	static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(data, *this);
+	bool retLeft = ret;
+
+	static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(data, *this);
+	bool retRight = ret;
+
+	ret = retLeft && retRight;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const
+{
+	bool &ret = *(bool*) data;
+
+	static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(data, *this);
+	bool retLeft = ret;
+
+	static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(data, *this);
+	bool retRight = ret;
+
+	ret = retLeft || retRight;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpIteration&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpSymbol&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpEmpty&) const
+{
+	bool &ret = *(bool*) data;
+	ret = true;
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::FormalRegExpEpsilon&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+// ----------------------------------------------------------------------------
+
+void RegExpEmpty::Visit(void* data, const regexp::FormalRegExp& regexp) const
+{
+	bool &ret = *(bool*) data;
+	ret = RegExpEmpty::REG_EXP_EMPTY.languageIsEmpty(regexp);
+}
+
+void RegExpEmpty::Visit(void* data, const regexp::UnboundedRegExp& regexp) const
+{
+	bool &ret = *(bool*) data;
+	ret = RegExpEmpty::REG_EXP_EMPTY.languageIsEmpty(regexp);
+}
+
+const RegExpEmpty RegExpEmpty::REG_EXP_EMPTY;
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/RegExpEmpty.h b/alib2algo/src/regexp/RegExpEmpty.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b2958e121a1cf60d0ee7035768d100262684711
--- /dev/null
+++ b/alib2algo/src/regexp/RegExpEmpty.h
@@ -0,0 +1,53 @@
+/*
+ * RegExpEmpty.h
+ *
+ *  Created on: 19. 1. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef REG_EXP_EMPTY_H_
+#define REG_EXP_EMPTY_H_
+
+#include <regexp/RegExp.h>
+#include <regexp/formal/FormalRegExpElements.h>
+#include <regexp/unbounded/UnboundedRegExpElements.h>
+
+namespace regexp
+{
+
+/**
+ * Determines whether regular expression is empty (regexp == \0)
+ *
+ */
+class RegExpEmpty : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type
+{
+public:
+	static bool languageIsEmpty(const regexp::RegExp& regexp);
+
+	static bool languageIsEmpty(const regexp::FormalRegExp& regexp);
+	static bool languageIsEmpty(const regexp::UnboundedRegExp& regexp);
+
+private:
+	void Visit(void* data, const regexp::UnboundedRegExp& regexp) const;
+	void Visit(void* data, const regexp::FormalRegExp& regexp) const;
+
+	void Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const;
+	void Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const;
+	void Visit(void* data, const regexp::UnboundedRegExpIteration& iteration) const;
+	void Visit(void* data, const regexp::UnboundedRegExpSymbol& symbol) const;
+	void Visit(void* data, const regexp::UnboundedRegExpEmpty& empty) const;
+	void Visit(void* data, const regexp::UnboundedRegExpEpsilon& epsilon) const;
+
+	void Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const;
+	void Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const;
+	void Visit(void* data, const regexp::FormalRegExpIteration& iteration) const;
+	void Visit(void* data, const regexp::FormalRegExpSymbol& symbol) const;
+	void Visit(void* data, const regexp::FormalRegExpEmpty& empty) const;
+	void Visit(void* data, const regexp::FormalRegExpEpsilon& epsilon) const;
+
+	static const RegExpEmpty REG_EXP_EMPTY;
+};
+
+} /* namespace regexp */
+
+#endif /* REG_EXP_EMPTY_H_ */
diff --git a/alib2algo/src/regexp/RegExpEpsilon.cpp b/alib2algo/src/regexp/RegExpEpsilon.cpp
index 74a832881bc9239c4746c9a55126d86435876429..c697cbbdd16061eb579353d0eec35df5bbb9e96a 100644
--- a/alib2algo/src/regexp/RegExpEpsilon.cpp
+++ b/alib2algo/src/regexp/RegExpEpsilon.cpp
@@ -19,23 +19,156 @@ bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp)
 
 bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp& regexp)
 {
-	return regexp.containsEmptyString();
+	bool out;
+	regexp.getRegExp().Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON);
+	return out;
 }
 
 bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExp& regexp)
 {
-	return regexp.containsEmptyString();
+	bool out;
+	regexp.getRegExp().Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON);
+	return out;
 }
 
-void RegExpEpsilon::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpElement& element)
+{
+	bool out;
+	element.Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON);
+	return out;
+}
+
+bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpElement& element)
+{
+	bool out;
+	element.Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON);
+	return out;
+}
+
+// ---------------------------------------------------------------------------
+
+void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const
+{
+	bool &ret = *(bool*) data;
+
+	for(const auto& element : alternation.getElements())
+	{
+		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
+		if(ret)
+		{
+			ret = true;
+			return;
+		}
+	}
+	
+	ret = false;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const
+{
+	bool &ret = *(bool*) data;
+
+	for(const auto& element : concatenation.getElements())
+	{
+		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
+		if(!ret)
+		{
+			ret = false;
+			return;
+		}
+	}
+	
+	ret = true;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpIteration&) const
+{
+	bool &ret = *(bool*) data;
+	ret = true;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const
+{
+	bool &ret = *(bool*) data;
+	ret = true;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+// ----------------------------------------------------------------------------
+
+void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const
+{
+	bool &ret = *(bool*) data;
+
+	static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
+	bool retLeft = ret;
+
+	static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
+	bool retRight = ret;
+
+	ret = retLeft || retRight;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const
+{
+	bool &ret = *(bool*) data;
+
+	static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
+	bool retLeft = ret;
+
+	static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON);
+	bool retRight = ret;
+
+	ret = retLeft && retRight;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpIteration&) const
+{
+	bool &ret = *(bool*) data;
+	ret = true;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpSymbol&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpEmpty&) const
+{
+	bool &ret = *(bool*) data;
+	ret = false;
+}
+
+void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpEpsilon&) const
+{
+	bool &ret = *(bool*) data;
+	ret = true;
+}
+
+// ---------------------------------------------------------------------------
+
+void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExp& regexp) const
 {
-    bool &ret = *(bool*) userData;
+    bool &ret = *(bool*) data;
     ret = RegExpEpsilon::REG_EXP_EPSILON.languageContainsEpsilon(regexp);
 }
 
-void RegExpEpsilon::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExp& regexp) const
 {
-    bool &ret = *(bool*) userData;
+    bool &ret = *(bool*) data;
     ret = RegExpEpsilon::REG_EXP_EPSILON.languageContainsEpsilon(regexp);
 }
 
diff --git a/alib2algo/src/regexp/RegExpEpsilon.h b/alib2algo/src/regexp/RegExpEpsilon.h
index 0f2642add7d360290552e8bb0eb3a8fd6e0f5bdd..4472068c2c856e87ecb974eedb962b284915b797 100644
--- a/alib2algo/src/regexp/RegExpEpsilon.h
+++ b/alib2algo/src/regexp/RegExpEpsilon.h
@@ -16,10 +16,11 @@ namespace regexp
 {
 
 /**
- * Calculates languageContainsEpsilon of regular expression.
+ * Checks, whether regexp (or its subtree) describes epsilon (empty string).
+ * TODO: Better API?
  *
  */
-class RegExpEpsilon : public regexp::VisitableRegExpBase::const_visitor_type
+class RegExpEpsilon : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type
 {
 public:
     static bool languageContainsEpsilon(const regexp::RegExp& regexp);
@@ -27,9 +28,27 @@ public:
     static bool languageContainsEpsilon(const regexp::FormalRegExp& regexp);
     static bool languageContainsEpsilon(const regexp::UnboundedRegExp& regexp);
 
+	static bool languageContainsEpsilon(const regexp::UnboundedRegExpElement& element);
+	static bool languageContainsEpsilon(const regexp::FormalRegExpElement& element);
+
 private:
-    void Visit(void* data, const regexp::UnboundedRegExp& regexp) const;
-    void Visit(void* data, const regexp::FormalRegExp& regexp) const;
+	void Visit(void* data, const regexp::UnboundedRegExp& regexp) const;
+	void Visit(void* data, const regexp::FormalRegExp& regexp) const;
+
+	void Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const;
+	void Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const;
+	void Visit(void* data, const regexp::UnboundedRegExpIteration& iteration) const;
+	void Visit(void* data, const regexp::UnboundedRegExpSymbol& symbol) const;
+	void Visit(void* data, const regexp::UnboundedRegExpEmpty& empty) const;
+	void Visit(void* data, const regexp::UnboundedRegExpEpsilon& epsilon) const;
+
+	void Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const;
+	void Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const;
+	void Visit(void* data, const regexp::FormalRegExpIteration& iteration) const;
+	void Visit(void* data, const regexp::FormalRegExpSymbol& symbol) const;
+	void Visit(void* data, const regexp::FormalRegExpEmpty& empty) const;
+	void Visit(void* data, const regexp::FormalRegExpEpsilon& epsilon) const;
+
 
     static const RegExpEpsilon REG_EXP_EPSILON;
 };
diff --git a/alib2algo/src/regexp/RegExpOptimize.cpp b/alib2algo/src/regexp/RegExpOptimize.cpp
index ca6b5d32b5a8552b1086e1f14ea8bb893ae011da..73a9740a4c1de43bd7116c049011838ab752cdb9 100644
--- a/alib2algo/src/regexp/RegExpOptimize.cpp
+++ b/alib2algo/src/regexp/RegExpOptimize.cpp
@@ -7,6 +7,8 @@
 
 #include "RegExpOptimize.h"
 
+#include "RegExpEpsilon.h"
+
 #include <cassert>
 #include <iostream>
 #include <iostream>
@@ -1117,7 +1119,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node )
 			auto it2 = it;
 			advance( it2, - (int)concat->elements.size( ) );
 
-			if( concat->containsEmptyString( ) &&
+			if( regexp::RegExpEpsilon::languageContainsEpsilon(*concat) &&
 				distance( concat->elements.begin( ), concat->elements.end( )) == distance ( it2, node->elements.end( ) ) &&
 				equal( concat->elements.begin( ), concat->elements.end( ), it2, [] ( UnboundedRegExpElement const * const & a, UnboundedRegExpElement const * const & b ) -> bool { return *a == *b; } ) )
 			{
@@ -1143,7 +1145,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node )
 
 			auto prev = std::prev( it );
 
-			if( iter->element->containsEmptyString( ) && *( iter->element ) == **prev )
+			if( regexp::RegExpEpsilon::languageContainsEpsilon(*(iter->element)) && *( iter->element ) == **prev )
 			{
 				delete * prev;
 				it = node->elements.erase( prev );
diff --git a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
index 66743585bb7c71522f85149e6aa98abbc40273f0..3e0a368f99de1bd821eb792cb5321d02529733a9 100644
--- a/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
+++ b/alib2algo/test-src/conversions/re2fa/re2faTest.cpp
@@ -7,12 +7,14 @@
 #include "conversions/fa2re/Algebraic.h"
 #include "determinize/nfa/NFADeterminizer.h"
 #include "minimize/dfa/MinimizeDFA.h"
+#include "normalize/dfa/NormalizeDFA.h"
 #include "epsilon/fsm/FSMEpsilonRemover.h"
 
 #include "regexp/unbounded/UnboundedRegExp.h"
 #include "regexp/RegExpFromStringParser.h"
 
 #include "automaton/FSM/NFA.h"
+#include <factory/DataFactory.hpp>
 
 CPPUNIT_TEST_SUITE_REGISTRATION( re2faTest );
 
@@ -80,16 +82,24 @@ void re2faTest::testBrzozowski() {
 	regexp::RegExpFromStringParser parser(inputs);
 	regexp::RegExp regexp1( parser.parseValue() );
 
-    conversions::re2fa::BrzozowskiDerivation brzozowski1;
-	automaton::DFA dfa1 = brzozowski1.convert(regexp1);
+	automaton::Automaton nfa1 = conversions::re2fa::BrzozowskiDerivation::convert(regexp1);
+	alib::DataFactory::toStdout(nfa1);
 
-	regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(dfa1) );
+	regexp::RegExp regexp2( conversions::fa2re::Algebraic::convert(static_cast<const automaton::NFA&>(nfa1.getData())) );
+	alib::DataFactory::toStdout(regexp2);
 
-    conversions::re2fa::BrzozowskiDerivation brzozowski2;
-	automaton::DFA dfa2 = brzozowski2.convert(regexp2);
+	automaton::Automaton nfa2 = conversions::re2fa::BrzozowskiDerivation::convert(regexp2);
 
-	automaton::DFA mdfa1 = minimize::MinimizeDFA::minimize(dfa1);
-	automaton::DFA mdfa2 = minimize::MinimizeDFA::minimize(dfa2);
+	automaton::DFA mdfa1_1 = determinize::NFADeterminizer::determinize(static_cast<const automaton::NFA&>(nfa1.getData()));
+	automaton::DFA mdfa1_2 = minimize::MinimizeDFA::minimize(mdfa1_1);
+	automaton::DFA mdfa1_3 = normalize::NormalizeDFA::normalize(mdfa1_2);
 
-	CPPUNIT_ASSERT( mdfa1 == mdfa2);
+	automaton::DFA mdfa2_1 = determinize::NFADeterminizer::determinize(static_cast<const automaton::NFA&>(nfa2.getData()));
+	automaton::DFA mdfa2_2 = minimize::MinimizeDFA::minimize(mdfa2_1);
+	automaton::DFA mdfa2_3 = normalize::NormalizeDFA::normalize(mdfa2_2);
+
+	alib::DataFactory::toStdout(mdfa1_3);
+	alib::DataFactory::toStdout(mdfa2_3);
+
+	CPPUNIT_ASSERT( mdfa1_3 == mdfa2_3);
 }
diff --git a/alib2algo/test-src/regexp/RegExpEmptyTest.cpp b/alib2algo/test-src/regexp/RegExpEmptyTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d451d65689f3eded0b6de2b67ecad26accad47de
--- /dev/null
+++ b/alib2algo/test-src/regexp/RegExpEmptyTest.cpp
@@ -0,0 +1,34 @@
+#include "RegExpEmptyTest.h"
+
+#include "regexp/RegExpEmpty.h"
+
+#include <sstream>
+#include <regexp/RegExp.h>
+#include <regexp/RegExpFromStringParser.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RegExpEmptyTest );
+
+void RegExpEmptyTest::setUp() {
+}
+
+void RegExpEmptyTest::tearDown() {
+}
+
+void RegExpEmptyTest::testRegExpEmpty() {
+	{
+		std::string input = "(#E #0 ) + ( #0 a + (b ( #0 (a*) ) ) )";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(regexp::RegExpEmpty::languageIsEmpty(re));
+	}
+	{
+		std::string input = "(#E + a ) + ( #0 a + (b ( #0 (a*) ) ) )";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(! regexp::RegExpEmpty::languageIsEmpty(re));
+	}
+}
diff --git a/alib2algo/test-src/regexp/RegExpEmptyTest.h b/alib2algo/test-src/regexp/RegExpEmptyTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b8ad5c43e986349f41e2b844c6428dc70c02b32
--- /dev/null
+++ b/alib2algo/test-src/regexp/RegExpEmptyTest.h
@@ -0,0 +1,21 @@
+#ifndef REGEXPEMPTY_TEST_H_
+#define REGEXPEMPTY_TEST_H_
+
+#include <string>
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class RegExpEmptyTest : public CppUnit::TestFixture
+{
+	CPPUNIT_TEST_SUITE( RegExpEmptyTest );
+	CPPUNIT_TEST( testRegExpEmpty );
+	CPPUNIT_TEST_SUITE_END();
+
+public:
+	void setUp();
+	void tearDown();
+
+	void testRegExpEmpty();
+};
+
+#endif /* REGEXPEMPTY_TEST_H_ */
diff --git a/alib2algo/test-src/regexp/RegExpEpsilonTest.cpp b/alib2algo/test-src/regexp/RegExpEpsilonTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86e177beb8af91690b5535d0f35e19bba1604bd3
--- /dev/null
+++ b/alib2algo/test-src/regexp/RegExpEpsilonTest.cpp
@@ -0,0 +1,73 @@
+#include "RegExpEpsilonTest.h"
+
+#include "regexp/RegExpEpsilon.h"
+#include <sstream>
+#include <regexp/RegExpFromStringParser.h>
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RegExpEpsilonTest );
+
+void RegExpEpsilonTest::setUp() {
+}
+
+void RegExpEpsilonTest::tearDown() {
+}
+
+void RegExpEpsilonTest::testRegExpEpsilon() {
+	{
+		std::string input = "#E + ( (a #E) + a*)";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
+	}	
+	{
+		std::string input = "( a* )( a* )";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
+	}	
+	{
+		std::string input = "a + #0";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re));
+	}	
+	{
+		std::string input = "#E + a #E + a*";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
+	}	
+	{
+		std::string input = "a* a*";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(regexp::RegExpEpsilon::languageContainsEpsilon(re));
+	}	
+	{
+		std::string input = "a s d #E + #E #0";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re));
+	}	
+	{
+		std::string input = "a + #0";
+		std::stringstream inputs(input);
+		regexp::RegExpFromStringParser parser(inputs);
+		regexp::RegExp re = parser.parseValue();
+
+		CPPUNIT_ASSERT(! regexp::RegExpEpsilon::languageContainsEpsilon(re));
+	}	
+}
diff --git a/alib2algo/test-src/regexp/RegExpEpsilonTest.h b/alib2algo/test-src/regexp/RegExpEpsilonTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b8531b6998c42c7a266d888239d1c177bca3834
--- /dev/null
+++ b/alib2algo/test-src/regexp/RegExpEpsilonTest.h
@@ -0,0 +1,21 @@
+#ifndef REGEXPEPSILON_TEST_H_
+#define REGEXPEPSILON_TEST_H_
+
+#include <string>
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class RegExpEpsilonTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( RegExpEpsilonTest );
+  CPPUNIT_TEST( testRegExpEpsilon );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void testRegExpEpsilon();
+};
+
+#endif /* REGEXPEPSILON_TEST_H_ */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp
index 9e928e57b4679557fd5650d0acd56a96ec287fa0..237f6bb309367e601d050526f3d60aa1e1757d41 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.cpp
@@ -138,14 +138,6 @@ bool UnboundedRegExp::removeSymbolFromAlphabet(const alphabet::Symbol & symbol)
 	return alphabet.erase(symbol);
 }
 
-bool UnboundedRegExp::isEmpty() const {
-	return regExp->isEmpty();
-}
-
-bool UnboundedRegExp::containsEmptyString() const {
-	return regExp->containsEmptyString();
-}
-
 void UnboundedRegExp::operator >>(std::ostream& out) const {
 	out << "(UnboundedRegExp " << *(this->regExp) << ")";
 }
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExp.h b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
index b89c86269303c8c2341cad6da496779def71eacc..046a6a39f426e5edb7e5986f665a4c07395dd924 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExp.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExp.h
@@ -105,16 +105,6 @@ public:
 	 */
 	bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol);
 	
-	/**
-	 * @return true if regexp represents empty language
-	 */
-	bool isEmpty() const;
-
-	/**
-	 * @return true if regexp matches empty string (epsilon)
-	 */
-	bool containsEmptyString() const;
-
 	/**
 	 * Prints XML representation of the RegExp to the output stream.
 	 * @param out output stream to which print the RegExp
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
index dad8b817cc0848141243920b5c2f7e473f766879..66656f173c274ee5beace76456381d913377f423 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.cpp
@@ -176,20 +176,4 @@ void UnboundedRegExpAlternation::computeMinimalAlphabet( std::set<alphabet::Symb
 		child->computeMinimalAlphabet(alphabet);
 }
 
-bool UnboundedRegExpAlternation::containsEmptyString() const {
-	for(const auto& e : elements)
-		if(e->containsEmptyString())
-			return true;
-
-	return false; // alternation of zero regexps is empty so by default it doesn't contain epsilon
-}
-
-bool UnboundedRegExpAlternation::isEmpty() const {
-	for(const auto& e : elements)
-		if(!e->isEmpty())
-			return false;
-
-	return true; // alternation of zero regexps is empty
-}
-
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
index 96e9547215af15085a9beda851dc00b595174fd1..b8e0d32c2f7190aabe9f6e149da8fa735f87ac20 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h
@@ -94,16 +94,6 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	/**
-	 * @copydoc UnboundedRegExpElement::containsEmptyString() const
-	 */
-	virtual bool containsEmptyString() const;
-
-	/**
-	 * @copydoc UnboundedRegExpElement::isEmpty() const
-	 */
-	virtual bool isEmpty() const;
-
 	friend class RegExpOptimize;
 };
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
index bcbe39ad3f835ae6e6d6ee019c37228ca02d4d38..f932c21a73d0f4a4dc00b64fd8f061032ef75b77 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.cpp
@@ -175,20 +175,4 @@ void UnboundedRegExpConcatenation::computeMinimalAlphabet( std::set<alphabet::Sy
 		child->computeMinimalAlphabet(alphabet);
 }
 
-bool UnboundedRegExpConcatenation::containsEmptyString() const {
-	for(const auto& e : elements)
-		if( ! e->containsEmptyString())
-			return false;
-
-	return true; // concatenation of zero regexps is epsilon so by default it does contain epsilon
-}
-
-bool UnboundedRegExpConcatenation::isEmpty() const {
-	for(const auto& e : elements)
-		if(e->isEmpty())
-			return true;
-
-	return false; // concatenation of zero regexps is epsilon
-}
-
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
index deb28d5af1236d17438c7bb9de98454828673cb4..e23f776cd3a3d4e9fa8b47bc3e3d19c5dfdb8fef 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h
@@ -93,16 +93,6 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 	
-	/**
-	 * @copydoc UnboundedRegExpElement::containsEmptyString() const
-	 */
-	virtual bool containsEmptyString() const;
-
-	/**
-	 * @copydoc UnboundedRegExpElement::isEmpty() const
-	 */
-	virtual bool isEmpty() const;
-
 	friend class RegExpOptimize;
 };
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
index 8874186afe80ff7325a76588a3590be9a0f6bd57..6a2b715dfa7b3699eb3df565165f16ddb3aded8c 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h
@@ -114,16 +114,6 @@ public:
 	 */
 	friend std::ostream& operator<<(std::ostream& out, const UnboundedRegExpElement& regexp);
 
-	/**
-	 * @return true if this subtree of regexp matches empty string (epsilon)
-	 */
-	virtual bool containsEmptyString() const = 0;
-
-	/**
-	 * @return true if this subtree describes empty language
-	 */
-	virtual bool isEmpty() const = 0;
-	
 	friend class UnboundedRegExp;
 	
 	friend class UnboundedRegExpAlternation;
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
index d5d2c73f6fbb0b2b4b5156fc4017e32ed973d5b3..11226123f39acd3b516691925ea227d85198d544 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.cpp
@@ -83,12 +83,4 @@ void UnboundedRegExpEmpty::computeMinimalAlphabet( std::set<alphabet::Symbol>&)
 
 }
 
-bool UnboundedRegExpEmpty::containsEmptyString() const {
-	return false;
-}
-
-bool UnboundedRegExpEmpty::isEmpty() const {
-	return true;
-}
-
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
index b940f5c281d1f2453c9dc4e80678a8dd73ca6df0..a1f86bc84a8b14e39cd1ab52927c0eba2a341640 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h
@@ -66,15 +66,6 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 	
-	/**
-	 * @copydoc UnboundedRegExpElement::containsEmptyString() const
-	 */
-	virtual bool containsEmptyString() const;
-
-	/**
-	 * @copydoc UnboundedRegExpElement::isEmpty() const
-	 */
-	virtual bool isEmpty() const;
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
index 706b4c455a76ca35a62c64f7f33a2276f65b2ecc..565211a136f79fc47b4b1c6a7a5eb841873bc2cf 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.cpp
@@ -83,12 +83,4 @@ void UnboundedRegExpEpsilon::computeMinimalAlphabet( std::set<alphabet::Symbol>&
 
 }
 
-bool UnboundedRegExpEpsilon::containsEmptyString() const {
-	return true;
-}
-
-bool UnboundedRegExpEpsilon::isEmpty() const {
-	return false;
-}
-
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
index a52138bce28bb0a93021aced09f4e722c615dd23..d13242e3e027ab4dd25c70e4648312030c1fc8ee 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h
@@ -68,15 +68,6 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	/**
-	 * @copydoc UnboundedRegExpElement::containsEmptyString() const
-	 */
-	virtual bool containsEmptyString() const;
-
-	/**
-	 * @copydoc UnboundedRegExpElement::isEmpty() const
-	 */
-	virtual bool isEmpty() const;
 };
 
 } /* namespace regexp */
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
index 7788d970ed60370fdf8789dd906914edf4fd354b..78e07bdc101341a3fc85f6af526316adf02af56b 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.cpp
@@ -130,13 +130,5 @@ void UnboundedRegExpIteration::computeMinimalAlphabet( std::set<alphabet::Symbol
 	element->computeMinimalAlphabet(alphabet);
 }
 
-bool UnboundedRegExpIteration::containsEmptyString() const {
-	return true;
-}
-
-bool UnboundedRegExpIteration::isEmpty() const {
-	return false;
-}
-
 } /* namespace regexp */
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
index 75cb849ee215b154dfff9e61bdf0a6b396022ce6..afa05a74150006437b7e985da2eb3a91155cf5b8 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h
@@ -92,16 +92,6 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 
-	/**
-	 * @copydoc UnboundedRegExpElement::containsEmptyString() const
-	 */
-	virtual bool containsEmptyString() const;
-
-	/**
-	 * @copydoc UnboundedRegExpElement::isEmpty() const
-	 */
-	virtual bool isEmpty() const;
-
 	friend class RegExpOptimize;
 };
 
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
index cb8ea6f2f19a61c420d21408b6c512c4808443c5..9cfafbf4f18b5b1ecc8cb62a77f58bd18cf381d8 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.cpp
@@ -102,14 +102,6 @@ void UnboundedRegExpSymbol::operator>>(std::ostream& out) const {
 	out << "(UnboundedRegExpSymbol " << symbol << ")";
 }
 
-bool UnboundedRegExpSymbol::containsEmptyString() const {
-	return false;
-}
-
-bool UnboundedRegExpSymbol::isEmpty() const {
-	return false;
-}
-
 bool UnboundedRegExpSymbol::testSymbol( const alphabet::Symbol & symbol ) const {
 	return symbol == this->symbol;
 }
diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
index 1b2bc5eee0ccc2e50427025a3ea3c0b86077beb3..858b8b4f61b2fdaa9fd047ec861994bd02bb8d9f 100644
--- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
+++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h
@@ -78,20 +78,10 @@ public:
 	 */
 	virtual void operator>>(std::ostream& out) const;
 	
-	/**
-	 * @copydoc UnboundedRegExpElement::containsEmptyString() const
-	 */
-	virtual bool containsEmptyString() const;
-
 	/**
 	 * Returns the string representation of RegExp Symbol.
 	 */
 	const alphabet::Symbol& getSymbol() const;
-
-	/**
-	 * @copydoc UnboundedRegExpElement::isEmpty() const
-	 */
-	virtual bool isEmpty() const;
 };
 
 } /* namespace regexp */