diff --git a/alib2algo/src/arbology/exact/BorderArrayNaive.cpp b/alib2algo/src/arbology/exact/BorderArrayNaive.cpp
index 14d3f367ffb3fe3ce26b7851e173843923667180..b6a574c2804e670065f6ba5dcbc06d5cf930a2c5 100644
--- a/alib2algo/src/arbology/exact/BorderArrayNaive.cpp
+++ b/alib2algo/src/arbology/exact/BorderArrayNaive.cpp
@@ -6,12 +6,6 @@
  */
 
 #include "BorderArrayNaive.h"
-#include "SubtreeJumpTable.h"
-
-#include <tree/ranked/PrefixRankedBarPattern.h>
-#include <tree/ranked/PrefixRankedPattern.h>
-#include <tree/Tree.h>
-#include <global/GlobalData.h>
 
 namespace arbology {
 
@@ -21,96 +15,7 @@ std::vector < size_t > BorderArrayNaive::ba ( const tree::Tree & pattern ) {
 	return dispatch ( pattern.getData ( ) );
 }
 
-bool BorderArrayNaive::matches ( const tree::PrefixRankedBarPattern < > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset ) {
-	unsigned i = 0;
-
-	while ( offset < stop && i < pattern.getContent ( ).size ( ) )
-		if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) {
-			i++;
-			offset++;
-		} else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) ) {
-			i = subtreeJumpTable[i];
-			offset = subtreeJumpTable[offset];
-		} else {
-			return false;
-		}
-
-	return true;
-}
-
-std::vector < size_t > BorderArrayNaive::ba ( const tree::PrefixRankedBarPattern < > & pattern ) {
-	std::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern );
-	std::vector < size_t > res;
-
-	for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ )
-		res.push_back ( 0 );
-
-	res[0] = -1;
-
-	for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) {
-		int min = i;
-
-		for ( unsigned j = 1; j < i; j++ )
-			if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) {
-				min = j;
-				break;
-			}
-
-		res[i] = i - min;
-	}
-
-	if ( common::GlobalData::verbose )
-		std::clog << res << std::endl;
-
-	return res;
-}
-
 auto BorderArrayPrefixRankedBarPattern = BorderArrayNaive::RegistratorWrapper < std::vector < size_t >, tree::PrefixRankedBarPattern < > > ( BorderArrayNaive::ba );
-
-bool BorderArrayNaive::matches ( const tree::PrefixRankedPattern < > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset ) {
-	unsigned i = 0;
-
-	while ( offset < stop && i < pattern.getContent ( ).size ( ) )
-		if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) {
-			i++;
-			offset++;
-		} else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) ) {
-			i = subtreeJumpTable[i];
-			offset = subtreeJumpTable[offset];
-		} else {
-			return false;
-		}
-
-	return true;
-}
-
-std::vector < size_t > BorderArrayNaive::ba ( const tree::PrefixRankedPattern < > & pattern ) {
-	std::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern );
-	std::vector < size_t > res;
-
-	for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ )
-		res.push_back ( 0 );
-
-	res[0] = -1;
-
-	for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) {
-		int min = i;
-
-		for ( unsigned j = 1; j < i; j++ )
-			if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) {
-				min = j;
-				break;
-			}
-
-		res[i] = i - min;
-	}
-
-	if ( common::GlobalData::verbose )
-		std::clog << res << std::endl;
-
-	return res;
-}
-
 auto BorderArrayPrefixRankedPattern = BorderArrayNaive::RegistratorWrapper < std::vector < size_t >, tree::PrefixRankedPattern < > > ( BorderArrayNaive::ba );
 
 } /* namespace exact */
diff --git a/alib2algo/src/arbology/exact/BorderArrayNaive.h b/alib2algo/src/arbology/exact/BorderArrayNaive.h
index 575af1b841972884effa0576914ea0edbe53f06b..8724366dc41cbb0eb4eeafaba8df3b8f92db77b6 100644
--- a/alib2algo/src/arbology/exact/BorderArrayNaive.h
+++ b/alib2algo/src/arbology/exact/BorderArrayNaive.h
@@ -8,10 +8,17 @@
 #ifndef _ARBOLOGY_BORDER_ARRAY_NAIVE_H_
 #define _ARBOLOGY_BORDER_ARRAY_NAIVE_H_
 
