diff --git a/src/name.cpp b/src/name.cpp
index ad15d08..58b1cc3 100644
--- a/src/name.cpp
+++ b/src/name.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).
@@ -25,10 +25,11 @@
 
 #include "name.hpp"
 
-#include "util/time.hpp"
 #include "encoding/block.hpp"
 #include "encoding/encoding-buffer.hpp"
+#include "util/time.hpp"
 
+#include <sstream>
 #include <boost/algorithm/string/trim.hpp>
 #include <boost/functional/hash.hpp>
 
@@ -43,15 +44,17 @@
 
 const size_t Name::npos = std::numeric_limits<size_t>::max();
 
+// ---- constructors, encoding, decoding ----
+
 Name::Name()
-  : m_nameBlock(tlv::Name)
+  : m_wire(tlv::Name)
 {
 }
 
 Name::Name(const Block& wire)
 {
-  m_nameBlock = wire;
-  m_nameBlock.parse();
+  m_wire = wire;
+  m_wire.parse();
 }
 
 Name::Name(const char* uri)
@@ -108,13 +111,12 @@
   }
 }
 
-Name
-Name::deepCopy() const
+std::string
+Name::toUri() const
 {
-  Name copiedName(*this);
-  copiedName.m_nameBlock.resetWire();
-  copiedName.wireEncode(); // "compress" the underlying buffer
-  return copiedName;
+  std::ostringstream os;
+  os << *this;
+  return os.str();
 }
 
 template<encoding::Tag TAG>
@@ -123,10 +125,9 @@
 {
   size_t totalLength = 0;
 
-  for (const_reverse_iterator i = rbegin(); i != rend(); ++i)
-    {
-      totalLength += i->wireEncode(encoder);
-    }
+  for (const_reverse_iterator i = rbegin(); i != rend(); ++i) {
+    totalLength += i->wireEncode(encoder);
+  }
 
   totalLength += encoder.prependVarNumber(totalLength);
   totalLength += encoder.prependVarNumber(tlv::Name);
@@ -142,8 +143,8 @@
 const Block&
 Name::wireEncode() const
 {
-  if (m_nameBlock.hasWire())
-    return m_nameBlock;
+  if (m_wire.hasWire())
+    return m_wire;
 
   EncodingEstimator estimator;
   size_t estimatedSize = wireEncode(estimator);
@@ -151,10 +152,10 @@
   EncodingBuffer buffer(estimatedSize, 0);
   wireEncode(buffer);
 
-  m_nameBlock = buffer.block();
-  m_nameBlock.parse();
+  m_wire = buffer.block();
+  m_wire.parse();
 
-  return m_nameBlock;
+  return m_wire;
 }
 
 void
@@ -163,99 +164,33 @@
   if (wire.type() != tlv::Name)
     BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding Name"));
 
-  m_nameBlock = wire;
-  m_nameBlock.parse();
+  m_wire = wire;
+  m_wire.parse();
 }
 
-std::string
-Name::toUri() const
+Name
+Name::deepCopy() const
 {
-  std::ostringstream os;
-  os << *this;
-  return os.str();
+  Name copiedName(*this);
+  copiedName.m_wire.resetWire();
+  copiedName.wireEncode(); // "compress" the underlying buffer
+  return copiedName;
 }
 
-Name&
-Name::append(const PartialName& name)
+// ---- accessors ----
+
+const name::Component&
+Name::at(ssize_t i) const
 {
-  if (&name == this)
-    // Copying from this name, so need to make a copy first.
-    return append(PartialName(name));
+  if (i < 0) {
+    i = size() + i;
+  }
 
-  for (size_t i = 0; i < name.size(); ++i)
-    append(name.at(i));
+  if (i < 0 || static_cast<size_t>(i) >= size()) {
+    BOOST_THROW_EXCEPTION(Error("Requested component does not exist (out of bounds)"));
+  }
 
-  return *this;
-}
-
-Name&
-Name::appendNumber(uint64_t number)
-{
-  m_nameBlock.push_back(Component::fromNumber(number));
-  return *this;
-}
-
-Name&
-Name::appendNumberWithMarker(uint8_t marker, uint64_t number)
-{
-  m_nameBlock.push_back(Component::fromNumberWithMarker(marker, number));
-  return *this;
-}
-
-Name&
-Name::appendVersion(uint64_t version)
-{
-  m_nameBlock.push_back(Component::fromVersion(version));
-  return *this;
-}
-
-Name&
-Name::appendVersion()
-{
-  appendVersion(time::toUnixTimestamp(time::system_clock::now()).count());
-  return *this;
-}
-
-Name&
-Name::appendSegment(uint64_t segmentNo)
-{
-  m_nameBlock.push_back(Component::fromSegment(segmentNo));
-  return *this;
-}
-
-Name&
-Name::appendSegmentOffset(uint64_t offset)
-{
-  m_nameBlock.push_back(Component::fromSegmentOffset(offset));
-  return *this;
-}
-
-Name&
-Name::appendTimestamp(const time::system_clock::TimePoint& timePoint)
-{
-  m_nameBlock.push_back(Component::fromTimestamp(timePoint));
-  return *this;
-}
-
-Name&
-Name::appendSequenceNumber(uint64_t seqNo)
-{
-  m_nameBlock.push_back(Component::fromSequenceNumber(seqNo));
-  return *this;
-}
-
-Name&
-Name::appendImplicitSha256Digest(const ConstBufferPtr& digest)
-{
-  m_nameBlock.push_back(Component::fromImplicitSha256Digest(digest));
-  return *this;
-}
-
-Name&
-Name::appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize)
-{
-  m_nameBlock.push_back(Component::fromImplicitSha256Digest(digest, digestSize));
-  return *this;
+  return reinterpret_cast<const Component&>(m_wire.elements()[i]);
 }
 
 PartialName
