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>
 {
