name: reorganize Name class

* Categorize class methods.
* Make append component methods inline.
* Make comparison operators non-member functions.
* Improve Doxygen.
* Simplify Name::at implementation.
* Reorder test cases.
* Add test coverage for Name::empty() and iterators.
* Make naming convention test case more readable,
  and move it to TestNameComponent test suite.

refs #4171

Change-Id: I5f7deff2535f8265ac4942f892879dd7e56f6414
diff --git a/tests/unit-tests/name.t.cpp b/tests/unit-tests/name.t.cpp
index 9840196..dff17e4 100644
--- a/tests/unit-tests/name.t.cpp
+++ b/tests/unit-tests/name.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -22,8 +22,6 @@
 #include "name.hpp"
 
 #include "boost-test.hpp"
-#include <boost/tuple/tuple.hpp>
-#include <boost/mpl/vector.hpp>
 #include <unordered_map>
 
 namespace ndn {
@@ -51,6 +49,8 @@
                            0x8,  0x3, // NameComponent
                              0x6e,  0x64,  0x6e};
 
+// ---- encoding, decoding ----
+
 BOOST_AUTO_TEST_CASE(Basic)
 {
   Name name("/hello/world");
@@ -89,23 +89,6 @@
   BOOST_CHECK_EQUAL(name.toUri(), "/local/ndn/prefix");
 }
 
-BOOST_AUTO_TEST_CASE(AppendsAndMultiEncode)
-{
-  Name name("/local");
-
-  BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
-                                Name1, Name1 + sizeof(Name1));
-
-  name.append("ndn");
-
-  BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
-                                Name2, Name2 + sizeof(Name2));
-
-  name.append("prefix");
-  BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
-                                TestName, TestName+sizeof(TestName));
-}
-
 BOOST_AUTO_TEST_CASE(ZeroLengthComponent)
 {
   static const uint8_t compOctets[] {0x08, 0x00};
@@ -130,183 +113,6 @@
   BOOST_CHECK(name2Encoded == nameBlock);
 }
 
