encoding: Fixing Block (and as a result Name) encoding bugs

As of this commit, all non-const operations on Block will call resetWire
to remove all references to the wire, so it will be recreated next time
"encode" method is called.  Also, all getter methods now have only const
versions and non-const access to the internal data structure is
prohibited.

Change-Id: If4b485dd62541d9d4d168a44490068e4deff56c1
diff --git a/examples/consumer-with-timer.cpp b/examples/consumer-with-timer.cpp
index 9af81da..6c7ef8c 100644
--- a/examples/consumer-with-timer.cpp
+++ b/examples/consumer-with-timer.cpp
@@ -40,21 +40,6 @@
                        ndn::bind(&onTimeout, boost::ref(face), _1));
 }
 
-void
-BlockPrinter(const ndn::Block &block, const std::string &indent="")
-{
-  std::cout << indent << block.type() << " (" << block.value_size() << ") [[";
-  std::cout.write(reinterpret_cast<const char *>(block.value()), block.value_size());
-  std::cout<< "]]" << std::endl;
-
-  for(ndn::Block::element_const_iterator i = block.getAll().begin();
-      i != block.getAll().end();
-      ++i)
-    {
-      BlockPrinter(*i, indent+"  ");
-    }
-}
-
 int main()
 {
   try {
diff --git a/examples/consumer.cpp b/examples/consumer.cpp
index 4dd1036..69a51e4 100644
--- a/examples/consumer.cpp
+++ b/examples/consumer.cpp
@@ -24,21 +24,6 @@
   std::cout << "Timeout" << std::endl;
 }
 
-void
-BlockPrinter(const ndn::Block& block, const std::string& indent="")
-{
-  std::cout << indent << block.type() << " (" << block.value_size() << ") [[";
-  std::cout.write(reinterpret_cast<const char *>(block.value()), block.value_size());
-  std::cout<< "]]" << std::endl;
-
-  for(ndn::Block::element_const_iterator i = block.getAll().begin();
-      i != block.getAll().end();
-      ++i)
-    {
-      BlockPrinter(*i, indent+"  ");
-    }
-}
-
 int main()
 {
   try {
diff --git a/src/encoding/block.cpp b/src/encoding/block.cpp
index e6a8b80..9c8ba1e 100644
--- a/src/encoding/block.cpp
+++ b/src/encoding/block.cpp
@@ -183,7 +183,7 @@
 }
 
 void
-Block::parse()
+Block::parse() const
 {
   if (!m_subBlocks.empty() || value_size()==0)
     return;
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index 45cf1ad..32523a5 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -120,9 +120,24 @@
   inline void
   reset();
 
-  void
-  parse();
+  /**
+   * @brief Reset wire buffer but keep sub elements (if any)
+   */
+  inline void
+  resetWire();
 
+  /**
+   * @brief Parse wire buffer into subblocks
+   *
+   * This method is not really const, but it does not modify any data.  It simply
+   * parses contents of the buffer into subblocks
+   */
+  void
+  parse() const;
+
+  /**
+   * @brief Encode subblocks into wire buffer
+   */
   void
   encode();
   
@@ -135,12 +150,6 @@
   inline const Block &
   get(uint32_t type) const;
 
-  inline Block &
-  get(uint32_t type);
-  
-  inline element_iterator
-  find(uint32_t type);
-
   inline element_const_iterator
   find(uint32_t type) const;
 
@@ -156,66 +165,48 @@
   inline void
   push_back(const Block &element);
   
-  /**
-   * @brief Get all subelements
-   */
-  inline const element_container&
-  getAll () const;
-
-  inline element_container&
-  getAll ();
-
-  inline const element_container&
-  elements () const;
-
-  inline element_container&
-  elements ();
-  
-  /**
-   * @brief Get all elements of the requested type
-   */
-  element_container
-  getAll(uint32_t type) const;
-
   inline Buffer::const_iterator
   begin() const;
 
   inline Buffer::const_iterator
   end() const;
 
+  inline const uint8_t*
+  wire() const;
+
   inline size_t
   size() const;
 
+  // inline const uint8_t*
+  // buf() const;
+  
   inline Buffer::const_iterator
   value_begin() const;
 
   inline Buffer::const_iterator
   value_end() const;
 
-  inline element_iterator
-  element_begin();
-
-  inline element_iterator
-  element_end();
-
-  inline element_const_iterator
-  element_begin() const;
-
-  inline element_const_iterator
-  element_end() const;
-  
-  inline const uint8_t*
-  wire() const;
-
-  // inline const uint8_t*
-  // buf() const;
-  
   inline const uint8_t*
   value() const;
 
   inline size_t
   value_size() const;
 
+  /**
+   * @brief Get all subelements
+   */
+  inline const element_container&
+  elements () const;
+
+  inline element_const_iterator
+  elements_begin() const;
+
+  inline element_const_iterator
+  elements_end() const;
+
+  inline size_t
+  elements_size() const;
+  
   Block
   blockFromValue() const;
 
@@ -231,7 +222,7 @@
   Buffer::const_iterator m_value_begin;
   Buffer::const_iterator m_value_end;
 
-  element_container m_subBlocks;
+  mutable element_container m_subBlocks;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -267,6 +258,16 @@
   m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator(); // not really necessary, but for safety
 }
 
+inline void
+Block::resetWire()
+{
+  m_buffer.reset(); // reset of the shared_ptr
+  // keep subblocks
+
+  // keep type
+  m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator(); // not really necessary, but for safety
+}
+
 inline uint32_t
 Block::type() const
 {
@@ -288,22 +289,6 @@
 
   throw Error("(Block::get) Requested a non-existed type [" + boost::lexical_cast<std::string>(type) + "] from Block");
 }
-
-inline Block &
-Block::get(uint32_t type)
-{
-  for (element_iterator i = m_subBlocks.begin ();
-       i != m_subBlocks.end();
-       i++)
-    {
-      if (i->type () == type)
-        {
-          return *i;
-        }
-    }
-
-  throw Error("(Block::get) Requested a non-existed type [" + boost::lexical_cast<std::string>(type) + "] from Block");
-}
   
 inline Block::element_const_iterator
 Block::find(uint32_t type) const
@@ -320,24 +305,11 @@
   return m_subBlocks.end();
 }
 
-inline Block::element_iterator
-Block::find(uint32_t type)
-{
-  for (element_iterator i = m_subBlocks.begin ();
-       i != m_subBlocks.end();
-       i++)
-    {
-      if (i->type () == type)
-        {
-          return i;
-        }
-    }
-  return m_subBlocks.end();
-}
-
 inline void
 Block::remove(uint32_t type)
 {
+  resetWire();
+
   element_container newContainer;
   newContainer.reserve(m_subBlocks.size());
   for (element_iterator i = m_subBlocks.begin();
@@ -348,17 +320,19 @@
         newContainer.push_back(*i);
   }
   m_subBlocks.swap(newContainer);
-  }
+}
 
 inline Block::element_iterator
 Block::erase(Block::element_iterator position)
 {
+  resetWire();
   return m_subBlocks.erase(position);
 }
 
 inline Block::element_iterator
 Block::erase(Block::element_iterator first, Block::element_iterator last)
 {
+  resetWire();
   return m_subBlocks.erase(first, last);
 }
 
