diff --git a/aarbology2/src/aarbology.cpp b/aarbology2/src/aarbology.cpp
index ebbfcd3e4f421e2e0e938a4b30aa38e90e34ed86..de0dbf57faac0df35b6b2ca70fce68d88ff483d1 100644
--- a/aarbology2/src/aarbology.cpp
+++ b/aarbology2/src/aarbology.cpp
@@ -14,6 +14,7 @@
 #include <factory/XmlDataFactory.hpp>
 #include <exception/CommonException.h>
 #include <tree/Tree.h>
+#include <tree/RankedTreeWrapper.h>
 #include <container/Container.h>
 #include <container/ObjectsSet.h>
 
@@ -30,6 +31,7 @@
 #include <arbology/exact/ExactNonlinearTreePatternAutomaton.h>
 #include <tree/properties/ExactSubtreeRepeatsNaive.h>
 #include <arbology/transform/BeginToEndIndex.h>
+#include <arbology/indexing/CompressedBitParallelIndexConstruction.h>
 
 int main ( int argc, char * argv[] ) {
 	try {
@@ -51,6 +53,7 @@ int main ( int argc, char * argv[] ) {
 		allowed.push_back ( "exactTreePatternAutomaton" );
 		allowed.push_back ( "exactNonlinearTreePatternAutomaton" );
 		allowed.push_back ( "exactSubtreeRepeatsNaive" );
+		allowed.push_back ( "compressedBitParallelIndex" );
 		TCLAP::ValuesConstraint < std::string > allowedVals ( allowed );
 
 		TCLAP::ValueArg < std::string > algorithm ( "a", "algorithm", "Execute algorithm", false, "exactSubtreeMatch", & allowedVals );
@@ -252,9 +255,20 @@ int main ( int argc, char * argv[] ) {
 			measurements::start ( "Output write", measurements::Type::AUXILIARY );
 
 			alib::XmlDataFactory::toStdout ( res );
+		} else if ( algorithm.getValue ( ) == "compressedBitParallelIndex" ) {
+			tree::RankedTreeWrapper subject = alib::XmlDataFactory::fromTokens < tree::RankedTreeWrapper > ( std::move ( sax::FromXMLParserHelper::parseInput(true, subjectInput).front ( ) ) );
+
+			measurements::end ( );
+			measurements::start ( "Algorithm", measurements::Type::MAIN );
+
+			indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > compressedBitParallelIndex = arbology::indexing::CompressedBitParallelIndexConstruction::construct ( subject );
+
+			measurements::end ( );
+			measurements::start ( "Output write", measurements::Type::AUXILIARY );
+
+			alib::XmlDataFactory::toStdout ( compressedBitParallelIndex );
 		} else {
 			throw exception::CommonException ( "Invalid algorithm" );
-			return 1;
 		}
 
 		measurements::end ( );
diff --git a/alib2algo/src/arbology/indexing/CompressedBitParallelIndexConstruction.cpp b/alib2algo/src/arbology/indexing/CompressedBitParallelIndexConstruction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3036dd7b955effb78e593a03662cfccd47d559ab
--- /dev/null
+++ b/alib2algo/src/arbology/indexing/CompressedBitParallelIndexConstruction.cpp
@@ -0,0 +1,22 @@
+/*
+ * CompressedBitParallelIndexConstruction.cpp
+ *
+ *  Created on: 6. 2. 2017
+ *      Author: Jan Travnicek
+ */
+
+#include "CompressedBitParallelIndexConstruction.h"
+
+namespace arbology {
+
+namespace indexing {
+
+indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > CompressedBitParallelIndexConstruction::construct ( const tree::RankedTreeWrapper & tree ) {
+	return dispatch ( tree.getData ( ) );
+}
+
+auto compressedBitParallelIndexConstructionPrefixRankedTree = CompressedBitParallelIndexConstruction::RegistratorWrapper < indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > >, tree::PrefixRankedTree < > > ( CompressedBitParallelIndexConstruction::construct );
+
+} /* namespace indexing */
+
+} /* namespace arbology */
diff --git a/alib2algo/src/arbology/indexing/CompressedBitParallelIndexConstruction.h b/alib2algo/src/arbology/indexing/CompressedBitParallelIndexConstruction.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2b53bb5eb17ebfeb61e82a1236424e01166f6d1
--- /dev/null
+++ b/alib2algo/src/arbology/indexing/CompressedBitParallelIndexConstruction.h
@@ -0,0 +1,57 @@
+/*
+ * CompressedBitParallelIndexConstruction.h
+ *
+ *  Created on: 6. 2. 2017
+ *      Author: Jan Travnicek
+ */
+
+#ifndef ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_
+#define ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_
+
+#include <indexes/arbology/CompressedBitParallelTreeIndex.h>
+#include <tree/RankedTreeWrapper.h>
+#include <tree/ranked/PrefixRankedTree.h>
+#include <core/multipleDispatch.hpp>
+#include <exception/CommonException.h>
+#include <tree/properties/SubtreeJumpTable.h>
+
+namespace arbology {
+
+namespace indexing {
+
+/**
+ * Constructs a compressed bit parallel index for given tree.
+ *
+ */
+
+class CompressedBitParallelIndexConstruction : public std::SingleDispatch < CompressedBitParallelIndexConstruction, indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > >, const tree::RankedTreeBase & > {
+public:
+	/**
+	 * Creates compressed bit parallel index for trees
+	 * @param tree tree to construct the index for
+	 * @return the index
+	 */
+	static indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > construct ( const tree::RankedTreeWrapper & tree );
+
+	template < class SymbolType, class RankType >
+	static indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < SymbolType, RankType > > construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree );
+};
+
+template < class SymbolType, class RankType >
+indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < SymbolType, RankType > > CompressedBitParallelIndexConstruction::construct ( const tree::PrefixRankedTree < SymbolType, RankType > & w ) {
+	std::map < std::ranked_symbol < SymbolType, RankType >, common::SparseBoolVector > res;
+
+	for ( const std::ranked_symbol < SymbolType, RankType > & symbol : w.getAlphabet ( ) )
+		res [ symbol ].resize ( w.getContent ( ).size ( ) );
+
+	for ( unsigned i = 0; i < w.getContent ( ).size ( ); ++i )
+		res [ w.getContent ( ) [ i ] ] [ i ] = true;
+
+	return indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < SymbolType, RankType > > ( w.getAlphabet ( ), res, tree::properties::SubtreeJumpTable::compute ( w ) );
+}
+
+} /* namespace indexing */
+
+} /* namespace arbology */
+
+#endif /* ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_CONSTRUCTION_H_ */
diff --git a/alib2algo/src/arbology/query/CompressedBitParallelismPatterns.cpp b/alib2algo/src/arbology/query/CompressedBitParallelismPatterns.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a3b6dd7d679b71f5b816ccfd8524054415d68e48
--- /dev/null
+++ b/alib2algo/src/arbology/query/CompressedBitParallelismPatterns.cpp
@@ -0,0 +1,24 @@
+/*
+ * CompressedBitParallelismPatterns.cpp
+ *
+ *  Created on: 2. 1. 2017
+ *      Author: Jan Travnicek
+ */
+
+#include "CompressedBitParallelismPatterns.h"
+
+#include <tree/ranked/PrefixRankedPattern.h>
+
+namespace arbology {
+
+namespace query {
+
+std::set < unsigned > CompressedBitParallelismPatterns::query ( const indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > & compressedBitParallelIndex, const tree::RankedTreeWrapper & tree ) {
+	return dispatch ( compressedBitParallelIndex, tree.getData ( ) );
+}
+
+auto CompressedBitParallelismPatternsPrefixRankedPattern = CompressedBitParallelismPatterns::RegistratorWrapper < std::set < unsigned >, tree::PrefixRankedPattern < > > ( CompressedBitParallelismPatterns::query );
+
+} /* namespace query */
+
+} /* namespace arbology */
diff --git a/alib2algo/src/arbology/query/CompressedBitParallelismPatterns.h b/alib2algo/src/arbology/query/CompressedBitParallelismPatterns.h
new file mode 100644
index 0000000000000000000000000000000000000000..8beb1cb26b8aed3d92e411d58448ef2d64fd6999
--- /dev/null
+++ b/alib2algo/src/arbology/query/CompressedBitParallelismPatterns.h
@@ -0,0 +1,83 @@
+/*
+ * CompressedBitParallelismPatterns.h
+ *
+ *  Created on: 2. 1. 2017
+ *      Author: Jan Travnicek
+ */
+
+#ifndef COMPRESSED_BIT_PARALLELISM_PATTERNS_H_
+#define COMPRESSED_BIT_PARALLELISM_PATTERNS_H_
+
+#include <indexes/arbology/CompressedBitParallelTreeIndex.h>
+#include <tree/RankedTreeWrapper.h>
+#include <tree/ranked/PrefixRankedTree.h>
+#include <core/multipleDispatch.hpp>
+#include <global/GlobalData.h>
+
+namespace arbology {
+
+namespace query {
+
+/**
+ * Query compressed bit parallel index for given tree.
+ *
+ */
+
+class CompressedBitParallelismPatterns : public std::SingleDispatchFirstStaticParam < CompressedBitParallelismPatterns, std::set < unsigned >, const indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > &, const tree::RankedTreeBase & > {
+
+public:
+	/**
+	 * Query a suffix trie
+	 * @param suffix trie to query
+	 * @param tree tree to query by
+	 * @return occurences of factors
+	 */
+	static std::set < unsigned > query ( const indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > & compressedBitParallelIndex, const tree::RankedTreeWrapper & pattern );
+
+	template < class SymbolType, class RankType >
+	static std::set < unsigned > query ( const indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < SymbolType, RankType > > & compressedBitParallelTreeIndex, const tree::PrefixRankedPattern < SymbolType, RankType > & pattern );
+};
+
+template < class SymbolType, class RankType >
+std::set < unsigned > CompressedBitParallelismPatterns::query ( const indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < SymbolType, RankType > > & compressedBitParallelIndex, const tree::PrefixRankedPattern < SymbolType, RankType > & pattern ) {
+	auto symbolIter = pattern.getContent ( ).begin ( );
+
+	typename std::map < std::ranked_symbol < SymbolType, RankType >, common::SparseBoolVector >::const_iterator symbolVectorIter = compressedBitParallelIndex.getData ( ).find ( * symbolIter );
+
+	if ( symbolVectorIter == compressedBitParallelIndex.getData ( ).end ( ) )
+		return { };
+
+	common::SparseBoolVector indexVector = symbolVectorIter->second;
+
+	for ( ++ symbolIter; symbolIter != pattern.getContent ( ).end ( ); ++ symbolIter ) {
+		if ( * symbolIter == pattern.getSubtreeWildcard ( ) ) {
+			common::SparseBoolVector newVector;
+			newVector.resize ( indexVector.size ( ) );
+
+			for ( unsigned i : ( indexVector << 1 ) )
+				newVector [ compressedBitParallelIndex.getJumps ( ) [ i ] - 1 ] = true;
+
+			indexVector = newVector;
+		} else {
+			symbolVectorIter = compressedBitParallelIndex.getData ( ).find ( * symbolIter );
+
+			if ( symbolVectorIter == compressedBitParallelIndex.getData ( ).end ( ) )
+				return { };
+
+			indexVector = ( indexVector << 1 ) & symbolVectorIter->second;
+		}
+	}
+
+	std::set < unsigned > res;
+
+	for ( unsigned i : indexVector )
+		res.insert ( i + 1 );
+
+	return res;
+}
+
+} /* namespace query */
+
+} /* namespace arbology */
+
+#endif /* COMPRESSED_BIT_PARALLELISM_PATTERNS_H_ */
diff --git a/alib2data/src/indexes/arbology/CompressedBitParallelTreeIndex.cpp b/alib2data/src/indexes/arbology/CompressedBitParallelTreeIndex.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a9cd05af0d77eb922851535eba384f38ad324b1
--- /dev/null
+++ b/alib2data/src/indexes/arbology/CompressedBitParallelTreeIndex.cpp
@@ -0,0 +1,14 @@
+/*
+ * CompressedBitParallelTreeIndex.cpp
+ *
+ *  Created on: Jan 8, 2017
+ *      Author: Jan Travnicek
+ */
+
+#include "CompressedBitParallelTreeIndex.h"
+
+namespace alib {
+
+auto arbologyCompressedBitParallelIndexParserRegister = xmlApi < alib::Object >::ParserRegister < indexes::arbology::CompressedBitParallelTreeIndex < > > ( );
+
+} /* namespace alib */
diff --git a/alib2data/src/indexes/arbology/CompressedBitParallelTreeIndex.h b/alib2data/src/indexes/arbology/CompressedBitParallelTreeIndex.h
new file mode 100644
index 0000000000000000000000000000000000000000..8005354788b79f5837bc941cff69894eee0a25f7
--- /dev/null
+++ b/alib2data/src/indexes/arbology/CompressedBitParallelTreeIndex.h
@@ -0,0 +1,251 @@
+/*
+ * CompressedBitParallelTreeIndex.h
+ *
+ *  Created on: Jan 8, 2017
+ *      Author: Jan Travnicek
+ */
+
+#ifndef ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_H_
+#define ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_H_
+
+#include <string>
+#include <iostream>
+#include <sstream>
+
+#include <common/DefaultSymbolType.h>
+
+#include <core/components.hpp>
+#include <exception/CommonException.h>
+
+#include <object/UniqueObject.h>
+#include <object/ObjectBase.h>
+
+#include <sax/FromXMLParserHelper.h>
+#include <core/xmlApi.hpp>
+
+#include <container/ObjectsSet.h>
+#include <container/ObjectsMap.h>
+#include <container/ObjectsVector.h>
+#include <common/SparseBoolVector.hpp>
+#include <primitive/Bool.h>
+
+namespace indexes {
+
+namespace arbology {
+
+class GeneralAlphabet;
+
+/**
+ * Represents regular expression parsed from the XML. Regular expression is stored
+ * as a tree of RegExpElement.
+ */
+template < class SymbolType = DefaultSymbolType >
+class CompressedBitParallelTreeIndex : public alib::ObjectBase, public std::Components < CompressedBitParallelTreeIndex < SymbolType >, SymbolType, std::tuple < GeneralAlphabet >, std::tuple < > > {
+protected:
+	std::map < SymbolType, common::SparseBoolVector > m_vectors;
+	std::vector < int > m_jumpTable;
+
+public:
+	/**
+	 * @copydoc SuffixTrieNode::clone() const
+	 */
+	virtual ObjectBase * clone ( ) const;
+
+	/**
+	 * @copydoc SuffixTrieNode::plunder() const
+	 */
+	virtual ObjectBase * plunder ( ) &&;
+
+	explicit CompressedBitParallelTreeIndex ( std::set < SymbolType > alphabet, std::map < SymbolType, common::SparseBoolVector > vectors, std::vector < int > jumpTable );
+
+	/**
+	 * @return Root node of the trie
+	 */
+	const std::map < SymbolType, common::SparseBoolVector > & getData ( ) const;
+
+	/**
+	 * @return subtree jump table
+	 */
+	const std::vector < int > & getJumps ( ) const;
+
+	const std::vector < SymbolType > & getString ( ) const;
+
+	const std::set < SymbolType > & getAlphabet ( ) const {
+		return this->template accessComponent < GeneralAlphabet > ( ).get ( );
+	}
+
+	/**
+	 * Sets the compressedBit vector for given symbol
+	 * @param tree root node to set
+	 */
+	void setCompressedBitVectorForSymbol ( SymbolType symbol, common::SparseBoolVector data );
+
+	/**
+	 * Removes symbol from the alphabet of symbol available in the regular expression
+	 * @param symbol removed symbol from the alphabet
+	 */
+	bool removeSymbolFromAlphabet ( const SymbolType & symbol ) {
+		return this->template accessComponent < GeneralAlphabet > ( ).remove ( symbol );
+	}
+
+	/**
+	 * Prints XML representation of the tree to the output stream.
+	 * @param out output stream to which print the tree
+	 * @param tree tree to print
+	 */
+	virtual void operator >>( std::ostream & out ) const;
+
+	virtual int compare ( const ObjectBase & other ) const {
+		if ( std::type_index ( typeid ( * this ) ) == std::type_index ( typeid ( other ) ) ) return this->compare ( ( decltype ( * this ) )other );
+
+		return std::type_index ( typeid ( * this ) ) - std::type_index ( typeid ( other ) );
+	}
+
+	virtual int compare ( const CompressedBitParallelTreeIndex & other ) const;
+
+	virtual explicit operator std::string ( ) const;
+
+	static const std::string & getXmlTagName ( ) {
+		static std::string xmlTagName = "CompressedBitParallelTreeIndex";
+
+		return xmlTagName;
+	}
+
+	static CompressedBitParallelTreeIndex parse ( std::deque < sax::Token >::iterator & input );
+
+	void compose ( std::deque < sax::Token > & out ) const;
+
+	virtual alib::ObjectBase * inc ( ) &&;
+};
+
+} /* namespace arbology */
+
+} /* namespace indexes */
+
+namespace indexes {
+
+namespace arbology {
+
+template < class SymbolType >
+CompressedBitParallelTreeIndex < SymbolType >::CompressedBitParallelTreeIndex ( std::set < SymbolType > alphabet, std::map < SymbolType, common::SparseBoolVector > vectors, std::vector < int > jumpTable ) : std::Components < CompressedBitParallelTreeIndex, SymbolType, std::tuple < GeneralAlphabet >, std::tuple < > > ( std::make_tuple ( std::move ( alphabet ) ), std::tuple < > ( ) ), m_vectors ( std::move ( vectors ) ), m_jumpTable ( jumpTable ) {
+}
+
+template < class SymbolType >
+alib::ObjectBase * CompressedBitParallelTreeIndex < SymbolType >::clone ( ) const {
+	return new CompressedBitParallelTreeIndex ( * this );
+}
+
+template < class SymbolType >
+alib::ObjectBase * CompressedBitParallelTreeIndex < SymbolType >::plunder ( ) && {
+	return new CompressedBitParallelTreeIndex ( std::move ( * this ) );
+}
+
+template < class SymbolType >
+const std::map < SymbolType, common::SparseBoolVector > & CompressedBitParallelTreeIndex < SymbolType >::getData ( ) const {
+	return m_vectors;
+}
+
+template < class SymbolType >
+const std::vector < int > & CompressedBitParallelTreeIndex < SymbolType >::getJumps ( ) const {
+	return m_jumpTable;
+}
+
+template < class SymbolType >
+const std::vector < SymbolType > & CompressedBitParallelTreeIndex < SymbolType >::getString ( ) const {
+	std::vector < SymbolType > res;
+
+	unsigned index = 0;
+
+	do {
+		for ( const std::pair < const SymbolType, common::SparseBoolVector > & compressedBitVector : m_vectors )
+			if ( compressedBitVector.second.size ( ) > index && compressedBitVector.second [ index ] ) {
+				res.push_back ( compressedBitVector.first );
+				continue;
+			}
+
+	} while ( res.size ( ) == index ++ + 1 );
+
+	return res;
+}
+
+template < class SymbolType >
+void CompressedBitParallelTreeIndex < SymbolType >::setCompressedBitVectorForSymbol ( SymbolType symbol, common::SparseBoolVector data ) {
+	this->m_vectors [ symbol ] = std::move ( data );
+}
+
+template < class SymbolType >
+void CompressedBitParallelTreeIndex < SymbolType >::operator >>( std::ostream & out ) const {
+	out << "(CompressedBitParallelTreeIndex " << this->m_vectors << ", " << m_jumpTable << ")";
+}
+
+template < class SymbolType >
+int CompressedBitParallelTreeIndex < SymbolType >::compare ( const CompressedBitParallelTreeIndex & other ) const {
+	auto first = std::tie ( getData ( ), getAlphabet ( ), getJumps ( ) );
+	auto second = std::tie ( other.getData ( ), other.getAlphabet ( ), other.getJumps ( ) );
+
+	static std::compare < decltype ( first ) > comp;
+
+	return comp ( first, second );
+}
+
+template < class SymbolType >
+CompressedBitParallelTreeIndex < SymbolType >::operator std::string ( ) const {
+	std::stringstream ss;
+	ss << * this;
+	return ss.str ( );
+}
+
+template < class SymbolType >
+CompressedBitParallelTreeIndex < SymbolType > CompressedBitParallelTreeIndex < SymbolType >::parse ( std::deque < sax::Token >::iterator & input ) {
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, CompressedBitParallelTreeIndex::getXmlTagName ( ) );
+	std::set < SymbolType > alphabet = alib::xmlApi < std::set < SymbolType > >::parse ( input );
+	std::map < SymbolType, common::SparseBoolVector > data = alib::xmlApi < std::map < SymbolType, common::SparseBoolVector > >::parse ( input );
+	std::vector < int > jumps = alib::xmlApi < std::vector < int > >::parse ( input );
+
+	CompressedBitParallelTreeIndex < SymbolType > res ( std::move ( alphabet ), std::move ( data ), std::move ( jumps ) );
+
+	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, CompressedBitParallelTreeIndex::getXmlTagName ( ) );
+	return res;
+}
+
+template < class SymbolType >
+void CompressedBitParallelTreeIndex < SymbolType >::compose ( std::deque < sax::Token > & out ) const {
+	out.emplace_back ( CompressedBitParallelTreeIndex::getXmlTagName ( ), sax::Token::TokenType::START_ELEMENT );
+	alib::xmlApi < std::set < SymbolType > >::compose ( out, getAlphabet ( ) );
+	alib::xmlApi < std::map < SymbolType, common::SparseBoolVector > >::compose ( out, getData ( ) );
+	alib::xmlApi < std::vector < int > >::compose ( out, getJumps ( ) );
+	out.emplace_back ( CompressedBitParallelTreeIndex::getXmlTagName ( ), sax::Token::TokenType::END_ELEMENT );
+}
+
+template < class SymbolType >
+alib::ObjectBase * CompressedBitParallelTreeIndex < SymbolType >::inc ( ) && {
+	return new alib::UniqueObject ( alib::Object ( std::move ( * this ) ), primitive::Integer ( 0 ) );
+}
+
+} /* namespace arbology */
+
+} /* namespace indexes */
+
+namespace std {
+
+template < class SymbolType >
+class ComponentConstraint < indexes::arbology::CompressedBitParallelTreeIndex < SymbolType >, SymbolType, indexes::arbology::GeneralAlphabet > {
+public:
+	static bool used ( const indexes::arbology::CompressedBitParallelTreeIndex < SymbolType > & index, const SymbolType & symbol ) {
+		const std::map < SymbolType, common::SparseBoolVector > & content = index.getData ( );
+
+		return content.find ( symbol ) != content.end ( );
+	}
+
+	static bool available ( const indexes::arbology::CompressedBitParallelTreeIndex < SymbolType > &, const SymbolType & ) {
+		return true;
+	}
+
+	static void valid ( const indexes::arbology::CompressedBitParallelTreeIndex < SymbolType > &, const SymbolType & ) {
+	}
+
+};
+
+} /* namespace std */
+
+#endif /* ARBOLOGY_COMPRESSED_BIT_PARALLEL_INDEX_H_ */
diff --git a/aquery2/src/aquery.cpp b/aquery2/src/aquery.cpp
index df81f9a05a088a1d8c5d7ced35692071f2e69ae5..b5ec252f630917c719ec1614777c8c5f3a4d1ea2 100644
--- a/aquery2/src/aquery.cpp
+++ b/aquery2/src/aquery.cpp
@@ -20,6 +20,7 @@
 #include <stringology/query/PositionHeapFactors.h>
 #include <stringology/query/BitParallelismFactors.h>
 #include <stringology/query/CompressedBitParallelismFactors.h>