@@ -277,11 +212,40 @@
   return result;
 }
 
+// ---- modifiers ----
+
+Name&
+Name::appendVersion()
+{
+  return appendVersion(time::toUnixTimestamp(time::system_clock::now()).count());
+}
+
+Name&
+Name::appendTimestamp()
+{
+  return appendTimestamp(time::system_clock::now());
+}
+
+Name&
+Name::append(const PartialName& name)
+{
+  if (&name == this)
+    // Copying from this name, so need to make a copy first.
+    return append(PartialName(name));
+
+  for (size_t i = 0; i < name.size(); ++i)
+    append(name.at(i));
+
+  return *this;
+}
+
+// ---- algorithms ----
+
 Name
 Name::getSuccessor() const
 {
   if (empty()) {
-    static uint8_t firstValue[] = { 0 };
+    static uint8_t firstValue[] {0};
     Name firstName;
     firstName.append(firstValue, 1);
     return firstName;
@@ -291,13 +255,15 @@
 }
 
 bool
-Name::equals(const Name& name) const
+Name::isPrefixOf(const Name& other) const
 {
-  if (size() != name.size())
+  // This name is longer than the name we are checking against.
+  if (size() > other.size())
     return false;
 
+  // Check if at least one of given components doesn't match.
   for (size_t i = 0; i < size(); ++i) {
-    if (at(i) != name.at(i))
+    if (get(i) != other.get(i))
       return false;
   }
 
@@ -305,15 +271,13 @@
 }
 
 bool
-Name::isPrefixOf(const Name& name) const
+Name::equals(const Name& other) const
 {
-  // This name is longer than the name we are checking against.
-  if (size() > name.size())
+  if (size() != other.size())
     return false;
 
-  // Check if at least one of given components doesn't match.
   for (size_t i = 0; i < size(); ++i) {
-    if (at(i) != name.at(i))
+    if (get(i) != other.get(i))
       return false;
   }
 
@@ -328,7 +292,7 @@
   size_t count = std::min(count1, count2);
 
   for (size_t i = 0; i < count; ++i) {
-    int comp = this->at(pos1 + i).compare(other.at(pos2 + i));
+    int comp = get(pos1 + i).compare(other.get(pos2 + i));
     if (comp != 0) { // i-th component differs
       return comp;
     }
@@ -337,20 +301,20 @@
   return count1 - count2;
 }
 
+// ---- stream operators ----
+
 std::ostream&
 operator<<(std::ostream& os, const Name& name)
 {
-  if (name.empty())
-    {
+  if (name.empty()) {
+    os << "/";
+  }
+  else {
+    for (const auto& component : name) {
       os << "/";
+      component.toUri(os);
     }
-  else
-    {
-      for (Name::const_iterator i = name.begin(); i != name.end(); i++) {
-        os << "/";
-        i->toUri(os);
-      }
-    }
+  }
   return os;
 }
 
@@ -367,6 +331,7 @@
 } // namespace ndn
 
 namespace std {
+
 size_t
 hash<ndn::Name>::operator()(const ndn::Name& name) const
 {
diff --git a/src/name.hpp b/src/name.hpp
index 880343c..1760def 100644
--- a/src/name.hpp
+++ b/src/name.hpp
@@ -26,29 +26,22 @@
 #ifndef NDN_NAME_HPP
 #define NDN_NAME_HPP
 
-#include "common.hpp"
 #include "name-component.hpp"
-
 #include <boost/iterator/reverse_iterator.hpp>
 
 namespace ndn {
 
 class Name;
 
-/**
- * @brief Partial name abstraction to represent an arbitrary sequence of name components
+/** @brief Represents an arbitrary sequence of name components
  */
-typedef Name PartialName;
+using PartialName = Name;
 
-/**
- * @brief Name abstraction to represent an absolute name
+/** @brief Represents an absolute name
  */
 class Name
 {
-public:
-  /**
-   * @brief Error that can be thrown from Name
-   */
+public: // nested types
   class Error : public name::Component::Error
   {
   public:
@@ -59,180 +52,156 @@
     }
   };
 
-  typedef name::Component Component;
+  using Component = name::Component;
+  using component_container = std::vector<Component>;
 
-  typedef std::vector<Component>  component_container;
+  // Name appears as a container of name components
+  using value_type             = Component;
+  using allocator_type         = void;
+  using reference              = Component&;
+  using const_reference        = const Component;
+  using pointer                = Component*;
+  using const_pointer          = const Component*;
+  using iterator               = Component*;
+  using const_iterator         = const Component*;
+  using reverse_iterator       = boost::reverse_iterator<iterator>;
+  using const_reverse_iterator = boost::reverse_iterator<const_iterator>;
+  using difference_type        = component_container::difference_type;
+  using size_type              = component_container::size_type;
 
-  typedef Component               value_type;
-  typedef void                    allocator_type;
-  typedef Component&              reference;
-  typedef const Component         const_reference;
-  typedef Component*              pointer;
-  typedef const Component*        const_pointer;
-  typedef Component*              iterator;
-  typedef const Component*        const_iterator;
-
-  typedef boost::reverse_iterator<iterator>       reverse_iterator;
-  typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
-
-  typedef component_container::difference_type difference_type;
-  typedef component_container::size_type       size_type;
-
-  /**
-   * @brief Create a new Name with no components.
+public: // constructors, encoding, decoding
+  /** @brief Create an empty name
+   *  @post empty() == true
    */
   Name();
 
-  /**
-   * @brief Create Name object from wire block
+  /** @brief Decode Name from wire encoding
+   *  @throw tlv::Error wire encoding is invalid
    *
-   * This is a more efficient equivalent for
-   * @code
+   *  This is a more efficient equivalent for
+   *  @code
    *    Name name;
    *    name.wireDecode(wire);
-   * @endcode
+   *  @endcode
    */
   explicit
   Name(const Block& wire);
 
-  /**
-   * @brief Create name from @p uri (NDN URI scheme)
-   * @param uri The null-terminated URI string
+  /** @brief Parse name from NDN URI
+   *  @param uri a null-terminated URI string
+   *  @sa https://named-data.net/doc/ndn-tlv/name.html#ndn-uri-scheme
    */
   Name(const char* uri);
 
-  /**
-   * @brief Create name from @p uri (NDN URI scheme)
-   * @param uri The URI string
+  /** @brief Create name from NDN URI
+   *  @param uri a URI string
+   *  @sa https://named-data.net/doc/ndn-tlv/name.html#ndn-uri-scheme
    */
   Name(std::string uri);
 
-  /**
-   * @brief Make a deep copy of the name, reallocating the underlying memory buffer
+  /** @brief Get URI representation of the name
+   *  @return URI representation; "ndn:" scheme identifier is not included
+   *  @sa https://named-data.net/doc/ndn-tlv/name.html#ndn-uri-scheme
+   *  @note To print URI representation into a stream, it is more efficient to use ``os << name``.
    */
-  Name
-  deepCopy() const;
+  std::string
+  toUri() const;
 
-  /**
-   * @brief Fast encoding or block size estimation
+  /** @brief Check if this Name instance already has wire encoding
+   */
+  bool
+  hasWire() const
+  {
+    return m_wire.hasWire();
+  }
+
+  /** @brief Fast encoding or block size estimation
    */
   template<encoding::Tag TAG>
   size_t
   wireEncode(EncodingImpl<TAG>& encoder) const;
 
+  /** @brief Perform wire encoding, or return existing wire encoding
+   *  @post hasWire() == true
+   */
   const Block&
   wireEncode() const;
 
+  /** @brief Decode name from wire encoding
+   *  @throw tlv::Error wire encoding is invalid
+   *  @post hasWire() == true
+   */
   void
   wireDecode(const Block& wire);
 
-  /**
-   * @brief Check if already has wire
+  /** @brief Make a deep copy of the name, reallocating the underlying memory buffer
+   */
+  Name
+  deepCopy() const;
+
+public: // access
+  /** @brief Check if name is empty
    */
   bool
-  hasWire() const;
-
-  /**
-   * @brief Append a new component, copying from value of length valueLength.
-   * @return This name so that you can chain calls to append.
-   */
-  Name&
-  append(const uint8_t* value, size_t valueLength)
+  empty() const
   {
-    m_nameBlock.push_back(Component(value, valueLength));
-    return *this;
+    return m_wire.elements().empty();
   }
 
-  /**
-   * @brief Append a new component, copying from value frome the range [@p first, @p last) of bytes
-   * @param first     Iterator pointing to the beginning of the buffer
-   * @param last      Iterator pointing to the ending of the buffer
-   * @tparam Iterator iterator type satisfying at least InputIterator concept.  Implementation
-   *                  is more optimal when the iterator type satisfies RandomAccessIterator concept.
-   *                  It is required that sizeof(std::iterator_traits<Iterator>::value_type) == 1.
-   * @return This name so that you can chain calls to append.
+  /** @brief Get number of components
    */
-  template<class Iterator>
-  Name&
-  append(Iterator first, Iterator last)
+  size_t
+  size() const
   {
-    m_nameBlock.push_back(Component(first, last));
-    return *this;
+    return m_wire.elements_size();
   }
 
-  /**
-   * @brief Append component @p value
+  /** @brief Get the component at the given index
+   *  @param i zero-based index; if negative, it starts at the end of this name
+   *  @warning Indexing out of bounds triggers undefined behavior.
    */
-  Name&
-  append(const Component& value)
+  const Component&
+  get(ssize_t i) const
   {
-    m_nameBlock.push_back(value);
-    return *this;
+    if (i < 0) {
+      i += size();
+    }
+    return reinterpret_cast<const Component&>(m_wire.elements()[i]);
   }
 
-  /**
-   * @brief Append name component that represented as a string
+  /** @brief Equivalent to get(i)
+   */
+  const Component&
+  operator[](ssize_t i) const
+  {
+    return get(i);
+  }
+
+  /** @brief Get the component at the given index
+   *  @param i zero-based index; if negative, size()+i is used instead
+   *  @throws Name::Error index is out of bounds
+   */
+  const Component&
+  at(ssize_t i) const;
+
+  /** @brief Extract some components as a sub-name (PartialName)
+   *  @param iStartComponent zero-based index of the first component;
+   *                         if negative, size()+iStartComponent is used instead
+   *  @param nComponents Number of components starting at iStartComponent.
+   *                     Use @p npos to get the PartialName until the end of this Name.
+   *  @return a new PartialName containing the extracted components
    *
-   * Note that this method is necessary to ensure correctness and unambiguity of
-   * ``append("string")`` operations (both Component and Name can be implicitly
-   * converted from string, each having different outcomes
-   */
-  Name&
-  append(const char* value)
-  {
-    m_nameBlock.push_back(Component(value));
-    return *this;
-  }
-
-  Name&
-  append(const Block& value)
-  {
-    if (value.type() == tlv::NameComponent)
-      m_nameBlock.push_back(value);
-    else
-      m_nameBlock.push_back(Block(tlv::NameComponent, value));
-
-    return *this;
-  }
-
-  /**
-   * @brief append a PartialName to this Name.
-   * @param name the components to append
-   * @return this name
-   */
-  Name&
-  append(const PartialName& name);
-
-  /**
-   * Clear all the components.
-   */
-  void
-  clear()
-  {
-    m_nameBlock = Block(tlv::Name);
-  }
-
-  /**
-   * @brief Extract a sub-name (PartialName) of @p nComponents components starting
-   *        from @p iStartComponent
-   * @param iStartComponent index of the first component;
-   *        if iStartComponent is negative, size()+iStartComponent is used instead
-   * @param nComponents The number of components starting at iStartComponent.
-   *                    Use npos to get the Partial Name until the end of this Name.
-   * @details If iStartComponent is out of bounds and is negative, returns the components
-   *          starting from the beginning of the Name.
-   *          If iStartComponent is out of bounds and is positive, returns the component "/".
-   *          If nComponents is out of bounds, returns the components until the end of
-   *          this Name
-   * @return A new partial name
+   *  If iStartComponent is positive and indexes out of bounds, returns an empty PartialName.
+   *  If iStartComponent is negative and indexes out of bounds, returns components starting from the
+   *  beginning of the Name. If nComponents is out of bounds, returns the components until the end
+   *  of this Name.
    */
   PartialName
   getSubName(ssize_t iStartComponent, size_t nComponents = npos) const;
 
-  /**
-   * @brief Extract a prefix (PartialName) of the name, containing first @p nComponents components
-   *
-   * @param nComponents The number of prefix components.  If nComponents is -N then return
+  /** @brief Extract a prefix of the name
+   *  @param nComponents Number of components; if negative, size()+nComponents is used instead
+   *  @return a new Name containing the prefix
    *                    the prefix up to name.size() - N. For example getPrefix(-1)
    *                    returns the name without the final component.
    * @return A new partial name
@@ -241,348 +210,31 @@
   getPrefix(ssize_t nComponents) const
   {
     if (nComponents < 0)
-      return getSubName(0, m_nameBlock.elements_size() + nComponents);
+      return getSubName(0, size() + nComponents);
     else
       return getSubName(0, nComponents);
   }
 
-  /**
-   * Encode this name as a URI.
-   * @return The encoded URI.
-   */
-  std::string
-  toUri() const;
-
-  /**
-   * @brief Append a component with the number encoded as nonNegativeInteger
-   *
-   * @see http://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
-   *
-   * @param number The non-negative number
-   * @return This name so that you can chain calls to append.
-   */
-  Name&
-  appendNumber(uint64_t number);
-
-  /**
-   * @brief Create a component encoded as NameComponentWithMarker
-   *
-   * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
-   *
-   * @param marker 1-byte marker octet
-   * @param number The non-negative number
-   */
-  Name&
-  appendNumberWithMarker(uint8_t marker, uint64_t number);
-
-  /**
-   * @brief Append version using NDN naming conventions
-   *
-   * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
-   */
-  Name&
-  appendVersion(uint64_t version);
-
-  /**
-   * @brief Append version using NDN naming conventions based on current UNIX timestamp
-   *        in milliseconds
-   *
-   * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
-   */
-  Name&
-  appendVersion();
-
-  /**
-   * @brief Append segment number (sequential) using NDN naming conventions
-   *
-   * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
-   */
-  Name&
-  appendSegment(uint64_t segmentNo);
-
-  /**
-   * @brief Append segment byte offset using NDN naming conventions
-   *
-   * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
-   */
-  Name&
-  appendSegmentOffset(uint64_t offset);
-
-  /**
-   * @brief Append timestamp using NDN naming conventions
-   *
-   * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
-   */
-  Name&
-  appendTimestamp(const time::system_clock::TimePoint& timePoint = time::system_clock::now());
-
-  /**
-   * @brief Append sequence number using NDN naming conventions
-   *
-   * @see http://named-data.net/doc/tech-memos/naming-conventions.pdf
-   */
-  Name&
-  appendSequenceNumber(uint64_t seqNo);
-
-  /**
-   * @brief Append ImplicitSha256Digest
-   */
-  Name&
-  appendImplicitSha256Digest(const ConstBufferPtr& digest);
-
-  /**
-   * @brief Append ImplicitSha256Digest
-   */
-  Name&
-  appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize);
-
-  /**
-   * @brief Get the successor of a name
-   *
-   * The successor of a name is defined as follows:
-   *
-   *     N represents the set of NDN Names, and X,Y ∈ N.
-   *     Operator < is defined by canonical order on N.
-   *     Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ N s.t. X < Z < Y.
-   *
-   * In plain words, successor of a name is the same name, but with its last component
-   * advanced to a next possible value.
-   *
-   * Examples:
-   *
-   * - successor for / is /%00
-   * - successor for /%00%01/%01%02 is /%00%01/%01%03
-   * - successor for /%00%01/%01%FF is /%00%01/%02%00
-   * - successor for /%00%01/%FF%FF is /%00%01/%00%00%00
-   *
-   * @return a new name
-   */
-  Name
-  getSuccessor() const;
-
-  /**
-   * Check if this name has the same component count and components as the given name.
-   * @param name The Name to check.
-   * @return true if the names are equal, otherwise false.
-   */
-  bool
-  equals(const Name& name) const;
-
-  /**
-   * @brief Check if the N components of this name are the same as the first N components
-   *        of the given name.
-   *
-   * @param name The Name to check.
-   * @return true if this matches the given name, otherwise false.  This always returns
-   *              true if this name is empty.
-   */
-  bool
-  isPrefixOf(const Name& name) const;
-
-  //
-  // vector equivalent interface.
-  //
-
-  /**
-   * @brief Check if name is emtpy
-   */
-  bool
-  empty() const
-  {
-    return m_nameBlock.elements().empty();
-  }
-
-  /**
-   * Get the number of components.
-   * @return The number of components.
-   */
-  size_t
-  size() const
-  {
-    return m_nameBlock.elements_size();
-  }
-
-  /**
-   * Get the component at the given index.
-   * @param i The index of the component, starting from 0.
-   * @return The name component at the index.
-   */
-  const Component&
-  get(ssize_t i) const
-  {
-    if (i >= 0)
-      return reinterpret_cast<const Component&>(m_nameBlock.elements()[i]);
-    else
-      return reinterpret_cast<const Component&>(m_nameBlock.elements()[size() + i]);
-  }
-
-  const Component&
-  operator[](ssize_t i) const
-  {
-    return get(i);
-  }
-
-  /**
-   * @brief Get component at the specified index
-   *
-   * Unlike get() and operator[] methods, at() checks for out of bounds
-   * and will throw Name::Error when it happens
-   *
-   * @throws Name::Error if index out of bounds
-   */
-  const Component&
-  at(ssize_t i) const
-  {
-    if ((i >= 0 && static_cast<size_t>(i) >= size()) ||
-        (i < 0  && static_cast<size_t>(-i) > size()))
-      BOOST_THROW_EXCEPTION(Error("Requested component does not exist (out of bounds)"));
-
-    return get(i);
-  }
-
-  /**
-   * @brief Compare this to the other Name using NDN canonical ordering.
-   *
-   * If the first components of each name are not equal, this returns a negative value if
-   * the first comes before the second using the NDN canonical ordering for name
-   * components, or a positive value if it comes after.  If they are equal, this compares
-   * the second components of each name, etc. If both names are the same up to the size
-   * of the shorter name, this returns a negative value if the first name is shorter than
-   * the second or a positive value if it is longer.  For example, if you std::sort gives:
-   * /a/b/d /a/b/cc /c /c/a /bb .
-   * This is intuitive because all names with the prefix /a are next to each other.
-   * But it may be also be counter-intuitive because /c comes before /bb according
-   * to NDN canonical ordering since it is shorter.
-   *
-   * @param other The other Name to compare with.
-   *
-   * @retval negative this comes before other in canonical ordering
-   * @retval zero this equals other
-   * @retval positive this comes after other in canonical ordering
-   *
-   * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
-   */
-  int
-  compare(const Name& other) const
-  {
-    return this->compare(0, npos, other);
-  }
-
-  /** \brief compares [pos1, pos1+count1) components in this Name
-   *         to [pos2, pos2+count2) components in \p other
-   *
-   *  This is equivalent to this->getSubName(pos1, count1).compare(other.getSubName(pos2, count2));
-   */
-  int
-  compare(size_t pos1, size_t count1,
-          const Name& other, size_t pos2 = 0, size_t count2 = npos) const;
-
-  /**
-   * Append the component
-   * @param component The component of type T.
-   */
-  template<class T> void
-  push_back(const T& component)
-  {
-    append(component);
-  }
-
-  /**
-   * Check if this name has the same component count and components as the given name.
-   * @param name The Name to check.
-   * @return true if the names are equal, otherwise false.
-   */
-  bool
-  operator==(const Name& name) const
-  {
-    return equals(name);
-  }
-
-  /**
-   * Check if this name has the same component count and components as the given name.
-   * @param name The Name to check.
-   * @return true if the names are not equal, otherwise false.
-   */
-  bool
-  operator!=(const Name& name) const
-  {
-    return !equals(name);
-  }
-
-  /**
-   * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
-   * @param other The other Name to compare with.
-   *
-   * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
-   */
-  bool
-  operator<=(const Name& other) const
-  {
-    return compare(other) <= 0;
-  }
-
-  /**
-   * Return true if this is less than the other Name in the NDN canonical ordering.
-   * @param other The other Name to compare with.
-   *
-   * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
-   */
-  bool
-  operator<(const Name& other) const
-  {
-    return compare(other) < 0;
-  }
-
-  /**
-   * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
-   * @param other The other Name to compare with.
-   *
-   * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
-   */
-  bool
-  operator>=(const Name& other) const
-  {
-    return compare(other) >= 0;
-  }
-
-  /**
-   * Return true if this is greater than the other Name in the NDN canonical ordering.
-   * @param other The other Name to compare with.
-   *
-   * @see http://named-data.net/doc/ndn-tlv/name.html#canonical-order
-   */
-  bool
-  operator>(const Name& other) const
-  {
-    return compare(other) > 0;
-  }
-
-  //
-  // Iterator interface to name components.
-  //
-
-  /**
-   * Begin iterator (const).
+public: // iterators
+  /** @brief Begin iterator
    */
   const_iterator
   begin() const
   {
-    return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().begin());
+    // XXX This triggers undefined behavior if name is empty (#4181)
+    return reinterpret_cast<const_iterator>(&*m_wire.elements().begin());
   }
 
-  /**
-   * End iterator (const).
-   *
-   * @todo Check if this crash when there are no elements in the buffer
+  /** @brief End iterator
    */
   const_iterator
   end() const
   {
-    return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().end());
+    // XXX This triggers undefined behavior if name is empty (#4181)
+    return reinterpret_cast<const_iterator>(&*m_wire.elements().end());
   }
 
-  /**
-   * Reverse begin iterator (const).
+  /** @brief Reverse begin iterator
    */
   const_reverse_iterator
   rbegin() const
@@ -590,8 +242,7 @@
     return const_reverse_iterator(end());
   }
 
-  /**
-   * Reverse end iterator (const).
+  /** @brief Reverse end iterator
    */
   const_reverse_iterator
   rend() const
@@ -599,30 +250,350 @@
     return const_reverse_iterator(begin());
   }
 