@@ -366,34 +340,10 @@
 inline void
 Block::push_back(const Block &element)
 {
+  resetWire();
   m_subBlocks.push_back(element);
 }
 
-
-inline const Block::element_container&
-Block::getAll () const
-{
-  return m_subBlocks;
-}
-
-inline Block::element_container&
-Block::getAll ()
-{
-  return m_subBlocks;
-}
-
-inline const Block::element_container&
-Block::elements () const
-{
-  return m_subBlocks;
-}
-
-inline Block::element_container&
-Block::elements ()
-{
-  return m_subBlocks;
-}
-
 inline Buffer::const_iterator
 Block::begin() const
 {
@@ -440,30 +390,6 @@
   return m_value_end;
 }
 
-inline Block::element_iterator
-Block::element_begin()
-{
-  return m_subBlocks.begin();
-}
-
-inline Block::element_iterator
-Block::element_end()
-{
-  return m_subBlocks.end();
-}
-
-inline Block::element_const_iterator
-Block::element_begin() const
-{
-  return m_subBlocks.begin();
-}
-
-inline Block::element_const_iterator
-Block::element_end() const
-{
-  return m_subBlocks.end();
-}
-
 inline const uint8_t*
 Block::wire() const
 {
@@ -473,15 +399,6 @@
   return &*m_begin;
 }
 
