diff --git a/alib2/src/alphabet/Blank.cpp b/alib2/src/alphabet/Blank.cpp
deleted file mode 100644
index 060950e349c3a76f65ce558f577cb57f3fbf6d5b..0000000000000000000000000000000000000000
--- a/alib2/src/alphabet/Blank.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Blank.cpp
- *
- *  Created on: Mar 26, 2013
- *      Author: Jan Travnicek
- */
-
-#include "Blank.h"
-
-namespace alphabet {
-
-Blank::Blank() : Symbol("") {
-
-}
-
-Blank Blank::BLANK = Blank();
-
-} /* namespace alphabet */
diff --git a/alib2/src/alphabet/Blank.h b/alib2/src/alphabet/Blank.h
deleted file mode 100644
index f7a9708153e1392a4ed5c86d182314737d6c8e98..0000000000000000000000000000000000000000
--- a/alib2/src/alphabet/Blank.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Blank.h
- *
- *  Created on: Mar 26, 2013
- *      Author: Jan Trávníček
- */
-
-#ifndef BLANK_H_
-#define BLANK_H_
-
-#include "Symbol.h"
-
-namespace alphabet {
-
-/**
- * Represents blank symbol in an alphabet.
- */
-class Blank : public Symbol {
-public:
-	/**
-	 * Creates a blank symbol.
-	 * @param symbol name of the symbol
-	 */
-	Blank();
-
-	static Blank BLANK;
-};
-
-} /* namespace alphabet */
-
-#endif /* BLANK_H_ */
diff --git a/alib2/src/alphabet/BlankSymbol.cpp b/alib2/src/alphabet/BlankSymbol.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c669f71ca99ec097ad2fafe8e8d60373234632ad
--- /dev/null
+++ b/alib2/src/alphabet/BlankSymbol.cpp
@@ -0,0 +1,54 @@
+/*
+ * BlankSymbol.cpp
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "BlankSymbol.h"
+
+namespace alphabet {
+
+BlankSymbol::BlankSymbol() : SymbolBase() {
+
+}
+
+SymbolBase* BlankSymbol::clone() const {
+	return new BlankSymbol(*this);
+}
+
+SymbolBase* BlankSymbol::plunder() && {
+	return new BlankSymbol(std::move(*this));
+}
+
+bool BlankSymbol::operator <(const SymbolBase& other) const {
+	return other > *this;
+}
+
+bool BlankSymbol::operator ==(const SymbolBase& other) const {
+	return other == *this;
+}
+
+bool BlankSymbol::operator >(const SymbolBase& other) const {
+	return other < *this;
+}
+
+bool BlankSymbol::operator ==(const BlankSymbol&) const {
+	return true;
+}
+
+bool BlankSymbol::operator <(const BlankSymbol&) const {
+	return false;
+}
+
+void BlankSymbol::operator>>(std::ostream& out) const {
+	out << "(Blank symbol)";
+}
+
+BlankSymbol::operator std::string () const {
+	return "";
+}
+
+BlankSymbol BlankSymbol::BLANK = BlankSymbol();
+
+} /* namespace alphabet */
diff --git a/alib2/src/alphabet/BlankSymbol.h b/alib2/src/alphabet/BlankSymbol.h
new file mode 100644
index 0000000000000000000000000000000000000000..dca5215d6478a0f010be3fbd920d1b007f4be454
--- /dev/null
+++ b/alib2/src/alphabet/BlankSymbol.h
@@ -0,0 +1,45 @@
+/*
+ * BlankSymbol.h
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Jan Trávníček
+ */
+
+#ifndef BLANK_SYMBOL_H_
+#define BLANK_SYMBOL_H_
+
+#include "Symbol.h"
+
+namespace alphabet {
+
+/**
+ * Represents blank symbol in an alphabet.
+ */
+class BlankSymbol : public SymbolBase, public std::element<BlankSymbol, SymbolBase::visitor_type> {
+public:
+	/**
+	 * Creates a blank symbol.
+	 * @param symbol name of the symbol
+	 */
+	BlankSymbol();
+
+	virtual SymbolBase* clone() const;
+	virtual SymbolBase* plunder() &&;
+	
+	virtual bool operator <(const SymbolBase& other) const;
+	virtual bool operator ==(const SymbolBase& other) const;
+	virtual bool operator >(const SymbolBase& other) const;
+
+	virtual bool operator ==(const BlankSymbol& other) const;
+	virtual bool operator <(const BlankSymbol& other) const;
+
+	virtual void operator>>(std::ostream& out) const;
+	
+	virtual operator std::string () const;
+
+	static BlankSymbol BLANK;
+};
+
+} /* namespace alphabet */
+
+#endif /* BLANK_SYMBOL_H_ */
diff --git a/alib2/src/alphabet/LabeledSymbol.cpp b/alib2/src/alphabet/LabeledSymbol.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6febbbf4f9356a88b5aa43dcb62bbb717f92c081
--- /dev/null
+++ b/alib2/src/alphabet/LabeledSymbol.cpp
@@ -0,0 +1,61 @@
+/*
+ * LabeledSymbol.cpp
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Martin Zak
+ */
+
+#include "LabeledSymbol.h"
+
+namespace alphabet {
+
+LabeledSymbol::LabeledSymbol(const label::Label& label) : label(label) {
+
+}
+
+LabeledSymbol::LabeledSymbol(label::Label&& label) : label(std::move(label)) {
+
+}
+
+SymbolBase* LabeledSymbol::clone() const {
+	return new LabeledSymbol(*this);
+}
+
+SymbolBase* LabeledSymbol::plunder() && {
+	return new LabeledSymbol(std::move(*this));
+}
+
+const label::Label& LabeledSymbol::getLabel() const {
+	return label;
+}
+
+bool LabeledSymbol::operator <(const SymbolBase& other) const {
+	return other > *this;
+}
+
+bool LabeledSymbol::operator ==(const SymbolBase& other) const {
+	return other == *this;
+}
+
+bool LabeledSymbol::operator >(const SymbolBase& other) const {
+	return other < *this;
+}
+
+bool LabeledSymbol::operator ==(const LabeledSymbol& other) const {
+	return this->label == other.label;
+}
+
+bool LabeledSymbol::operator <(const LabeledSymbol& other) const {
+	return this->label < other.label;
+}
+
+void LabeledSymbol::operator>>(std::ostream& out) const {
+	out << "(LabeledSymbol " << this->label << ")";
+}
+
+LabeledSymbol::operator std::string () const {
+	return (std::string) label;
+}
+
+} /* namespace alphabet */
+
diff --git a/alib2/src/alphabet/LabeledSymbol.h b/alib2/src/alphabet/LabeledSymbol.h
new file mode 100644
index 0000000000000000000000000000000000000000..16c0954febcda012c88db7a32393f36a48e7f981
--- /dev/null
+++ b/alib2/src/alphabet/LabeledSymbol.h
@@ -0,0 +1,54 @@
+/*
+ * tabeledSymbol.h
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Martin Zak
+ */
+
+#ifndef LABELED_SYMBOL_H_
+#define LABELED_SYMBOL_H_
+
+#include "../label/Label.h"
+#include "SymbolBase.h"
+#include <ostream>
+
+namespace alphabet {
+
+/**
+ * Represents symbol in an alphabet.
+ */
+class LabeledSymbol : public SymbolBase, public std::element<LabeledSymbol, SymbolBase::visitor_type> {
+protected:
+	label::Label label;
+	
+public:
+	/**
+	 * Creates new symbol with given name.
+	 * @param symbol name of the symbol
+	 */
+	explicit LabeledSymbol(const label::Label& label);
+	explicit LabeledSymbol(label::Label&& label);
+
+	virtual SymbolBase* clone() const;
+	virtual SymbolBase* plunder() &&;
+	
+	/**
+	 * @return name of the symbol
+	 */
+	const label::Label& getLabel() const;
+
+	virtual bool operator <(const SymbolBase& other) const;
+	virtual bool operator ==(const SymbolBase& other) const;
+	virtual bool operator >(const SymbolBase& other) const;
+
+	virtual bool operator ==(const LabeledSymbol& other) const;
+	virtual bool operator <(const LabeledSymbol& other) const;
+
+	virtual void operator>>(std::ostream& out) const;
+
+	virtual operator std::string () const;
+};
+
+} /* namespace alphabet */
+
+#endif /* LABELED_SYMBOL_H_ */
diff --git a/alib2/src/alphabet/Symbol.cpp b/alib2/src/alphabet/Symbol.cpp
index c8cbf2a7ca817bfdad9290d82ff03b5984dd0fc4..1f6c50f741e07f2a9078a543df41758f837b9b2b 100644
--- a/alib2/src/alphabet/Symbol.cpp
+++ b/alib2/src/alphabet/Symbol.cpp
@@ -1,49 +1,86 @@
 /*
  * Symbol.cpp
  *
- *  Created on: Mar 26, 2013
- *      Author: Martin Zak
+ *  Created on: Apr 16, 2013
+ *      Author: Jan Travnicek
  */
 
 #include "Symbol.h"
 
 namespace alphabet {
 
-Symbol::Symbol(const std::string& symbol) : symbol(symbol) {
+Symbol::Symbol(const SymbolBase& symbol) : symbol(symbol.clone()) {
 
 }
 
-Symbol::Symbol(std::string&& symbol) : symbol(std::move(symbol)) {
+Symbol::Symbol(SymbolBase&& symbol) : symbol(std::move(symbol).plunder()) {
 
 }
 
-const std::string& Symbol::getSymbol() const {
-	return symbol;
+Symbol::Symbol(const Symbol& other) : symbol(other.getSymbol().clone()) {
+
+}
+
+Symbol::Symbol(Symbol&& other) noexcept : symbol(std::move(other.getSymbol()).plunder()) {
+	other.symbol = NULL;
+}
+
+Symbol& Symbol::operator=(const Symbol& other) {
+	if(this == &other) return *this;
+
+	delete symbol;
+	symbol = other.getSymbol().clone();
+
+	return *this;
+}
+
+Symbol& Symbol::operator=(Symbol&& other) noexcept {
+	std::swap(this->symbol, other.symbol);
+	return *this;
+}
+
+Symbol::~Symbol() {
+	delete symbol;
+}
+
+const SymbolBase& Symbol::getSymbol() const {
+	return *symbol;
+}
+
+SymbolBase& Symbol::getSymbol() {
+	return *symbol;
 }
 
-bool Symbol::operator <(const Symbol& other) const {
-	return symbol < other.symbol;
+void Symbol::setSymbol(const SymbolBase& symbol) {
+	delete this->symbol;
+	this->symbol = symbol.clone();
 }
 
-bool Symbol::operator ==(const Symbol& other) const {
-	return symbol == other.symbol;
+void Symbol::setSymbol(SymbolBase&& symbol) {
+	delete this->symbol;
+	this->symbol = std::move(symbol).plunder();
 }
 
-bool Symbol::operator >(const Symbol& other) const {
-	return symbol > other.symbol;
+bool Symbol::operator<(const Symbol& other) const {
+	return *symbol < *other.symbol;
 }
 
-bool Symbol::operator !=(const Symbol& other) const {
-	return symbol != other.symbol;
+bool Symbol::operator!=(const Symbol& other) const {
+	return !(*this == other);
 }
 
-std::ostream& operator<<(std::ostream& out, const Symbol& symbol) {
-	if(symbol.symbol.size() == 0) {
-		out << "(Blank)";
-	} else {
-		out << "(Symbol " << symbol.symbol << ")";
-	}
-	return out;
+bool Symbol::operator==(const Symbol& other) const {
+	return *symbol == *other.symbol;
+}
+
+std::ostream& operator<<(std::ostream& os, const Symbol& symbol) {
+	os << symbol.getSymbol();
+	return os;
+}
+
+Symbol::operator std::string() const {
+	return (std::string) *symbol;
 }
 
 } /* namespace alphabet */
+
diff --git a/alib2/src/alphabet/Symbol.h b/alib2/src/alphabet/Symbol.h
index a7c39ba3b372b765708b1228d2a6bca0e30da11c..6500eedbac95f9569bd29888579828bc7257df5f 100644
--- a/alib2/src/alphabet/Symbol.h
+++ b/alib2/src/alphabet/Symbol.h
@@ -1,45 +1,51 @@
 /*
  * Symbol.h
  *
- *  Created on: Mar 26, 2013
- *      Author: Martin Zak
+ *  Created on: Apr 10, 2013
+ *      Author: Jan Travnicek
  */
 
 #ifndef SYMBOL_H_
 #define SYMBOL_H_
 
-#include <string>
-#include <ostream>
+#include "../std/visitor.hpp"
+#include "SymbolBase.h"
 
 namespace alphabet {
 
 /**
- * Represents symbol in an alphabet.
+ * Wrapper around automata.
  */
-class Symbol {
+class Symbol : public std::element<Symbol, std::visitor<Symbol> > { //TODO toto udělat v std templatované
 protected:
-	std::string symbol;
+	SymbolBase* symbol;
 public:
-	/**
-	 * Creates new symbol with given name.
-	 * @param symbol name of the symbol
-	 */
-	explicit Symbol(const std::string& symbol);
-	explicit Symbol(std::string&& symbol);
-
-	/**
-	 * @return name of the symbol
-	 */
-	const std::string& getSymbol() const;
-
-	bool operator <(const Symbol& other) const;
-	bool operator ==(const Symbol& other) const;
-	bool operator >(const Symbol& other) const;
-	bool operator !=(const Symbol& other) const;
-
-	friend std::ostream& operator<<(std::ostream&, const Symbol&);
+	explicit Symbol(const SymbolBase& symbol);
+	explicit Symbol(SymbolBase&& symbol);
+	Symbol(const Symbol& other);
+	Symbol(Symbol&&) noexcept;
+	Symbol& operator=(const Symbol& other);
+	Symbol& operator=(Symbol&& other) noexcept;
+	virtual ~Symbol() noexcept;
+
+	const SymbolBase& getSymbol() const;
+	SymbolBase& getSymbol();
+
+	void setSymbol(const SymbolBase& symbol);
+	void setSymbol(SymbolBase&& symbol);
+	
+	bool operator<(const Symbol& other) const;
+
+	bool operator!=(const Symbol& other) const;
+
+	bool operator==(const Symbol& other) const;
+
+	friend std::ostream& operator<<(std::ostream& os, const Symbol& symbol);
+
+	operator std::string () const;
 };
 
 } /* namespace alphabet */
 
 #endif /* SYMBOL_H_ */
+
diff --git a/alib2/src/alphabet/SymbolBase.cpp b/alib2/src/alphabet/SymbolBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58e7c3300ec84b0bfc9261ffffc2d6f34ce66221
--- /dev/null
+++ b/alib2/src/alphabet/SymbolBase.cpp
@@ -0,0 +1,45 @@
+/*
+ * SymbolBase.cpp
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "SymbolBase.h"
+#include <typeinfo>
+
+#include "LabeledSymbol.h"
+#include "BlankSymbol.h"
+
+namespace alphabet {
+
+SymbolBase::~SymbolBase() noexcept {
+
+}
+
+bool SymbolBase::operator !=(const SymbolBase& other) const {
+	return !(*this == other);
+}
+
+std::ostream& operator<<(std::ostream& out, const SymbolBase& symbol) {
+	symbol >> out;
+	return out;
+}
+
+bool SymbolBase::operator==(const LabeledSymbol&) const {
+	return false;
+}
+
+bool SymbolBase::operator==(const BlankSymbol&) const {
+	return false;
+}
+
+bool SymbolBase::operator<(const LabeledSymbol& other) const {
+	return typeid(*this).before(typeid(other));
+}
+
+bool SymbolBase::operator<(const BlankSymbol& other) const {
+	return typeid(*this).before(typeid(other));
+}
+
+} /* namespace alphabet */
diff --git a/alib2/src/alphabet/SymbolBase.h b/alib2/src/alphabet/SymbolBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..98de64cf0178dae84a0d07134ea8878c9cd46f5f
--- /dev/null
+++ b/alib2/src/alphabet/SymbolBase.h
@@ -0,0 +1,49 @@
+/*
+ * SymbolBase.h
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef SYMBOL_BASE_H_
+#define SYMBOL_BASE_H_
+
+#include "../label/LabelBase.h"
+#include <ostream>
+	
+namespace alphabet {
+
+class LabeledSymbol;
+class BlankSymbol;
+
+/**
+ * Represents symbol in an alphabet.
+ */
+class SymbolBase : virtual public std::elementBase<std::visitor<LabeledSymbol, BlankSymbol> > {
+public:
+	virtual ~SymbolBase() noexcept;
+
+	virtual SymbolBase* clone() const = 0;
+	virtual SymbolBase* plunder() && = 0; 
+
+	virtual bool operator <(const SymbolBase& other) const = 0;
+	virtual bool operator ==(const SymbolBase& other) const = 0;
+	virtual bool operator >(const SymbolBase& other) const = 0;
+	bool operator !=(const SymbolBase& other) const;
+
+	virtual bool operator==(const LabeledSymbol& other) const;
+	virtual bool operator==(const BlankSymbol& other) const;
+
+	virtual bool operator<(const LabeledSymbol& other) const;
+	virtual bool operator<(const BlankSymbol& other) const;
+
+	friend std::ostream& operator<<(std::ostream&, const SymbolBase&);
+
+	virtual void operator>>(std::ostream& out) const = 0;
+
+	virtual operator std::string () const = 0;
+};
+
+} /* namespace alphabet */
+
+#endif /* SYMBOL_BASE_H_ */
diff --git a/alib2/src/automaton/AutomatonFromXMLParser.cpp b/alib2/src/automaton/AutomatonFromXMLParser.cpp
index 9e5330d76973a2bcced90d19a274aaacc45879f6..f79d0c96c2203e0a25fc1f46d2b48d24ee28f0e5 100644
--- a/alib2/src/automaton/AutomatonFromXMLParser.cpp
+++ b/alib2/src/automaton/AutomatonFromXMLParser.cpp
@@ -8,7 +8,10 @@
 #include "AutomatonFromXMLParser.h"
 
 #include "../sax/ParserException.h"
-#include "../alphabet/Blank.h"
+#include "../alphabet/BlankSymbol.h"
+#include "../label/StringLabel.h"
+#include "../label/Label.h"
+#include "../alphabet/LabeledSymbol.h"
 
 namespace automaton {
 
@@ -139,7 +142,7 @@ std::set<alphabet::Symbol> AutomatonFromXMLParser::parseInputAlphabet(std::list<
 	popToken(input, sax::Token::START_ELEMENT, "inputAlphabet");
 	while (isTokenType(input, sax::Token::START_ELEMENT)) {
 		popToken(input, sax::Token::START_ELEMENT, "symbol");
-		inputSymbols.insert(alphabet::Symbol(parseLabel(input)));
+		inputSymbols.insert(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 		popToken(input, sax::Token::END_ELEMENT, "symbol");
 	}
 	popToken(input, sax::Token::END_ELEMENT, "inputAlphabet");
@@ -182,7 +185,7 @@ std::set<alphabet::Symbol> AutomatonFromXMLParser::parseStackAlphabet(std::list<
 	popToken(input, sax::Token::START_ELEMENT, "stackAlphabet");
 	while (isTokenType(input, sax::Token::START_ELEMENT)) {
 		popToken(input, sax::Token::START_ELEMENT, "symbol");
-		stackSymbols.insert(alphabet::Symbol(parseLabel(input)));
+		stackSymbols.insert(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 		popToken(input, sax::Token::END_ELEMENT, "symbol");
 	}
 	popToken(input, sax::Token::END_ELEMENT, "stackAlphabet");
@@ -194,7 +197,7 @@ std::set<alphabet::Symbol> AutomatonFromXMLParser::parseInitialSymbols(std::list
 	popToken(input, sax::Token::START_ELEMENT, "initialAlphabet");
 	while (isTokenType(input, sax::Token::START_ELEMENT)) {
 		popToken(input, sax::Token::START_ELEMENT, "symbol");
-		initialSymbols.insert(alphabet::Symbol(parseLabel(input)));
+		initialSymbols.insert(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 		popToken(input, sax::Token::END_ELEMENT, "symbol");
 	}
 	popToken(input, sax::Token::END_ELEMENT, "initialAlphabet");
@@ -206,7 +209,7 @@ std::set<alphabet::Symbol> AutomatonFromXMLParser::parseTapeAlphabet(std::list<s
 	popToken(input, sax::Token::START_ELEMENT, "tapeAlphabet");
 	while (isTokenType(input, sax::Token::START_ELEMENT)) {
 		popToken(input, sax::Token::START_ELEMENT, "symbol");
-		tapeSymbols.insert(alphabet::Symbol(parseLabel(input)));
+		tapeSymbols.insert(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 		popToken(input, sax::Token::END_ELEMENT, "symbol");
 	}
 	popToken(input, sax::Token::END_ELEMENT, "tapeAlphabet");
@@ -216,13 +219,12 @@ std::set<alphabet::Symbol> AutomatonFromXMLParser::parseTapeAlphabet(std::list<s
 alphabet::Symbol AutomatonFromXMLParser::parseBlankSymbol(std::list<sax::Token>& input) {
 	popToken(input, sax::Token::START_ELEMENT, "blankSymbol");
 	
-	alphabet::Symbol result("");
+	alphabet::Symbol result = alphabet::Symbol(alphabet::BlankSymbol());
 	if (isToken(input, sax::Token::START_ELEMENT, "blank")) {
-		result = alphabet::Blank();
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT,"blank");
 	} else {
-		result = alphabet::Symbol(parseLabel(input));
+		result = alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input)))));
 	}
 
 	popToken(input, sax::Token::END_ELEMENT, "blankSymbol");
@@ -331,7 +333,7 @@ std::vector<alphabet::Symbol> AutomatonFromXMLParser::parseTransitionPop(std::li
 	popToken(input, sax::Token::START_ELEMENT, "pop");
 	while (isTokenType(input, sax::Token::START_ELEMENT)) {
 		popToken(input, sax::Token::START_ELEMENT, "symbol");
-		pops.push_back(alphabet::Symbol(parseLabel(input)));
+		pops.push_back(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 		popToken(input, sax::Token::END_ELEMENT, "symbol");
 	}
 	popToken(input, sax::Token::END_ELEMENT, "pop");
@@ -343,7 +345,7 @@ std::vector<alphabet::Symbol> AutomatonFromXMLParser::parseTransitionPush(std::l
 	popToken(input, sax::Token::START_ELEMENT, "push");
 	while (isTokenType(input, sax::Token::START_ELEMENT)) {
 		popToken(input, sax::Token::START_ELEMENT, "symbol");
-		pushes.push_back(alphabet::Symbol(parseLabel(input)));
+		pushes.push_back(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 		popToken(input, sax::Token::END_ELEMENT, "symbol");
 	}
 	popToken(input, sax::Token::END_ELEMENT, "push");
@@ -352,14 +354,14 @@ std::vector<alphabet::Symbol> AutomatonFromXMLParser::parseTransitionPush(std::l
 
 alphabet::Symbol AutomatonFromXMLParser::parseTransitionOutputSymbol(std::list<sax::Token>& input) {
 	popToken(input, sax::Token::START_ELEMENT, "output");
-	alphabet::Symbol result = alphabet::Symbol(parseLabel(input));
+	alphabet::Symbol result = alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input)))));
 	popToken(input, sax::Token::END_ELEMENT, "output");
 	return result;
 }
 
 alphabet::Symbol AutomatonFromXMLParser::parseTransitionInputSymbol(std::list<sax::Token>& input) {
 	popToken(input, sax::Token::START_ELEMENT, "input");
-	alphabet::Symbol result = alphabet::Symbol(parseLabel(input));
+	alphabet::Symbol result = alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input)))));
 	popToken(input, sax::Token::END_ELEMENT, "input");
 	return result;
 }
@@ -373,7 +375,7 @@ std::variant<string::Epsilon, alphabet::Symbol> AutomatonFromXMLParser::parseTra
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT, "epsilon");
 	} else {
-		result.set<alphabet::Symbol>(alphabet::Symbol(parseLabel(input)));
+		result.set<alphabet::Symbol>(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 	}
 	
 	popToken(input, sax::Token::END_ELEMENT, "input");
@@ -390,7 +392,7 @@ std::variant<string::Epsilon, alphabet::Symbol> AutomatonFromXMLParser::parseTra
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT, "epsilon");
 	} else {
-		result.set<alphabet::Symbol>(alphabet::Symbol(parseLabel(input)));
+		result.set<alphabet::Symbol>(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 	}
 	
 	popToken(input, sax::Token::END_ELEMENT, "output");
@@ -407,11 +409,11 @@ std::variant<string::Epsilon, alphabet::Symbol> AutomatonFromXMLParser::parseTra
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT, "epsilon");
 	} else if (isToken(input, sax::Token::START_ELEMENT, "blank")) {
-		result.set<alphabet::Symbol>(alphabet::Blank());
+		result.set<alphabet::Symbol>(alphabet::Symbol(alphabet::BlankSymbol()));
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT,"blank");
 	} else {
-		result.set<alphabet::Symbol>(alphabet::Symbol(parseLabel(input)));
+		result.set<alphabet::Symbol>(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 	}
 	
 	popToken(input, sax::Token::END_ELEMENT, "input");
@@ -428,11 +430,11 @@ std::variant<string::Epsilon, alphabet::Symbol> AutomatonFromXMLParser::parseTra
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT, "epsilon");
 	} else if (isToken(input, sax::Token::START_ELEMENT, "blank")) {
-		result.set<alphabet::Symbol>(alphabet::Blank());
+		result.set<alphabet::Symbol>(alphabet::Symbol(alphabet::BlankSymbol()));
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT,"blank");
 	} else {
-		result.set<alphabet::Symbol>(alphabet::Symbol(parseLabel(input)));
+		result.set<alphabet::Symbol>(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(parseLabel(input))))));
 	}
 	
 	popToken(input, sax::Token::END_ELEMENT, "output");