+public: // modifiers
+  /** @brief Append a component
+   *  @return a reference to this name, to allow chaining
+   */
+  Name&
+  append(const Component& component)
+  {
+    m_wire.push_back(component);
+    return *this;
+  }
+
+  /** @brief Append a component, copying from a zero-terminated byte string
+   *  @param value a zero-terminated string; it will be constructed as a component as is
+   *               and will not be interpreted as a URI
+   *  @note This overload is necessary to ensure unambiguity of ``append("string")``, because both
+   *        Component and PartialName are implicitly convertible from zero-terminated byte string.
+   *        This overload ensures the string is constructed as a Component.
+   */
+  Name&
+  append(const char* value)
+  {
+    return append(Component(value));
+  }
+
+  /** @brief Append a component, copying from [@p value, @p value + @p valueLength)
+   *  @return a reference to this name, to allow chaining
+   */
+  Name&
+  append(const uint8_t* value, size_t valueLength)
+  {
+    return append(Component(value, valueLength));
+  }
+
+  /** @brief Append a component, copying from [@p first, @p last)
+   *  @tparam Iterator an InputIterator dereferencing to a one-octet value type. More efficient
+   *                   implementation is available when @p Iterator additionally satisfies
+   *                   RandomAccessIterator concept.
+   *  @param first     begin position of the value
+   *  @param last      end position of the value
+   *  @return a reference to this name, to allow chaining
+   */
+  template<class Iterator>
+  Name&
+  append(Iterator first, Iterator last)
+  {
+    static_assert(sizeof(std::iterator_traits<Iterator>::value_type) == 1,
+                  "iterator does not dereference to one-octet value type");
+    return append(Component(first, last));
+  }
+
+  /** @brief Append a component, decoding from a Block
+   *  @param value a Block; if its TLV-TYPE is not NameComponent, it is nested into a NameComponent
+   *  @return a reference to this name, to allow chaining
+   */
+  Name&
+  append(const Block& value)
+  {
+    if (value.type() == tlv::NameComponent) {
+      m_wire.push_back(value);
+    }
+    else {
+      m_wire.push_back(Block(tlv::NameComponent, value));
+    }
+
+    return *this;
+  }
+
+  /** @brief Append a component with a nonNegativeInteger
+   *  @sa number the number
+   *  @return a reference to this name, to allow chaining
+   *  @sa https://named-data.net/doc/ndn-tlv/tlv.html#non-negative-integer-encoding
+   */
+  Name&
+  appendNumber(uint64_t number)
+  {
+    return append(Component::fromNumber(number));
+  }
+
+  /** @brief Append a component with a marked number
+   *  @param marker 1-octet marker
+   *  @param number the number
+   *
+   *  The component is encoded as a 1-octet marker, followed by a nonNegativeInteger.
+   *
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendNumberWithMarker(uint8_t marker, uint64_t number)
+  {
+    return append(Component::fromNumberWithMarker(marker, number));
+  }
+
+  /** @brief Append a version component
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendVersion(uint64_t version)
+  {
+    return append(Component::fromVersion(version));
+  }
+
+  /** @brief Append a version component based on current time
+   *
+   *  The version number is the current UNIX timestamp in milliseconds
+   *
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendVersion();
+
+  /** @brief Append a segment number (sequential) component
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendSegment(uint64_t segmentNo)
+  {
+    return append(Component::fromSegment(segmentNo));
+  }
+
+  /** @brief Append a segment byte offset component
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendSegmentOffset(uint64_t offset)
+  {
+    return append(Component::fromSegmentOffset(offset));
+  }
+
+  /** @brief Append a timestamp component
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendTimestamp(const time::system_clock::TimePoint& timePoint)
+  {
+    return append(Component::fromTimestamp(timePoint));
+  }
+
+  /** @brief Append a timestamp component based on current time
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendTimestamp();
+
+  /** @brief Append a sequence number component
+   *  @return a reference to this name, to allow chaining
+   *  @sa NDN Naming Conventions https://named-data.net/doc/tech-memos/naming-conventions.pdf
+   */
+  Name&
+  appendSequenceNumber(uint64_t seqNo)
+  {
+    return append(Component::fromSequenceNumber(seqNo));
+  }
+
+  /** @brief Append an ImplicitSha256Digest component
+   *  @return a reference to this name, to allow chaining
+   */
+  Name&
+  appendImplicitSha256Digest(const ConstBufferPtr& digest)
+  {
+    return append(Component::fromImplicitSha256Digest(digest));
+  }
+
+  /** @brief Append an ImplicitSha256Digest component
+   *  @return a reference to this name, to allow chaining
+   */
+  Name&
+  appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize)
+  {
+    return append(Component::fromImplicitSha256Digest(digest, digestSize));
+  }
+
+  /** @brief Append a PartialName
+   *  @param name the components to append
+   *  @return a reference to this name, to allow chaining
+   */
+  Name&
+  append(const PartialName& name);
+
+  /** @brief Append a component
+   *  @note This makes push_back an alias of append, giving Name a similar API as STL vector.
+   */
+  template<class T>
+  void
+  push_back(const T& component)
+  {
+    append(component);
+  }
+
+  /** @brief Remove all components
+   *  @post empty() == true
+   */
+  void
+  clear()
+  {
+    m_wire = Block(tlv::Name);
+  }
+
+public: // algorithms
+  /** @brief Get the successor of a name
+   *
+   *  The successor of a name is defined as follows:
+   *
+   *      N represents the set of NDN Names, and X,Y ∈ N.
+   *      Operator < is defined by canonical order on N.
+   *      Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ N s.t. X < Z < Y.
+   *
+   *  In plain words, successor of a name is the same name, but with its last component
+   *  advanced to a next possible value.
+   *
+   *  Examples:
+   *
+   *  - successor for / is /%00
+   *  - successor for /%00%01/%01%02 is /%00%01/%01%03
+   *  - successor for /%00%01/%01%FF is /%00%01/%02%00
+   *  - successor for /%00%01/%FF%FF is /%00%01/%00%00%00
+   *
+   *  @return a new Name containing the successor
+   */
+  Name
+  getSuccessor() const;
+
+  /** @brief Check if this name is a prefix of another name
+   *
+   *  This name is a prefix of @p other if the N components of this name are same as the first N
+   *  components of @p other.
+   *
+   *  @retval true this name is a prefix of @p other
+   *  @retval false this name is not a prefix of @p other
+   */
+  bool
+  isPrefixOf(const Name& other) const;
+
+  /** @brief Check if this name equals another name
+   *
+   *  Two names are equal if they have the same number of components, and components at each index
+   *  are equal.
+   */
+  bool
+  equals(const Name& other) const;
+
+  /** @brief Compare this to the other Name using NDN canonical ordering.
+   *
+   *  If the first components of each name are not equal, this returns a negative value if
+   *  the first comes before the second using the NDN canonical ordering for name
+   *  components, or a positive value if it comes after.  If they are equal, this compares
+   *  the second components of each name, etc. If both names are the same up to the size
+   *  of the shorter name, this returns a negative value if the first name is shorter than
+   *  the second or a positive value if it is longer.  For example, if you std::sort gives:
+   *  /a/b/d /a/b/cc /c /c/a /bb .
+   *  This is intuitive because all names with the prefix /a are next to each other.
+   *  But it may be also be counter-intuitive because /c comes before /bb according
+   *  to NDN canonical ordering since it is shorter.
+   *
+   *  @param other The other Name to compare with.
+   *
+   *  @retval negative this comes before other in canonical ordering
+   *  @retval zero this equals other
+   *  @retval positive this comes after other in canonical ordering
+   *
+   *  @sa https://named-data.net/doc/ndn-tlv/name.html#canonical-order
+   */
+  int
+  compare(const Name& other) const
+  {
+    return this->compare(0, npos, other);
+  }
+
+  /** @brief compares [pos1, pos1+count1) components in this Name
+   *         to [pos2, pos2+count2) components in @p other
+   *
+   *  This is equivalent to this->getSubName(pos1, count1).compare(other.getSubName(pos2, count2));
+   */
+  int
+  compare(size_t pos1, size_t count1,
+          const Name& other, size_t pos2 = 0, size_t count2 = npos) const;
+
 public:
   /** \brief indicates "until the end" in getSubName and compare
    */
   static const size_t npos;
 
 private:
-  mutable Block m_nameBlock;
+  mutable Block m_wire;
 };
 
+inline bool
+operator==(const Name& lhs, const Name& rhs)
+{
+  return lhs.equals(rhs);
+}
+
+inline bool
+operator!=(const Name& lhs, const Name& rhs)
+{
+  return !lhs.equals(rhs);
+}
+
+inline bool
+operator<=(const Name& lhs, const Name& rhs)
+{
+  return lhs.compare(rhs) <= 0;
+}
+
+inline bool
+operator<(const Name& lhs, const Name& rhs)
+{
+  return lhs.compare(rhs) < 0;
+}
+
+inline bool
+operator>=(const Name& lhs, const Name& rhs)
+{
+  return lhs.compare(rhs) >= 0;
+}
+
+inline bool
+operator>(const Name& lhs, const Name& rhs)
+{
+  return lhs.compare(rhs) > 0;
+}
+
+/** @brief Print URI representation of a name
+ *  @sa https://named-data.net/doc/ndn-tlv/name.html#ndn-uri-scheme
+ */
 std::ostream&
 operator<<(std::ostream& os, const Name& name);
 
+/** @brief Parse URI from stream as Name
+ *  @sa https://named-data.net/doc/ndn-tlv/name.html#ndn-uri-scheme
+ */
 std::istream&
 operator>>(std::istream& is, Name& name);
 