-// inline const uint8_t*
-// Block::buf() const
-// {
-//   if (!hasWire())
-//       throw Error("(Block::wire) Underlying wire buffer is empty");
-
-//   return &*m_begin;
-// }
-
 inline const uint8_t*
 Block::value() const
 {
@@ -500,6 +417,31 @@
   return m_value_end - m_value_begin;
 }
 
+inline const Block::element_container&
+Block::elements () const
+{
+  return m_subBlocks;
+}
+
+inline Block::element_const_iterator
+Block::elements_begin() const
+{
+  return m_subBlocks.begin();
+}
+
+inline Block::element_const_iterator
+Block::elements_end() const
+{
+  return m_subBlocks.end();
+}
+
+inline size_t
+Block::elements_size() const
+{
+  return m_subBlocks.size();
+}
+
+
 } // ndn
 
 #include "block-helpers.hpp"
diff --git a/src/exclude.cpp b/src/exclude.cpp
index 264919b..983daaf 100644
--- a/src/exclude.cpp
+++ b/src/exclude.cpp
@@ -213,14 +213,14 @@
   wire_ = wire;
   wire_.parse();
 
-  Block::element_const_iterator i = wire_.getAll().begin();
+  Block::element_const_iterator i = wire_.elements_begin();
   if (i->type() == Tlv::Any)
     {
       appendExclude(name::Component(), true);
       ++i;
     }
 