diff --git a/alib2/src/automaton/AutomatonToXMLComposer.cpp b/alib2/src/automaton/AutomatonToXMLComposer.cpp
index 37ce44074cba5a7e14e16f04b89cf6b8d41850ba..f90fdfbbb76611c93155cc39a3a41e3916393972 100644
--- a/alib2/src/automaton/AutomatonToXMLComposer.cpp
+++ b/alib2/src/automaton/AutomatonToXMLComposer.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "AutomatonToXMLComposer.h"
-#include "../alphabet/Blank.h"
+#include "../alphabet/BlankSymbol.h"
 
 namespace automaton {
 
@@ -130,7 +130,7 @@ void AutomatonToXMLComposer::printState(std::list<sax::Token>& out, const State&
 
 void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
-	out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER));
+	out.push_back(sax::Token((std::string) symbol, sax::Token::CHARACTER));
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
@@ -139,22 +139,22 @@ void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const std::v
 	if(symbol.is<string::Epsilon>()) {
 		out.push_back(sax::Token("epsilon", sax::Token::START_ELEMENT));
 		out.push_back(sax::Token("epsilon", sax::Token::END_ELEMENT));
-	} else if(symbol.get<alphabet::Symbol>() == alphabet::Blank::BLANK) {
+	} else if(symbol.get<alphabet::Symbol>().getSymbol() == alphabet::BlankSymbol::BLANK) {
 		out.push_back(sax::Token("blank", sax::Token::START_ELEMENT));
 		out.push_back(sax::Token("blank", sax::Token::END_ELEMENT));
 	} else {
-		out.push_back(sax::Token(symbol.get<alphabet::Symbol>().getSymbol(), sax::Token::CHARACTER));
+		out.push_back(sax::Token((std::string) symbol.get<alphabet::Symbol>(), sax::Token::CHARACTER));
 	}
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
 
 void AutomatonToXMLComposer::printSymbol(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) {
 	out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
-	if(symbol == alphabet::Blank::BLANK) {
+	if(symbol.getSymbol() == alphabet::BlankSymbol::BLANK) {
 		out.push_back(sax::Token("blank", sax::Token::START_ELEMENT));
 		out.push_back(sax::Token("blank", sax::Token::START_ELEMENT));
 	} else {
-		out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER));
+		out.push_back(sax::Token((std::string) symbol, sax::Token::CHARACTER));
 	}
 	out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
 }
