name: Optimization of Name implementation

Now, Name directly uses Block as underlying storage for name components
and name::Components (aka Name::Components) class is a helper wrapped on
top of Block class.

Change-Id: I15ca58cc6dba76dd02e973709b7b153c2613de51
refs: #1171
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index da81e64..f515727 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -348,12 +348,12 @@
   for (element_iterator i = m_subBlocks.begin();
        i != m_subBlocks.end();
        ++i)
-    {
+  {
       if (i->type() != type)
         newContainer.push_back(*i);
-    }
+  }
   m_subBlocks.swap(newContainer);
-}
+  }
 
 inline Block::element_iterator
 Block::erase(Block::element_iterator position)
diff --git a/src/encoding/encoding-buffer.hpp b/src/encoding/encoding-buffer.hpp
index eac26f9..8870941 100644
--- a/src/encoding/encoding-buffer.hpp
+++ b/src/encoding/encoding-buffer.hpp
@@ -24,8 +24,8 @@
 namespace ndn {
 
 namespace encoding {
-const bool Buffer = true;
-const bool Estimator = false;
+static const bool Buffer = true;
+static const bool Estimator = false;
 } // encoding
 
 template<bool isRealEncoderNotEstimator>
@@ -91,9 +91,6 @@
   prependByteArray (const uint8_t *arr, size_t len);
 
   inline size_t
-  prependBuffer (const Buffer& arr);
-
-  inline size_t
   prependNonNegativeInteger (uint64_t varNumber);
 
   inline size_t
@@ -106,9 +103,6 @@
   appendByteArray (const uint8_t *arr, size_t len);
 
   inline size_t
-  appendBuffer (const Buffer& arr);
-
-  inline size_t
   appendNonNegativeInteger (uint64_t varNumber);
 
   inline size_t
@@ -158,9 +152,6 @@
   prependByteArray (const uint8_t *arr, size_t len);
 
   inline size_t
-  prependBuffer (const Buffer& arr);
-
-  inline size_t
   prependNonNegativeInteger (uint64_t varNumber);
 
   inline size_t
@@ -173,9 +164,6 @@
   appendByteArray (const uint8_t *arr, size_t len);
 
   inline size_t
-  appendBuffer (const Buffer& arr);
-
-  inline size_t
   appendNonNegativeInteger (uint64_t varNumber);
 
   inline size_t
@@ -324,24 +312,6 @@
 }
 
 inline size_t