-  while (i != wire_.getAll().end())
+  while (i != wire_.elements_end())
     {
       if (i->type() != Tlv::NameComponent)
         throw Error("Incorrect format of Exclude filter");
@@ -228,7 +228,7 @@
       Name::Component excludedComponent (i->value(), i->value_size());
       ++i;
 
-      if (i != wire_.getAll().end())
+      if (i != wire_.elements_end())
         {
           if (i->type() == Tlv::Any)
             {
diff --git a/src/interest.cpp b/src/interest.cpp
index da3cab6..99e5040 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -134,7 +134,7 @@
         (booleanBlock(Tlv::MustBeFresh));
     }
 
-    if (!selectors.getAll().empty())
+    if (!selectors.elements().empty())
       {
         selectors.encode();
         wire_.push_back(selectors);
@@ -180,64 +180,64 @@
   name_.wireDecode(wire_.get(Tlv::Name));
 
   // Selectors
-  Block::element_iterator selectors = wire_.find(Tlv::Selectors);
-  if (selectors != wire_.getAll().end())
+  Block::element_const_iterator selectors = wire_.find(Tlv::Selectors);
+  if (selectors != wire_.elements_end())
     {
       selectors->parse();
 
       // MinSuffixComponents
-      Block::element_iterator val = selectors->find(Tlv::MinSuffixComponents);
-      if (val != selectors->getAll().end())
+      Block::element_const_iterator val = selectors->find(Tlv::MinSuffixComponents);
+      if (val != selectors->elements_end())
         {
           minSuffixComponents_ = readNonNegativeInteger(*val);
         }
 
       // MaxSuffixComponents
       val = selectors->find(Tlv::MaxSuffixComponents);
-      if (val != selectors->getAll().end())
+      if (val != selectors->elements_end())
         {
           maxSuffixComponents_ = readNonNegativeInteger(*val);
         }
 
       // Exclude
       val = selectors->find(Tlv::Exclude);
-      if (val != selectors->getAll().end())
+      if (val != selectors->elements_end())
         {
           exclude_.wireDecode(*val);
         }
 
       // ChildSelector
       val = selectors->find(Tlv::ChildSelector);
-      if (val != selectors->getAll().end())
+      if (val != selectors->elements_end())
         {
           childSelector_ = readNonNegativeInteger(*val);
         }
 
       //MustBeFresh aka AnswerOriginKind
       val = selectors->find(Tlv::MustBeFresh);
-      if (val != selectors->getAll().end())
+      if (val != selectors->elements_end())
         {
           mustBeFresh_ = true;
         }
     }
   
   // Nonce
-  Block::element_iterator val = wire_.find(Tlv::Nonce);
-  if (val != wire_.getAll().end())
+  Block::element_const_iterator val = wire_.find(Tlv::Nonce);
+  if (val != wire_.elements_end())
     {
       nonce_ = readNonNegativeInteger(*val);
     }
 
   // Scope
   val = wire_.find(Tlv::Scope);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       scope_ = readNonNegativeInteger(*val);
     }
   
   // InterestLifetime
   val = wire_.find(Tlv::InterestLifetime);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       interestLifetime_ = readNonNegativeInteger(*val);
     }
diff --git a/src/key-locator.hpp b/src/key-locator.hpp
index a3fb896..54c9725 100644
--- a/src/key-locator.hpp
+++ b/src/key-locator.hpp
@@ -102,10 +102,10 @@
   wire_ = value;
   wire_.parse();
   
-  if (!wire_.getAll().empty() && wire_.getAll().front().type() == Tlv::Name)
+  if (!wire_.elements().empty() && wire_.elements_begin()->type() == Tlv::Name)
     {
       type_ = KeyLocator_Name;
-      name_.wireDecode(wire_.getAll().front());
+      name_.wireDecode(*wire_.elements_begin());
     }
   else
     {
diff --git a/src/management/ndnd-controller.cpp b/src/management/ndnd-controller.cpp
index 302699e..a897e27 100644
--- a/src/management/ndnd-controller.cpp
+++ b/src/management/ndnd-controller.cpp
@@ -175,14 +175,14 @@
   Block content = data.getContent();
   content.parse();
 
-  if (content.getAll().empty())
+  if (content.elements().empty())
     {
       if (static_cast<bool>(onFail))
         onFail("Empty response");
       return;
     }
 
-  Block::element_iterator val = content.getAll().begin();
+  Block::element_const_iterator val = content.elements_begin();
   
   switch(val->type())
     {
@@ -221,14 +221,14 @@
   Block content = data.getContent();
   content.parse();
 
-  if (content.getAll().empty())
+  if (content.elements().empty())
     {
       if (static_cast<bool>(onFail))
         onFail("Empty response");
       return;
     }
 
-  Block::element_iterator val = content.getAll().begin();
+  Block::element_const_iterator val = content.elements_begin();
   
   switch(val->type())
     {
diff --git a/src/management/ndnd-face-instance.hpp b/src/management/ndnd-face-instance.hpp
index 03a8589..0de85ff 100644
--- a/src/management/ndnd-face-instance.hpp
+++ b/src/management/ndnd-face-instance.hpp
@@ -226,57 +226,57 @@
   //                  FreshnessPeriod?
 
   // Action
-  Block::element_iterator val = wire_.find(Tlv::FaceManagement::Action);
-  if (val != wire_.getAll().end())
+  Block::element_const_iterator val = wire_.find(Tlv::FaceManagement::Action);
+  if (val != wire_.elements_end())
     {
       action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
     }
 
   // FaceID
   val = wire_.find(Tlv::FaceManagement::FaceID);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       faceId_ = readNonNegativeInteger(*val);
     }
 
   // IPProto
   val = wire_.find(Tlv::FaceManagement::IPProto);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       ipProto_ = readNonNegativeInteger(*val);
     }
 
   // Host
   val = wire_.find(Tlv::FaceManagement::Host);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       host_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
     }
 
   // Port
   val = wire_.find(Tlv::FaceManagement::Port);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       port_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
     }
 
   // MulticastInterface
   val = wire_.find(Tlv::FaceManagement::MulticastInterface);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       multicastInterface_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
     }
 
   // MulticastTTL
   val = wire_.find(Tlv::FaceManagement::MulticastTTL);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       multicastTtl_ = readNonNegativeInteger(*val);
     }
 
   // FreshnessPeriod
   val = wire_.find(Tlv::FreshnessPeriod);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       freshnessPeriod_ = readNonNegativeInteger(*val);
     }