-#include <tree/TreeFeatures.h>
+#include <vector>
+
 #include <core/multipleDispatch.hpp>
+#include <global/GlobalData.h>
 
-#include <vector>
+#include "SubtreeJumpTable.h"
+
+#include <tree/Tree.h>
+#include <tree/TreeFeatures.h>
+#include <tree/ranked/PrefixRankedBarPattern.h>
+#include <tree/ranked/PrefixRankedPattern.h>
 
 namespace arbology {
 
@@ -22,9 +29,11 @@ namespace exact {
  * To get rid of zeros in BCS table we ignore last haystack character
  */
 class BorderArrayNaive : public std::SingleDispatch < BorderArrayNaive, std::vector < size_t >, const tree::TreeBase & > {
-	static bool matches ( const tree::PrefixRankedBarPattern < > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset );
+	template < class SymbolType, class RankType >
+	static bool matches ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset );
 
-	static bool matches ( const tree::PrefixRankedPattern < > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset );
+	template < class SymbolType, class RankType >
+	static bool matches ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset );
 
 public:
 	/**
@@ -37,16 +46,110 @@ public:
 	 * Search for pattern in linear string.
 	 * @return set set of occurences
 	 */
-	static std::vector < size_t > ba ( const tree::PrefixRankedBarPattern < > & pattern );
+	template < class SymbolType, class RankType >
+	static std::vector < size_t > ba ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern );
 
 	/**
 	 * Search for pattern in linear string.
 	 * @return set set of occurences
 	 */
-	static std::vector < size_t > ba ( const tree::PrefixRankedPattern < > & pattern );
+	template < class SymbolType, class RankType >
+	static std::vector < size_t > ba ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern );
 
 };
 
+template < class SymbolType, class RankType >
+bool BorderArrayNaive::matches ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset ) {
+	unsigned i = 0;
+
+	while ( offset < stop && i < pattern.getContent ( ).size ( ) )
+		if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) {
+			i++;
+			offset++;
+		} else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) ) {
+			i = subtreeJumpTable[i];
+			offset = subtreeJumpTable[offset];
+		} else {
+			return false;
+		}
+
+	return true;
+}
+
+template < class SymbolType, class RankType >
+std::vector < size_t > BorderArrayNaive::ba ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern ) {
+	std::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern );
+	std::vector < size_t > res;
+
+	for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ )
+		res.push_back ( 0 );
+
+	res[0] = -1;
+
+	for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) {
+		int min = i;
+
+		for ( unsigned j = 1; j < i; j++ )
+			if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) {
+				min = j;
+				break;
+			}
+
+		res[i] = i - min;
+	}
+
+	if ( common::GlobalData::verbose )
+		std::clog << res << std::endl;
+
+	return res;
+}
+
+template < class SymbolType, class RankType >
+bool BorderArrayNaive::matches ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern, const std::vector < int > & subtreeJumpTable, int stop, int offset ) {
+	unsigned i = 0;
+
+	while ( offset < stop && i < pattern.getContent ( ).size ( ) )
+		if ( pattern.getContent ( )[i] == pattern.getContent ( )[offset] ) {
+			i++;
+			offset++;
+		} else if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getContent ( )[offset] == pattern.getSubtreeWildcard ( ) ) ) {
+			i = subtreeJumpTable[i];
+			offset = subtreeJumpTable[offset];
+		} else {
+			return false;
+		}
+
+	return true;
+}
+
+template < class SymbolType, class RankType >
+std::vector < size_t > BorderArrayNaive::ba ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern ) {
+	std::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern );
+	std::vector < size_t > res;
+
+	for ( unsigned i = 0; i <= pattern.getContent ( ).size ( ); i++ )
+		res.push_back ( 0 );
+
+	res[0] = -1;
+
+	for ( unsigned i = 1; i <= pattern.getContent ( ).size ( ); i++ ) {
+		int min = i;
+
+		for ( unsigned j = 1; j < i; j++ )
+			if ( matches ( pattern, patternSubtreeJumpTable, i, j ) ) {
+				min = j;
+				break;
+			}
+
+		res[i] = i - min;
+	}
+
+	if ( common::GlobalData::verbose )
+		std::clog << res << std::endl;
+
+	return res;
+}
+
 } /* namespace exact */
 
 } /* namespace arbology */