table: NameTree enumeration

refs #1318

Change-Id: I26f25cefe8f2939ca884103f1b081c0c02325207
diff --git a/tests/table/name-tree.cpp b/tests/table/name-tree.cpp
index 4411fd2..e44c401 100644
--- a/tests/table/name-tree.cpp
+++ b/tests/table/name-tree.cpp
@@ -5,7 +5,6 @@
  */
 
 #include "table/name-tree.hpp"
-
 #include "tests/test-common.hpp"
 
 namespace nfd {
@@ -19,7 +18,7 @@
 {
   Name prefix("ndn:/named-data/research/abc/def/ghi");
 
-  name_tree::Entry npe = name_tree::Entry(prefix);
+  name_tree::Entry npe(prefix);
   BOOST_CHECK_EQUAL(npe.getPrefix(), prefix);
 
   // examine all the get methods
@@ -39,7 +38,7 @@
   std::vector< shared_ptr<pit::Entry> >& pitList = npe.getPitEntries();
   BOOST_CHECK_EQUAL(pitList.size(), 0);
 
-  // examine all the set method 
+  // examine all the set method
 
   npe.setHash(12345);
   BOOST_CHECK_EQUAL(npe.getHash(), 12345);
@@ -49,15 +48,15 @@
   npe.setParent(parent);
   BOOST_CHECK_EQUAL(npe.getParent(), parent);
 
-  // Insert FIB 
+  // Insert FIB
 
   shared_ptr<fib::Entry> fibEntry(new fib::Entry(prefix));
   shared_ptr<fib::Entry> fibEntryParent(new fib::Entry(parentName));
-  
+
   npe.setFibEntry(fibEntry);
   BOOST_CHECK_EQUAL(npe.getFibEntry(), fibEntry);
 
-  // Erase a FIB that does not exist 
+  // Erase a FIB that does not exist
   BOOST_CHECK_EQUAL(npe.
   eraseFibEntry(fibEntryParent), false);
   BOOST_CHECK_EQUAL(npe.getFibEntry(), fibEntry);
@@ -70,7 +69,7 @@
   // Insert a PIT
 
   shared_ptr<pit::Entry> PitEntry(make_shared<pit::Entry>(prefix));
-  shared_ptr<pit::Entry> PitEntry2(make_shared<pit::Entry>(parentName)); 
+  shared_ptr<pit::Entry> PitEntry2(make_shared<pit::Entry>(parentName));
 
   Name prefix3("ndn:/named-data/research/abc/def");
   shared_ptr<pit::Entry> PitEntry3(make_shared<pit::Entry>(prefix3));
@@ -107,25 +106,25 @@
   NameTree nt(nBuckets);
 
   BOOST_CHECK_EQUAL(nt.size(), 0);
-  BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets); 
+  BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
 
-  Name nameABC = ("ndn:/a/b/c");
+  Name nameABC("ndn:/a/b/c");
   shared_ptr<name_tree::Entry> npeABC = nt.lookup(nameABC);
   BOOST_CHECK_EQUAL(nt.size(), 4);
-  
-  Name nameABD = ("/a/b/d");
+
+  Name nameABD("/a/b/d");
   shared_ptr<name_tree::Entry> npeABD = nt.lookup(nameABD);
   BOOST_CHECK_EQUAL(nt.size(), 5);
 
-  Name nameAE = ("/a/e/");
+  Name nameAE("/a/e/");
   shared_ptr<name_tree::Entry> npeAE = nt.lookup(nameAE);
   BOOST_CHECK_EQUAL(nt.size(), 6);
 
-  Name nameF = ("/f");
+  Name nameF("/f");
   shared_ptr<name_tree::Entry> npeF = nt.lookup(nameF);
   BOOST_CHECK_EQUAL(nt.size(), 7);
 
-  // validate lookup() and findExactMatch() 
+  // validate lookup() and findExactMatch()
 
   Name nameAB ("/a/b");
   BOOST_CHECK_EQUAL(npeABC->getParent(), nt.findExactMatch(nameAB));
@@ -138,7 +137,7 @@
   BOOST_CHECK_EQUAL(npeF->getParent(), nt.findExactMatch(nameRoot));
   BOOST_CHECK_EQUAL(nt.size(), 7);
 
-  Name name0 = ("/does/not/exist");
+  Name name0("/does/not/exist");
   shared_ptr<name_tree::Entry> npe0 = nt.findExactMatch(name0);
   BOOST_CHECK(!static_cast<bool>(npe0));
 
@@ -174,8 +173,6 @@
   temp = nt.findLongestPrefixMatch(nameRootLPM);
   BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameRoot));
 