diff --git a/src/management/ndnd-forwarding-entry.hpp b/src/management/ndnd-forwarding-entry.hpp
index 0a02c7e..5cd81ab 100644
--- a/src/management/ndnd-forwarding-entry.hpp
+++ b/src/management/ndnd-forwarding-entry.hpp
@@ -154,36 +154,36 @@
   //                       FreshnessPeriod?
 
   // Action
-  Block::element_iterator val = wire_.find(Tlv::FaceManagement::Action);
-  if (val != wire_.getAll().end())
+  Block::element_const_iterator val = wire_.find(Tlv::FaceManagement::Action);
+  if (val != wire_.elements_end())
     {
       action_ = std::string(reinterpret_cast<const char*>(val->value()), val->value_size());
     }
 
   // Name
   val = wire_.find(Tlv::Name);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       prefix_.wireDecode(*val);
     }
 
   // FaceID
   val = wire_.find(Tlv::FaceManagement::FaceID);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       faceId_ = readNonNegativeInteger(*val);
     }
 
   // ForwardingFlags
   val = wire_.find(Tlv::FaceManagement::ForwardingFlags);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       forwardingFlags_.wireDecode(*val);
     }
 
   // FreshnessPeriod
   val = wire_.find(Tlv::FreshnessPeriod);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       freshnessPeriod_ = readNonNegativeInteger(*val);
     }
diff --git a/src/management/ndnd-status-response.hpp b/src/management/ndnd-status-response.hpp
index 1543bed..74e15fe 100644
--- a/src/management/ndnd-status-response.hpp
+++ b/src/management/ndnd-status-response.hpp
@@ -106,8 +106,8 @@
 
   code_ = readNonNegativeInteger(wire_.get(Tlv::FaceManagement::StatusCode));
 
-  Block::element_iterator val = wire_.find(Tlv::FaceManagement::StatusText);
-  if (val != wire_.getAll().end())
+  Block::element_const_iterator val = wire_.find(Tlv::FaceManagement::StatusText);
+  if (val != wire_.elements_end())
     {
       info_.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
     }
diff --git a/src/management/nfd-control-response.hpp b/src/management/nfd-control-response.hpp
index 238d1c5..1e6ec24 100644
--- a/src/management/nfd-control-response.hpp
+++ b/src/management/nfd-control-response.hpp
@@ -142,8 +142,8 @@
   if (m_wire.type() != tlv::nfd_control::ControlResponse)
     throw Error("Requested decoding of ControlResponse, but Block is of different type");  
   