-EncodingImpl<encoding::Buffer>::prependBuffer (const Buffer& arr)
-{
-  if ((m_buffer->begin () + arr.size ()) > m_begin)
-    resize (m_buffer->size () * 2 + arr.size (), true);
-
-  m_begin -= arr.size ();
-  std::copy (arr.begin (), arr.end (), m_begin);
-  return arr.size ();
-}
-
-inline size_t
-EncodingImpl<encoding::Estimator>::prependBuffer (const Buffer& arr)
-{
-  m_size += arr.size ();
-  return arr.size ();
-}
-
-inline size_t
 EncodingImpl<encoding::Buffer>::prependNonNegativeInteger (uint64_t varNumber)
 {
   if (varNumber < 253) {
@@ -469,23 +439,6 @@
 }
 
 inline size_t
-EncodingImpl<encoding::Buffer>::appendBuffer (const Buffer& arr)
-{
-  if ((m_end + arr.size ()) > m_buffer->end ())
-    resize (m_buffer->size () * 2 + arr.size (), false);
-
-  std::copy (arr.begin (), arr.end (), m_end);
-  m_end -= arr.size ();
-  return arr.size ();
-}
-
-inline size_t
-EncodingImpl<encoding::Estimator>::appendBuffer (const Buffer& arr)
-{
-  return prependBuffer(arr);
-}
-
-inline size_t
 EncodingImpl<encoding::Buffer>::appendNonNegativeInteger (uint64_t varNumber)
 {
   if (varNumber < 253) {
diff --git a/src/exclude.cpp b/src/exclude.cpp
index 677548c..11edd82 100644
--- a/src/exclude.cpp
+++ b/src/exclude.cpp
@@ -186,8 +186,8 @@
         {
           OBufferStream os;
           Tlv::writeVarNumber(os, Tlv::NameComponent);
-          Tlv::writeVarNumber(os, i->first.getValue().size());
-          os.write(reinterpret_cast<const char *>(i->first.getValue().buf()), i->first.getValue().size());
+          Tlv::writeVarNumber(os, i->first.value_size());
+          os.write(reinterpret_cast<const char *>(i->first.value()), i->first.value_size());
           
           wire_.push_back(Block(os.buf()));
 
diff --git a/src/name-component.cpp b/src/name-component.cpp
new file mode 100644
index 0000000..3956e80
--- /dev/null
+++ b/src/name-component.cpp
@@ -0,0 +1,167 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "name-component.hpp"
+
+#include "util/time.hpp"
+#include "util/string-helper.hpp"
+
+namespace ndn {
+namespace name {
+
+Component 
+Component::fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset)
+{
+  std::string trimmedString(escapedString + beginOffset, escapedString + endOffset);
+  trim(trimmedString);
+  std::string value = unescape(trimmedString);
+        
+  if (value.find_first_not_of(".") == std::string::npos) {
+    // Special case for component of only periods.  
+    if (value.size() <= 2)
+      // Zero, one or two periods is illegal.  Ignore this component.
+      return Component();
+    else
+      // Remove 3 periods.
+      return Component((const uint8_t *)&value[3], value.size() - 3); 
+  }
+  else
+    return Component((const uint8_t *)&value[0], value.size()); 
+}
+
+void
+Component::toEscapedString(std::ostream& result) const
+{
+  const uint8_t *valuePtr = value();
+  size_t valueSize = value_size();
+  
+  bool gotNonDot = false;
+  for (unsigned i = 0; i < valueSize; ++i) {
+    if (valuePtr[i] != 0x2e) {
+      gotNonDot = true;
+      break;
+    }
+  }
+  if (!gotNonDot) {
+    // Special case for component of zero or more periods.  Add 3 periods.
+    result << "...";
+    for (size_t i = 0; i < valueSize; ++i)
+      result << '.';
+  }
+  else {
+    // In case we need to escape, set to upper case hex and save the previous flags.
+    std::ios::fmtflags saveFlags = result.flags(std::ios::hex | std::ios::uppercase);
+    
+    for (size_t i = 0; i < valueSize; ++i) {
+      uint8_t x = valuePtr[i];
+      // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
+      if ((x >= 0x30 && x <= 0x39) || (x >= 0x41 && x <= 0x5a) ||
+          (x >= 0x61 && x <= 0x7a) || x == 0x2b || x == 0x2d || 
+          x == 0x2e || x == 0x5f)
+        result << x;
+      else {
+        result << '%';
+        if (x < 16)
+          result << '0';
+        result << (unsigned int)x;
+      }
+    }
+    
+    // Restore.
+    result.flags(saveFlags);
+  }  
+}
+
+
+uint64_t
+Component::toNumberWithMarker(uint8_t marker) const
+{
+  if (empty() || *value_begin() != marker)
+    throw Error("Name component does not begin with the expected marker");
+  
+  uint64_t result = 0;
+  for (Buffer::const_iterator i = value_begin()+1; i != value_end(); ++i) {
+    result <<= 8;
+    result |= *i;
+  }
+  
+  return result;
+}
+
+Component 
+Component::fromNumber(uint64_t number)
+{
+  ptr_lib::shared_ptr<Buffer> value(new Buffer);
+  
+  // First encode in little endian.
+  while (number != 0) {
+    value->push_back(number & 0xff);
+    number >>= 8;
+  }
+  
+  // Make it big endian.
+  reverse(value->begin(), value->end());
+  return Component(value);
+}
+
+Component
+Component::fromNumberWithMarker(uint64_t number, uint8_t marker)
+{
+  ptr_lib::shared_ptr<Buffer> value(new Buffer);
+  
+  // Add the leading marker.
+  value->push_back(marker);
+  
+  // First encode in little endian.
+  while (number != 0) {
+    value->push_back(number & 0xff);
+    number >>= 8;
+  }
+  
+  // Make it big endian.
+  reverse(value->begin() + 1, value->end());
+  return Component(value);
+}
+
+uint64_t
+Component::toNumber() const
+{
+  uint64_t result = 0;
+  for (Buffer::const_iterator i = value_begin(); i != value_end(); ++i) {
+    result <<= 8;
+    result |= *i;
+  }
+  
+  return result;
+}
+
+int
+Component::compare(const Component& other) const
+{
+  // Imitate ndn_Exclude_compareComponents.
+  if (value_size() < other.value_size())
+    return -1;
+  if (value_size() > other.value_size())
+    return 1;
+
+  if (value_size() == 0)
+    return 0;
+  
+  // The components are equal length.  Just do a byte compare.  
+  return std::memcmp(value(), other.value(), value_size());
+}
+
+// const Block &
+// wireEncode() const
+// {
+  
+// }
+
+} // namespace name
+} // namespace ndn
diff --git a/src/name-component.hpp b/src/name-component.hpp
new file mode 100644
index 0000000..c8ca77e
--- /dev/null
+++ b/src/name-component.hpp
@@ -0,0 +1,334 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * @author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ * @author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_NAME_COMPONENT_HPP
+#define NDN_NAME_COMPONENT_HPP
+
+#include "common.hpp"
+#include "encoding/block.hpp"
+#include "encoding/encoding-buffer.hpp"
+
+namespace ndn {
+namespace name {
+
+/**
+ * A Name::Component holds a read-only name component value.
+ */
+class Component : public Block
+{
+public:
+  /// @brief Error that can be thrown from the block
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+  
+  /**
+   * Create a new Name::Component with a null value.
+   */
+  Component()
+    : Block(Tlv::NameComponent)
+  {    
+  }
+
+  // copy constructor OK
+  
+  /**
+   * Create a new Name::Component, taking another pointer to the Blob value.
+   * @param value A blob with a pointer to an immutable array.  The pointer is copied.
+   */
+  Component(const ConstBufferPtr &buffer)
+    : Block (Tlv::NameComponent, buffer)
+  {
+  }
+  
+  /**
+   * Create a new Name::Component, copying the given value.
+   * @param value The value byte array.
+   */
+  Component(const Buffer& value) 
+    : Block (Tlv::NameComponent, ConstBufferPtr(new Buffer(value)))
+  {
+  }
+
+  /**
+   * Create a new Name::Component, copying the given value.
+   * @param value Pointer to the value byte array.
+   * @param valueLen Length of value.
+   */
+  Component(const uint8_t *value, size_t valueLen) 
+    : Block (Tlv::NameComponent, ConstBufferPtr(new Buffer(value, valueLen)))
+  {
+  }
+
+  template<class InputIterator>
+  Component(InputIterator begin, InputIterator end)
+    : Block (Tlv::NameComponent, ConstBufferPtr(new Buffer(begin, end)))
+  {
+  }
+    
+  Component(const char *string)
+    : Block (Tlv::NameComponent, ConstBufferPtr(new Buffer(string, ::strlen(string))))
+  {
+  }
+
+  /**
+   * @brief Fast encoding or block size estimation
+   */
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T> &block) const;
+  
+  /**
+   * Make a Blob value by decoding the escapedString between beginOffset and endOffset according to the NDN URI Scheme.
+   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
+   * which means the component should be skipped in a URI name.
+   * @param escapedString The escaped string.  It does not need to be null-terminated because we only scan to endOffset.
+   * @param beginOffset The offset in escapedString of the beginning of the portion to decode.
+   * @param endOffset The offset in escapedString of the end of the portion to decode.
+   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+   */
+  static Component 
+  fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset);
+
+  /**
+   * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
+   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
+   * which means the component should be skipped in a URI name.
+   * @param escapedString The null-terminated escaped string.
+   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+   */
+  static Component 
+  fromEscapedString(const char *escapedString)
+  {
+    return fromEscapedString(escapedString, 0, ::strlen(escapedString));
+  }
+
+  /**
+   * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
+   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
+   * which means the component should be skipped in a URI name.
+   * @param escapedString The escaped string.
+   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
+   */
+  static Component 
+  fromEscapedString(const std::string& escapedString)
+  {
+    return fromEscapedString(escapedString.c_str());
+  }
+
+  /**
+   * Write the value to result, escaping characters according to the NDN URI Scheme.
+   * This also adds "..." to a value with zero or more ".".
+   * @param value the buffer with the value to escape
+   * @param result the string stream to write to.
+   */
+  void 
+  toEscapedString(std::ostream& result) const;
+  
+  /**
+   * Convert the value by escaping characters according to the NDN URI Scheme.
+   * This also adds "..." to a value with zero or more ".".
+   * @param value the buffer with the value to escape
+   * @return The escaped string.
+   */
+  inline std::string
+  toEscapedString() const
+  {
+    std::ostringstream result;
+    toEscapedString(result);
+    return result.str();
+  }
+    
+  /**
+   * Interpret this name component as a network-ordered number and return an integer.
+   * @return The integer number.
+   */
+  uint64_t
+  toNumber() const;
+
+  /**
+   * Interpret this name component as a network-ordered number with a marker and return an integer.
+   * @param marker The required first byte of the component.
+   * @return The integer number.
+   * @throw runtime_error If the first byte of the component does not equal the marker.
+   */
+  uint64_t
+  toNumberWithMarker(uint8_t marker) const;
+    
+  /**
+   * Interpret this name component as a segment number according to NDN name conventions (a network-ordered number 
+   * where the first byte is the marker 0x00).
+   * @return The integer segment number.
+   * @throw runtime_error If the first byte of the component is not the expected marker.
+   */
+  uint64_t
+  toSegment() const
+  {
+    return toNumberWithMarker(0x00);
+  }
+    
+  /**
+   * @deprecated Use toSegment.
+   */
+  uint64_t
+  toSeqNum() const
+  {
+    return toSegment();
+  }
+        
+  /**
+   * Interpret this name component as a version number according to NDN name conventions (a network-ordered number 
+   * where the first byte is the marker 0xFD).  Note that this returns the exact number from the component
+   * without converting it to a time representation.
+   * @return The integer segment number.
+   * @throw runtime_error If the first byte of the component is not the expected marker.
+   */
+  uint64_t
+  toVersion() const
+  {
+    return toNumberWithMarker(0xFD);
+  }
+    
+  /**
+   * Create a component whose value is the network-ordered encoding of the number.
+   * Note: if the number is zero, the result is empty.
+   * @param number The number to be encoded.
+   * @return The component value.
+   */
+  static Component 
+  fromNumber(uint64_t number);
+    
+  /**
+   * Create a component whose value is the marker appended with the network-ordered encoding of the number.
+   * Note: if the number is zero, no bytes are used for the number - the result will have only the marker.
+   * @param number The number to be encoded.  
+   * @param marker The marker to use as the first byte of the component.
+   * @return The component value.
+   */
+  static Component 
+  fromNumberWithMarker(uint64_t number, uint8_t marker);
+
+  /**
+   * Check if this is the same component as other.
+   * @param other The other Component to compare with.
+   * @return true if the components are equal, otherwise false.
+   */
+  bool
+  equals(const Component& other) const
+  {
+    if (value_size() != other.value_size())
+      return false;
+
+    return std::equal(value_begin(), value_end(), other.value_begin());
+  }
+
+  bool
+  empty() const
+  {
+    return !hasValue();
+  }
+    
+  /**
+   * Check if this is the same component as other.
+   * @param other The other Component to compare with.
+   * @return true if the components are equal, otherwise false.
+   */
+  bool
+  operator == (const Component& other) const { return equals(other); }
+
+  /**
+   * Check if this is not the same component as other.
+   * @param other The other Component to compare with.
+   * @return true if the components are not equal, otherwise false.
+   */
+  bool
+  operator != (const Component& other) const { return !equals(other); }
+    
+  /**
+   * Compare this to the other Component using NDN canonical ordering.
+   * @param other The other Component to compare with.
+   * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
+   * 1 if *this comes after other in the canonical ordering.
+   *
+   * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+   */
+  int
+  compare(const Component& other) const;
+  
+  /**
+   * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
+   * @param other The other Component to compare with.
+   *
+   * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+   */
+  bool
+  operator <= (const Component& other) const { return compare(other) <= 0; }
+  
+  /**
+   * Return true if this is less than the other Component in the NDN canonical ordering.
+   * @param other The other Component to compare with.
+   *
+   * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+   */
+  bool
+  operator < (const Component& other) const { return compare(other) < 0; }
+
+  /**
+   * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
+   * @param other The other Component to compare with.
+   *
+   * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+   */
+  bool
+  operator >= (const Component& other) const { return compare(other) >= 0; }
+
+  /**
+   * Return true if this is greater than the other Component in the NDN canonical ordering.
+   * @param other The other Component to compare with.
+   *
+   * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+   */
+  bool
+  operator > (const Component& other) const { return compare(other) > 0; }
+
+  // 
+  // !!! MUST NOT INCLUDE ANY DATA HERE !!!
+  //
+  // This class is just a helper and is directly reinterpret_cast'ed from Block
+};
+
+inline std::ostream &
+operator << (std::ostream &os, const Component &component)
+{
+  component.toEscapedString(os);
+  return os;
+}
+
+template<bool T>
+inline size_t
+Component::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t total_len = 0;
+  total_len += block.prependByteArray (value(), value_size());
+  total_len += block.prependVarNumber (value_size());
+  total_len += block.prependVarNumber (Tlv::NameComponent);
+  return total_len;
+}
+
+template
+size_t
+Component::wireEncode<true>(EncodingBuffer& block) const;
+
+template
+size_t
+Component::wireEncode<false>(EncodingEstimator& block) const;
+
+
+} // namespace name
+} // namespace ndn
+
+#endif // NDN_NAME_COMPONENT_HPP
diff --git a/src/name.cpp b/src/name.cpp
index fe1f739..5f4a018 100644
--- a/src/name.cpp
+++ b/src/name.cpp
@@ -6,124 +6,31 @@
  * See COPYING for copyright and distribution information.
  */
 
