diff --git a/astat2/src/AutomataStat.h b/astat2/src/AutomataStat.h
index f8fa347612ed441961ee372f76d3f0513f57f4d6..4b1af31fa767b3db73465ccb2bcbfb6e06e068c6 100644
--- a/astat2/src/AutomataStat.h
+++ b/astat2/src/AutomataStat.h
@@ -9,26 +9,25 @@
 #define AUTOMATA_STAT_H_
 
 #include <common/multipleDispatch.hpp>
-#include <algorithm>
-#include <deque>
-#include <set>
 
 #include "automaton/Automaton.h"
-#include <automaton/common/State.h>
+#include "automaton/AutomatonFeatures.h"
 
 #include "AutomataSettings.h"
 
-class AutomataStat : public std::SingleDispatchLastStaticParam<void, automaton::AutomatonBase, const AutomataSettings&> {
+class AutomataStat : public std::SingleDispatchLastStaticParam < void, automaton::AutomatonBase, const AutomataSettings & > {
 public:
-	static void stat(const automaton::Automaton& automaton, const AutomataSettings& settings);
+	static void stat ( const automaton::Automaton & automaton, const AutomataSettings & settings );
 
-	static void stat(const automaton::NFA& automaton, const AutomataSettings& settings);
-	static void stat(const automaton::DFA& automaton, const AutomataSettings& settings);
+	static void stat ( const automaton::NFA & automaton, const AutomataSettings & settings );
+	static void stat ( const automaton::DFA & automaton, const AutomataSettings & settings );
 
-	static AutomataStat& getInstance() {
+	static AutomataStat & getInstance ( ) {
 		static AutomataStat res;
+
 		return res;
 	}
+
 };
 
 #endif /* AUTOMATA_STAT_H_ */
diff --git a/astat2/src/GrammarSettings.h b/astat2/src/GrammarSettings.h
index ece01e5b7a53658fcbd099fd9322b3b997413d71..2748bfb6c2ef02d46dfbfc87d0b2560c6d3d0dc8 100644
--- a/astat2/src/GrammarSettings.h
+++ b/astat2/src/GrammarSettings.h
@@ -13,7 +13,7 @@
 struct GrammarSettings {
 	PrintingOptions nonterminals;
 	PrintingOptions terminals;
-	PrintingOptions initialNonterminal;
+	PrintingOptions initialSymbols;
 	PrintingOptions rules;
 };
 
diff --git a/astat2/src/GrammarStat.cpp b/astat2/src/GrammarStat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c7bd92082ea0c1976b942c70a0ba7b4753b44936
--- /dev/null
+++ b/astat2/src/GrammarStat.cpp
@@ -0,0 +1,176 @@
+/*
+ * GrammarStat.cpp
+ *
+ *  Created on: 20. 9. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "GrammarStat.h"
+
+#include <exception/AlibException.h>
+
+#include <grammar/Regular/RightRG.h>
+#include <grammar/Regular/RightLG.h>
+
+#include <factory/XmlDataFactory.hpp>
+#include <container/ObjectsSet.h>
+#include <container/ObjectsMap.h>
+#include <container/ObjectsVariant.h>
+#include <container/ObjectsVector.h>
+#include <iostream>
+
+void GrammarStat::stat ( const grammar::Grammar & grammar, const GrammarSettings & settings ) {
+	getInstance ( ).dispatch ( grammar.getData ( ), settings );
+}
+
+void GrammarStat::stat ( const grammar::RightRG & grammar, const GrammarSettings & settings ) {
+	switch ( settings.nonterminals ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getNonterminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << grammar.getNonterminalAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << grammar.getNonterminalAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getNonterminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.terminals ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getTerminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << grammar.getTerminalAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << grammar.getTerminalAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getTerminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.initialSymbols ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getInitialSymbol ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << 1 << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << 1 << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getInitialSymbol ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.rules ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getRules ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << grammar.getRules ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << grammar.getRules ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getRules ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto GrammarStatRightRG = GrammarStat::RegistratorWrapper < void, grammar::RightRG > ( GrammarStat::getInstance ( ), GrammarStat::stat );
+
+void GrammarStat::stat ( const grammar::RightLG & grammar, const GrammarSettings & settings ) {
+	switch ( settings.nonterminals ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getNonterminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << grammar.getNonterminalAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << grammar.getNonterminalAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getNonterminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.terminals ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getTerminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << grammar.getTerminalAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << grammar.getTerminalAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getTerminalAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.initialSymbols ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getInitialSymbol ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << 1 << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << 1 << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getInitialSymbol ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.rules ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( grammar.getRules ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << grammar.getRules ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << grammar.getRules ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( grammar.getRules ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto GrammarStatRightLG = GrammarStat::RegistratorWrapper < void, grammar::RightLG > ( GrammarStat::getInstance ( ), GrammarStat::stat );
diff --git a/astat2/src/GrammarStat.h b/astat2/src/GrammarStat.h
index 690dbbab8f09470df92d53589439f8fe166acac1..a40c2a8d25af34dd94c28b0d72d667c6f704ced7 100644
--- a/astat2/src/GrammarStat.h
+++ b/astat2/src/GrammarStat.h
@@ -8,9 +8,26 @@
 #ifndef GRAMMAR_STAT_H_
 #define GRAMMAR_STAT_H_
 
+#include <common/multipleDispatch.hpp>
+
 #include "grammar/Grammar.h"
+#include "grammar/GrammarFeatures.h"
 
 #include "GrammarSettings.h"
 
+class GrammarStat : public std::SingleDispatchLastStaticParam < void, grammar::GrammarBase, const GrammarSettings & > {
+public:
+	static void stat ( const grammar::Grammar & grammar, const GrammarSettings & settings );
+
+	static void stat ( const grammar::RightRG & grammar, const GrammarSettings & settings );
+	static void stat ( const grammar::RightLG & grammar, const GrammarSettings & settings );
+
+	static GrammarStat & getInstance ( ) {
+		static GrammarStat res;
+
+		return res;
+	}
+
+};
 
 #endif /* GRAMMAR_STAT_H_ */
diff --git a/astat2/src/RegExpStat.cpp b/astat2/src/RegExpStat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0c0a858f3862851d0075c186d27f40ffd8700c6
--- /dev/null
+++ b/astat2/src/RegExpStat.cpp
@@ -0,0 +1,109 @@
+/*
+ * RegExpStat.cpp
+ *
+ *  Created on: 20. 9. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "RegExpStat.h"
+
+#include <exception/AlibException.h>
+
+#include <regexp/formal/FormalRegExp.h>
+#include <regexp/unbounded/UnboundedRegExp.h>
+
+#include <factory/XmlDataFactory.hpp>
+#include <iostream>
+#include <container/ObjectsSet.h>
+
+void RegExpStat::stat ( const regexp::RegExp & regexp, const RegExpSettings & settings ) {
+	getInstance ( ).dispatch ( regexp.getData ( ), settings );
+}
+
+unsigned RegExpStat::countNodes ( const regexp::FormalRegExpElement & ) {
+	throw exception::AlibException ( "unimplemented" );
+}
+
+void RegExpStat::stat ( const regexp::FormalRegExp & regexp, const RegExpSettings & settings ) {
+	switch ( settings.alphabet ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( regexp.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << regexp.getAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << regexp.getAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( regexp.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.nodes ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( & regexp.getRegExp ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << countNodes ( regexp.getRegExp ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		alib::XmlDataFactory::toStdout ( & regexp.getRegExp ( ) );
+		std::cout << countNodes ( regexp.getRegExp ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto RegExpStatFormalRegExp = RegExpStat::RegistratorWrapper < void, regexp::FormalRegExp > ( RegExpStat::getInstance ( ), RegExpStat::stat );
+
+unsigned RegExpStat::countNodes ( const regexp::UnboundedRegExpElement & ) {
+	throw exception::AlibException ( "unimplemented" );
+}
+
+void RegExpStat::stat ( const regexp::UnboundedRegExp & regexp, const RegExpSettings & settings ) {
+	switch ( settings.alphabet ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( regexp.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << regexp.getAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << regexp.getAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( regexp.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.nodes ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( & regexp.getRegExp ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << countNodes ( regexp.getRegExp ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		alib::XmlDataFactory::toStdout ( & regexp.getRegExp ( ) );
+		std::cout << countNodes ( regexp.getRegExp ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto RegExpStatUnboundedRegExp = RegExpStat::RegistratorWrapper < void, regexp::UnboundedRegExp > ( RegExpStat::getInstance ( ), RegExpStat::stat );
diff --git a/astat2/src/RegExpStat.h b/astat2/src/RegExpStat.h
index be57cf81e5e495bbe4a937dae79aea40a3fe8da9..4c777d2728fb033da41894a9616c90c47f80dfe3 100644
--- a/astat2/src/RegExpStat.h
+++ b/astat2/src/RegExpStat.h
@@ -5,12 +5,33 @@
  *	  Author: Jan Travnicek
  */
 
-#ifndef REG_EXP_STATS_H_
-#define REG_EXP_STATS_H_
+#ifndef REG_EXP_STAT_H_
+#define REG_EXP_STAT_H_
+
+#include <common/multipleDispatch.hpp>
 
 #include "regexp/RegExp.h"
+#include "regexp/RegExpFeatures.h"
 
 #include "RegExpSettings.h"
 
+class RegExpStat : public std::SingleDispatchLastStaticParam < void, regexp::RegExpBase, const RegExpSettings & > {
+	static unsigned countNodes ( const regexp::FormalRegExpElement & node );
+
+	static unsigned countNodes ( const regexp::UnboundedRegExpElement & node );
+
+public:
+	static void stat ( const regexp::RegExp & regexp, const RegExpSettings & settings );
+
+	static void stat ( const regexp::UnboundedRegExp & regexp, const RegExpSettings & settings );
+	static void stat ( const regexp::FormalRegExp & regexp, const RegExpSettings & settings );
+
+	static RegExpStat & getInstance ( ) {
+		static RegExpStat res;
+
+		return res;
+	}
+
+};
 
-#endif /* REG_EXP_STATS_H_ */
+#endif /* REG_EXP_STAT_H_ */
diff --git a/astat2/src/StringSettings.h b/astat2/src/StringSettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ef4519431289c615c8ad07fd69412504b247060
--- /dev/null
+++ b/astat2/src/StringSettings.h
@@ -0,0 +1,18 @@
+/*
+ * StringSettings.h
+ *
+ *  Created on: 26. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef __STRING_SETTINGS_H__
+#define __STRING_SETTINGS_H__
+
+#include "PrintingOptions.h"
+
+struct StringSettings {
+	PrintingOptions content;
+	PrintingOptions alphabet;
+};
+
+#endif /* __STRING_SETTINGS_H__ */
diff --git a/astat2/src/StringStat.cpp b/astat2/src/StringStat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..45fed42d1df6c4093e0fcab19406edd6341bdebd
--- /dev/null
+++ b/astat2/src/StringStat.cpp
@@ -0,0 +1,102 @@
+/*
+ * StringStat.cpp
+ *
+ *  Created on: 20. 9. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "StringStat.h"
+
+#include <exception/AlibException.h>
+
+#include <string/LinearString.h>
+#include <string/CyclicString.h>
+
+#include <factory/XmlDataFactory.hpp>
+#include <iostream>
+#include <container/ObjectsSet.h>
+#include <container/ObjectsVector.h>
+
+void StringStat::stat ( const string::String & string, const StringSettings & settings ) {
+	getInstance ( ).dispatch ( string.getData ( ), settings );
+}
+
+void StringStat::stat ( const string::LinearString & string, const StringSettings & settings ) {
+	switch ( settings.alphabet ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( string.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << string.getAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << string.getAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( string.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.content ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( string.getContent ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << string.getContent ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		alib::XmlDataFactory::toStdout ( string.getContent ( ) );
+		std::cout << string.getContent ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto StringStatFormalString = StringStat::RegistratorWrapper < void, string::LinearString > ( StringStat::getInstance ( ), StringStat::stat );
+
+void StringStat::stat ( const string::CyclicString & string, const StringSettings & settings ) {
+	switch ( settings.alphabet ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( string.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << string.getAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << string.getAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( string.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.content ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( string.getContent ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << string.getContent ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		alib::XmlDataFactory::toStdout ( string.getContent ( ) );
+		std::cout << string.getContent ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto StringStatUnboundedString = StringStat::RegistratorWrapper < void, string::CyclicString > ( StringStat::getInstance ( ), StringStat::stat );
diff --git a/astat2/src/StringStat.h b/astat2/src/StringStat.h
new file mode 100644
index 0000000000000000000000000000000000000000..dbe31a89762c05a402b38222735cd969321f0bf2
--- /dev/null
+++ b/astat2/src/StringStat.h
@@ -0,0 +1,33 @@
+/*
+ * StringStat.h
+ *
+ *  Created on: 20. 9. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef STRING_STAT_H_
+#define STRING_STAT_H_
+
+#include <common/multipleDispatch.hpp>
+
+#include "string/String.h"
+#include "string/StringFeatures.h"
+
+#include "StringSettings.h"
+
+class StringStat : public std::SingleDispatchLastStaticParam < void, string::StringBase, const StringSettings & > {
+public:
+	static void stat ( const string::String & string, const StringSettings & settings );
+
+	static void stat ( const string::LinearString & string, const StringSettings & settings );
+	static void stat ( const string::CyclicString & string, const StringSettings & settings );
+
+	static StringStat & getInstance ( ) {
+		static StringStat res;
+
+		return res;
+	}
+
+};
+
+#endif /* STRING_STAT_H_ */
diff --git a/astat2/src/TreeSettings.h b/astat2/src/TreeSettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..105703de36d8720539a2897785f12dd3ee0c5276
--- /dev/null
+++ b/astat2/src/TreeSettings.h
@@ -0,0 +1,18 @@
+/*
+ * TreeSettings.h
+ *
+ *  Created on: 26. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef __TREE_SETTINGS_H__
+#define __TREE_SETTINGS_H__
+
+#include "PrintingOptions.h"
+
+struct TreeSettings {
+	PrintingOptions nodes;
+	PrintingOptions alphabet;
+};
+
+#endif /* __TREE_SETTINGS_H__ */
diff --git a/astat2/src/TreeStat.cpp b/astat2/src/TreeStat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fe6e982d812d12906244d02c1c8db59f4ebd12eb
--- /dev/null
+++ b/astat2/src/TreeStat.cpp
@@ -0,0 +1,119 @@
+/*
+ * TreeStat.cpp
+ *
+ *  Created on: 20. 9. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "TreeStat.h"
+
+#include <exception/AlibException.h>
+
+#include <tree/ranked/RankedTree.h>
+#include <tree/unranked/UnrankedTree.h>
+
+#include <factory/XmlDataFactory.hpp>
+#include <iostream>
+#include <container/ObjectsSet.h>
+
+void TreeStat::stat ( const tree::Tree & tree, const TreeSettings & settings ) {
+	getInstance ( ).dispatch ( tree.getData ( ), settings );
+}
+
+unsigned TreeStat::countNodes ( const tree::RankedNode & node ) {
+	unsigned res = 1;
+
+	for ( const tree::RankedNode * child : node.getChildren ( ) )
+		res += countNodes ( * child );
+
+	return res;
+}
+
+void TreeStat::stat ( const tree::RankedTree & tree, const TreeSettings & settings ) {
+	switch ( settings.alphabet ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( tree.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << tree.getAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << tree.getAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( tree.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.nodes ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( & tree.getRoot ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << countNodes ( tree.getRoot ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		alib::XmlDataFactory::toStdout ( & tree.getRoot ( ) );
+		std::cout << countNodes ( tree.getRoot ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto TreeStatFormalTree = TreeStat::RegistratorWrapper < void, tree::RankedTree > ( TreeStat::getInstance ( ), TreeStat::stat );
+
+unsigned TreeStat::countNodes ( const tree::UnrankedNode & node ) {
+	unsigned res = 1;
+
+	for ( const tree::UnrankedNode * child : node.getChildren ( ) )
+		res += countNodes ( * child );
+
+	return res;
+}
+
+void TreeStat::stat ( const tree::UnrankedTree & tree, const TreeSettings & settings ) {
+	switch ( settings.alphabet ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( tree.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << tree.getAlphabet ( ).size ( ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		std::cout << tree.getAlphabet ( ).size ( ) << std::endl;
+		alib::XmlDataFactory::toStdout ( tree.getAlphabet ( ) );
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+
+	switch ( settings.nodes ) {
+	case PrintingOptions::PRINT:
+		alib::XmlDataFactory::toStdout ( & tree.getRoot ( ) );
+		break;
+
+	case PrintingOptions::QUANTITY:
+		std::cout << countNodes ( tree.getRoot ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::BOTH:
+		alib::XmlDataFactory::toStdout ( & tree.getRoot ( ) );
+		std::cout << countNodes ( tree.getRoot ( ) ) << std::endl;
+		break;
+
+	case PrintingOptions::NOOP:
+		break;
+	}
+}
+
+auto TreeStatUnboundedTree = TreeStat::RegistratorWrapper < void, tree::UnrankedTree > ( TreeStat::getInstance ( ), TreeStat::stat );
diff --git a/astat2/src/TreeStat.h b/astat2/src/TreeStat.h
new file mode 100644
index 0000000000000000000000000000000000000000..f877729cb18684b92752582d7de26a62adcda7f2
--- /dev/null
+++ b/astat2/src/TreeStat.h
@@ -0,0 +1,37 @@
+/*
+ * TreeStat.h
+ *
+ *  Created on: 20. 9. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef TREE_STAT_H_
+#define TREE_STAT_H_
+
+#include <common/multipleDispatch.hpp>
+
+#include "tree/Tree.h"
+#include "tree/TreeFeatures.h"
+
+#include "TreeSettings.h"
+
+class TreeStat : public std::SingleDispatchLastStaticParam < void, tree::TreeBase, const TreeSettings & > {
+	static unsigned countNodes ( const tree::RankedNode & node );
+
+	static unsigned countNodes ( const tree::UnrankedNode & node );
+
+public:
+	static void stat ( const tree::Tree & tree, const TreeSettings & settings );
+
+	static void stat ( const tree::RankedTree & tree, const TreeSettings & settings );
+	static void stat ( const tree::UnrankedTree & tree, const TreeSettings & settings );
+
+	static TreeStat & getInstance ( ) {
+		static TreeStat res;
+
+		return res;
+	}
+
+};
+
+#endif /* TREE_STAT_H_ */
diff --git a/astat2/src/astat.cpp b/astat2/src/astat.cpp
index 0570db9ed967b4e89107657b6bf8afc46cd985c0..e036c8dc61cb3f0700e6c2f759a9da7b53ce8b5b 100644
--- a/astat2/src/astat.cpp
+++ b/astat2/src/astat.cpp
@@ -14,139 +14,259 @@
 #include "AutomataStat.h"
 #include "GrammarStat.h"
 #include "RegExpStat.h"
+#include "StringStat.h"
+#include "TreeStat.h"
 #include "SetStat.h"
 
-PrintingOptions translatePrintingOptions(std::string value) {
-	if(value == "noop") {
+PrintingOptions translatePrintingOptions ( std::string value ) {
+	if ( value == "noop" )
 		return PrintingOptions::NOOP;
-	} else if(value == "print") {
+	else if ( value == "print" )
 		return PrintingOptions::PRINT;
-	} else if(value == "quantity") {
+	else if ( value == "quantity" )
 		return PrintingOptions::QUANTITY;
-	} else if(value == "both") {
+	else if ( value == "both" )
 		return PrintingOptions::BOTH;
-	} else {
-		throw exception::AlibException("Invalid Argument in translate printing options (" + value + ")");
-	}
+	else
+		throw exception::AlibException ( "Invalid Argument in translate printing options (" + value + ")" );
 }
 
-int main(int argc, char* argv[]) {
+int main ( int argc, char * argv[] ) {
 	try {
-		TCLAP::CmdLine cmd("Prints usefull information about automata, grammars, regexps, ...", ' ', "0.01");
+		TCLAP::CmdLine cmd ( "Prints usefull information about automata, grammars, regexps, ...", ' ', "0.01" );
+
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+		std::vector < std::string > allowedPrintingOptions {
+			"noop", "print", "size", "both"
+		};
+		TCLAP::ValuesConstraint < std::string > allowedPrintingOptionsVals ( allowedPrintingOptions );
+
+		TCLAP::ValueArg < std::string > presentation ( "p", "presentation", "How to print data", true, "noop", & allowedPrintingOptionsVals );
+		cmd.add ( presentation );
+
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+		std::vector < std::string > automatonPrintingOptions {
+			"states", "finalStates", "initialStates", "inputAlphabet", "transitions"
+		};
+		TCLAP::ValuesConstraint < std::string > automatonPrintingOptionsVals ( automatonPrintingOptions );
+
+		TCLAP::MultiArg < std::string > automaton ( "", "automaton", "Display stats of automata", false, & automatonPrintingOptionsVals );
+
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+		std::vector < std::string > grammarPrintingOptions {
+			"nonterminals", "terminals", "initialSymbols", "rules"
+		};
+		TCLAP::ValuesConstraint < std::string > grammarPrintingOptionsVals ( grammarPrintingOptions );
+
+		TCLAP::MultiArg < std::string > grammar ( "", "grammar", "Display stats of grammars", false, & grammarPrintingOptionsVals );
 
-		std::vector<std::string> allowedPrintingOptions {"noop", "print", "quantity", "both"};
-		TCLAP::ValuesConstraint<std::string> allowedPrintingOptionsVals( allowedPrintingOptions );
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-		std::vector<std::string> automataPrintingOptions {"states", "finalStates", "initialStates", "inputAlphabet", "transitions"};
-		TCLAP::ValuesConstraint<std::string> automataPrintingOptionsVals( automataPrintingOptions );
+		std::vector < std::string > regexpPrintingOptions {
+			"alphabet", "nodes"
+		};
+		TCLAP::ValuesConstraint < std::string > regexpPrintingOptionsVals ( regexpPrintingOptions );
 
-		TCLAP::ValueArg<std::string> presentation(	"p",	"presentation",	"How to print data",		true,	"noop",	&allowedPrintingOptionsVals );
-		cmd.add(presentation);
+		TCLAP::MultiArg < std::string > regexp ( "", "regexp", "Display stats of regexps", false, & regexpPrintingOptionsVals );
 
-		TCLAP::MultiArg<std::string> automaton(		"a",	"automaton",	"Display stats of automata",	false,	&automataPrintingOptionsVals);
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-		TCLAP::SwitchArg setContainer(			"s",	"set",		"Display stats of sets",	false);
+		std::vector < std::string > stringPrintingOptions {
+			"alphabet", "content"
+		};
+		TCLAP::ValuesConstraint < std::string > stringPrintingOptionsVals ( stringPrintingOptions );
 
-		std::vector<TCLAP::Arg*> xorlist;
-		xorlist.push_back(&automaton);
-		xorlist.push_back(&setContainer);
-		cmd.xorAdd( xorlist );
+		TCLAP::MultiArg < std::string > string ( "", "string", "Display stats of strings", false, & stringPrintingOptionsVals );
 
-		TCLAP::ValueArg<std::string> file(		"i",	"input",	"Read from file",		false,	"-",	"file");
-		cmd.add( file );
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-		TCLAP::SwitchArg measure(		"m",	"measure",	"Measure times",		false);
-		cmd.add( measure );
+		std::vector < std::string > treePrintingOptions {
+			"alphabet", "nodes"
+		};
+		TCLAP::ValuesConstraint < std::string > treePrintingOptionsVals ( treePrintingOptions );
 
-		TCLAP::SwitchArg verbose(		"v",	"verbose",	"Be verbose",			false);
-		cmd.add( verbose );
+		TCLAP::MultiArg < std::string > tree ( "", "tree", "Display stats of trees", false, & treePrintingOptionsVals );
 
-		cmd.parse(argc, argv);
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-		std::chrono::measurements::start("Overal", std::chrono::measurements::Type::OVERALL);
-		std::chrono::measurements::start("Input read", std::chrono::measurements::Type::AUXILARY);
+		TCLAP::SwitchArg set ( "", "set", "Display stats of sets", false );
 
-		PrintingOptions printingOption = translatePrintingOptions(presentation.getValue());
+		// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
-		std::deque<sax::Token> tokens;
-		if(file.isSet()) {
-			if(file.getValue() == "-") {
-				sax::SaxParseInterface::parseStdin(tokens);
-			} else {
-				sax::SaxParseInterface::parseFile(file.getValue(), tokens);
-			}
+		std::vector < TCLAP::Arg * > xorlist;
+		xorlist.push_back ( & automaton );
+		xorlist.push_back ( & grammar );
+		xorlist.push_back ( & regexp );
+		xorlist.push_back ( & string );
+		xorlist.push_back ( & tree );
+		xorlist.push_back ( & set );
+		cmd.xorAdd ( xorlist );
+
+		TCLAP::ValueArg < std::string > file ( "i", "input", "Read from file", false, "-", "file" );
+		cmd.add ( file );
+
+		TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false );
+		cmd.add ( measure );
+
+		TCLAP::SwitchArg verbose ( "v", "verbose", "Be verbose", false );
+		cmd.add ( verbose );
+
+		cmd.parse ( argc, argv );
+
+		std::chrono::measurements::start ( "Overal", std::chrono::measurements::Type::OVERALL );
+		std::chrono::measurements::start ( "Input read", std::chrono::measurements::Type::AUXILARY );
+
+		PrintingOptions printingOption = translatePrintingOptions ( presentation.getValue ( ) );
+
+		std::deque < sax::Token > tokens;
+
+		if ( file.isSet ( ) ) {
+			if ( file.getValue ( ) == "-" )
+				sax::SaxParseInterface::parseStdin ( tokens );
+			else
+				sax::SaxParseInterface::parseFile ( file.getValue ( ), tokens );
 		} else {
-			sax::SaxParseInterface::parseStdin(tokens);
+			sax::SaxParseInterface::parseStdin ( tokens );
 		}
 
-		if( alib::XmlDataFactory::first<automaton::Automaton>(tokens) && automaton.isSet()) {
-			AutomataSettings settings = {PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP };
-			std::set<std::string> values {automaton.getValue().begin(), automaton.getValue().end()};
+		if ( alib::XmlDataFactory::first < automaton::Automaton > ( tokens ) && automaton.isSet ( ) ) {
+			AutomataSettings settings = { PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP };
+			std::set < std::string > values {
+				automaton.getValue ( ).begin ( ), automaton.getValue ( ).end ( )
+			};
 
-			if(values.count("states")) {
+			if ( values.count ( "states" ) )
 				settings.states = printingOption;
-			}
-			if(values.count("finalStates")) {
+
+			if ( values.count ( "finalStates" ) )
 				settings.finalStates = printingOption;
-			}
-			if(values.count("initialStates")) {
+
+			if ( values.count ( "initialStates" ) )
 				settings.initialStates = printingOption;
-			}
-			if(values.count("inputAlphabet")) {
+
+			if ( values.count ( "inputAlphabet" ) )
 				settings.inputAlphabet = printingOption;
-			}
-			if(values.count("transitions")) {
+
+			if ( values.count ( "transitions" ) )
 				settings.transitions = printingOption;
-			}
 
-			automaton::Automaton automaton = alib::XmlDataFactory::fromTokens<automaton::Automaton>(tokens);
+			automaton::Automaton automaton = alib::XmlDataFactory::fromTokens < automaton::Automaton > ( tokens );
+
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Stats print", std::chrono::measurements::Type::MAIN );
+
+			AutomataStat::stat ( automaton, settings );
+		} else if ( alib::XmlDataFactory::first < grammar::Grammar > ( tokens ) && grammar.isSet ( ) ) {
+			GrammarSettings settings = { PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP, PrintingOptions::NOOP };
+			std::set < std::string > values {
+				grammar.getValue ( ).begin ( ), grammar.getValue ( ).end ( )
+			};
+
+			if ( values.count ( "nonterminals" ) )
+				settings.nonterminals = printingOption;
+
+			if ( values.count ( "terminals" ) )
+				settings.terminals = printingOption;
+
+			if ( values.count ( "initialSymbols" ) )
+				settings.initialSymbols = printingOption;
+
+			if ( values.count ( "rules" ) )
+				settings.rules = printingOption;
+
+			grammar::Grammar grammar = alib::XmlDataFactory::fromTokens < grammar::Grammar > ( tokens );
+
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Stats print", std::chrono::measurements::Type::MAIN );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Stats print", std::chrono::measurements::Type::MAIN);
+			GrammarStat::stat ( grammar, settings );
+		} else if ( alib::XmlDataFactory::first < regexp::RegExp > ( tokens ) && regexp.isSet ( ) ) {
+			RegExpSettings settings = { PrintingOptions::NOOP, PrintingOptions::NOOP };
+			std::set < std::string > values {
+				regexp.getValue ( ).begin ( ), regexp.getValue ( ).end ( )
+			};
 
-			AutomataStat::stat(automaton, settings);
-		} else if( alib::XmlDataFactory::first<grammar::Grammar>(tokens) /* && grammar.isSet() */) {
+			if ( values.count ( "alphabet" ) )
+				settings.alphabet = printingOption;
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Stats print", std::chrono::measurements::Type::MAIN);
+			if ( values.count ( "nodes" ) )
+				settings.nodes = printingOption;
 
-			grammar::Grammar grammar = alib::XmlDataFactory::fromTokens<grammar::Grammar>(tokens);
-		} else if( alib::XmlDataFactory::first<regexp::RegExp>(tokens) /* && regexp.isSet() */) {
+			regexp::RegExp regexp = alib::XmlDataFactory::fromTokens < regexp::RegExp > ( tokens );
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Stats print", std::chrono::measurements::Type::MAIN);
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Stats print", std::chrono::measurements::Type::MAIN );
 
-			regexp::RegExp regexp = alib::XmlDataFactory::fromTokens<regexp::RegExp>(tokens);
-		} else if( alib::XmlDataFactory::first<container::ObjectsSet>(tokens) && setContainer.isSet()) {
+			RegExpStat::stat ( regexp, settings );
+		} else if ( alib::XmlDataFactory::first < string::String > ( tokens ) && string.isSet ( ) ) {
+			StringSettings settings = { PrintingOptions::NOOP, PrintingOptions::NOOP };
+			std::set < std::string > values {
+				string.getValue ( ).begin ( ), string.getValue ( ).end ( )
+			};
 
-			std::chrono::measurements::end();
-			std::chrono::measurements::start("Stats print", std::chrono::measurements::Type::MAIN);
+			if ( values.count ( "alphabet" ) )
+				settings.alphabet = printingOption;
 
-			SetSettings settings = {PrintingOptions::NOOP};
+			if ( values.count ( "content" ) )
+				settings.content = printingOption;
+
+			string::String string = alib::XmlDataFactory::fromTokens < string::String > ( tokens );
+
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Stats print", std::chrono::measurements::Type::MAIN );
+
+			StringStat::stat ( string, settings );
+		} else if ( alib::XmlDataFactory::first < tree::Tree > ( tokens ) && tree.isSet ( ) ) {
+			TreeSettings settings = { PrintingOptions::NOOP, PrintingOptions::NOOP };
+			std::set < std::string > values {
+				tree.getValue ( ).begin ( ), tree.getValue ( ).end ( )
+			};
+
+			if ( values.count ( "alphabet" ) )
+				settings.alphabet = printingOption;
+
+			if ( values.count ( "nodes" ) )
+				settings.nodes = printingOption;
+
+			tree::Tree tree = alib::XmlDataFactory::fromTokens < tree::Tree > ( tokens );
+
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Stats print", std::chrono::measurements::Type::MAIN );
+
+			TreeStat::stat ( tree, settings );
+		} else if ( alib::XmlDataFactory::first < container::ObjectsSet > ( tokens ) && set.isSet ( ) ) {
+			SetSettings settings = { PrintingOptions::NOOP };
 			settings.general = printingOption;
 
-			container::ObjectsSet data = alib::XmlDataFactory::fromTokens<container::ObjectsSet>(tokens);
-			SetStat::stat(data, settings);
+			container::ObjectsSet data = alib::XmlDataFactory::fromTokens < container::ObjectsSet > ( tokens );
+
+			std::chrono::measurements::end ( );
+			std::chrono::measurements::start ( "Stats print", std::chrono::measurements::Type::MAIN );
+
+			SetStat::stat ( data, settings );
 		} else {
-			throw exception::AlibException( "Input not recognized." );
+			throw exception::AlibException ( "Input not recognized." );
 		}
 
-		std::chrono::measurements::end();
-		std::chrono::measurements::end();
+		std::chrono::measurements::end ( );
+		std::chrono::measurements::end ( );
 
-		if(measure.getValue()) std::clog << std::chrono::measurements::results() << std::endl;
+		if ( measure.getValue ( ) ) std::clog << std::chrono::measurements::results ( ) << std::endl;
 
 		return 0;
 	} catch ( const exception::AlibException & exception ) {
-		alib::XmlDataFactory::toStdout( exception );
+		alib::XmlDataFactory::toStdout ( exception );
 		return 1;
-	} catch (const TCLAP::ArgException& exception) {
-		std::cout << exception.error() << std::endl;
+	} catch ( const TCLAP::ArgException & exception ) {
+		std::cout << exception.error ( ) << std::endl;
 		return 2;
-	} catch (const std::exception& exception) {
-		std::cerr << "Exception caught: " << exception.what() << std::endl;
+	} catch ( const std::exception & exception ) {
+		std::cerr << "Exception caught: " << exception.what ( ) << std::endl;
 		return 3;
-	} catch (...) {
+	} catch ( ... ) {
 		std::cerr << "Unknown exception caught." << std::endl;
 		return 127;
 	}