-  Block::element_iterator val = m_wire.getAll().begin();
-  if (val == m_wire.getAll().end() ||
+  Block::element_const_iterator val = m_wire.elements_begin();
+  if (val == m_wire.elements_end() ||
       val->type() != tlv::nfd_control::StatusCode)
     {
       throw Error("Incorrect ControlResponse format (StatusCode missing or not the first item)");
@@ -152,7 +152,7 @@
   m_code = readNonNegativeInteger(*val);
   ++val;
 
-  if (val == m_wire.getAll().end() ||
+  if (val == m_wire.elements_end() ||
       val->type() != tlv::nfd_control::StatusText)
     {
       throw Error("Incorrect ControlResponse format (StatusText missing or not the second item)");
@@ -160,7 +160,7 @@
   m_text.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
   ++val;
 
-  if (val != m_wire.getAll().end())
+  if (val != m_wire.elements_end())
     m_body = *val;
   else
     m_body = Block();
diff --git a/src/management/nfd-fib-management-options.hpp b/src/management/nfd-fib-management-options.hpp
index 67e344c..ba56d93 100644
--- a/src/management/nfd-fib-management-options.hpp
+++ b/src/management/nfd-fib-management-options.hpp
@@ -162,22 +162,22 @@
   wire_.parse ();
 
   // Name
-  Block::element_iterator val = wire_.find(Tlv::Name);
-  if (val != wire_.getAll().end())
+  Block::element_const_iterator val = wire_.find(Tlv::Name);
+  if (val != wire_.elements_end())
     {
       name_.wireDecode(*val);
     }
 
   // FaceID
   val = wire_.find(tlv::nfd_control::FaceId);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       faceId_ = readNonNegativeInteger(*val);
     }
 
   // Cost
   val = wire_.find(tlv::nfd_control::Cost);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements_end())
     {
       cost_ = readNonNegativeInteger(*val);
     }
diff --git a/src/meta-info.hpp b/src/meta-info.hpp
index 5ad07f6..1c78cc7 100644
--- a/src/meta-info.hpp
+++ b/src/meta-info.hpp
@@ -95,15 +95,15 @@
   //                FreshnessPeriod?
   
   // ContentType
-  Block::element_iterator val = wire_.find(Tlv::ContentType);
-  if (val != wire_.getAll().end())
+  Block::element_const_iterator val = wire_.find(Tlv::ContentType);
+  if (val != wire_.elements().end())
     {
       type_ = readNonNegativeInteger(*val);
     }
 
   // FreshnessPeriod
   val = wire_.find(Tlv::FreshnessPeriod);
-  if (val != wire_.getAll().end())
+  if (val != wire_.elements().end())
     {
       freshnessPeriod_ = readNonNegativeInteger(*val);
     }
diff --git a/src/name.hpp b/src/name.hpp
index 96a2e9d..d58e485 100644
--- a/src/name.hpp
+++ b/src/name.hpp
@@ -125,7 +125,7 @@
   Name& 
   append(const uint8_t *value, size_t valueLength) 
   {
-    m_nameBlock.elements().push_back(Component(value, valueLength));
+    m_nameBlock.push_back(Component(value, valueLength));
     return *this;
   }
 
@@ -136,21 +136,21 @@
   // Name& 
   // append(const Buffer& value) 
   // {
-  //   m_nameBlock.elements().push_back(value);
+  //   m_nameBlock.push_back(value);
   //   return *this;
   // }
   
   Name& 
   append(const ConstBufferPtr &value)
   {
-    m_nameBlock.elements().push_back(value);
+    m_nameBlock.push_back(value);
     return *this;
   }
   
   Name& 
   append(const Component &value)
   {
-    m_nameBlock.elements().push_back(value);
+    m_nameBlock.push_back(value);
     return *this;
   }
 
@@ -164,7 +164,7 @@
   Name& 
   append(const char *value)
   {
-    m_nameBlock.elements().push_back(Component(value));
+    m_nameBlock.push_back(Component(value));
     return *this;
   }
   
@@ -172,9 +172,9 @@
   append(const Block &value)
   {
     if (value.type() == Tlv::NameComponent)
-      m_nameBlock.elements().push_back(value);
+      m_nameBlock.push_back(value);
     else
-      m_nameBlock.elements().push_back(Block(Tlv::NameComponent, value));
+      m_nameBlock.push_back(Block(Tlv::NameComponent, value));
 
     return *this;
   }
@@ -223,7 +223,7 @@
   getPrefix(int nComponents) const
   {
     if (nComponents < 0)
-      return getSubName(0, m_nameBlock.elements().size() + nComponents);
+      return getSubName(0, m_nameBlock.elements_size() + nComponents);
     else
       return getSubName(0, nComponents);
   }
@@ -243,7 +243,7 @@
   Name& 
   appendSegment(uint64_t segment)
   {
-    m_nameBlock.elements().push_back(Component::fromNumberWithMarker(segment, 0x00));
+    m_nameBlock.push_back(Component::fromNumberWithMarker(segment, 0x00));
     return *this;
   }
 
@@ -256,7 +256,7 @@
   Name& 
   appendVersion(uint64_t version)
   {
-    m_nameBlock.elements().push_back(Component::fromNumberWithMarker(version, 0xFD));
+    m_nameBlock.push_back(Component::fromNumberWithMarker(version, 0xFD));
     return *this;
   }
 
@@ -306,7 +306,7 @@
    * @return The number of components.
    */
   size_t 
-  size() const { return m_nameBlock.elements().size(); }
+  size() const { return m_nameBlock.elements_size(); }
 
   /**
    * Get the component at the given index.
@@ -427,48 +427,33 @@
   }
 
   /**
-   * Begin iterator.
-   */
-  iterator
-  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 reinterpret_cast<const_iterator>(&*m_nameBlock.elements().end()); }
+  end() const
+  {
+    return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().end());
+  }
 
   /**
-   * End iterator.
-   */
-  iterator
-  end() { return reinterpret_cast<iterator>(&*m_nameBlock.elements().end()); }
-  
-  /**
    * Reverse begin iterator (const).
    */
   const_reverse_iterator