diff --git a/alib2/src/automaton/FSM/CompactNFA.cpp b/alib2/src/automaton/FSM/CompactNFA.cpp
index a325de3834a05c1e49795a89490253d68a829636..f3eac6a63a58032f93761610a4d99c3760a4fa1a 100644
--- a/alib2/src/automaton/FSM/CompactNFA.cpp
+++ b/alib2/src/automaton/FSM/CompactNFA.cpp
@@ -42,7 +42,7 @@ bool CompactNFA::removeInputSymbol(const alphabet::Symbol& symbol) {
 	for (std::map<std::pair<State, string::String>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
 			transition++) {
 		if (transition->first.second.getAlphabet().count(symbol) == 1)
-			throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is used.");
+			throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used.");
 	}
 
 	return inputAlphabet.erase(symbol);
diff --git a/alib2/src/automaton/FSM/DFA.cpp b/alib2/src/automaton/FSM/DFA.cpp
index 68e4e843057bb1405833305fd26cd81c59d4e3b1..1cd714289853c1729d49065c9c60bf4494473c17 100644
--- a/alib2/src/automaton/FSM/DFA.cpp
+++ b/alib2/src/automaton/FSM/DFA.cpp
@@ -46,7 +46,7 @@ bool DFA::removeInputSymbol(const alphabet::Symbol& symbol) {
 	for (std::map<std::pair<State, alphabet::Symbol>, State>::const_iterator transition = transitions.begin(); transition != transitions.end();
 			transition++) {
 		if (transition->first.second == symbol)
-			throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is used.");
+			throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used.");
 	}
 
 	return inputAlphabet.erase(symbol);
@@ -58,7 +58,7 @@ bool DFA::addTransition(const State& from, const alphabet::Symbol& input, const
 		throw AutomatonException("State \"" + from.getName() + "\" doesn't exist.");
 
 	if (inputAlphabet.find(input) == inputAlphabet.end())
-		throw AutomatonException("Input symbol \"" + input.getSymbol() + "\" doesn't exist.");
+		throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist.");
 
 	if (states.find(to) == states.end())
 		throw AutomatonException("State \"" + to.getName() + "\" doesn't exist.");
@@ -70,7 +70,7 @@ bool DFA::addTransition(const State& from, const alphabet::Symbol& input, const
 			return false;
 		else
 			throw AutomatonException(
-				"Transition (\"" + from.getName() + "\", \"" + input.getSymbol() + "\") -> \"" + to.getName()
+				"Transition (\"" + from.getName() + "\", \"" + (std::string) input + "\") -> \"" + to.getName()
 						+ "\" already exists.");
 	}
 	
@@ -86,7 +86,7 @@ bool DFA::removeTransition(const State& from, const alphabet::Symbol& input, con
 
 	if(transitions.find(key)->second != to)
 		throw AutomatonException(
-				"Transition (\"" + from.getName() + "\", \"" + input.getSymbol()
+				"Transition (\"" + from.getName() + "\", \"" + (std::string) input
 						+ "\") -> \"" + to.getName() + "\" doesn't exist.");
 
 	transitions.erase(key);
diff --git a/alib2/src/automaton/FSM/EpsilonNFA.cpp b/alib2/src/automaton/FSM/EpsilonNFA.cpp
index 59795c35c61fb0df0dbf2e738dc0b321f9f02f21..5e4a855d4bd0fba83a02000c0b55d0e61be07f5b 100644
--- a/alib2/src/automaton/FSM/EpsilonNFA.cpp
+++ b/alib2/src/automaton/FSM/EpsilonNFA.cpp
@@ -43,7 +43,7 @@ bool EpsilonNFA::removeInputSymbol(const alphabet::Symbol& symbol) {
 	for (std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> >, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
 			transition++) {
 		if (transition->first.second.is<alphabet::Symbol>() && transition->first.second.get<alphabet::Symbol>() == symbol)
-			throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is used.");
+			throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used.");
 	}
 
 	return inputAlphabet.erase(symbol);
@@ -55,7 +55,7 @@ bool EpsilonNFA::addTransition(const State& from, const std::variant<string::Eps
 		throw AutomatonException("State \"" + from.getName() + "\" doesn't exist.");
 
 	if (input.is<alphabet::Symbol>() && inputAlphabet.find(input.get<alphabet::Symbol>()) == inputAlphabet.end())
-		throw AutomatonException("Input symbol \"" + input.get<alphabet::Symbol>().getSymbol() + "\" doesn't exist.");
+		throw AutomatonException("Input symbol \"" + (std::string) input.get<alphabet::Symbol>() + "\" doesn't exist.");
 
 	if (states.find(to) == states.end())
 		throw AutomatonException("State \"" + to.getName() + "\" doesn't exist.");
diff --git a/alib2/src/automaton/FSM/ExtendedNFA.cpp b/alib2/src/automaton/FSM/ExtendedNFA.cpp
index 2cf6504ae8000bfe64f8ad7d79682a172ac4bd6a..d788fe1b97a68c7584c86ca37bb923e9ce98e483 100644
--- a/alib2/src/automaton/FSM/ExtendedNFA.cpp
+++ b/alib2/src/automaton/FSM/ExtendedNFA.cpp
@@ -42,7 +42,7 @@ bool ExtendedNFA::removeInputSymbol(const alphabet::Symbol& symbol) {
 	for (std::map<std::pair<State, regexp::RegExp>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
 			transition++) {
 		if (transition->first.second.getAlphabet().count(symbol) == 1)
-			throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is used.");
+			throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used.");
 	}
 
 	return inputAlphabet.erase(symbol);
diff --git a/alib2/src/automaton/FSM/NFA.cpp b/alib2/src/automaton/FSM/NFA.cpp
index 38e4ef9d507a2e12583339287918ebba38382357..0b07e0f9e1e78686f4f24023352de98b35892bb1 100644
--- a/alib2/src/automaton/FSM/NFA.cpp
+++ b/alib2/src/automaton/FSM/NFA.cpp
@@ -40,7 +40,7 @@ bool NFA::removeInputSymbol(const alphabet::Symbol& symbol) {
 	for (std::map<std::pair<State, alphabet::Symbol>, std::set<State> >::const_iterator transition = transitions.begin(); transition != transitions.end();
 			transition++) {
 		if (transition->first.second == symbol)
-			throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is used.");
+			throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is used.");
 	}
 
 	return inputAlphabet.erase(symbol);
@@ -51,7 +51,7 @@ bool NFA::addTransition(const State& from, const alphabet::Symbol& input, const
 		throw AutomatonException("State \"" + from.getName() + "\" doesn't exist.");
 
 	if (inputAlphabet.find(input) == inputAlphabet.end())
-		throw AutomatonException("Input symbol \"" + input.getSymbol() + "\" doesn't exist.");
+		throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist.");
 
 	if (states.find(to) == states.end())
 		throw AutomatonException("State \"" + to.getName() + "\" doesn't exist.");
diff --git a/alib2/src/automaton/PDA/PDA.cpp b/alib2/src/automaton/PDA/PDA.cpp
index 7dd36ad9f7ab07588e0cc1953854c6f4bf58c621..ec6ce1b45dacd0c1124a4d5057f43491c477a18c 100644
--- a/alib2/src/automaton/PDA/PDA.cpp
+++ b/alib2/src/automaton/PDA/PDA.cpp
@@ -44,7 +44,7 @@ bool PDA::removeState(const State& state) {
 bool PDA::removeInputSymbol(const alphabet::Symbol& symbol) {
 	for (std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::set<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 \"" + symbol.getSymbol() + "\" is used in transition.");
+			throw AutomatonException("Symbol \"" + (std::string) symbol + "\" is used in transition.");
 	}
 
 	return inputAlphabet.erase(symbol);
@@ -75,16 +75,16 @@ bool PDA::removeStackSymbol(const alphabet::Symbol& symbol) {
 		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 \"" + symbol.getSymbol() + "\" is used in transition.");
+				throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
 		}
 		for (std::set<std::pair<State, std::vector<alphabet::Symbol> > >::const_iterator target = transition->second.begin(); target != transition->second.end(); target++) {
 			if (std::find(target->second.begin(), target->second.end(), symbol) != target->second.end())
-				throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" is used in transition.");
+				throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is used in transition.");
 		}
 	}
 
 	if(initialSymbols.find(symbol) != initialSymbols.end()) {
-		throw AutomatonException("Stack symbol \"" + symbol.getSymbol() + "\" is start symbol.");
+		throw AutomatonException("Stack symbol \"" + (std::string) symbol + "\" is start symbol.");
 	}
 
 	return stackAlphabet.erase(symbol);
@@ -100,7 +100,7 @@ bool PDA::addTransition(const State& from, const alphabet::Symbol& input, const
 	}
 
 	if (inputAlphabet.find(input) == inputAlphabet.end()) {
-		throw AutomatonException("Input symbol \"" + input.getSymbol() + "\" doesn't exist.");
+		throw AutomatonException("Input symbol \"" + (std::string) input + "\" doesn't exist.");
 	}
 
 	if (states.find(to) == states.end()) {
@@ -109,13 +109,13 @@ bool PDA::addTransition(const State& from, const alphabet::Symbol& input, const
 
 	for(std::vector<alphabet::Symbol>::const_iterator popSymbol = pop.begin(); popSymbol != pop.end(); popSymbol++) {
 		if (stackAlphabet.find(*popSymbol) == stackAlphabet.end()) {
-			throw AutomatonException("Stack symbol \"" + popSymbol->getSymbol() + "\" doesn't exist.");
+			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 \"" + pushSymbol->getSymbol() + "\" doesn't exist.");
+			throw AutomatonException("Stack symbol \"" + (std::string) *pushSymbol + "\" doesn't exist.");
 		}
 	}
 
@@ -144,7 +144,7 @@ const std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>
 
 bool PDA::addInitialSymbol(const alphabet::Symbol& start) {
 	if (stackAlphabet.find(start) == stackAlphabet.end()) {
-		throw AutomatonException("Stack symbol \"" + start.getSymbol() + "\" doesn't exist.");
+		throw AutomatonException("Stack symbol \"" + (std::string) start + "\" doesn't exist.");
 	}
 	
 	return this->initialSymbols.insert(start).second;
diff --git a/alib2/src/automaton/TM/OneTapeDTM.cpp b/alib2/src/automaton/TM/OneTapeDTM.cpp
index 4084985dd4449a036a45b4dc65f10d035d5b03ac..a9992677c5e232a762b5107f996af463190e4cbb 100644
--- a/alib2/src/automaton/TM/OneTapeDTM.cpp
+++ b/alib2/src/automaton/TM/OneTapeDTM.cpp
@@ -8,7 +8,6 @@
 #include "OneTapeDTM.h"
 #include "../../std/map.hpp"
 #include "../AutomatonException.h"
-#include "../../alphabet/Blank.h"
 
 namespace automaton {
 
@@ -49,12 +48,12 @@ bool OneTapeDTM::removeInputSymbol(const alphabet::Symbol& symbol) {
 
 bool OneTapeDTM::removeTapeSymbol(const alphabet::Symbol& symbol) {
 	if (inputAlphabet.find(symbol) != inputAlphabet.end()) {
-		throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" is in input alphabet.");
+		throw AutomatonException("Tape symbol \"" + (std::string) symbol + "\" is in input alphabet.");
 	}
 
 	for (std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::Symbol, Shift> >::const_iterator transition = transitions.begin(); transition != transitions.end(); transition++) {
 		if (symbol == transition->first.second || symbol == std::get<1>(transition->second))
-			throw AutomatonException("Tape symbol \"" + symbol.getSymbol() + "\" is used in transition.");
+			throw AutomatonException("Tape symbol \"" + (std::string) symbol + "\" is used in transition.");
 	}
 
 	return inputAlphabet.erase(symbol);
@@ -67,7 +66,7 @@ bool OneTapeDTM::addTransition(const State& from, const alphabet::Symbol& input,
 
 	if (input != blankSymbol)
 		if (tapeAlphabet.find(input) == tapeAlphabet.end()) {
-			throw AutomatonException("Tape symbol \"" + input.getSymbol() + "\" doesn't exist.");
+			throw AutomatonException("Tape symbol \"" + (std::string) input + "\" doesn't exist.");
 		}
 
 	if (states.find(to) == states.end()) {
@@ -76,7 +75,7 @@ bool OneTapeDTM::addTransition(const State& from, const alphabet::Symbol& input,
 
 	if (input != blankSymbol)
 		if (tapeAlphabet.find(output) == tapeAlphabet.end()) {
-			throw AutomatonException("Tape symbol  \"" + output.getSymbol() + "\" doesn't exist.");
+			throw AutomatonException("Tape symbol  \"" + (std::string) output + "\" doesn't exist.");
 		}
 
 	std::pair<State, alphabet::Symbol> key = std::make_pair(from, input);
@@ -88,7 +87,7 @@ bool OneTapeDTM::addTransition(const State& from, const alphabet::Symbol& input,
 			return false;
 		else
 			throw AutomatonException(
-				"Transition (\"" + from.getName() + "\", \"" + input.getSymbol() + "\") -> ? already exists.");
+				"Transition (\"" + from.getName() + "\", \"" + (std::string) input + "\") -> ? already exists.");
 	}
 
 	transitions.insert(std::make_pair(key, value));
@@ -104,7 +103,7 @@ bool OneTapeDTM::removeTransition(const State& from, const alphabet::Symbol& inp
 	std::tuple<State, alphabet::Symbol, Shift > value(to, output, shift);
 	if(transitions.find(key)->second != value) 
 		throw AutomatonException(
-				"Transition (\"" + from.getName() + "\", \"" + input.getSymbol() + "\") -> ? doesn't exists.");
+				"Transition (\"" + from.getName() + "\", \"" + (std::string) input + "\") -> ? doesn't exists.");
 
 	transitions.erase(key);
 	return true;
diff --git a/alib2/src/automaton/common/BlankSymbolInputTapeAlphabet.cpp b/alib2/src/automaton/common/BlankSymbolInputTapeAlphabet.cpp
index f1bb347c4b1330567c0328b9d152247964085351..fc3aa67646713bf206d6218e8fc9b5a6b763da31 100644
--- a/alib2/src/automaton/common/BlankSymbolInputTapeAlphabet.cpp
+++ b/alib2/src/automaton/common/BlankSymbolInputTapeAlphabet.cpp
@@ -22,11 +22,11 @@ const std::set<alphabet::Symbol>& BlankSymbolInputTapeAlphabet::getInputAlphabet
 
 bool BlankSymbolInputTapeAlphabet::addInputSymbol(const alphabet::Symbol& symbol) {
 	if (tapeAlphabet.find(symbol) == tapeAlphabet.end()) {
-		throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" is not in tape alphabet.");
+		throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" is not in tape alphabet.");
 	}
 
 	if (symbol == blankSymbol) {
-		throw AutomatonException("Input symbol \"" + symbol.getSymbol() + "\" cannot be blank symbol.");
+		throw AutomatonException("Input symbol \"" + (std::string) symbol + "\" cannot be blank symbol.");
 	}
 
 	return inputAlphabet.insert(symbol).second;
@@ -74,10 +74,10 @@ const std::set<alphabet::Symbol>& BlankSymbolInputTapeAlphabet::getTapeAlphabet(
 
 void BlankSymbolInputTapeAlphabet::setBlankSymbol(const alphabet::Symbol& symbol) {
 	if (inputAlphabet.find(symbol) != inputAlphabet.end())
-		throw AutomatonException("Blank symbol \"" + symbol.getSymbol() + "\" is in input alphabet.");
+		throw AutomatonException("Blank symbol \"" + (std::string) symbol + "\" is in input alphabet.");
 
 	if (tapeAlphabet.find(symbol) == tapeAlphabet.end())
-		throw AutomatonException("Blank symbol \"" + symbol.getSymbol() + "\" is not in tape alphabet.");
+		throw AutomatonException("Blank symbol \"" + (std::string) symbol + "\" is not in tape alphabet.");
 
 	blankSymbol = symbol;
 
diff --git a/alib2/src/label/IntegerLabel.cpp b/alib2/src/label/IntegerLabel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..704e7e29e81983eea5f64a07e3af156ab5f517a1
--- /dev/null
+++ b/alib2/src/label/IntegerLabel.cpp
@@ -0,0 +1,45 @@
+/*
+ * IntegerLabel.cpp
+ *
+ *  Created on: Mar 26, 2013
+ *      Author:Jan Travnicek 
+ */
+
+#include "IntegerLabel.h"
+
+namespace label {
+
+IntegerLabel::IntegerLabel(int label) : label(label) {
+
+}
+
+int IntegerLabel::getData() const {
+	return label;
+}
+
+bool IntegerLabel::operator <(const IntegerLabel& other) const {
+	return label < other.label;
+}
+
+bool IntegerLabel::operator >(const LabelBase& other) const {
+	return other < *this;
+}
+
+bool IntegerLabel::operator ==(const IntegerLabel& other) const {
+	return label == other.label;
+}
+
+bool IntegerLabel::operator ==(const LabelBase& other) const {
+	return other == *this;
+}
+
+void IntegerLabel::operator>>(std::ostream& out) const {
+	out << "(IntegerLabel " << label << ")";
+}
+
+IntegerLabel::operator std::string() const {
+	return std::to_string(label);
+}
+
+} /* namespace label */
+
diff --git a/alib2/src/label/IntegerLabel.h b/alib2/src/label/IntegerLabel.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a10f95f31af33878320f61a6061246f665dd0e7
--- /dev/null
+++ b/alib2/src/label/IntegerLabel.h
@@ -0,0 +1,50 @@
+/*
+ * IntegerLabel.h
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef INTEGER_LABEL_H_
+#define INTEGER_LABEL_H_
+
+#include <ostream>
+
+#include "LabelBase.h"
+
+namespace label {
+
+/**
+ * Represents symbol in an alphabet.
+ */
+class IntegerLabel : public LabelBase {
+protected:
+	int label;
+public:
+	/**
+	 * Creates new symbol with given name.
+	 * @param symbol name of the symbol
+	 */
+	explicit IntegerLabel(int label);
+
+	/**
+	 * @return name of the symbol
+	 */
+	int getData() const;
+
+	virtual bool operator <(const IntegerLabel& other) const;
+	
+	virtual bool operator>(const LabelBase& other) const;
+	
+	virtual bool operator ==(const IntegerLabel& other) const;
+	
+	virtual bool operator ==(const LabelBase& other) const;
+
+	virtual void operator>>(std::ostream&) const;
+
+	virtual operator std::string() const;
+};
+
+} /* namespace label */
+
+#endif /* INTEGER_LABEL_H_ */
diff --git a/alib2/src/label/Label.cpp b/alib2/src/label/Label.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0988de7d0cf945fe6928bb503cdeec1957aa234
--- /dev/null
+++ b/alib2/src/label/Label.cpp
@@ -0,0 +1,86 @@
+/*
+ * Label.cpp
+ *
+ *  Created on: Apr 16, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "Label.h"
+
+namespace label {
+
+Label::Label(const LabelBase& label) : label(label.clone()) {
+
+}
+
+Label::Label(LabelBase&& label) : label(std::move(label).plunder()) {
+
+}
+
+Label::Label(const Label& other) : label(other.getLabel().clone()) {
+
+}
+
+Label::Label(Label&& other) noexcept : label(std::move(other.getLabel()).plunder()) {
+	other.label = NULL;
+}
+
+Label& Label::operator=(const Label& other) {
+	if(this == &other) return *this;
+
+	delete label;
+	label = other.getLabel().clone();
+
+	return *this;
+}
+
+Label& Label::operator=(Label&& other) noexcept {
+	std::swap(this->label, other.label);
+	return *this;
+}
+
+Label::~Label() {
+	delete label;
+}
+
+const LabelBase& Label::getLabel() const {
+	return *label;
+}
+
+LabelBase& Label::getLabel() {
+	return *label;
+}
+
+void Label::setLabel(const LabelBase& label) {
+	delete this->label;
+	this->label = label.clone();
+}
+
+void Label::setLabel(LabelBase&& label) {
+	delete this->label;
+	this->label = std::move(label).plunder();
+}
+
+bool Label::operator!=(const Label& other) const {
+	return !(*this == other);
+}
+
+bool Label::operator<(const Label& other) const {
+	return *label < *other.label;
+}
+
+bool Label::operator==(const Label& other) const {
+	return *label == *other.label;
+}
+
+std::ostream& operator<<(std::ostream& os, const Label& label) {
+	os << label.getLabel();
+	return os;
+}
+
+Label::operator std::string () const {
+	return (std::string) *label;
+}
+
+} /* namespace label */
+
diff --git a/alib2/src/label/Label.h b/alib2/src/label/Label.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ad0a161282413c40d4139295909d44f6a4e3cfc
--- /dev/null
+++ b/alib2/src/label/Label.h
@@ -0,0 +1,51 @@
+/*
+ * Label.h
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef LABEL_H_
+#define LABEL_H_
+
+#include "../std/visitor.hpp"
+#include "LabelBase.h"
+
+namespace label {
+
+/**
+ * Wrapper around automata.
+ */
+class Label : public std::element<Label, std::visitor<Label> > {
+protected:
+	LabelBase* label;
+public:
+	explicit Label(const LabelBase& label);
+	explicit Label(LabelBase&& label);
+	Label(const Label& other);
+	Label(Label&&) noexcept;
+	Label& operator=(const Label& other);
+	Label& operator=(Label&& other) noexcept;
+	virtual ~Label() noexcept;
+
+	const LabelBase& getLabel() const;
+	LabelBase& getLabel();
+
+	void setLabel(const LabelBase& label);
+	void setLabel(LabelBase&& label);
+
+	bool operator<(const Label& other) const;
+	
+	bool operator!=(const Label& other) const;
+
+	bool operator==(const Label& other) const;
+
+	friend std::ostream& operator<<(std::ostream& os, const Label& label);
+
+	operator std::string () const;
+};
+
+} /* namespace label */
+
+#endif /* LABEL_H_ */
+
diff --git a/alib2/src/label/LabelBase.cpp b/alib2/src/label/LabelBase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8be945d0f8bd7d2b614e492d94ad3b877379d5b8
--- /dev/null
+++ b/alib2/src/label/LabelBase.cpp
@@ -0,0 +1,62 @@
+/*
+ * LabelBase.cpp
+ *
+ *  Created on: Apr 16, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "LabelBase.h"
+#include <typeinfo>
+
+#include "StringLabel.h"
+#include "IntegerLabel.h"
+
+namespace label {
+
+LabelBase::~LabelBase() {
+
+}
+
+bool LabelBase::operator<(const StringLabel& other) const {
+	return typeid(this).before(typeid(other));
+}
+
+bool LabelBase::operator<(const IntegerLabel& other) const {
+	return typeid(this).before(typeid(other));
+}
+
+bool LabelBase::operator>(const LabelBase& other) const {
+	return other < *this;
+}
+
+bool LabelBase::operator<(const LabelBase& other) const {
+	return other > *this;
+}
+
+bool LabelBase::operator>=(const LabelBase& other) const {
+	return !(*this < other);
+}
+
+bool LabelBase::operator<=(const LabelBase& other) const {
+	return !(*this > other);
+}
+
+bool LabelBase::operator!=(const LabelBase& other) const {
+	return !(*this == other);
+}
+
+bool LabelBase::operator==(const StringLabel&) const {
+	return false;
+}
+
+bool LabelBase::operator==(const IntegerLabel&) const {
+	return false;
+}
+
+std::ostream& operator<<(std::ostream& os, const LabelBase& label) {
+	label >> os;
+	return os;
+}
+
+} /* namespace label */
+
diff --git a/alib2/src/label/LabelBase.h b/alib2/src/label/LabelBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e7a04b15f1c3511d7d168ca577b63067f905c71
--- /dev/null
+++ b/alib2/src/label/LabelBase.h
@@ -0,0 +1,61 @@
+/*
+ * LabelBase.h
+ *
+ *  Created on: Apr 10, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef LABEL_BASE_H_
+#define LABEL_BASE_H_
+
+#include "../std/visitor.hpp"
+
+namespace label {
+
+class StringLabel;
+class IntegerLabel;
+
+/**
+ * Abstract base class for all automata.
+ */
+class LabelBase : virtual public std::elementBase<std::visitor<StringLabel, IntegerLabel> > {
+public:
+	virtual LabelBase* clone() const = 0;
+
+	virtual LabelBase* plunder() && = 0;
+
+	virtual ~LabelBase() noexcept;
+	
+	virtual bool operator<(const LabelBase& other) const = 0;
+	
+	virtual bool operator<(const StringLabel& other) const;
+	
+	virtual bool operator<(const IntegerLabel& other) const;
+	
+	virtual bool operator>(const LabelBase& other) const = 0;
+
+	
+	bool operator>=(const LabelBase& other) const;
+
+	bool operator<=(const LabelBase& other) const;
+
+	bool operator!=(const LabelBase& other) const;
+
+	
+	virtual bool operator==(const LabelBase& other) const = 0;
+
+	virtual bool operator==(const StringLabel& other) const;
+
+	virtual bool operator==(const IntegerLabel& other) const;
+
+	friend std::ostream& operator<<(std::ostream& os, const LabelBase& label);
+
+	virtual void operator>>(std::ostream&) const = 0;
+
+	virtual operator std::string() const = 0;
+};
+
+} /* namespace label */
+
+#endif /* LABEL_BASE_H_ */
+
diff --git a/alib2/src/label/StringLabel.cpp b/alib2/src/label/StringLabel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ebddcf5162662f0842a129c02abd98d70176182b
--- /dev/null
+++ b/alib2/src/label/StringLabel.cpp
@@ -0,0 +1,62 @@
+/*
+ * StringLabel.cpp
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Jan Travicek
+ */
+
+#include "StringLabel.h"
+
+namespace label {
+
+StringLabel::StringLabel(const std::string& label) : label(label) {
+
+}
+
+StringLabel::StringLabel(std::string&& label) : label(std::move(label)) {
+
+}
+
+LabelBase* StringLabel::clone() const {
+	return new StringLabel(*this);
+}
+
+LabelBase* StringLabel::plunder() && {
+	return new StringLabel(std::move(*this));
+}
+
+const std::string& StringLabel::getData() const {
+	return label;
+}
+
+bool StringLabel::operator<(const LabelBase& other) const {
+	return other > *this;
+}
+
+bool StringLabel::operator==(const LabelBase& other) const {
+	return other == *this;
+}
+
+bool StringLabel::operator >(const LabelBase& other) const {
+	return other < *this;
+}
+
+
+bool StringLabel::operator <(const StringLabel& other) const {
+	return label < other.label;
+}
+
+bool StringLabel::operator ==(const StringLabel& other) const {
+	return label == other.label;
+}
+
+void StringLabel::operator>>(std::ostream& out) const {
+	out << "(StringLabel " << label << ")";
+}
+
+StringLabel::operator std::string() const {
+	return label;
+}
+
+} /* namespace label */
+
diff --git a/alib2/src/label/StringLabel.h b/alib2/src/label/StringLabel.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1d14f17a1201cffe540898c3665dd59a676a369
--- /dev/null
+++ b/alib2/src/label/StringLabel.h
@@ -0,0 +1,58 @@
+/*
+ * StringLabel.h
+ *
+ *  Created on: Mar 26, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef STRING_LABEL_H_
+#define STRING_LABEL_H_
+
+#include <string>
+#include <ostream>
+
+#include "LabelBase.h"
+
+namespace label {
+
+/**
+ * Represents symbol in an alphabet.
+ */
+class StringLabel : public LabelBase, public std::element<StringLabel, LabelBase::visitor_type>{
+protected:
+	std::string label;
+public:
+	virtual LabelBase* clone() const;
+
+	virtual LabelBase* plunder() &&;
+
+	/**
+	 * Creates new symbol with given name.
+	 * @param symbol name of the symbol
+	 */
+	explicit StringLabel(const std::string& label);
+	explicit StringLabel(std::string&& label);
+
+	virtual bool operator<(const LabelBase& other) const;
+	
+	virtual bool operator>(const LabelBase& other) const;
+
+	virtual bool operator==(const LabelBase& other) const;
+
+	/**
+	 * @return name of the symbol
+	 */
+	const std::string& getData() const;
+
+	virtual bool operator <(const StringLabel& other) const;
+	virtual bool operator ==(const StringLabel& other) const;
+
+	virtual void operator>>(std::ostream&) const;
+
+	virtual operator std::string () const;
+};
+
+} /* namespace label */
+
+#endif /* STRING_LABEL_H_ */
+
diff --git a/alib2/src/regexp/RegExp.cpp b/alib2/src/regexp/RegExp.cpp
index c5082cd1a24e0564e55b59c10a20fd62cb87d738..076fb86b4e4c8024d9ae6b9b306d4fa1d87c80a6 100644
--- a/alib2/src/regexp/RegExp.cpp
+++ b/alib2/src/regexp/RegExp.cpp
@@ -13,6 +13,8 @@
 #include <iostream>
 #include <algorithm>
 
+#include "../std/set.hpp"
+
 namespace regexp {
 
 RegExp::RegExp() {
@@ -82,14 +84,14 @@ void RegExp::setRegExp(const RegExpElement& regExp) {
 	delete this->regExp;
 	this->regExp = regExp.clone();
 	if(!this->regExp->attachRegExp(this))
-		throw alib::AlibException("Input symbols not in the alphabet."); 
+		throw alib::AlibException("Input symbols not in the alphabet.");
 }
 
 void RegExp::setRegExp(RegExpElement&& regExp) {
 	delete this->regExp;
 	this->regExp = std::move(regExp).plunder();
 	if(!this->regExp->attachRegExp(this))
-		throw alib::AlibException("Input symbols not in the alphabet."); 
+		throw alib::AlibException("Input symbols not in the alphabet.");
 }
 
 const std::set<alphabet::Symbol>& RegExp::getAlphabet() const {
@@ -99,7 +101,7 @@ const std::set<alphabet::Symbol>& RegExp::getAlphabet() const {
 void RegExp::addSymbolToAlphabet(const alphabet::Symbol & symbol) {
 	std::pair<std::set<alphabet::Symbol>::iterator, bool> ret = alphabet.insert(symbol);
 	if (!ret.second)
-		throw alib::AlibException("Symbol \"" + symbol.getSymbol() + "\" is already in the alphabet.");
+		throw alib::AlibException("Symbol \"" + (std::string) symbol + "\" is already in the alphabet.");
 }
 
 void RegExp::setAlphabet(const std::set<alphabet::Symbol> & symbols) {
@@ -108,18 +110,18 @@ void RegExp::setAlphabet(const std::set<alphabet::Symbol> & symbols) {
 
 	for(const alphabet::Symbol& symbol : removedSymbols) {
 		if(this->regExp->testSymbol(symbol))
-			throw alib::AlibException("Input symbol \"" + symbol.getSymbol() + "\" is used.");  
+			throw alib::AlibException("Input symbol \"" + (std::string) symbol + "\" is used.");
 	}
 	this->alphabet = symbols;
 }
 
 void RegExp::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) {
 	if(this->regExp->testSymbol(symbol))
-		throw alib::AlibException("Input symbol \"" + symbol.getSymbol() + "\" is used.");  
+		throw alib::AlibException("Input symbol \"" + (std::string) symbol + "\" is used.");
 	
 	int removed = alphabet.erase(symbol);
 	if (!removed)
-		throw alib::AlibException("Input symbol \"" + symbol.getSymbol() + "\" doesn't exist.");  
+		throw alib::AlibException("Input symbol \"" + (std::string) symbol + "\" doesn't exist.");
 }
 
 bool RegExp::isEmpty() const {
diff --git a/alib2/src/regexp/RegExpFromStringParser.cpp b/alib2/src/regexp/RegExpFromStringParser.cpp
index 54b81c7ab00d8a69e0052aa1863717337b8a1bc1..7e5ba3ea0d0d7ca13601e86361549c83a975b9a6 100644
--- a/alib2/src/regexp/RegExpFromStringParser.cpp
+++ b/alib2/src/regexp/RegExpFromStringParser.cpp
@@ -1,5 +1,6 @@
 #include "RegExpFromStringParser.h"
 #include "../AlibException.h"
+#include "../label/StringLabel.h"
 
 namespace regexp {
 
@@ -105,7 +106,7 @@ RegExpElement* RegExpFromStringParser::factor() {
   } else if(token.type == RegExpFromStringLexer::SYMBOL) {
     std::string symbol = token.value;
     m_Lexer.next();
-    return this->star(new RegExpSymbol(symbol));
+    return this->star(new RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(symbol))))));
   } else {
     throw alib::AlibException();
   }
@@ -123,4 +124,4 @@ RegExpElement* RegExpFromStringParser::star(RegExpElement* elem) {
   }
 }
 
-}
\ No newline at end of file
+}
diff --git a/alib2/src/regexp/RegExpFromXMLParser.cpp b/alib2/src/regexp/RegExpFromXMLParser.cpp
index 3769fe004e1324bd30ec74ebec1a38fe6009e0bd..18509c833da7e52edec10d6e5b9d794f06377f20 100644
--- a/alib2/src/regexp/RegExpFromXMLParser.cpp
+++ b/alib2/src/regexp/RegExpFromXMLParser.cpp
@@ -7,6 +7,7 @@
 
 #include "RegExpFromXMLParser.h"
 #include "../sax/ParserException.h"
+#include "../label/StringLabel.h"
 
 namespace regexp {
 
@@ -134,7 +135,7 @@ template <class T>
 T* RegExpFromXMLParser::parseSymbol(std::list<sax::Token>& input) {
 	popToken(input, sax::Token::START_ELEMENT, "symbol");
 
-	T* symbol = new T(popTokenData(input, sax::Token::CHARACTER));
+	T* symbol = new T(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(popTokenData(input, sax::Token::CHARACTER))))));
 	popToken(input, sax::Token::END_ELEMENT, "symbol");
 	return symbol;
 }
diff --git a/alib2/src/regexp/RegExpSymbol.cpp b/alib2/src/regexp/RegExpSymbol.cpp
index d2d2ad2930d8dc430cb5abae3d1f921551138bf7..d62251f019aaf77c06a6edadb50816f26391a350 100644
--- a/alib2/src/regexp/RegExpSymbol.cpp
+++ b/alib2/src/regexp/RegExpSymbol.cpp
@@ -9,11 +9,11 @@
 
 namespace regexp {
   
-RegExpSymbol::RegExpSymbol(const RegExpSymbol& other) : alphabet::Symbol(other.symbol) {
+RegExpSymbol::RegExpSymbol(const RegExpSymbol& other) : symbol(other.symbol) {
   
 }
 
-RegExpSymbol::RegExpSymbol(RegExpSymbol&& other) noexcept : alphabet::Symbol(std::move(other.symbol)) {
+RegExpSymbol::RegExpSymbol(RegExpSymbol&& other) noexcept : symbol(std::move(other.symbol)) {
 	this->attachRegExp(NULL);
 }
 
@@ -36,12 +36,12 @@ RegExpSymbol& RegExpSymbol::operator=(RegExpSymbol&& other) {
 	return *this;
 }
 
-RegExpSymbol::RegExpSymbol(const std::string& symbol) :
-		alphabet::Symbol(symbol) {
+RegExpSymbol::RegExpSymbol(const alphabet::Symbol& symbol) :
+		symbol(symbol) {
 }
 
-RegExpSymbol::RegExpSymbol(std::string&& symbol) :
-		alphabet::Symbol(std::move(symbol)) {
+RegExpSymbol::RegExpSymbol(alphabet::Symbol&& symbol) :
+		symbol(std::move(symbol)) {
 }
 
 RegExpElement* RegExpSymbol::clone() const {
@@ -53,11 +53,11 @@ RegExpElement* RegExpSymbol::plunder() && {
 }
 
 bool RegExpSymbol::operator==(const alphabet::Symbol& other) const {
-	return (const alphabet::Symbol&) *this == other;
+	return this->symbol == other;
 }
 
 bool operator==(const alphabet::Symbol& first, const RegExpSymbol& second) {
-	return first == (const alphabet::Symbol&) second;
+	return first == second.symbol;
 }
 
 bool RegExpSymbol::operator<(const RegExpElement& other) const {
@@ -74,11 +74,11 @@ bool RegExpSymbol::operator>(const RegExpElement& other) const {
 
 
 bool RegExpSymbol::operator<(const RegExpSymbol& other) const {
-	return this->symbol < other.symbol;
+	return symbol < other.symbol;
 }
 
 bool RegExpSymbol::operator==(const RegExpSymbol& other) const {
-	return this->symbol == other.symbol;
+	return symbol == other.symbol;
 }
 
 void RegExpSymbol::operator>>(std::ostream& out) const {
@@ -94,22 +94,21 @@ bool RegExpSymbol::isEmpty() const {
 }
 
 bool RegExpSymbol::testSymbol( const alphabet::Symbol & symbol ) const {
-	if( symbol == *this ) return true;
-	return false;
+	return symbol == this->symbol;
 }
 
 bool RegExpSymbol::attachRegExp(const RegExp * regexp ) {
 	if(this->parentRegExp == regexp) return true;
 	this->parentRegExp = regexp;
 	if(regexp == NULL) return true;
-	return this->parentRegExp->getAlphabet().find(*this) != this->parentRegExp->getAlphabet().end();
+	return this->parentRegExp->getAlphabet().find(this->symbol) != this->parentRegExp->getAlphabet().end();
 }
 
 void RegExpSymbol::computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const {
-	alphabet.insert(*this);
+	alphabet.insert(this->symbol);
 }
 
-const std::string& RegExpSymbol::getSymbol() const {
+const alphabet::Symbol& RegExpSymbol::getSymbol() const {
 	return this->symbol;
 }
 
diff --git a/alib2/src/regexp/RegExpSymbol.h b/alib2/src/regexp/RegExpSymbol.h
index c32dea2405f177fe2dd17f08a2f27c83641f2d2d..8f8d25e8a7423eee023ff208ac6ed55a80fe9ab3 100644
--- a/alib2/src/regexp/RegExpSymbol.h
+++ b/alib2/src/regexp/RegExpSymbol.h
@@ -8,17 +8,19 @@
 #ifndef REG_EXP_SYMBOL_H_
 #define REG_EXP_SYMBOL_H_
 
-#include <string>
+#include "../label/Label.h"
 #include "RegExpElement.h"
-#include "../alphabet/Symbol.h"
+#include "../alphabet/LabeledSymbol.h"
 
 namespace regexp {
 
 /**
  * Represents symbol in the regular expression. Contains name of the symbol.
  */
-class RegExpSymbol : protected alphabet::Symbol, public RegExpElement, public std::element<RegExpSymbol, RegExpElement::visitor_type> {
+class RegExpSymbol : public RegExpElement, public std::element<RegExpSymbol, RegExpElement::visitor_type> {
 protected:
+	alphabet::Symbol symbol;
+
 	/**
 	 * @copydoc RegExpElement::clone() const
 	 */
@@ -41,8 +43,8 @@ protected:
 	 */
 	virtual void computeMinimalAlphabet( std::set<alphabet::Symbol>& alphabet ) const;
 public:
-	explicit RegExpSymbol(const std::string& symbol);
-	explicit RegExpSymbol(std::string&& symbol);
+	explicit RegExpSymbol(const alphabet::Symbol& symbol);
+	explicit RegExpSymbol(alphabet::Symbol&& symbol);
 	
 	RegExpSymbol(const RegExpSymbol& other);
 	RegExpSymbol(RegExpSymbol&& other) noexcept;
@@ -72,7 +74,7 @@ public:
 	/**
 	 * Returns the string representation of RegExp Symbol.
 	 */
-	const std::string& getSymbol() const;
+	const alphabet::Symbol& getSymbol() const;
 
 	/**
 	 * @copydoc RegExpElement::isEmpty() const
@@ -83,3 +85,4 @@ public:
 } /* namespace regexp */
 
 #endif /* REG_EXP_SYMBOL_H_ */
+
diff --git a/alib2/src/regexp/RegExpToStringComposer.cpp b/alib2/src/regexp/RegExpToStringComposer.cpp
index d2a7bc73c718d05156232f50183fdc5181935e48..ac09f0a0627c0d5674e8b141e769d93baaa1ec3c 100644
--- a/alib2/src/regexp/RegExpToStringComposer.cpp
+++ b/alib2/src/regexp/RegExpToStringComposer.cpp
@@ -78,14 +78,13 @@ void RegExpToStringComposer::Visit(void* userData, const RegExpSymbol& symbol) {
 			index += with.length();
 		}
 	};
-	
-	if( std::any_of(symbol.getSymbol().begin(), symbol.getSymbol().end(), testEscape) ) {
-		std::string tmp = symbol.getSymbol();
+	std::string tmp = (std::string) symbol.getSymbol();	
+	if( std::any_of(tmp.begin(), tmp.end(), testEscape) ) {
 		replace(tmp, "\\", "\\\\" );
 		replace(tmp, "\"", "\\\"" );
 		out << '"' << tmp << '"';
 	} else {
-		out << symbol.getSymbol();
+		out << tmp;
 	}
 }
 
diff --git a/alib2/src/regexp/RegExpToXMLComposer.cpp b/alib2/src/regexp/RegExpToXMLComposer.cpp
index fa4d304f5a3fb03f070ab8d9e97fcf94094cee56..adb9e5314633cf588f18bca8a9d244eff4203030 100644
--- a/alib2/src/regexp/RegExpToXMLComposer.cpp
+++ b/alib2/src/regexp/RegExpToXMLComposer.cpp
@@ -17,7 +17,7 @@ void RegExpToXMLComposer::Visit(void* userData, const RegExp& regexp) {
 		out.push_back(sax::Token("alphabet", sax::Token::START_ELEMENT));
 		for (const auto& symbol: regexp.getAlphabet()) {
 			out.push_back(sax::Token("symbol", sax::Token::START_ELEMENT));
-			out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER));
+			out.push_back(sax::Token((std::string) symbol, sax::Token::CHARACTER));
 			out.push_back(sax::Token("symbol", sax::Token::END_ELEMENT));
 		}
 		out.push_back(sax::Token("alphabet", sax::Token::END_ELEMENT));
@@ -70,7 +70,7 @@ void RegExpToXMLComposer::Visit(void* userData, const RegExpSymbol& symbol) {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
 	out.push_back(sax::Token("symbol", sax::Token::START_ELEMENT));
-	out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER));
+	out.push_back(sax::Token((std::string) symbol.getSymbol(), sax::Token::CHARACTER));
 	out.push_back(sax::Token("symbol", sax::Token::END_ELEMENT));
 }
 
diff --git a/alib2/src/string/StringFromStringParser.cpp b/alib2/src/string/StringFromStringParser.cpp
index 008f48709745775e7065dc9c5fc4c2a670c7fb83..153aed88ee45c28203a47f25a56c5e0e02cb26fb 100644
--- a/alib2/src/string/StringFromStringParser.cpp
+++ b/alib2/src/string/StringFromStringParser.cpp
@@ -1,6 +1,9 @@
 #include "StringFromStringParser.h"
 #include "../AlibException.h"
 #include "Epsilon.h"
+#include "../label/StringLabel.h"
+#include "../label/Label.h"
+#include "../alphabet/LabeledSymbol.h"
 
 namespace string {
 
@@ -24,7 +27,7 @@ std::vector<alphabet::Symbol> StringFromStringParser::parseContent() {
   while(token.type == StringFromStringLexer::SYMBOL) {
     std::string symbol = token.value;
     m_Lexer.next();
-    data.push_back(alphabet::Symbol(symbol));
+    data.push_back(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(symbol)))));
   }
   return data;
 }
diff --git a/alib2/src/string/StringFromXMLParser.cpp b/alib2/src/string/StringFromXMLParser.cpp
index 487f6267d9a595283e05468c2db92b24ab88536a..d0d7c3898842b636a40c98a457a8e6591b2354fa 100644
--- a/alib2/src/string/StringFromXMLParser.cpp
+++ b/alib2/src/string/StringFromXMLParser.cpp
@@ -8,6 +8,9 @@
 #include "StringFromXMLParser.h"
 #include "../sax/ParserException.h"
 #include "Epsilon.h"
+#include "../label/StringLabel.h"
+#include "../label/Label.h"
+#include "../alphabet/LabeledSymbol.h"
 
 namespace string {
 
@@ -36,7 +39,7 @@ alphabet::Symbol StringFromXMLParser::parseSymbol(std::list<sax::Token>& input)
 	popToken(input, sax::Token::START_ELEMENT, "symbol");
 
 	if (input.front().getType() == sax::Token::CHARACTER) {
-		alphabet::Symbol symbol = alphabet::Symbol(input.front().getData());
+		alphabet::Symbol symbol = alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel(input.front().getData()))));
 		input.pop_front();
 		popToken(input, sax::Token::END_ELEMENT, "symbol");
 		return symbol;
diff --git a/alib2/src/string/StringToStringComposer.cpp b/alib2/src/string/StringToStringComposer.cpp
index 748f74072b5fadf003145472b307082c74887761..0c605bd62ffc5016cd41410b2e89cca715e412fd 100644
--- a/alib2/src/string/StringToStringComposer.cpp
+++ b/alib2/src/string/StringToStringComposer.cpp
@@ -7,6 +7,8 @@
 
 #include "StringToStringComposer.h"
 #include <algorithm>
+#include "../label/LabelBase.h"
+#include "../alphabet/LabeledSymbol.h"
 
 namespace string {
 
@@ -24,13 +26,13 @@ void StringToStringComposer::Visit(std::stringstream& out, const alphabet::Symbo
 		}
 	};
 	
-	if( std::any_of(symbol.getSymbol().begin(), symbol.getSymbol().end(), testEscape) ) {
-		std::string tmp = symbol.getSymbol();
+	std::string tmp = (std::string) symbol;	
+	if( std::any_of(tmp.begin(), tmp.end(), testEscape) ) {
 		replace(tmp, "\\", "\\\\" );
 		replace(tmp, "\"", "\\\"" );
 		out << '"' << tmp << '"';
 	} else {
-		out << symbol.getSymbol();
+		out << tmp;
 	}
 }
 
@@ -41,7 +43,7 @@ void StringToStringComposer::Visit(std::stringstream& out, const String& string)
 			first = false;
 		else
 			out << ' ';
-  
+
 		Visit(out, symbol);
 	}
 }
diff --git a/alib2/src/string/StringToXMLComposer.cpp b/alib2/src/string/StringToXMLComposer.cpp
index c8fbd88dabf42ae77bdb9a825494d29f070121da..67d4a75b18e70a7c0b4b41ab8e58990d91418fc0 100644
--- a/alib2/src/string/StringToXMLComposer.cpp
+++ b/alib2/src/string/StringToXMLComposer.cpp
@@ -6,12 +6,13 @@
  */
 
 #include "StringToXMLComposer.h"
+#include "../alphabet/LabeledSymbol.h"
 
 namespace string {
 
 void StringToXMLComposer::Visit(std::list<sax::Token>& out, const alphabet::Symbol& symbol) {
 	out.push_back(sax::Token("symbol", sax::Token::START_ELEMENT));
-	out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER));
+	out.push_back(sax::Token((std::string) symbol, sax::Token::CHARACTER));
 	out.push_back(sax::Token("symbol", sax::Token::END_ELEMENT));
 }
 
diff --git a/alib2/test-src/automaton/AutomatonTest.cpp b/alib2/test-src/automaton/AutomatonTest.cpp
index 9519029dbf9cca96d0910004a103ac17e2722835..6b92539852146b1208b10e4140845c145c510d5e 100644
--- a/alib2/test-src/automaton/AutomatonTest.cpp
+++ b/alib2/test-src/automaton/AutomatonTest.cpp
@@ -12,6 +12,10 @@
 
 #include "factory/AutomatonFactory.h"
 
+#include "label/StringLabel.h"
+#include "label/Label.h"
+#include "alphabet/LabeledSymbol.h"
+
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
 CPPUNIT_TEST_SUITE_REGISTRATION( AutomatonTest );
@@ -25,7 +29,7 @@ void AutomatonTest::tearDown() {
 void AutomatonTest::testXMLParser() {
   automaton::UnknownAutomaton automaton;
   automaton.setStates({automaton::State("1"), automaton::State("2"), automaton::State("3")});
-  automaton.setInputSymbols({alphabet::Symbol("a"), alphabet::Symbol("b")});
+  automaton.setInputSymbols({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b"))))});
   automaton.addTransition(automaton::UnknownTransition());
   
   CPPUNIT_ASSERT( automaton == automaton );
@@ -56,11 +60,11 @@ void AutomatonTest::testDFAParser() {
   automaton.addState(automaton::State("1"));
   automaton.addState(automaton::State("2"));
   automaton.addState(automaton::State("3"));
-  automaton.addInputSymbol(alphabet::Symbol("a"));
-  automaton.addInputSymbol(alphabet::Symbol("b"));
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))));
+  automaton.addInputSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))));
   
-  automaton.addTransition(automaton::State("1"), alphabet::Symbol("a"), automaton::State("2"));
-  automaton.addTransition(automaton::State("2"), alphabet::Symbol("b"), automaton::State("1"));
+  automaton.addTransition(automaton::State("1"), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("a")))), automaton::State("2"));
+  automaton.addTransition(automaton::State("2"), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("b")))), automaton::State("1"));
 
   automaton.addFinalState(automaton::State("3"));
   
diff --git a/alib2/test-src/regexp/RegExpTest.cpp b/alib2/test-src/regexp/RegExpTest.cpp
index b330ccf7177a7b2f48553b57ca3efb024f419d5d..7d45f528a872f569e433cf75503617afae02b426 100644
--- a/alib2/test-src/regexp/RegExpTest.cpp
+++ b/alib2/test-src/regexp/RegExpTest.cpp
@@ -12,6 +12,8 @@
 
 #include "factory/RegExpFactory.h"
 
+#include "label/StringLabel.h"
+
 #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y))
 
 CPPUNIT_TEST_SUITE_REGISTRATION( RegExpTest );
@@ -24,14 +26,14 @@ void RegExpTest::tearDown() {
 
 void RegExpTest::testCopyConstruct() {
   regexp::RegExp regexp;
-  regexp.setAlphabet({alphabet::Symbol("1"), alphabet::Symbol("2"), alphabet::Symbol("3")});
+  regexp.setAlphabet({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))});
   regexp.setRegExp(regexp::Alternation(
 		regexp::Concatenation(
-			regexp::RegExpSymbol("1"),
-			regexp::RegExpSymbol("2")
+			regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))),
+			regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))))
 				     ),
 		regexp::Iteration(
-			regexp::RegExpSymbol("1")
+			regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))))
 				 )
 			   )
 		       );