-BOOST_AUTO_TEST_CASE(AppendNumber)
-{
-  Name name;
-  for (uint32_t i = 0; i < 10; i++)
-    {
-      name.appendNumber(i);
-    }
-
-  BOOST_CHECK_EQUAL(name.size(), 10);
-
-  for (uint32_t i = 0; i < 10; i++)
-    {
-      BOOST_CHECK_EQUAL(name[i].toNumber(), i);
-    }
-}
-
-class Numeric
-{
-public:
-  typedef std::list<boost::tuple<function<name::Component(uint64_t)>,
-                                 function<uint64_t(const name::Component&)>,
-                                 function<Name&(Name&, uint64_t)>,
-                                 Name/*expected*/,
-                                 uint64_t/*value*/,
-                                 function<bool(const name::Component&)> > > Dataset;
-
-  Numeric()
-  {
-    dataset.push_back(boost::make_tuple(bind(&name::Component::fromNumberWithMarker,
-                                             0xAA, _1),
-                                        bind(&name::Component::toNumberWithMarker, _1, 0xAA),
-                                        bind(&Name::appendNumberWithMarker, _1, 0xAA, _2),
-                                        Name("/%AA%03%E8"),
-                                        1000,
-                                        bind(&name::Component::isNumberWithMarker, _1, 0xAA)));
-    dataset.push_back(boost::make_tuple(&name::Component::fromSegment,
-                                        bind(&name::Component::toSegment, _1),
-                                        bind(&Name::appendSegment, _1, _2),
-                                        Name("/%00%27%10"),
-                                        10000,
-                                        bind(&name::Component::isSegment, _1)));
-    dataset.push_back(boost::make_tuple(&name::Component::fromSegmentOffset,
-                                        bind(&name::Component::toSegmentOffset, _1),
-                                        bind(&Name::appendSegmentOffset, _1, _2),
-                                        Name("/%FB%00%01%86%A0"),
-                                        100000,
-                                        bind(&name::Component::isSegmentOffset, _1)));
-    dataset.push_back(boost::make_tuple(&name::Component::fromVersion,
-                                        bind(&name::Component::toVersion, _1),
-                                        bind(static_cast<Name&(Name::*)(uint64_t)>(
-                                               &Name::appendVersion), _1, _2),
-                                        Name("/%FD%00%0FB%40"),
-                                        1000000,
-                                        bind(&name::Component::isVersion, _1)));
-    dataset.push_back(boost::make_tuple(&name::Component::fromSequenceNumber,
-                                        bind(&name::Component::toSequenceNumber, _1),
-                                        bind(&Name::appendSequenceNumber, _1, _2),
-                                        Name("/%FE%00%98%96%80"),
-                                        10000000,
-                                        bind(&name::Component::isSequenceNumber, _1)));
-  }
-
-  Dataset dataset;
-};
-
-class Timestamp
-{
-public:
-  typedef std::list<boost::tuple<function<name::Component(const time::system_clock::TimePoint&)>,
-                                 function<time::system_clock::TimePoint(const name::Component&)>,
-                                 function<Name&(Name&, const time::system_clock::TimePoint&)>,
-                                 Name/*expected*/,
-                                 time::system_clock::TimePoint/*value*/,
-                                 function<bool(const name::Component&)> > > Dataset;
-  Timestamp()
-  {
-    dataset.push_back(boost::make_tuple(&name::Component::fromTimestamp,
-                                        ndn::bind(&name::Component::toTimestamp, _1),
-                                        ndn::bind(&Name::appendTimestamp, _1, _2),
-                                        Name("/%FC%00%04%7BE%E3%1B%00%00"),
-                                        time::getUnixEpoch() + time::days(14600/*40 years*/),
-                                        bind(&name::Component::isTimestamp, _1)));
-  }
-
-  Dataset dataset;
-};
-
-typedef boost::mpl::vector<Numeric, Timestamp> ConventionsDatasets;
-
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(NamingConventions, T, ConventionsDatasets, T)
-{
-  // // These octets are obtained by the snippet below.
-  // // This check is intended to detect unexpected encoding change in the future.
-  // for (typename T::Dataset::const_iterator it = this->dataset.begin();
-  //      it != this->dataset.end(); ++it) {
-  //   Name name;
-  //   name.append(it->template get<0>()(it->template get<4>()));
-  //   std::cout << name << std::endl;
-  // }
-
-  name::Component invalidComponent1;
-  name::Component invalidComponent2("1234567890");
-
-  for (typename T::Dataset::const_iterator it = this->dataset.begin();
-       it != this->dataset.end(); ++it) {
-    const Name& expected = it->template get<3>();
-    BOOST_TEST_MESSAGE("Check " << expected[0].toUri());
-
-    BOOST_CHECK_EQUAL(expected[0].isGeneric(), true);
-
-    name::Component actualComponent = it->template get<0>()(it->template get<4>());
-    BOOST_CHECK_EQUAL(actualComponent, expected[0]);
-
-    Name actualName;
-    it->template get<2>()(actualName, it->template get<4>());
-    BOOST_CHECK_EQUAL(actualName, expected);
-
-    BOOST_CHECK_EQUAL(it->template get<5>()(expected[0]), true);
-    BOOST_REQUIRE_NO_THROW(it->template get<1>()(expected[0]));
-    BOOST_CHECK_EQUAL(it->template get<1>()(expected[0]), it->template get<4>());
-
-    BOOST_CHECK_EQUAL(it->template get<5>()(invalidComponent1), false);
-    BOOST_CHECK_EQUAL(it->template get<5>()(invalidComponent2), false);
-
-    BOOST_REQUIRE_THROW(it->template get<1>()(invalidComponent1), name::Component::Error);
-    BOOST_REQUIRE_THROW(it->template get<1>()(invalidComponent2), name::Component::Error);
-  }
-}
-
-BOOST_AUTO_TEST_CASE(GetSuccessor)
-{
-  BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%02").getSuccessor(), Name("ndn:/%00%01/%01%03"));
-  BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%FF").getSuccessor(), Name("ndn:/%00%01/%02%00"));
-  BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%FF%FF").getSuccessor(), Name("ndn:/%00%01/%00%00%00"));
-  BOOST_CHECK_EQUAL(Name().getSuccessor(), Name("ndn:/%00"));
-}
-
-BOOST_AUTO_TEST_CASE(Markers)
-{
-  Name name;
-  uint64_t number;
-
-  BOOST_REQUIRE_NO_THROW(number = name.appendSegment(30923).at(-1).toSegment());
-  BOOST_CHECK_EQUAL(number, 30923);
-
-  BOOST_REQUIRE_NO_THROW(number = name.appendSegmentOffset(589).at(-1).toSegmentOffset());
-  BOOST_CHECK_EQUAL(number, 589);
-
-  BOOST_REQUIRE_NO_THROW(number = name.appendVersion().at(-1).toVersion());
-
-  BOOST_REQUIRE_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
-  BOOST_CHECK_EQUAL(number, 25912);
-
-  const time::system_clock::TimePoint tp = time::system_clock::now();
-  time::system_clock::TimePoint tp2;
-  BOOST_REQUIRE_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
-  BOOST_CHECK_LE(std::abs(time::duration_cast<time::microseconds>(tp2 - tp).count()), 1);
-
-  BOOST_REQUIRE_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
-  BOOST_CHECK_EQUAL(number, 11676);
-}
-
-BOOST_AUTO_TEST_CASE(UnorderedMap)
-{
-  std::unordered_map<Name, int> map;
-  Name name1("/1");
-  Name name2("/2");
-  Name name3("/3");
-  map[name1] = 1;
-  map[name2] = 2;
-  map[name3] = 3;
-
-  BOOST_CHECK_EQUAL(map[name1], 1);
-  BOOST_CHECK_EQUAL(map[name2], 2);
-  BOOST_CHECK_EQUAL(map[name3], 3);
-}
-
 BOOST_AUTO_TEST_CASE(ImplicitSha256Digest)
 {
   Name n;
@@ -361,54 +167,6 @@
   BOOST_CHECK(n2.get(1).isGeneric());
 }
 