-  rbegin() const { return const_reverse_iterator(end()); }
-
-  /**
-   * Reverse begin iterator.
-   */
-  reverse_iterator
-  rbegin() { return reverse_iterator(end()); }
+  rbegin() const
+  {
+    return const_reverse_iterator(end());
+  }
 
   /**
    * Reverse end iterator (const).
    */
   const_reverse_iterator
-  rend() const { return const_reverse_iterator(begin()); }
-
-  /**
-   * Reverse end iterator.
-   */
-  reverse_iterator
-  rend() { return reverse_iterator(begin()); }
+  rend() const
+  {
+    return const_reverse_iterator(begin());
+  }
 
 private:
   mutable Block m_nameBlock;
diff --git a/src/security/signature-sha256-with-rsa.hpp b/src/security/signature-sha256-with-rsa.hpp
index b59c765..cfcef90 100644
--- a/src/security/signature-sha256-with-rsa.hpp
+++ b/src/security/signature-sha256-with-rsa.hpp
@@ -33,8 +33,8 @@
       throw Signature::Error("Incorrect signature type");
 
     info_.parse();
-    Block::element_iterator i = info_.find(Tlv::KeyLocator);
-    if (i != info_.getAll().end())
+    Block::element_const_iterator i = info_.find(Tlv::KeyLocator);
+    if (i != info_.elements_end())
       {
         keyLocator_.wireDecode(*i);
       }
diff --git a/src/security/validator.cpp b/src/security/validator.cpp
index 8b1c17f..7979120 100644
--- a/src/security/validator.cpp
+++ b/src/security/validator.cpp
@@ -144,11 +144,8 @@
   try{
     const Block &nameBlock = interestName.wireEncode();
 
-    if(nameBlock.getAll().size() != interestName.size()) //HACK!! we should change it when Name::Component is changed to derive from Block.
-      const_cast<Block&>(nameBlock).parse();
-
-    Signature sig((++nameBlock.getAll().rbegin())->blockFromValue(), 
-                  (nameBlock.getAll().rbegin())->blockFromValue());
+    Signature sig((++nameBlock.elements().rbegin())->blockFromValue(), 
+                  (nameBlock.elements().rbegin())->blockFromValue());
 
     switch(sig.getType()){
     case Signature::Sha256WithRsa:
@@ -156,7 +153,7 @@
         SignatureSha256WithRsa sigSha256Rsa(sig);
 
         return verifySignature(nameBlock.value(), 
-                               nameBlock.value_size() - (nameBlock.getAll().rbegin())->size(), 
+                               nameBlock.value_size() - (nameBlock.elements().rbegin())->size(), 
                                sigSha256Rsa, key);
       }
     default:
diff --git a/tests/test-name.cpp b/tests/test-name.cpp
index b6501d6..cabfd2f 100644
--- a/tests/test-name.cpp
+++ b/tests/test-name.cpp
@@ -41,8 +41,8 @@
   //   }
   // std::cout << std::endl;
   
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(TestName, TestName+sizeof(TestName),
-                                  wire.begin(), wire.end());
+  BOOST_CHECK_EQUAL_COLLECTIONS(TestName, TestName+sizeof(TestName),
+                                wire.begin(), wire.end());
 }
 
 