-inline bool
-Name::hasWire() const
-{
-  return m_nameBlock.hasWire();
-}
-
 } // namespace ndn
 
 namespace std {
+
 template<>
 struct hash<ndn::Name>
 {
diff --git a/tests/unit-tests/name-component.t.cpp b/tests/unit-tests/name-component.t.cpp
index 8a99b2f..651b160 100644
--- a/tests/unit-tests/name-component.t.cpp
+++ b/tests/unit-tests/name-component.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -20,6 +20,7 @@
  */
 
 #include "name-component.hpp"
+#include "name.hpp"
 
 #include "boost-test.hpp"
 #include <boost/mpl/vector.hpp>
@@ -205,6 +206,149 @@
 
 BOOST_AUTO_TEST_SUITE_END() // CreateFromIterators
 
+BOOST_AUTO_TEST_SUITE(NamingConvention)
+
+template<typename ArgType>
+struct ConventionTest
+{
+  function<name::Component(ArgType)> makeComponent;
+  function<ArgType(const name::Component&)> getValue;
+  function<Name&(Name&, ArgType)> append;
+  Name expected;
+  ArgType value;
+  function<bool(const name::Component&)> isComponent;
+};
+
+class NumberWithMarker
+{
+public:
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {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)};
+  }
+};
+
+class Segment
+{
+public:
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&name::Component::fromSegment,
+            bind(&name::Component::toSegment, _1),
+            bind(&Name::appendSegment, _1, _2),
+            Name("/%00%27%10"),
+            10000,
+            bind(&name::Component::isSegment, _1)};
+  }
+};
+
+class SegmentOffset
+{
+public:
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&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)};
+  }
+};
+
+class Version
+{
+public:
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&name::Component::fromVersion,
+            bind(&name::Component::toVersion, _1),
+            [] (Name& name, uint64_t version) -> Name& { return name.appendVersion(version); },
+            Name("/%FD%00%0FB%40"),
+            1000000,
+            bind(&name::Component::isVersion, _1)};
+  }
+};
+
+class Timestamp
+{
+public:
+  ConventionTest<time::system_clock::TimePoint>
+  operator()() const
+  {
+    return {&name::Component::fromTimestamp,
+            bind(&name::Component::toTimestamp, _1),
+            [] (Name& name, time::system_clock::TimePoint t) -> Name& { return name.appendTimestamp(t); },
+            Name("/%FC%00%04%7BE%E3%1B%00%00"),
+            time::getUnixEpoch() + time::days(14600), // 40 years
+            bind(&name::Component::isTimestamp, _1)};
+  }
+};
+
+class SequenceNumber
+{
+public:
+  ConventionTest<uint64_t>
+  operator()() const
+  {
+    return {&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)};
+  }
+};
+
+using ConventionTests = boost::mpl::vector<
+  NumberWithMarker,
+  Segment,
+  SegmentOffset,
+  Version,
+  Timestamp,
+  SequenceNumber
+>;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(Convention, T, ConventionTests)
+{
+  name::Component invalidComponent1;
+  name::Component invalidComponent2("1234567890");
+
+  auto test = T()();
+
+  const Name& expected = test.expected;
+  BOOST_TEST_MESSAGE("Check " << expected[0].toUri());
+
+  BOOST_CHECK_EQUAL(expected[0].isGeneric(), true);
+
+  name::Component actualComponent = test.makeComponent(test.value);
+  BOOST_CHECK_EQUAL(actualComponent, expected[0]);
+
+  Name actualName;
+  test.append(actualName, test.value);
+  BOOST_CHECK_EQUAL(actualName, expected);
+
+  BOOST_CHECK_EQUAL(test.isComponent(expected[0]), true);
+  BOOST_CHECK_EQUAL(test.getValue(expected[0]), test.value);
+
+  BOOST_CHECK_EQUAL(test.isComponent(invalidComponent1), false);
+  BOOST_CHECK_EQUAL(test.isComponent(invalidComponent2), false);
+
+  BOOST_CHECK_THROW(test.getValue(invalidComponent1), name::Component::Error);
+  BOOST_CHECK_THROW(test.getValue(invalidComponent2), name::Component::Error);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // NamingConvention
+
 BOOST_AUTO_TEST_SUITE_END() // TestNameComponent
 
 } // namespace tests
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
