diff --git a/alib/src/regexp/Alternation.cpp b/alib/src/regexp/Alternation.cpp
index df3a0c7f3a22cf4c6c7d7c2a35eef56b797b17e4..2103548d5353a39f940ef9bb52be9ab5cace74d4 100644
--- a/alib/src/regexp/Alternation.cpp
+++ b/alib/src/regexp/Alternation.cpp
@@ -54,5 +54,13 @@ RegExpElement* Alternation::clone() const {
 	return new Alternation(*this);
 }
 
+bool Alternation::containsEmptyString() const {
+	for(const auto& e : getElements())
+		if(e->containsEmptyString())
+			return true;
+
+	return false;
+}
+
 } /* namespace regexp */
 
diff --git a/alib/src/regexp/Alternation.h b/alib/src/regexp/Alternation.h
index d728756a04a31828ab3e14848732a08191a00838..c237a10498803856e2c026b74fce0869fe6d302e 100644
--- a/alib/src/regexp/Alternation.h
+++ b/alib/src/regexp/Alternation.h
@@ -42,6 +42,11 @@ public:
 	 * @copydoc RegExpElement::clone() const
 	 */
 	RegExpElement* clone() const;
+
+	/**
+	 * @copydoc RegExpElement::containsEmptyString() const
+	 */
+	bool containsEmptyString() const;
 };
 
 } /* namespace regexp */
diff --git a/alib/src/regexp/Concatenation.cpp b/alib/src/regexp/Concatenation.cpp
index be3dda2631a8f0d533a7d2731f3908b9ab73f473..1404382056ad880b652b129f1c561289555f48f4 100644
--- a/alib/src/regexp/Concatenation.cpp
+++ b/alib/src/regexp/Concatenation.cpp
@@ -54,4 +54,13 @@ RegExpElement* Concatenation::clone() const {
 	return new Concatenation(*this);
 }
 
+bool Concatenation::containsEmptyString() const {
+	for( const auto& e : getElements())
+		if( ! e->containsEmptyString())
+			return false;
+
+	return true;
+}
+
+
 } /* namespace regexp */
diff --git a/alib/src/regexp/Concatenation.h b/alib/src/regexp/Concatenation.h
index 6175fc67574d075162d22cd2f58885ed73ef65a6..e239009e0d5d44912e1816587a4b1dc0f5eac021 100644
--- a/alib/src/regexp/Concatenation.h
+++ b/alib/src/regexp/Concatenation.h
@@ -43,6 +43,10 @@ public:
 	 */
 	RegExpElement* clone() const;
 
+	/**
+	 * @copydoc RegExpElement::containsEmptyString() const
+	 */
+	bool containsEmptyString() const;
 };
 
 } /* namespace regexp */
diff --git a/alib/src/regexp/Iteration.cpp b/alib/src/regexp/Iteration.cpp
index b99bb60c1c3a098947e5d191061dc1d4849e8ba1..3ea0614175d91a2205bd503dea9039764b8659d1 100644
--- a/alib/src/regexp/Iteration.cpp
+++ b/alib/src/regexp/Iteration.cpp
@@ -65,5 +65,9 @@ RegExpElement* Iteration::clone() const {
 	return new Iteration(*this);
 }
 
+bool Iteration::containsEmptyString() const {
+	return true;
+}
+
 } /* namespace regexp */
 
diff --git a/alib/src/regexp/Iteration.h b/alib/src/regexp/Iteration.h
index 23faa47a2b9379826bed4cd1e7a5d51e6fbe9f92..645519714732ed334b762bf8bdce5fc2cd0159a0 100644
--- a/alib/src/regexp/Iteration.h
+++ b/alib/src/regexp/Iteration.h
@@ -48,6 +48,11 @@ public:
 	 * @copydoc RegExpElement::clone() const
 	 */
 	RegExpElement* clone() const;
+
+	/**
+	 * @copydoc RegExpElement::containsEmptyString() const
+	 */
+	bool containsEmptyString() const;
 };
 
 } /* namespace regexp */
diff --git a/alib/src/regexp/RegExp.cpp b/alib/src/regexp/RegExp.cpp
index 727dc909a1040177934b61829bd423e44bc198a5..bf745304852efdef9267941a52f9e073186f9cc6 100644
--- a/alib/src/regexp/RegExp.cpp
+++ b/alib/src/regexp/RegExp.cpp
@@ -74,6 +74,13 @@ bool RegExp::isEmpty() const {
 	return regExp == NULL || dynamic_cast<const RegExpEmpty*>(regExp);
 }
 
+bool RegExp::containsEmptyString() const {
+	if(regExp)
+		return regExp->containsEmptyString();
+
+	return false;
+}
+
 void RegExp::toXML(ostream& out) {
 	RegExpPrinter::toXML(*this, out);
 }
diff --git a/alib/src/regexp/RegExp.h b/alib/src/regexp/RegExp.h
index 3f0220309a5cc394895b0a199a1df44a8bb82402..1242304c603afbdb73bbfaad0f5cb8899a7f29e0 100644
--- a/alib/src/regexp/RegExp.h
+++ b/alib/src/regexp/RegExp.h
@@ -60,6 +60,11 @@ public:
 	 */
 	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/alib/src/regexp/RegExpElement.cpp b/alib/src/regexp/RegExpElement.cpp