-  // nt.dump(std::cout);
-
   bool eraseResult = false;
   temp = nt.findExactMatch(nameABC);
   if (static_cast<bool>(temp))
@@ -187,7 +184,7 @@
 
   eraseResult = false;
   temp = nt.findExactMatch(nameABCLPM);
-  if (static_cast<bool>(temp)) 
+  if (static_cast<bool>(temp))
     eraseResult = nt.
   eraseEntryIfEmpty(temp);
   BOOST_CHECK(!static_cast<bool>(temp));
@@ -201,18 +198,16 @@
 
   eraseResult = false;
   temp = nt.findExactMatch(nameABC);
-  if (static_cast<bool>(temp)) 
+  if (static_cast<bool>(temp))
     eraseResult = nt.
   eraseEntryIfEmpty(temp);
   BOOST_CHECK_EQUAL(nt.size(), 6);
   BOOST_CHECK_EQUAL(eraseResult, true);
   BOOST_CHECK(!static_cast<bool>(nt.findExactMatch(nameABC)));
 
-  // nt.dump(std::cout);
-
   BOOST_CHECK_EQUAL(nt.getNBuckets(), 16);
 
-  // should resize now 
+  // should resize now
   Name nameABCD("a/b/c/d");
   nt.lookup(nameABCD);
   Name nameABCDE("a/b/c/d/e");
@@ -220,9 +215,7 @@
   BOOST_CHECK_EQUAL(nt.size(), 9);
   BOOST_CHECK_EQUAL(nt.getNBuckets(), 32);
 
-  // nt.dump(std::cout);
-
-  // try to erase /a/b/c, should return false 
+  // try to erase /a/b/c, should return false
   temp = nt.findExactMatch(nameABC);
   BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
   eraseResult = nt.
@@ -232,38 +225,556 @@
   BOOST_CHECK_EQUAL(temp->getPrefix(), nameABC);
 
   temp = nt.findExactMatch(nameABD);
-  if (static_cast<bool>(temp)) 
+  if (static_cast<bool>(temp))
     nt.
   eraseEntryIfEmpty(temp);
   BOOST_CHECK_EQUAL(nt.size(), 8);
-  
-  // nt.dump(std::cout);
+}
 
-  shared_ptr<std::vector<shared_ptr<name_tree::Entry> > > fullList;
-  fullList = nt.fullEnumerate();
-  BOOST_CHECK_EQUAL(fullList->size(), 8);
-  // for (size_t j = 0; j < (*fullList).size(); j++)
-  // {
-  //  temp = (*fullList)[j];
-  //  std::cout << temp->getPrefix().toUri() << std::endl;
-  // }
+BOOST_AUTO_TEST_CASE(NameTreeIteratorFullEnumerate)
+{
+  using namespace std;
 
-  shared_ptr<std::vector<shared_ptr<name_tree::Entry> > > partialList;
-  partialList = nt.partialEnumerate(nameA);
-  BOOST_CHECK_EQUAL(partialList->size(), 6);
-  // for (size_t j = 0; j < (*partialList).size(); j++)
-  // {
-  //  temp = (*partialList)[j];
-  //  std::cout << temp->getPrefix().toUri() << std::endl;
-  // }
+  size_t nBuckets = 1024;
+  NameTree nt(nBuckets);
 
-  partialList = nt.partialEnumerate(nameRoot);
-  BOOST_CHECK_EQUAL(partialList->size(), 8);
-  // for (size_t j = 0; j < (*partialList).size(); j++)
-  // {
-  //  temp = (*partialList)[j];
-  //  std::cout << temp->getPrefix().toUri() << std::endl;
-  // }
+  BOOST_CHECK_EQUAL(nt.size(), 0);
+  BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);
+
+  Name nameABC("ndn:/a/b/c");
+  shared_ptr<name_tree::Entry> npeABC = nt.lookup(nameABC);
+  BOOST_CHECK_EQUAL(nt.size(), 4);
+
+  Name nameABD("/a/b/d");
+  shared_ptr<name_tree::Entry> npeABD = nt.lookup(nameABD);
+  BOOST_CHECK_EQUAL(nt.size(), 5);
+
+  Name nameAE("/a/e/");
+  shared_ptr<name_tree::Entry> npeAE = nt.lookup(nameAE);
+  BOOST_CHECK_EQUAL(nt.size(), 6);
+
+  Name nameF("/f");
+  shared_ptr<name_tree::Entry> npeF = nt.lookup(nameF);
+  BOOST_CHECK_EQUAL(nt.size(), 7);
+
+  Name nameRoot("/");
+  shared_ptr<name_tree::Entry> npeRoot = nt.lookup(nameRoot);
+  BOOST_CHECK_EQUAL(nt.size(), 7);
+
+  Name nameA("/a");
+  Name nameAB("/a/b");
+
+  bool hasRoot  = false;
+  bool hasA     = false;
+  bool hasAB    = false;
+  bool hasABC   = false;
+  bool hasABD   = false;
+  bool hasAE    = false;
+  bool hasF     = false;
+
+  int counter = 0;
+  NameTree::const_iterator it = nt.fullEnumerate();
+
+  for(; it != nt.end(); it++)
+  {
+    counter++;
+
+    if (it->getPrefix() == nameRoot)
+      hasRoot = true;
+    if (it->getPrefix() == nameA)
+      hasA    = true;
+    if (it->getPrefix() == nameAB)
+      hasAB   = true;
+    if (it->getPrefix() == nameABC)
+      hasABC  = true;
+    if (it->getPrefix() == nameABD)
+      hasABD  = true;
+    if (it->getPrefix() == nameAE)
+      hasAE   = true;
+    if (it->getPrefix() == nameF)
+      hasF    = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasRoot , true);
+  BOOST_CHECK_EQUAL(hasA    , true);
+  BOOST_CHECK_EQUAL(hasAB   , true);
+  BOOST_CHECK_EQUAL(hasABC  , true);
+  BOOST_CHECK_EQUAL(hasABD  , true);
+  BOOST_CHECK_EQUAL(hasAE   , true);
+  BOOST_CHECK_EQUAL(hasF    , true);
+
+  BOOST_CHECK_EQUAL(counter , 7);
+}
+
+// Predicates for testing the partial enumerate function
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NameA_Only(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  bool first = nameA.equals(entry.getPrefix());
+  return std::make_pair(first, true);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_Except_NameA(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  bool first = !(nameA.equals(entry.getPrefix()));
+  return std::make_pair(first, true);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NoSubNameA(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  bool second = !(nameA.equals(entry.getPrefix()));
+  return std::make_pair(true, second);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NoNameA_NoSubNameAB(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  Name nameAB("/a/b");
+  bool first = !(nameA.equals(entry.getPrefix()));
+  bool second = !(nameAB.equals(entry.getPrefix()));
+  return std::make_pair(first, second);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_NoNameA_NoSubNameAC(const name_tree::Entry& entry)
+{
+  Name nameA("/a");
+  Name nameAC("/a/c");
+  bool first = !(nameA.equals(entry.getPrefix()));
+  bool second = !(nameAC.equals(entry.getPrefix()));
+  return std::make_pair(first, second);
+}
+
+static inline std::pair<bool, bool>
+predicate_NameTreeEntry_Example(const name_tree::Entry& entry)
+{
+  Name nameRoot("/");
+  Name nameA("/a");
+  Name nameAB("/a/b");
+  Name nameABC("/a/b/c");
+  Name nameAD("/a/d");
+  Name nameE("/e");
+  Name nameF("/f");
+
+  bool first = false;
+  bool second = false;
+
+  Name name = entry.getPrefix();
+
+  if (name == nameRoot || name == nameAB || name == nameABC || name == nameAD)
+  {
+    first = true;
+  }
+
+  if(name == nameRoot || name == nameA || name == nameF)
+  {
+    second = true;
+  }
+
+  return std::make_pair(first, second);
+}
+
+BOOST_AUTO_TEST_CASE(NameTreeIteratorPartialEnumerate)
+{
+  using namespace std;
+  typedef NameTree::const_iterator const_iterator;
+
+  size_t nBuckets = 16;
+  NameTree nameTree(nBuckets);
+  int counter = 0;
+
+  // empty nameTree, should return end();
+  Name nameA("/a");
+  bool hasA = false;
+  const_iterator itA = nameTree.partialEnumerate(nameA);
+  BOOST_CHECK(itA == nameTree.end());
+
+  // We have "/", "/a", "/a/b", "a/c" now.
+  Name nameAB("/a/b");
+  bool hasAB = false;
+  nameTree.lookup(nameAB);
+
+  Name nameAC("/a/c");
+  bool hasAC = false;
+  nameTree.lookup(nameAC);
+  BOOST_CHECK_EQUAL(nameTree.size(), 4);
+
+  // Enumerate on some name that is not in nameTree
+  Name name0="/0";
+  const_iterator it0 = nameTree.partialEnumerate(name0);
+  BOOST_CHECK(it0 == nameTree.end());
+
+  // Accept "root" nameA only
+  const_iterator itAOnly = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NameA_Only);
+  BOOST_CHECK_EQUAL(itAOnly->getPrefix(), nameA);
+  BOOST_CHECK(++itAOnly == nameTree.end());
+
+  // Accept anything except "root" nameA
+  const_iterator itExceptA = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_Except_NameA);
+  hasA = false;
+  hasAB = false;
+  hasAC = false;
+
+  counter = 0;
+  for (; itExceptA != nameTree.end(); itExceptA++)
+  {
+    counter++;
+
+    if (itExceptA->getPrefix() == nameA)
+      hasA  = true;
+
+    if (itExceptA->getPrefix() == nameAB)
+      hasAB = true;
+
+    if (itExceptA->getPrefix() == nameAC)
+      hasAC = true;
+  }
+  BOOST_CHECK_EQUAL(hasA,  false);
+  BOOST_CHECK_EQUAL(hasAB, true);
+  BOOST_CHECK_EQUAL(hasAC, true);
+
+  BOOST_CHECK_EQUAL(counter, 2);
+
+  Name nameAB1("a/b/1");
+  bool hasAB1 = false;
+  nameTree.lookup(nameAB1);
+
+  Name nameAB2("a/b/2");
+  bool hasAB2 = false;
+  nameTree.lookup(nameAB2);
+
+  Name nameAC1("a/c/1");
+  bool hasAC1 = false;
+  nameTree.lookup(nameAC1);
+
+  Name nameAC2("a/c/2");
+  bool hasAC2 = false;
+  nameTree.lookup(nameAC2);
+
+  BOOST_CHECK_EQUAL(nameTree.size(), 8);
+
+  // No NameA
+  // No SubTree from NameAB
+  const_iterator itNoNameANoSubNameAB = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoNameA_NoSubNameAB);
+  hasA   = false;
+  hasAB  = false;
+  hasAB1 = false;
+  hasAB2 = false;
+  hasAC  = false;
+  hasAC1 = false;
+  hasAC2 = false;
+
+  counter = 0;
+
+  for (; itNoNameANoSubNameAB != nameTree.end(); itNoNameANoSubNameAB++)
+  {
+    counter++;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameA)
+      hasA   = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAB)
+      hasAB  = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAB1)
+      hasAB1 = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAB2)
+      hasAB2 = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAC)
+      hasAC  = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAC1)
+      hasAC1 = true;
+
+    if (itNoNameANoSubNameAB->getPrefix() == nameAC2)
+      hasAC2 = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasA,   false);
+  BOOST_CHECK_EQUAL(hasAB,  true);
+  BOOST_CHECK_EQUAL(hasAB1, false);
+  BOOST_CHECK_EQUAL(hasAB2, false);
+  BOOST_CHECK_EQUAL(hasAC,  true);
+  BOOST_CHECK_EQUAL(hasAC1, true);
+  BOOST_CHECK_EQUAL(hasAC2, true);
+
+  BOOST_CHECK_EQUAL(counter, 4);
+
+  // No NameA
+  // No SubTree from NameAC
+  const_iterator itNoNameANoSubNameAC = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoNameA_NoSubNameAC);
+  hasA   = false;
+  hasAB  = false;
+  hasAB1 = false;
+  hasAB2 = false;
+  hasAC  = false;
+  hasAC1 = false;
+  hasAC2 = false;
+
+  counter = 0;
+
+  for (; itNoNameANoSubNameAC != nameTree.end(); itNoNameANoSubNameAC++)
+  {
+    counter++;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameA)
+      hasA   = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAB)
+      hasAB  = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAB1)
+      hasAB1 = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAB2)
+      hasAB2 = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAC)
+      hasAC  = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAC1)
+      hasAC1 = true;
+
+    if (itNoNameANoSubNameAC->getPrefix() == nameAC2)
+      hasAC2 = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasA,   false);
+  BOOST_CHECK_EQUAL(hasAB,  true);
+  BOOST_CHECK_EQUAL(hasAB1, true);
+  BOOST_CHECK_EQUAL(hasAB2, true);
+  BOOST_CHECK_EQUAL(hasAC,  true);
+  BOOST_CHECK_EQUAL(hasAC1, false);
+  BOOST_CHECK_EQUAL(hasAC2, false);
+
+  BOOST_CHECK_EQUAL(counter, 4);
+
+  // No Subtree from NameA
+  const_iterator itNoANoSubNameA = nameTree.partialEnumerate(nameA, &predicate_NameTreeEntry_NoSubNameA);
+
+  hasA   = false;
+  hasAB  = false;
+  hasAB1 = false;
+  hasAB2 = false;
+  hasAC  = false;
+  hasAC1 = false;
+  hasAC2 = false;
+
+  counter = 0;
+
+  for (; itNoANoSubNameA != nameTree.end(); itNoANoSubNameA++)
+  {
+    counter++;
+
+    if (itNoANoSubNameA->getPrefix() == nameA)
+      hasA   = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAB)
+      hasAB  = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAB1)
+      hasAB1 = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAB2)
+      hasAB2 = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAC)
+      hasAC  = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAC1)
+      hasAC1 = true;
+
+    if (itNoANoSubNameA->getPrefix() == nameAC2)
+      hasAC2 = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasA,   true);
+  BOOST_CHECK_EQUAL(hasAB,  false);
+  BOOST_CHECK_EQUAL(hasAB1, false);
+  BOOST_CHECK_EQUAL(hasAB2, false);
+  BOOST_CHECK_EQUAL(hasAC,  false);
+  BOOST_CHECK_EQUAL(hasAC1, false);
+  BOOST_CHECK_EQUAL(hasAC2, false);
+
+  BOOST_CHECK_EQUAL(counter, 1);
+
+  // Example
+  // /
+  // /A
+  // /A/B x
+  // /A/B/C
+  // /A/D x
+  // /E
+  // /F
+
+  NameTree nameTreeExample(nBuckets);
+
+  Name nameRoot("/");
+  bool hasRoot = false;
+
+  nameTreeExample.lookup(nameA);
+  hasA = false;
+  nameTreeExample.lookup(nameAB);
+  hasAB = false;
+
+  Name nameABC("a/b/c");
+  bool hasABC = false;
+  nameTreeExample.lookup(nameABC);
+
+  Name nameAD("/a/d");
+  nameTreeExample.lookup(nameAD);
+  bool hasAD = false;
+
+  Name nameE("/e");
+  nameTreeExample.lookup(nameE);
+  bool hasE = false;
+
+  Name nameF("/f");
+  nameTreeExample.lookup(nameF);
+  bool hasF = false;
+
+  counter = 0;
+  const_iterator itExample = nameTreeExample.partialEnumerate(nameA, &predicate_NameTreeEntry_Example);
+
+  for (; itExample != nameTreeExample.end(); itExample++)
+  {
+    counter++;
+
+    if (itExample->getPrefix() == nameRoot)
+      hasRoot = true;
+
+    if (itExample->getPrefix() == nameA)
+     hasA     = true;
+
+    if (itExample->getPrefix() == nameAB)
+     hasAB    = true;
+
+    if (itExample->getPrefix() == nameABC)
+     hasABC   = true;
+
+    if (itExample->getPrefix() == nameAD)
+     hasAD    = true;
+
+    if (itExample->getPrefix() == nameE)
+     hasE     = true;
+
+    if (itExample->getPrefix() == nameF)
+      hasF    = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasRoot, false);
+  BOOST_CHECK_EQUAL(hasA,    false);
+  BOOST_CHECK_EQUAL(hasAB,   true);
+  BOOST_CHECK_EQUAL(hasABC,  false);
+  BOOST_CHECK_EQUAL(hasAD,   true);
+  BOOST_CHECK_EQUAL(hasE,    false);
+  BOOST_CHECK_EQUAL(hasF,    false);
+
+  BOOST_CHECK_EQUAL(counter, 2);
+}
+
+
+BOOST_AUTO_TEST_CASE(NameTreeIteratorFindAllMatches)
+{
+  using namespace std;
+
+  size_t nBuckets = 16;
+  NameTree nt(nBuckets);
+  int counter = 0;
+
+  Name nameABCDEF("a/b/c/d/e/f");
+  shared_ptr<name_tree::Entry> npeABCDEF = nt.lookup(nameABCDEF);
+
+  Name nameAAC("a/a/c");
+  shared_ptr<name_tree::Entry> npeAAC = nt.lookup(nameAAC);
+
+  Name nameAAD1("a/a/d/1");
+  shared_ptr<name_tree::Entry> npeAAD1 = nt.lookup(nameAAD1);
+
+  Name nameAAD2("a/a/d/2");
+  shared_ptr<name_tree::Entry> npeAAD2 = nt.lookup(nameAAD2);
+
+
+  BOOST_CHECK_EQUAL(nt.size(), 12);
+
+  Name nameRoot ("/");
+  Name nameA    ("/a");
+  Name nameAB   ("/a/b");
+  Name nameABC  ("/a/b/c");
+  Name nameABCD ("/a/b/c/d");
+  Name nameABCDE("/a/b/c/d/e");
+  Name nameAA   ("/a/a");
+  Name nameAAD  ("/a/a/d");
+
+  bool hasRoot    = false;
+  bool hasA       = false;
+  bool hasAB      = false;
+  bool hasABC     = false;
+  bool hasABCD    = false;
+  bool hasABCDE   = false;
+  bool hasABCDEF  = false;
+  bool hasAA      = false;
+  bool hasAAC     = false;
+  bool hasAAD     = false;
+  bool hasAAD1    = false;
+  bool hasAAD2    = false;
+
+  counter = 0;
+
+  for (NameTree::const_iterator it = nt.findAllMatches(nameABCDEF);
+      it != nt.end(); it++)
+  {
+    counter++;
+
+    if (it->getPrefix() == nameRoot)
+      hasRoot   = true;
+    if (it->getPrefix() == nameA)
+      hasA      = true;
+    if (it->getPrefix() == nameAB)
+      hasAB     = true;
+    if (it->getPrefix() == nameABC)
+      hasABC    = true;
+    if (it->getPrefix() == nameABCD)
+      hasABCD   = true;
+    if (it->getPrefix() == nameABCDE)
+      hasABCDE  = true;
+    if (it->getPrefix() == nameABCDEF)
+      hasABCDEF = true;
+    if (it->getPrefix() == nameAA)
+      hasAA     = true;
+    if (it->getPrefix() == nameAAC)
+      hasAAC    = true;
+    if (it->getPrefix() == nameAAD)
+      hasAAD    = true;
+    if (it->getPrefix() == nameAAD1)
+      hasAAD1   = true;
+    if (it->getPrefix() == nameAAD2)
+      hasAAD2   = true;
+  }
+
+  BOOST_CHECK_EQUAL(hasRoot   , true);
+  BOOST_CHECK_EQUAL(hasA      , true);
+  BOOST_CHECK_EQUAL(hasAB     , true);
+  BOOST_CHECK_EQUAL(hasABC    , true);
+  BOOST_CHECK_EQUAL(hasABCD   , true);
+  BOOST_CHECK_EQUAL(hasABCDE  , true);
+  BOOST_CHECK_EQUAL(hasABCDEF , true);
+  BOOST_CHECK_EQUAL(hasAA     , false);
+  BOOST_CHECK_EQUAL(hasAAC    , false);
+  BOOST_CHECK_EQUAL(hasAAD    , false);
+  BOOST_CHECK_EQUAL(hasAAD1   , false);
+  BOOST_CHECK_EQUAL(hasAAD2   , false);
+
+  BOOST_CHECK_EQUAL(counter, 7);
 }
 
 BOOST_AUTO_TEST_SUITE_END()