@@ -55,6 +55,33 @@
   BOOST_CHECK_EQUAL(name.toUri(), "/local/ndn/prefix");
 }
 
+BOOST_AUTO_TEST_CASE (AppendsAndMultiEncode)
+{
+  Name name("/local");
+
+  const uint8_t name1[] = {0x3,  0x7, // Name
+                           0x4,  0x5, // NameComponent
+                           0x6c,  0x6f,  0x63,  0x61,  0x6c};
+  
+  BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
+                                name1, name1 + sizeof(name1));
+
+  name.append("ndn");
+  
+  const uint8_t name2[] = {0x3,  0xc, // Name
+                           0x4,  0x5, // NameComponent
+                           0x6c,  0x6f,  0x63,  0x61,  0x6c,
+                           0x4,  0x3, // NameComponent
+                           0x6e,  0x64,  0x6e};
+  
+  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_SUITE_END()
 
 } // namespace ndn
diff --git a/tools/tlvdump.cpp b/tools/tlvdump.cpp
index 0589cd3..3c9bd81 100644
--- a/tools/tlvdump.cpp
+++ b/tools/tlvdump.cpp
@@ -66,7 +66,7 @@
 
   
 void
-BlockPrinter(ndn::Block &block, const std::string &indent="")
+BlockPrinter(const ndn::Block& block, const std::string& indent="")
 {
   std::cout << indent;
   printTypeInfo(block.type());
@@ -82,7 +82,7 @@
     // @todo: Figure how to deterministically figure out that value is not recursive TLV block
   }
 
-  if (block.getAll().empty())
+  if (block.elements().empty())
     {
       std::cout << " [[";
       ndn::name::Component(block.value(), block.value_size()).toEscapedString(std::cout);
@@ -90,8 +90,8 @@
     }
   std::cout << std::endl;
   
-  for(ndn::Block::element_iterator i = block.getAll().begin();
-      i != block.getAll().end();
+  for(ndn::Block::element_const_iterator i = block.elements_begin();
+      i != block.elements_end();
       ++i)
     {
       BlockPrinter(*i, indent+"  ");
@@ -99,7 +99,7 @@
 }
 
 void
-HexPrinter(ndn::Block &block, const std::string &indent="")
+HexPrinter(const ndn::Block& block, const std::string &indent="")
 {
   std::cout << indent;
   for (ndn::Buffer::const_iterator i = block.begin (); i != block.value_begin(); ++i)
@@ -109,7 +109,7 @@
     }
   std::cout << "\n";
   
-  if (block.getAll().size() == 0 && block.value_size() > 0)
+  if (block.elements_size() == 0 && block.value_size() > 0)
     {
       std::cout << indent << "    ";
       for (ndn::Buffer::const_iterator i = block.value_begin (); i != block.value_end(); ++i)
@@ -121,8 +121,8 @@
     }
   else
     {
-      for(ndn::Block::element_iterator i = block.getAll().begin();
-          i != block.getAll().end();
+      for(ndn::Block::element_const_iterator i = block.elements_begin();
+          i != block.elements_end();
           ++i)
         {
           HexPrinter(*i, indent+"    ");