-BOOST_AUTO_TEST_CASE(Compare)
-{
-  BOOST_CHECK_EQUAL(Name("/A")  .compare(Name("/A")),   0);
-  BOOST_CHECK_EQUAL(Name("/A")  .compare(Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/A")  .compare(Name("/B")),   0);
-  BOOST_CHECK_GT   (Name("/B")  .compare(Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/A")  .compare(Name("/AA")),  0);
-  BOOST_CHECK_GT   (Name("/AA") .compare(Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/A")  .compare(Name("/A/C")), 0);
-  BOOST_CHECK_GT   (Name("/A/C").compare(Name("/A")),   0);
-
-  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/A")),   0);
-  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/B")),   0);
-  BOOST_CHECK_GT   (Name("/Z/B/Y")  .compare(1, 1, Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/AA")),  0);
-  BOOST_CHECK_GT   (Name("/Z/AA/Y") .compare(1, 1, Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/A/C")), 0);
-  BOOST_CHECK_GT   (Name("/Z/A/C/Y").compare(1, 2, Name("/A")),   0);
-
-  BOOST_CHECK_EQUAL(Name("/Z/A")  .compare(1, Name::npos, Name("/A")),   0);
-  BOOST_CHECK_EQUAL(Name("/Z/A")  .compare(1, Name::npos, Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/Z/A")  .compare(1, Name::npos, Name("/B")),   0);
-  BOOST_CHECK_GT   (Name("/Z/B")  .compare(1, Name::npos, Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/Z/A")  .compare(1, Name::npos, Name("/AA")),  0);
-  BOOST_CHECK_GT   (Name("/Z/AA") .compare(1, Name::npos, Name("/A")),   0);
-  BOOST_CHECK_LT   (Name("/Z/A")  .compare(1, Name::npos, Name("/A/C")), 0);
-  BOOST_CHECK_GT   (Name("/Z/A/C").compare(1, Name::npos, Name("/A")),   0);
-
-  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/X/A/W"),   1, 1), 0);
-  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/X/A/W"),   1, 1), 0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/B/W"),   1, 1), 0);
-  BOOST_CHECK_GT   (Name("/Z/B/Y")  .compare(1, 1, Name("/X/A/W"),   1, 1), 0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/AA/W"),  1, 1), 0);
-  BOOST_CHECK_GT   (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A/W"),   1, 1), 0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/A/C/W"), 1, 2), 0);
-  BOOST_CHECK_GT   (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A/W"),   1, 1), 0);
-
-  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/X/A"),   1), 0);
-  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/X/A"),   1), 0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/B"),   1), 0);
-  BOOST_CHECK_GT   (Name("/Z/B/Y")  .compare(1, 1, Name("/X/A"),   1), 0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/AA"),  1), 0);
-  BOOST_CHECK_GT   (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A"),   1), 0);
-  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/A/C"), 1), 0);
-  BOOST_CHECK_GT   (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A"),   1), 0);
-}
-
 BOOST_AUTO_TEST_CASE(NameWithSpaces)
 {
   Name name("/ hello\t/\tworld \r\n");
@@ -417,6 +175,62 @@
   BOOST_CHECK_THROW(Name("/hello//world"), name::Component::Error);
 }
 
+BOOST_AUTO_TEST_CASE(DeepCopy)
+{
+  Name n1("/hello/world");
+  Name n2 = n1.deepCopy();
+
+  BOOST_CHECK_EQUAL(n1, n2);
+  BOOST_CHECK_NE(&n1.wireEncode(), &n2.wireEncode());
+
+  EncodingBuffer buffer(1024, 0);
+  n1.wireEncode(buffer);
+  Name n3(buffer.block());
+
+  BOOST_CHECK_EQUAL(n1, n3);
+  BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), 1024);
+  n3 = n3.deepCopy();
+
+  BOOST_CHECK_LT(n3.wireEncode().size(), 1024);
+  BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), n3.wireEncode().size());
+}
+
+// ---- iterators ----
+
+BOOST_AUTO_TEST_CASE(ForwardIterator)
+{
+  name::Component comps[] {
+    name::Component("A"),
+    name::Component("B"),
+    name::Component("C"),
+    name::Component("D")
+  };
+
+  Name n0;
+  BOOST_CHECK_EQUAL_COLLECTIONS(n0.begin(), n0.end(), comps, comps + 0);
+
+  Name n4("/A/B/C/D");
+  BOOST_CHECK_EQUAL_COLLECTIONS(n4.begin(), n4.end(), comps, comps + 4);
+}
+
+BOOST_AUTO_TEST_CASE(ReverseIterator)
+{
+  name::Component comps[] {
+    name::Component("D"),
+    name::Component("C"),
+    name::Component("B"),
+    name::Component("A")
+  };
+
+  Name n0;
+  BOOST_CHECK_EQUAL_COLLECTIONS(n0.rbegin(), n0.rend(), comps, comps + 0);
+
+  Name n4("/A/B/C/D");
+  BOOST_CHECK_EQUAL_COLLECTIONS(n4.rbegin(), n4.rend(), comps, comps + 4);
+}
+
+// ---- modifiers ----
+
 BOOST_AUTO_TEST_CASE(Append)
 {
   PartialName toAppend("/and");
@@ -436,6 +250,126 @@
   }
 }
 
+BOOST_AUTO_TEST_CASE(AppendsAndMultiEncode)
+{
+  Name name("/local");
+  BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
+                                Name1, Name1 + sizeof(Name1));
+
+  name.append("ndn");
+  BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
+                                Name2, Name2 + sizeof(Name2));
+
+  name.append("prefix");
+  BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
+                                TestName, TestName+sizeof(TestName));
+}
+
+BOOST_AUTO_TEST_CASE(AppendNumber)
+{
+  Name name;
+  for (uint32_t i = 0; i < 10; i++) {
+    name.appendNumber(i);
+  }
+
+  BOOST_CHECK_EQUAL(name.size(), 10);
+
+  for (uint32_t i = 0; i < 10; i++) {
+    BOOST_CHECK_EQUAL(name[i].toNumber(), i);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(Markers)
+{
+  // TestNameComponent/NamingConvention provides additional coverage for these methods,
+  // including verifications of the wire format.
+
+  Name name;
+  uint64_t number;
+
+  BOOST_REQUIRE_NO_THROW(number = name.appendSegment(30923).at(-1).toSegment());
+  BOOST_CHECK_EQUAL(number, 30923);
+
+  BOOST_REQUIRE_NO_THROW(number = name.appendSegmentOffset(589).at(-1).toSegmentOffset());
+  BOOST_CHECK_EQUAL(number, 589);
+
+  BOOST_REQUIRE_NO_THROW(number = name.appendVersion().at(-1).toVersion());
+
+  BOOST_REQUIRE_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
+  BOOST_CHECK_EQUAL(number, 25912);
+
+  const time::system_clock::TimePoint tp = time::system_clock::now();
+  time::system_clock::TimePoint tp2;
+  BOOST_REQUIRE_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
+  BOOST_CHECK_LE(std::abs(time::duration_cast<time::microseconds>(tp2 - tp).count()), 1);
+
+  BOOST_REQUIRE_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
+  BOOST_CHECK_EQUAL(number, 11676);
+}
+
+BOOST_AUTO_TEST_CASE(Clear)
+{
+  Name n("/A");
+  BOOST_CHECK_EQUAL(n.empty(), false);
+
+  n.clear();
+  BOOST_CHECK_EQUAL(n.empty(), true);
+  BOOST_CHECK_EQUAL(n.size(), 0);
+}
+
+// ---- algorithms ----
+
+BOOST_AUTO_TEST_CASE(GetSuccessor)
+{
+  BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%02").getSuccessor(), Name("ndn:/%00%01/%01%03"));
+  BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%FF").getSuccessor(), Name("ndn:/%00%01/%02%00"));
+  BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%FF%FF").getSuccessor(), Name("ndn:/%00%01/%00%00%00"));
+  BOOST_CHECK_EQUAL(Name().getSuccessor(), Name("ndn:/%00"));
+}
+
+BOOST_AUTO_TEST_CASE(Compare)
+{
+  BOOST_CHECK_EQUAL(Name("/A")  .compare(Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/A")  .compare(Name("/B")),   0);
+  BOOST_CHECK_GT   (Name("/B")  .compare(Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/A")  .compare(Name("/AA")),  0);
+  BOOST_CHECK_GT   (Name("/AA") .compare(Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/A")  .compare(Name("/A/C")), 0);
+  BOOST_CHECK_GT   (Name("/A/C").compare(Name("/A")),   0);
+
+  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/B")),   0);
+  BOOST_CHECK_GT   (Name("/Z/B/Y")  .compare(1, 1, Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/AA")),  0);
+  BOOST_CHECK_GT   (Name("/Z/AA/Y") .compare(1, 1, Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/A/C")), 0);
+  BOOST_CHECK_GT   (Name("/Z/A/C/Y").compare(1, 2, Name("/A")),   0);
+
+  BOOST_CHECK_EQUAL(Name("/Z/A")  .compare(1, Name::npos, Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/Z/A")  .compare(1, Name::npos, Name("/B")),   0);
+  BOOST_CHECK_GT   (Name("/Z/B")  .compare(1, Name::npos, Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/Z/A")  .compare(1, Name::npos, Name("/AA")),  0);
+  BOOST_CHECK_GT   (Name("/Z/AA") .compare(1, Name::npos, Name("/A")),   0);
+  BOOST_CHECK_LT   (Name("/Z/A")  .compare(1, Name::npos, Name("/A/C")), 0);
+  BOOST_CHECK_GT   (Name("/Z/A/C").compare(1, Name::npos, Name("/A")),   0);
+
+  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/X/A/W"),   1, 1), 0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/B/W"),   1, 1), 0);
+  BOOST_CHECK_GT   (Name("/Z/B/Y")  .compare(1, 1, Name("/X/A/W"),   1, 1), 0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/AA/W"),  1, 1), 0);
+  BOOST_CHECK_GT   (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A/W"),   1, 1), 0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/A/C/W"), 1, 2), 0);
+  BOOST_CHECK_GT   (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A/W"),   1, 1), 0);
+
+  BOOST_CHECK_EQUAL(Name("/Z/A/Y")  .compare(1, 1, Name("/X/A"),   1), 0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/B"),   1), 0);
+  BOOST_CHECK_GT   (Name("/Z/B/Y")  .compare(1, 1, Name("/X/A"),   1), 0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/AA"),  1), 0);
+  BOOST_CHECK_GT   (Name("/Z/AA/Y") .compare(1, 1, Name("/X/A"),   1), 0);
+  BOOST_CHECK_LT   (Name("/Z/A/Y")  .compare(1, 1, Name("/X/A/C"), 1), 0);
+  BOOST_CHECK_GT   (Name("/Z/A/C/Y").compare(1, 2, Name("/X/A"),   1), 0);
+}
+
 BOOST_AUTO_TEST_CASE(SubName)
 {
   Name name("/hello/world");
@@ -474,24 +408,19 @@
   BOOST_CHECK_EQUAL("/first/second/last", name.getSubName(-10, 10));
 }
 
-BOOST_AUTO_TEST_CASE(DeepCopy)
+BOOST_AUTO_TEST_CASE(UnorderedMap)
 {
-  Name n1("/hello/world");
-  Name n2 = n1.deepCopy();
+  std::unordered_map<Name, int> map;
+  Name name1("/1");
+  Name name2("/2");
+  Name name3("/3");
+  map[name1] = 1;
+  map[name2] = 2;
+  map[name3] = 3;
 
-  BOOST_CHECK_EQUAL(n1, n2);
-  BOOST_CHECK_NE(&n1.wireEncode(), &n2.wireEncode());
-
-  EncodingBuffer buffer(1024, 0);
-  n1.wireEncode(buffer);
-  Name n3(buffer.block());
-
-  BOOST_CHECK_EQUAL(n1, n3);
-  BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), 1024);
-  n3 = n3.deepCopy();
-
-  BOOST_CHECK_LT(n3.wireEncode().size(), 1024);
-  BOOST_CHECK_EQUAL(n3.wireEncode().getBuffer()->size(), n3.wireEncode().size());
+  BOOST_CHECK_EQUAL(map[name1], 1);
+  BOOST_CHECK_EQUAL(map[name2], 2);
+  BOOST_CHECK_EQUAL(map[name3], 3);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestName