diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0870594266feabc8d9f09b0c8438beb7d1224e26
--- /dev/null
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp
@@ -0,0 +1,88 @@
+/*
+ * ExactSubtreeMatch.cpp
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#include "ExactSubtreeMatch.h"
+#include <exception/AlibException.h>
+#include <tree/ranked/RankedTree.h>
+#include <tree/unranked/UnrankedTree.h>
+
+#include <deque>
+#include <foreach>
+
+namespace arbology {
+
+namespace exact {
+
+std::set<unsigned> ExactSubtreeMatch::match(const tree::Tree& subject, const tree::Tree& pattern) {
+	std::set<unsigned> data;
+	Accept((void*) &data, subject.getData(), pattern.getData(), ExactSubtreeMatch::EXACT_SUBTREE_MATCH);
+	return data;
+}
+
+bool ExactSubtreeMatch::matchHelper(const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern) {
+	if(subject.getSymbol() != pattern.getSymbol()) return false;
+	if(subject.getChildren().size() != pattern.getChildren().size()) return false;
+	for(const std::tuple<const tree::UnrankedNode*, const tree::UnrankedNode*>& childs : std::make_pair_foreach(subject.getChildren(), pattern.getChildren())) {
+		if(!matchHelper(*std::get<0>(childs), *std::get<1>(childs))) return false;
+	}
+	return true;
+}
+
+bool ExactSubtreeMatch::matchHelper(const tree::RankedNode& subject, const tree::RankedNode& pattern) {
+	if(subject.getSymbol() != pattern.getSymbol()) return false;
+	// ranked symbols are the same test for number of children is not needed
+	for(const std::tuple<const tree::RankedNode*, const tree::RankedNode*>& childs : std::make_pair_foreach(subject.getChildren(), pattern.getChildren())) {
+		if(!matchHelper(*std::get<0>(childs), *std::get<1>(childs))) return false;
+	}
+	return true;
+}
+
+void ExactSubtreeMatch::matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern) {
+	if(matchHelper(subject, pattern)) occ.insert(index);
+	index++;
+	for(const tree::UnrankedNode* child : subject.getChildren()) {
+		matchInternal(index, occ, *child, pattern);
+	}
+}
+
+void ExactSubtreeMatch::matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::RankedNode& subject, const tree::RankedNode& pattern) {
+	if(matchHelper(subject, pattern)) occ.insert(index);
+	index++;
+	for(const tree::RankedNode* child : subject.getChildren()) {
+		matchInternal(index, occ, *child, pattern);
+	}
+}
+
+std::set<unsigned> ExactSubtreeMatch::match(const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) {
+	unsigned i = 0;
+	std::set<unsigned> occ;
+	matchInternal(i, occ, subject.getRoot(), pattern.getRoot());
+	return occ;
+}
+
+std::set<unsigned> ExactSubtreeMatch::match(const tree::RankedTree& subject, const tree::RankedTree& pattern) {
+	unsigned i = 0;
+	std::set<unsigned> occ;
+	matchInternal(i, occ, subject.getRoot(), pattern.getRoot());
+	return occ;
+}
+
+void ExactSubtreeMatch::Visit(void* data, const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) const {
+	std::set<unsigned> & res = *((std::set<unsigned>*) data);
+	res = this->match(subject, pattern);
+}
+
+void ExactSubtreeMatch::Visit(void* data, const tree::RankedTree& subject, const tree::RankedTree& pattern) const {
+	std::set<unsigned> & res = *((std::set<unsigned>*) data);
+	res = this->match(subject, pattern);
+}
+
+const ExactSubtreeMatch ExactSubtreeMatch::EXACT_SUBTREE_MATCH;
+
+} /* namespace exact */
+
+} /* namespace arbology */
diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbfd582ee809257bd133a2a7f02dca778ff7e008
--- /dev/null
+++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h
@@ -0,0 +1,50 @@
+/*
+ * ExactSubtreeMatch.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef _EXACT_SUBTREE_MATCH_H_
+#define _EXACT_SUBTREE_MATCH_H_
+
+#include <tree/Tree.h>
+#include <tree/ranked/RankedTree.h>
+#include <tree/unranked/UnrankedTree.h>
+
+#include <set>
+
+namespace arbology {
+
+namespace exact {
+
+class ExactSubtreeMatch : public tree::VisitableTreeBase::const_promoting_visitor_type {
+public:
+	ExactSubtreeMatch() {}
+
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static std::set<unsigned> match(const tree::Tree& subject, const tree::Tree& pattern);
+
+	static std::set<unsigned> match(const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern);
+	static std::set<unsigned> match(const tree::RankedTree& subject, const tree::RankedTree& pattern);
+private:
+	static bool matchHelper(const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern);
+	static bool matchHelper(const tree::RankedNode& subject, const tree::RankedNode& pattern);
+
+	static void matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern);
+	static void matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::RankedNode& subject, const tree::RankedNode& pattern);
+
+	void Visit(void*, const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) const;
+	void Visit(void*, const tree::RankedTree& subject, const tree::RankedTree& pattern) const;
+
+	static const ExactSubtreeMatch EXACT_SUBTREE_MATCH;
+};
+
+} /* namespace exact */
+
+} /* namespace arbology */
+
+#endif /* _EXACT_SUBTREE_MATCH_H_ */
diff --git a/alib2algo/src/stringology/exact/ExactMatch.cpp b/alib2algo/src/stringology/exact/ExactFactorMatch.cpp
similarity index 57%
rename from alib2algo/src/stringology/exact/ExactMatch.cpp
rename to alib2algo/src/stringology/exact/ExactFactorMatch.cpp
index b68b7e1df56e8772440c32dee7a58cb6732a50c7..fe388a234ba7f2c4f6243972497ceedec7ccf5d6 100644
--- a/alib2algo/src/stringology/exact/ExactMatch.cpp
+++ b/alib2algo/src/stringology/exact/ExactFactorMatch.cpp
@@ -1,11 +1,11 @@
 /*
- * ExactMatch.cpp
+ * ExactFactorMatch.cpp
  *
  *  Created on: 9. 2. 2014
  *      Author: Jan Travnicek
  */
 
-#include "ExactMatch.h"
+#include "ExactFactorMatch.h"
 #include <exception/AlibException.h>
 #include <string/LinearString.h>
 
@@ -15,13 +15,13 @@ namespace stringology {
 
 namespace exact {
 
-std::set<unsigned> ExactMatch::match(const string::String& subject, const string::String& pattern) {
+std::set<unsigned> ExactFactorMatch::match(const string::String& subject, const string::String& pattern) {
 	std::set<unsigned> data;
-	Accept((void*) &data, subject.getData(), pattern.getData(), ExactMatch::EXACT_MATCH);
+	Accept((void*) &data, subject.getData(), pattern.getData(), ExactFactorMatch::EXACT_FACTOR_MATCH);
 	return data;
 }
 
-std::set<unsigned> ExactMatch::match(const string::LinearString& subject, const string::LinearString& pattern) {
+std::set<unsigned> ExactFactorMatch::match(const string::LinearString& subject, const string::LinearString& pattern) {
 	std::set<unsigned> occ;
 	for(unsigned i = 0; i <= subject.getContent().size() - pattern.getContent().size(); i++) {
 		unsigned j = 0;
@@ -35,20 +35,20 @@ std::set<unsigned> ExactMatch::match(const string::LinearString& subject, const
 	return occ;
 }
 
-void ExactMatch::Visit(void*, const string::Epsilon&, const string::Epsilon&) const {
+void ExactFactorMatch::Visit(void*, const string::Epsilon&, const string::Epsilon&) const {
 	throw exception::AlibException("Unsupported string type Epsilon");
 }
 
-void ExactMatch::Visit(void* data, const string::LinearString& subject, const string::LinearString& pattern) const {
+void ExactFactorMatch::Visit(void* data, const string::LinearString& subject, const string::LinearString& pattern) const {
 	std::set<unsigned> & res = *((std::set<unsigned>*) data);
 	res = this->match(subject, pattern);
 }
 
-void ExactMatch::Visit(void*, const string::CyclicString&, const string::CyclicString&) const {
+void ExactFactorMatch::Visit(void*, const string::CyclicString&, const string::CyclicString&) const {
 	throw exception::AlibException("Unsupported string type CyclicString");
 }
 
-const ExactMatch ExactMatch::EXACT_MATCH;
+const ExactFactorMatch ExactFactorMatch::EXACT_FACTOR_MATCH;
 
 } /* namespace exact */
 
diff --git a/alib2algo/src/stringology/exact/ExactMatch.h b/alib2algo/src/stringology/exact/ExactFactorMatch.h
similarity index 82%
rename from alib2algo/src/stringology/exact/ExactMatch.h
rename to alib2algo/src/stringology/exact/ExactFactorMatch.h
index faf97daecccfbc9f7d07a92035ef47e5832d6c3b..df9f5a12982323db87c97b2cdfd3ccf58f8d76b4 100644
--- a/alib2algo/src/stringology/exact/ExactMatch.h
+++ b/alib2algo/src/stringology/exact/ExactFactorMatch.h
@@ -1,5 +1,5 @@
 /*
- * ExactMatch.h
+ * ExactFactorMatch.h
  *
  *  Created on: 9. 2. 2014
  *      Author: Jan Travnicek
@@ -14,9 +14,9 @@ namespace stringology {
 
 namespace exact {
 
-class ExactMatch : public string::VisitableStringBase::const_promoting_visitor_type {
+class ExactFactorMatch : public string::VisitableStringBase::const_promoting_visitor_type {
 public:
-	ExactMatch() {}
+	ExactFactorMatch() {}
 
 	/**
 	 * Performs conversion.
@@ -30,7 +30,7 @@ private:
 	void Visit(void*, const string::LinearString& subject, const string::LinearString& pattern) const;
 	void Visit(void*, const string::CyclicString& subject, const string::CyclicString& pattern) const;
 
-	static const ExactMatch EXACT_MATCH;
+	static const ExactFactorMatch EXACT_FACTOR_MATCH;
 };
 
 } /* namespace exact */
diff --git a/astringology2/src/astringology.cpp b/astringology2/src/astringology.cpp
index c87d86ecbb201e8f5cf79190a3742a020dc0eb65..fee3b130ed7c3830cd6d2cde21aa9e151859ffe8 100644
--- a/astringology2/src/astringology.cpp
+++ b/astringology2/src/astringology.cpp
@@ -14,7 +14,7 @@
 #include <automaton/Automaton.h>
 #include <container/Container.h>
 
-#include <stringology/exact/ExactMatch.h>
+#include <stringology/exact/ExactFactorMatch.h>
 #include <stringology/exact/BoyerMooreHorspool.h>
 #include <stringology/exact/ExactMatchingAutomaton.h>
 #include <stringology/exact/ExactFactorAutomaton.h>
@@ -33,12 +33,12 @@ int main(int argc, char* argv[]) {
 		allowed.push_back("exactSubsequenceAutomaton");
 		allowed.push_back("exactNondeterministicSubsequenceAutomaton");
 		allowed.push_back("exactMultiNondeterministicSubsequenceAutomaton");
-		allowed.push_back("exactMatch");
+		allowed.push_back("exactFactorMatch");
 		allowed.push_back("boyerMooreHorspool");
 		allowed.push_back("borderArray");
 		TCLAP::ValuesConstraint<std::string> allowedVals( allowed );
 
-		TCLAP::ValueArg<std::string> algorithm(	"a",	"algorithm",	"Execute algorithm",		false,	"exactMatch",	&allowedVals);
+		TCLAP::ValueArg<std::string> algorithm(	"a",	"algorithm",	"Execute algorithm",		false,	"exactFactorMatch",	&allowedVals);
 		cmd.add(algorithm);
 
 		TCLAP::MultiArg<std::string> subject(	"s",	"subject",	"Subject string from file",	false,	"file");
@@ -51,7 +51,7 @@ int main(int argc, char* argv[]) {
 
 		int needPattern = 0;
 		int needSubject = 0;
-		if( algorithm.getValue() == "exactMatch") {
+		if( algorithm.getValue() == "exactFactorMatch") {
 			needPattern = needSubject = 1;
 		} else if( algorithm.getValue() == "boyerMooreHorspool") {
 			needPattern = needSubject = 1;
@@ -104,10 +104,10 @@ int main(int argc, char* argv[]) {
 			patternTokens.emplace_back(std::move(tmp));
 		}
 
-		if( algorithm.getValue() == "exactMatch") {
+		if( algorithm.getValue() == "exactFactorMatch") {
 			string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front());
 			string::String pattern = alib::XmlDataFactory::fromTokens<string::String>(patternTokens.front());
-			std::set<unsigned> res = stringology::exact::ExactMatch::match(subject, pattern);
+			std::set<unsigned> res = stringology::exact::ExactFactorMatch::match(subject, pattern);
 			alib::XmlDataFactory::toStdout(res);
 			return 0;
 		} else if( algorithm.getValue() == "boyerMooreHorspool") {
diff --git a/tests.astringology.sh b/tests.astringology.sh
index 57b62962fa9007ba15ffe380d98213de82b972ea..6c76981108b111169b64ee07e1aa07946a019bb2 100755
--- a/tests.astringology.sh
+++ b/tests.astringology.sh
@@ -134,7 +134,7 @@ function runTest {
 	for SUBJECT_FILE in `ls $TESTS_DIR/astringology.test*.subject.xml`; do
 		PATTERN_FILE=${SUBJECT_FILE%.subject.xml}.pattern.xml
 		if [ -f  ]; then
-			Occs=`./astringology2 -a exactMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s`
+			Occs=`./astringology2 -a exactFactorMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s`
 
 			runTest2 "$Occs" "$2" "$SUBJECT_FILE" "$PATTERN_FILE"
 			registerResult $?
@@ -151,7 +151,7 @@ function runTest {
 		cat <(generateSubject) > $SUBJECT_FILE
 		cat <(generatePattern) > $PATTERN_FILE
 
-		Occs=`./astringology2 -a exactMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s`
+		Occs=`./astringology2 -a exactFactorMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s`
 
 		runTest2 "$Occs" "$2" "$SUBJECT_FILE" "$PATTERN_FILE"
 		registerResult $?