+#include <arbology/query/CompressedBitParallelismPatterns.h>
 
 int main ( int argc, char * argv[] ) {
 	try {
@@ -34,6 +35,7 @@ int main ( int argc, char * argv[] ) {
 		allowed.push_back ( "positionHeapFactors" );
 		allowed.push_back ( "bitParallelismFactors" );
 		allowed.push_back ( "compressedBitParallelismFactors" );
+		allowed.push_back ( "compressedBitParallelismPatterns" );
 		TCLAP::ValuesConstraint < std::string > allowedVals ( allowed );
 
 		TCLAP::ValueArg < std::string > query ( "q", "query", "Query index", false, "exactFactorMatch", & allowedVals );
@@ -125,6 +127,19 @@ int main ( int argc, char * argv[] ) {
 			measurements::end ( );
 			measurements::start ( "Output write", measurements::Type::AUXILIARY );
 
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( query.getValue ( ) == "compressedBitParallelismPatterns" ) {
+			indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > compressedBitParallelTreeIndex = alib::XmlDataFactory::fromTokens < indexes::arbology::CompressedBitParallelTreeIndex < std::ranked_symbol < DefaultSymbolType, DefaultRankType > > > ( sax::FromXMLParserHelper::parseInput ( indexInput ) );
+			tree::RankedTreeWrapper pattern = alib::XmlDataFactory::fromTokens < tree::RankedTreeWrapper > ( std::move ( sax::FromXMLParserHelper::parseInput(true, patternInput).front ( ) ) );
+
+			measurements::end ( );
+			measurements::start ( "Algorithm", measurements::Type::MAIN );
+
+			std::set < unsigned > res = arbology::query::CompressedBitParallelismPatterns::query ( compressedBitParallelTreeIndex, pattern );
+
+			measurements::end ( );
+			measurements::start ( "Output write", measurements::Type::AUXILIARY );
+
 			alib::XmlDataFactory::toStdout ( res );
 		} else {
 			throw exception::CommonException ( "Invalid algorithm" );
diff --git a/tests.aarbology.sh b/tests.aarbology.sh
index ec0dc460158ef0bd140da95eea6ec6228283f2e9..4188340f3c1356297d5c62d9dc5a7a6d2e695bad 100755
--- a/tests.aarbology.sh
+++ b/tests.aarbology.sh
@@ -410,6 +410,8 @@ function runTestNonlinearPatternEnds {
 	clearResults
 }
 
+runTestPatternEnds "Exact Pattern Matching Using Compressed Bit Vectors (PrefixRanked)" "./aarbology2 -a compressedBitParallelIndex -s <(./acast2 -t PrefixRankedTree -i \"\$SUBJECT_FILE\" ) | ./aquery2 -q compressedBitParallelismPatterns -i - -p <( ./acast2 -t PrefixRankedPattern -i \"\$PATTERN_FILE\" ) | ./astat2 -p size"
+
 runTestPatternEnds "Exact Pattern Matching Automaton (PrefixRanked)" "./aarbology2 -a exactPatternMatchingAutomaton -p <(./acast2 -t PrefixRankedPattern -i <(./aaccess2 --tree alphabet -o add -i \"\$PATTERN_FILE\" -a <( ./aaccess2 --tree alphabet -o get -i \"\$SUBJECT_FILE\" ) ) ) | ./adeterminize2 | ./arun2 -t occurrences -a - -i <( ./acast2 -t PrefixRankedTree -i \"\$SUBJECT_FILE\" | ./acast2 -t LinearString ) | ./astat2 -p size"
 
 RAND_SIZE_SUBJECT=120