@@ -50,7 +52,7 @@ void RegExpTest::testEqual() {
   
   regexp::RegExpFromStringParser parser(input);
   regexp::RegExp regexp = parser.parse();
-  
+
   regexp::RegExpToStringComposer composer;
   std::string output = composer.compose(regexp);
   
@@ -63,14 +65,14 @@ void RegExpTest::testEqual() {
 void RegExpTest::testXMLParser() {
   
   regexp::RegExp regexp;
-  regexp.setAlphabet({alphabet::Symbol("1"), alphabet::Symbol("2"), alphabet::Symbol("3")});
+  regexp.setAlphabet({alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))), alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3"))))});
   regexp.setRegExp(regexp::Alternation(
 		regexp::Concatenation(
-			regexp::RegExpSymbol("1"),
-			regexp::RegExpSymbol("2")
+			regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1"))))),
+			regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))))
 				     ),
 		regexp::Iteration(
-			regexp::RegExpSymbol("1")
+			regexp::RegExpSymbol(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))))
 				 )
 			   )
 		       );
@@ -97,7 +99,7 @@ void RegExpTest::testXMLParser() {
 }
 
 void RegExpTest::testOrder() {
-  regexp::RegExpSymbol s1("1");
+  regexp::RegExpSymbol s1(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))));
   regexp::RegExpEmpty e1;
   regexp::RegExpEpsilon e2;
   regexp::Iteration i1(s1);
@@ -271,9 +273,9 @@ void RegExpTest::testOrder() {
 }
 
 void RegExpTest::testOrder2() {
-  regexp::RegExpSymbol s1("1");
-  regexp::RegExpSymbol s2("2");
-  regexp::RegExpSymbol s3("3");
+  regexp::RegExpSymbol s1(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))));
+  regexp::RegExpSymbol s2(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("2")))));
+  regexp::RegExpSymbol s3(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("3")))));
   
   regexp::RegExpEmpty e1;
   regexp::RegExpEpsilon e2;