-#include <stdexcept>
+#include "name.hpp"
+
 #include <algorithm>
 #include <cstring>
-#include "name.hpp"
-#include "util/time.hpp"
 
+#include "util/time.hpp"
 #include "util/string-helper.hpp"
 
-using namespace std;
-
 namespace ndn {
 
-uint64_t
-Name::Component::toNumberWithMarker(uint8_t marker) const
-{
-  if (empty() || *getValue().begin() != marker)
-    throw runtime_error("Name component does not begin with the expected marker");
-  
-  uint64_t result = 0;
-  for (Buffer::const_iterator i = getValue().begin()+1; i != getValue().end(); ++i) {
-    result <<= 8;
-    result |= *i;
-  }
-  
-  return result;
-}
-
-Name::Component 
-Name::Component::fromNumber(uint64_t number)
-{
-  ptr_lib::shared_ptr<Buffer> value(new Buffer);
-  
-  // First encode in little endian.
-  while (number != 0) {
-    value->push_back(number & 0xff);
-    number >>= 8;
-  }
-  
-  // Make it big endian.
-  reverse(value->begin(), value->end());
-  return Component(value);
-}
-
-Name::Component
-Name::Component::fromNumberWithMarker(uint64_t number, uint8_t marker)
-{
-  ptr_lib::shared_ptr<Buffer> value(new Buffer);
-  
-  // Add the leading marker.
-  value->push_back(marker);
-  
-  // First encode in little endian.
-  while (number != 0) {
-    value->push_back(number & 0xff);
-    number >>= 8;
-  }
-  
-  // Make it big endian.
-  reverse(value->begin() + 1, value->end());
-  return Component(value);
-}
-
-uint64_t
-Name::Component::toNumber() const
-{
-  uint64_t result = 0;
-  for (Buffer::const_iterator i = getValue().begin(); i != getValue().end(); ++i) {
-    result <<= 8;
-    result |= *i;
-  }
-  
-  return result;
-}
-
-int
-Name::Component::compare(const Name::Component& other) const
-{
-  // Imitate ndn_Exclude_compareComponents.
-  if (getValue().size() < other.getValue().size())
-    return -1;
-  if (getValue().size() > other.getValue().size())
-    return 1;
-
-  // The components are equal length.  Just do a byte compare.  
-  return std::memcmp(getValue().buf(), other.getValue().buf(), getValue().size());
-}
-
-inline size_t
-Name::Component::wireEncode (EncodingBuffer& blk)
-{
-  size_t total_len = 0;
-  total_len += blk.prependBuffer (*value_);
-  total_len += blk.prependVarNumber (value_->size ());
-  total_len += blk.prependVarNumber (Tlv::NameComponent);
-  return total_len;
-}
-
-// const Block &
-// Name::wireEncode() const
-// {
-  
-// }
-
 void 
 Name::set(const char *uri_cstr) 
 {
-  components_.clear();
+  clear();
   
-  string uri = uri_cstr;
+  std::string uri = uri_cstr;
   trim(uri);
   if (uri.size() == 0)
     return;
 
   size_t iColon = uri.find(':');
-  if (iColon != string::npos) {
+  if (iColon != std::string::npos) {
     // Make sure the colon came before a '/'.
     size_t iFirstSlash = uri.find('/');
-    if (iFirstSlash == string::npos || iColon < iFirstSlash) {
+    if (iFirstSlash == std::string::npos || iColon < iFirstSlash) {
       // Omit the leading protocol such as ndn:
       uri.erase(0, iColon + 1);
       trim(uri);
@@ -135,7 +42,7 @@
     if (uri.size() >= 2 && uri[1] == '/') {
       // Strip the authority following "//".
       size_t iAfterAuthority = uri.find('/', 2);
-      if (iAfterAuthority == string::npos)
+      if (iAfterAuthority == std::string::npos)
         // Unusual case: there was only an authority.
         return;
       else {
@@ -154,13 +61,13 @@
   // Unescape the components.
   while (iComponentStart < uri.size()) {
     size_t iComponentEnd = uri.find("/", iComponentStart);
-    if (iComponentEnd == string::npos)
+    if (iComponentEnd == std::string::npos)
       iComponentEnd = uri.size();
     
-    Component component(fromEscapedString(&uri[0], iComponentStart, iComponentEnd));
+    Component component = Component::fromEscapedString(&uri[0], iComponentStart, iComponentEnd);
     // Ignore illegal components.  This also gets rid of a trailing '/'.
     if (!component.empty())
-      components_.push_back(Component(component));
+      append(Component(component));
     
     iComponentStart = iComponentEnd + 1;
   }
@@ -173,8 +80,8 @@
     // Copying from this name, so need to make a copy first.
     return append(Name(name));
 
-  for (size_t i = 0; i < name.components_.size(); ++i)
-    components_.push_back(name.components_[i]);
+  for (size_t i = 0; i < name.size(); ++i)
+    append(name.at(i));
   
   return *this;
 }
@@ -192,8 +99,8 @@
   Name result;
   
   size_t iEnd = iStartComponent + nComponents;
-  for (size_t i = iStartComponent; i < iEnd && i < components_.size(); ++i)
-    result.components_.push_back(components_[i]);
+  for (size_t i = iStartComponent; i < iEnd && i < size(); ++i)
+    result.append(at(i));
   
   return result;
 }
@@ -203,8 +110,8 @@
 {
   Name result;
   
-  for (size_t i = iStartComponent; i < components_.size(); ++i)
-    result.components_.push_back(components_[i]);
+  for (size_t i = iStartComponent; i < size(); ++i)
+    result.append(at(i));
   
   return result;
 }
@@ -212,11 +119,11 @@
 bool 
 Name::equals(const Name& name) const
 {
-  if (components_.size() != name.components_.size())
+  if (size() != name.size())
     return false;
 
-  for (size_t i = 0; i < components_.size(); ++i) {
-    if (components_[i].getValue() != name.components_[i].getValue())
+  for (size_t i = 0; i < size(); ++i) {
+    if (at(i) != name.at(i))
       return false;
   }
 
@@ -226,92 +133,25 @@
 bool 
 Name::isPrefixOf(const Name& name) const
 {
-  // Imitate ndn_Name_match.
-  
   // This name is longer than the name we are checking it against.
-  if (components_.size() > name.components_.size())
+  if (size() > name.size())
     return false;
 
   // Check if at least one of given components doesn't match.
-  for (size_t i = 0; i < components_.size(); ++i) {
-    if (components_[i].getValue() != name.components_[i].getValue())
+  for (size_t i = 0; i < size(); ++i) {
+    if (at(i) != name.at(i))
       return false;
   }
 
   return true;
 }
 
-Name::Component 
-Name::fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset)
-{
-  string trimmedString(escapedString + beginOffset, escapedString + endOffset);
-  trim(trimmedString);
-  string value = unescape(trimmedString);
-        
-  if (value.find_first_not_of(".") == string::npos) {
-    // Special case for component of only periods.  
-    if (value.size() <= 2)
-      // Zero, one or two periods is illegal.  Ignore this component.
-      return Component();
-    else
-      // Remove 3 periods.
-      return Component((const uint8_t *)&value[3], value.size() - 3); 
-  }
-  else
-    return Component((const uint8_t *)&value[0], value.size()); 
-}
-
-Name::Component
-Name::fromEscapedString(const char *escapedString)
-{
-  return fromEscapedString(escapedString, 0, ::strlen(escapedString));
-}
-
-void
-Name::toEscapedString(const uint8_t *value, size_t valueSize, std::ostream& result)
-{
-  bool gotNonDot = false;
-  for (unsigned i = 0; i < valueSize; ++i) {
-    if (value[i] != 0x2e) {
-      gotNonDot = true;
-      break;
-    }
-  }
-  if (!gotNonDot) {
-    // Special case for component of zero or more periods.  Add 3 periods.
-    result << "...";
-    for (size_t i = 0; i < valueSize; ++i)
-      result << '.';
-  }
-  else {
-    // In case we need to escape, set to upper case hex and save the previous flags.
-    ios::fmtflags saveFlags = result.flags(ios::hex | ios::uppercase);
-    
-    for (size_t i = 0; i < valueSize; ++i) {
-      uint8_t x = value[i];
-      // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
-      if ((x >= 0x30 && x <= 0x39) || (x >= 0x41 && x <= 0x5a) ||
-          (x >= 0x61 && x <= 0x7a) || x == 0x2b || x == 0x2d || 
-          x == 0x2e || x == 0x5f)
-        result << x;
-      else {
-        result << '%';
-        if (x < 16)
-          result << '0';
-        result << (unsigned int)x;
-      }
-    }
-    
-    // Restore.
-    result.flags(saveFlags);
-  }  
-}
 
 int
 Name::compare(const Name& other) const
 {
   for (size_t i = 0; i < size() && i < other.size(); ++i) {
-    int comparison = components_[i].compare(other.components_[i]);
+    int comparison = at(i).compare(other.at(i));
     if (comparison == 0)
       // The components at this index are equal, so check the next components.
       continue;
@@ -350,50 +190,34 @@
 const Block &
 Name::wireEncode() const
 {
-  if (wire_.hasWire())
-    return wire_;
+  if (m_nameBlock.hasWire())
+    return m_nameBlock;
 
-  wire_ = Block(Tlv::Name);
-  for (Name::const_iterator i = begin(); i != end(); i++) {
-    OBufferStream os;
-    Tlv::writeVarNumber(os, Tlv::NameComponent);
-    Tlv::writeVarNumber(os, i->getValue().size());
-    os.write(reinterpret_cast<const char*>(i->getValue().buf()), i->getValue().size());
-
-    wire_.push_back(Block(os.buf()));
-  }
+  for (Block::element_iterator i = m_nameBlock.element_begin();
+       i != m_nameBlock.element_end();
+       ++i)
+    {
+      i->encode();
+    }
         
-  wire_.encode();
-  return wire_;
+  m_nameBlock.encode();
+  return m_nameBlock;
 }
 
 void
 Name::wireDecode(const Block &wire)
 {
-  clear();
-  
-  wire_ = wire;
-  wire_.parse();
-
-  components_.clear();
-  components_.reserve(wire_.getAll().size());
-
-  for (Block::element_const_iterator i = wire_.getAll().begin();
-       i != wire_.getAll().end();
-       ++i)
-    {
-      append(i->value(), i->value_size());
-    }
+  m_nameBlock = wire;
+  m_nameBlock.parse();
 }
 
-
 size_t
 Name::wireEncode (EncodingBuffer& blk)
 {
   size_t total_len = 0;
   
-  for (std::vector<Component>::reverse_iterator i = components_.rbegin ();
-       i != components_.rend ();
+  for (reverse_iterator i = rbegin (); 
+       i != rend ();
        ++i)
     {
       total_len += i->wireEncode (blk);
diff --git a/src/name.hpp b/src/name.hpp
index 78bdfd7..78b3b9d 100644
--- a/src/name.hpp
+++ b/src/name.hpp
@@ -10,279 +10,60 @@
 #ifndef NDN_NAME_HPP
 #define NDN_NAME_HPP
 
-#include <vector>
-#include <string>
-#include <sstream>
-#include <string.h>
+#include "common.hpp"
+#include "name-component.hpp"
+
 #include "encoding/block.hpp"
 #include "encoding/encoding-buffer.hpp"
 
+#include <boost/iterator/reverse_iterator.hpp>
+
 namespace ndn {
-    
+
 /**
  * A Name holds an array of Name::Component and represents an NDN name.
  */
 class Name : public ptr_lib::enable_shared_from_this<Name> {
 public:
-  /**
-   * A Name::Component holds a read-only name component value.
-   */
-  class Component
-  {
-  public:
-    /**
-     * Create a new Name::Component with a null value.
-     */
-    Component() 
-    {    
-    }
+  /// @brief Error that can be thrown from the block
+  struct Error : public name::Component::Error { Error(const std::string &what) : name::Component::Error(what) {} };
 
-    // copy constructor OK
+  typedef name::Component Component;
+
+  typedef std::vector<Component>  component_container;
+
+  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;
   
-    /**
-     * Create a new Name::Component, taking another pointer to the Blob value.
-     * @param value A blob with a pointer to an immutable array.  The pointer is copied.
-     */
-    Component(const ConstBufferPtr &buffer)
-    : value_ (buffer)
-    {
-    }
+  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;
   
-    /**
-     * Create a new Name::Component, copying the given value.
-     * @param value The value byte array.
-     */
-    Component(const Buffer& value) 
-      : value_ (new Buffer(value))
-    {
-    }
-
-    /**
-     * Create a new Name::Component, copying the given value.
-     * @param value Pointer to the value byte array.
-     * @param valueLen Length of value.
-     */
-    Component(const uint8_t *value, size_t valueLen) 
-      : value_ (new Buffer(value, valueLen))
-    {
-    }
-
-    template<class InputIterator>
-    Component(InputIterator begin, InputIterator end)
-      : value_ (new Buffer(begin, end))
-    {
-    }
-    
-    Component(const char *string)
-      : value_ (new Buffer(string, ::strlen(string)))
-    {
-    }
-
-    const Buffer& 
-    getValue() const { return *value_; }
-
-    /**
-     * Write this component value to result, escaping characters according to the NDN URI Scheme.
-     * This also adds "..." to a value with zero or more ".".
-     * @param result the string stream to write to.
-     */
-    void 
-    toEscapedString(std::ostream& result) const
-    {
-      Name::toEscapedString(*value_, result);
-    }
-
-    /**
-     * Convert this component value by escaping characters according to the NDN URI Scheme.
-     * This also adds "..." to a value with zero or more ".".
-     * @return The escaped string.
-     */
-    std::string
-    toEscapedString() const
-    {
-      return Name::toEscapedString(*value_);
-    }
-    
-    /**
-     * Interpret this name component as a network-ordered number and return an integer.
-     * @return The integer number.
-     */
-    uint64_t
-    toNumber() const;
-
-    /**
-     * Interpret this name component as a network-ordered number with a marker and return an integer.
-     * @param marker The required first byte of the component.
-     * @return The integer number.
-     * @throw runtime_error If the first byte of the component does not equal the marker.
-     */
-    uint64_t
-    toNumberWithMarker(uint8_t marker) const;
-    
-    /**
-     * Interpret this name component as a segment number according to NDN name conventions (a network-ordered number 
-     * where the first byte is the marker 0x00).
-     * @return The integer segment number.
-     * @throw runtime_error If the first byte of the component is not the expected marker.
-     */
-    uint64_t
-    toSegment() const
-    {
-      return toNumberWithMarker(0x00);
-    }
-    
-    /**
-     * @deprecated Use toSegment.
-     */
-    uint64_t
-    toSeqNum() const
-    {
-      return toSegment();
-    }
-        
-    /**
-     * Interpret this name component as a version number according to NDN name conventions (a network-ordered number 
-     * where the first byte is the marker 0xFD).  Note that this returns the exact number from the component
-     * without converting it to a time representation.
-     * @return The integer segment number.
-     * @throw runtime_error If the first byte of the component is not the expected marker.
-     */
-    uint64_t
-    toVersion() const
-    {
-      return toNumberWithMarker(0xFD);
-    }
-    
-    /**
-     * Create a component whose value is the network-ordered encoding of the number.
-     * Note: if the number is zero, the result is empty.
-     * @param number The number to be encoded.
-     * @return The component value.
-     */
-    static Component 
-    fromNumber(uint64_t number);
-    
-    /**
-     * Create a component whose value is the marker appended with the network-ordered encoding of the number.
-     * Note: if the number is zero, no bytes are used for the number - the result will have only the marker.
-     * @param number The number to be encoded.  
-     * @param marker The marker to use as the first byte of the component.
-     * @return The component value.
-     */
-    static Component 
-    fromNumberWithMarker(uint64_t number, uint8_t marker);
-
-    /**
-     * Check if this is the same component as other.
-     * @param other The other Component to compare with.
-     * @return true if the components are equal, otherwise false.
-     */
-    bool
-    equals(const Component& other) const
-    {
-      return *value_ == *other.value_;
-    }
-
-    bool
-    empty() const
-    {
-      return !value_ || value_->empty();
-    }
-    
-    /**
-     * Check if this is the same component as other.
-     * @param other The other Component to compare with.
-     * @return true if the components are equal, otherwise false.
-     */
-    bool
-    operator == (const Component& other) const { return equals(other); }
-
-    /**
-     * Check if this is not the same component as other.
-     * @param other The other Component to compare with.
-     * @return true if the components are not equal, otherwise false.
-     */
-    bool
-    operator != (const Component& other) const { return !equals(other); }
-    
-    /**
-     * Compare this to the other Component using NDN canonical ordering.
-     * @param other The other Component to compare with.
-     * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
-     * 1 if *this comes after other in the canonical ordering.
-     *
-     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
-     */
-    int
-    compare(const Component& other) const;
-  
-    /**
-     * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
-     * @param other The other Component to compare with.
-     *
-     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
-     */
-    bool
-    operator <= (const Component& other) const { return compare(other) <= 0; }
-  
-    /**
-     * Return true if this is less than the other Component in the NDN canonical ordering.
-     * @param other The other Component to compare with.
-     *
-     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
-     */
-    bool
-    operator < (const Component& other) const { return compare(other) < 0; }
-
-    /**
-     * Return true if this is less than or equal to the other Component in the NDN canonical ordering.
-     * @param other The other Component to compare with.
-     *
-     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
-     */
-    bool
-    operator >= (const Component& other) const { return compare(other) >= 0; }
-
-    /**
-     * Return true if this is greater than the other Component in the NDN canonical ordering.
-     * @param other The other Component to compare with.
-     *
-     * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
-     */
-    bool
-    operator > (const Component& other) const { return compare(other) > 0; }
-
-    inline size_t
-    wireEncode (EncodingBuffer& blk);
-    
-  private:
-    ConstBufferPtr value_;
-  };
-
   /**
    * Create a new Name with no components.
    */
-  Name() {
+  Name()
+    : m_nameBlock(Tlv::Name)
+  {
   }
   
-  /**
-   * Create a new Name, copying the name components.
-   * @param components A vector of Component
-   */
-  Name(const std::vector<Component>& components)
-  : components_(components)
-  {
-  }
-
-  Name(const Block &name)
-  {
-    for (Block::element_const_iterator i = name.getAll().begin();
-         i != name.getAll().end();
-         ++i)
-      {
-        append(Component(i->value_begin(), i->value_end()));
-      }
-  }
+  // Name(const Block &name)
+  // {
+  //   for (Block::element_const_iterator i = name.getAll().begin();
+  //        i != name.getAll().end();
+  //        ++i)
+  //     {
+  //       append(Component(i->value_begin(), i->value_end()));
+  //     }
+  // }
   
   /**
    * Parse the uri according to the NDN URI Scheme and create the name with the components.
@@ -323,7 +104,10 @@
    * @param uri The URI string.
    */
   void 
-  set(const std::string& uri) { set(uri.c_str()); }  
+  set(const std::string& uri)
+  {
+    set(uri.c_str());
+  }  
   
   /**
    * Append a new component, copying from value of length valueLength.
@@ -332,32 +116,32 @@
   Name& 
   append(const uint8_t *value, size_t valueLength) 
   {
-    components_.push_back(Component(value, valueLength));
+    m_nameBlock.elements().push_back(Component(value, valueLength));
     return *this;
   }
 
-  /**
-   * Append a new component, copying from value.
-   * @return This name so that you can chain calls to append.
-   */
-  Name& 
-  append(const Buffer& value) 
-  {
-    components_.push_back(value);
-    return *this;
-  }
+  // /**
+  //  * Append a new component, copying from value.
+  //  * @return This name so that you can chain calls to append.
+  //  */
+  // Name& 
+  // append(const Buffer& value) 
+  // {
+  //   m_nameBlock.elements().push_back(value);
+  //   return *this;
+  // }
   
   Name& 
   append(const ConstBufferPtr &value)
   {
-    components_.push_back(value);
+    m_nameBlock.elements().push_back(value);
     return *this;
   }
   
   Name& 
   append(const Component &value)
   {
-    components_.push_back(value);
+    m_nameBlock.elements().push_back(value);
     return *this;
   }
 
@@ -371,14 +155,14 @@
   Name& 
   append(const char *value)
   {
-    components_.push_back(Component(value));
+    m_nameBlock.elements().push_back(Component(value));
     return *this;
   }
   
   Name&
   append(const Block &value)
   {
-    components_.push_back(Component(value.begin(), value.end()));
+    m_nameBlock.elements().push_back(Component(value.begin(), value.end()));
     return *this;
   }
   
@@ -389,82 +173,17 @@
    */
   Name&
   append(const Name& name);
-  
-  /**
-   * @deprecated Use append.
-   */
-  Name& 
-  appendComponent(const uint8_t *value, size_t valueLength) 
-  {
-    return append(value, valueLength);
-  }
-
-  /**
-   * @deprecated Use append.
-   */
-  Name& 
-  appendComponent(const Buffer& value) 
-  {
-    return append(value);
-  }
-  
-  /**
-   * @deprecated Use append.
-   */
-  Name& 
-  appendComponent(const ConstBufferPtr &value)
-  {
-    return append(value);
-  }
-
-  /**
-   * @deprecated Use append.
-   */
-  Name& 
-  addComponent(const uint8_t *value, size_t valueLength) 
-  {
-    return append(value, valueLength);
-  }
-
-  /**
-   * @deprecated Use append.
-   */
-  Name& 
-  addComponent(const Buffer& value) 
-  {
-    return append(value);
-  }
-  
-  /**
-   * @deprecated Use append.
-   */
-  Name& 
-  addComponent(const ConstBufferPtr &value)
-  {
-    return append(value);
-  }
-  
+    
   /**
    * Clear all the components.
    */
   void 
-  clear() {
-    components_.clear();
+  clear()
+  {
+    m_nameBlock = Block(Tlv::Name);
   }
   
   /**
-   * @deprecated use size().
-   */
-  size_t 
-  getComponentCount() const { return size(); }
-  
-  /**
-   * @deprecated Use get(i).
-   */
-  const Component& 
-  getComponent(size_t i) const { return get(i); }
-  
-  /**
    * Get a new name, constructed as a subset of components.
    * @param iStartComponent The index if the first component to get.
    * @param nComponents The number of components starting at iStartComponent.
@@ -491,7 +210,7 @@
   getPrefix(int nComponents) const
   {
     if (nComponents < 0)
-      return getSubName(0, components_.size() + nComponents);
+      return getSubName(0, m_nameBlock.elements().size() + nComponents);
     else
       return getSubName(0, nComponents);
   }
@@ -511,7 +230,7 @@
   Name& 
   appendSegment(uint64_t segment)
   {
-    components_.push_back(Component::fromNumberWithMarker(segment, 0x00));
+    m_nameBlock.elements().push_back(Component::fromNumberWithMarker(segment, 0x00));
     return *this;
   }
 
@@ -524,7 +243,7 @@
   Name& 
   appendVersion(uint64_t version)
   {
-    components_.push_back(Component::fromNumberWithMarker(version, 0xFD));
+    m_nameBlock.elements().push_back(Component::fromNumberWithMarker(version, 0xFD));
     return *this;
   }
 
@@ -559,73 +278,6 @@
     return isPrefixOf(name);
   }
   
-  /**
-   * Make a Blob value by decoding the escapedString between beginOffset and endOffset according to the NDN URI Scheme.
-   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
-   * which means the component should be skipped in a URI name.
-   * @param escapedString The escaped string.  It does not need to be null-terminated because we only scan to endOffset.
-   * @param beginOffset The offset in escapedString of the beginning of the portion to decode.
-   * @param endOffset The offset in escapedString of the end of the portion to decode.
-   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
-   */
-  static Component 
-  fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset);
-
-  /**
-   * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
-   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
-   * which means the component should be skipped in a URI name.
-   * @param escapedString The null-terminated escaped string.
-   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
-   */
-  static Component 
-  fromEscapedString(const char *escapedString);
-
-  /**
-   * Make a Blob value by decoding the escapedString according to the NDN URI Scheme.
-   * If the escaped string is "", "." or ".." then return a Blob with a null pointer, 
-   * which means the component should be skipped in a URI name.
-   * @param escapedString The escaped string.
-   * @return The Blob value. If the escapedString is not a valid escaped component, then the Blob is a null pointer.
-   */
-  static Component 
-  fromEscapedString(const std::string& escapedString) { return fromEscapedString(escapedString.c_str()); }
-
-  /**
-   * Write the value to result, escaping characters according to the NDN URI Scheme.
-   * This also adds "..." to a value with zero or more ".".
-   * @param value the buffer with the value to escape
-   * @param result the string stream to write to.
-   */
-  static void 
-  toEscapedString(const uint8_t *value, size_t valueSize, std::ostream& result);
-
-  inline static void 
-  toEscapedString(const std::vector<uint8_t>& value, std::ostream& result)
-  {
-    toEscapedString(&*value.begin(), value.size(), result);
-  }
-  
-  /**
-   * Convert the value by escaping characters according to the NDN URI Scheme.
-   * This also adds "..." to a value with zero or more ".".
-   * @param value the buffer with the value to escape
-   * @return The escaped string.
-   */
-  inline static std::string
-  toEscapedString(const uint8_t *value, size_t valueSize)
-  {
-    std::ostringstream result;
-    toEscapedString(value, valueSize, result);
-    return result.str();
-  }
-
-  static inline std::string
-  toEscapedString(const std::vector<uint8_t>& value)
-  {
-    return toEscapedString(&*value.begin(), value.size());
-  }
-  
   //
   // vector equivalent interface.
   //
@@ -634,14 +286,14 @@
    * @brief Check if name is emtpy
    */
   bool
-  empty() const { return components_.empty(); }
+  empty() const { return m_nameBlock.elements().empty(); }
   
   /**
    * Get the number of components.
    * @return The number of components.
    */
   size_t 
-  size() const { return components_.size(); }
+  size() const { return m_nameBlock.elements().size(); }
 
   /**
    * Get the component at the given index.
@@ -652,11 +304,23 @@
   get(ssize_t i) const
   {
     if (i >= 0)
-      return components_[i];
+      return reinterpret_cast<const Component&>(m_nameBlock.elements()[i]);
     else
-      return components_[size() + i];
+      return reinterpret_cast<const Component&>(m_nameBlock.elements()[size() + i]);
+  }
+
+  const Component&
+  operator [] (ssize_t i) const
+  {
+    return get(i);
   }
   
+  const Component&
+  at(ssize_t i) const
+  {
+    return get(i);
+  }
+
   /**
    * Compare this to the other Name using NDN canonical ordering.  If the first components of each name are not equal, 
    * this returns -1 if the first comes before the second using the NDN canonical ordering for name components, or 1 if it comes after.
@@ -674,12 +338,6 @@
   int
   compare(const Name& other) const;
 
-  const Component&
-  operator [] (int i) const
-  {
-    return get(i);
-  }
-
   /**
    * Append the component
    * @param component The component of type T.
@@ -745,82 +403,67 @@
   //
   // Iterator interface to name components.
   //
-  typedef std::vector<Component>::iterator iterator;
-  typedef std::vector<Component>::const_iterator const_iterator;
-  typedef std::vector<Component>::reverse_iterator reverse_iterator;
-  typedef std::vector<Component>::const_reverse_iterator const_reverse_iterator;
-  typedef std::vector<Component>::reference reference;
-  typedef std::vector<Component>::const_reference const_reference;
-
-  typedef std::vector<Component>::difference_type difference_type;
-  typedef std::vector<Component>::size_type size_type;
-  
-  typedef std::vector<Component>::value_type value_type;
 
   /**
    * Begin iterator (const).
    */
   const_iterator
-  begin() const { return components_.begin(); }
+  begin() const
+  {
+    return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().begin());
+  }
 
   /**
    * Begin iterator.
    */
   iterator
-  begin() { return components_.begin(); }
+  begin() { return reinterpret_cast<iterator>(&*m_nameBlock.elements().begin()); }
 
   /**
    * End iterator (const).
+   *
+   * @todo Check if this crash when there are no elements in the buffer
    */
   const_iterator
-  end() const { return components_.end(); }
+  end() const { return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().end()); }
 
   /**
    * End iterator.
    */
   iterator
-  end() { return components_.end(); }
-
+  end() { return reinterpret_cast<iterator>(&*m_nameBlock.elements().end()); }
+  
   /**
    * Reverse begin iterator (const).
    */
   const_reverse_iterator
-  rbegin() const { return components_.rbegin(); }
+  rbegin() const { return const_reverse_iterator(end()); }
 
   /**
    * Reverse begin iterator.
    */
   reverse_iterator
-  rbegin() { return components_.rbegin(); }
+  rbegin() { return reverse_iterator(end()); }
 
   /**
    * Reverse end iterator (const).
    */
   const_reverse_iterator
-  rend() const { return components_.rend(); }
+  rend() const { return const_reverse_iterator(begin()); }
 
   /**
    * Reverse end iterator.
    */
   reverse_iterator
-  rend() { return components_.rend(); }
+  rend() { return reverse_iterator(begin()); }
 
 private:
-  std::vector<Component> components_;
-
-  mutable Block wire_;
+  mutable Block m_nameBlock;
 };
 
 std::ostream &
 operator << (std::ostream &os, const Name &name);
 
-inline std::ostream &
-operator << (std::ostream &os, const Name::Component &component)
-{
-  component.toEscapedString(os);
-  return os;
-}
-
 inline std::string 
 Name::toUri() const
 {
@@ -829,7 +472,7 @@
   return os.str();
 }
 
-}
+} // namespace ndn
 
 #endif
 
diff --git a/src/util/string-helper.hpp b/src/util/string-helper.hpp
index ee3f5bd..de0c41f 100644
--- a/src/util/string-helper.hpp
+++ b/src/util/string-helper.hpp
@@ -13,7 +13,7 @@
 
 namespace ndn {
 
-const char *WHITESPACE_CHARS = " \n\r\t";
+static const char *WHITESPACE_CHARS = " \n\r\t";
 
 /**
  * Modify str in place to erase whitespace on the left.