index d7231b3c07966d117afbd903ef011838569cb75b..25f706ba7a5b268057cf0052a7a962771a0d8855 100644
--- a/alib/src/regexp/RegExpElement.cpp
+++ b/alib/src/regexp/RegExpElement.cpp
@@ -10,6 +10,7 @@
 namespace regexp {
 
 RegExpElement::~RegExpElement() {
+
 }
 
 } /* namespace regexp */
diff --git a/alib/src/regexp/RegExpElement.h b/alib/src/regexp/RegExpElement.h
index 2cc340c6b3d88fb6faf14ba9ac6a533833aedcff..ee7a13d2f2b190ecdbd48c2961caa2032cd98006 100644
--- a/alib/src/regexp/RegExpElement.h
+++ b/alib/src/regexp/RegExpElement.h
@@ -24,6 +24,11 @@ public:
 	 * @return copy of the element
 	 */
 	virtual RegExpElement* clone() const = 0;
+
+	/**
+	 * @return true if this subtree of regexp matches empty string (epsilon)
+	 */
+	virtual bool containsEmptyString() const = 0;
 };
 
 } /* namespace regexp */
diff --git a/alib/src/regexp/RegExpEmpty.cpp b/alib/src/regexp/RegExpEmpty.cpp
index 3c5b5711ac36921712a284f6fea4b5e3a916b392..fbfa0371c3bbeb86477577cb69084d81439e14ad 100644
--- a/alib/src/regexp/RegExpEmpty.cpp
+++ b/alib/src/regexp/RegExpEmpty.cpp
@@ -16,5 +16,9 @@ RegExpElement* RegExpEmpty::clone() const {
 	return new RegExpEmpty();
 }
 
+bool RegExpEmpty::containsEmptyString() const {
+	return false;
+}
+
 } /* namespace regexp */
 
diff --git a/alib/src/regexp/RegExpEmpty.h b/alib/src/regexp/RegExpEmpty.h
index 937d04e6797cd4858fc83e8d8b3a3e2f0807d931..dbdf6f4e9f5c89c79d1e4e938c3cadbc09ac4817 100644
--- a/alib/src/regexp/RegExpEmpty.h
+++ b/alib/src/regexp/RegExpEmpty.h
@@ -25,6 +25,11 @@ public:
 	 * @copydoc RegExpElement::clone() const
 	 */
 	RegExpElement* clone() const;
+
+	/**
+	 * @copydoc RegExpElement::containsEmptyString() const
+	 */
+	bool containsEmptyString() const;
 };
 
 } /* namespace regexp */
diff --git a/alib/src/regexp/RegExpEpsilon.cpp b/alib/src/regexp/RegExpEpsilon.cpp
index fff799e81c8e469c0a02edd5319ea5f5beb846a0..80b12b40763dc494af3712dc6d17936a258e41ad 100644
--- a/alib/src/regexp/RegExpEpsilon.cpp
+++ b/alib/src/regexp/RegExpEpsilon.cpp
@@ -16,5 +16,9 @@ RegExpElement* RegExpEpsilon::clone() const {
 	return new RegExpEpsilon();
 }
 
+bool RegExpEpsilon::containsEmptyString() const {
+	return true;
+}
+
 } /* namespace regexp */
 
diff --git a/alib/src/regexp/RegExpEpsilon.h b/alib/src/regexp/RegExpEpsilon.h
index 2d48546fcc99b3137e7967d17c4c8f29d6b2859f..ff3bfb3d1c2440cd6520ecfb3841ba2ec5d79ace 100644
--- a/alib/src/regexp/RegExpEpsilon.h
+++ b/alib/src/regexp/RegExpEpsilon.h
@@ -27,6 +27,11 @@ public:
 	 * @copydoc RegExpElement::clone() const
 	 */
 	RegExpElement* clone() const;
+
+	/**
+	 * @copydoc RegExpElement::containsEmptyString() const
+	 */
+	bool containsEmptyString() const;
 };
 
 } /* namespace regexp */
diff --git a/alib/src/regexp/RegExpSymbol.cpp b/alib/src/regexp/RegExpSymbol.cpp
index 95f5642371bfae32c6b138bb31bc3bff2da28b3c..f460d554964dfc33ef510ca48d1dbf434757b8ce 100644
--- a/alib/src/regexp/RegExpSymbol.cpp
+++ b/alib/src/regexp/RegExpSymbol.cpp
@@ -21,5 +21,9 @@ RegExpElement* RegExpSymbol::clone() const {
 	return new RegExpSymbol(this->symbol);
 }
 
+bool RegExpSymbol::containsEmptyString() const {
+	return false;
+}
+
 } /* namespace regexp */
 
diff --git a/alib/src/regexp/RegExpSymbol.h b/alib/src/regexp/RegExpSymbol.h
index bb6db856d9d6835ccd6cd9d2fa350f5fa1a27e8a..588680bf2d35be94a1d26f154d2aed6f68e9f8f4 100644
--- a/alib/src/regexp/RegExpSymbol.h
+++ b/alib/src/regexp/RegExpSymbol.h
@@ -29,6 +29,11 @@ public:
 	 * @copydoc RegExpElement::clone() const
 	 */
 	RegExpElement* clone() const;
+
+	/**
+	 * @copydoc RegExpElement::containsEmptyString() const
+	 */
+	bool containsEmptyString() const;
 };
 
 } /* namespace regexp */