model: Another major change: switching to NDN.cxx API for ndn::Name

NDN.cxx code is almost exactly the same, with minor NS-3 specific customizations

Refs #1011 (http://redmine.named-data.net/issues/1011)
diff --git a/apps/ndn-consumer-zipf-mandelbrot.cc b/apps/ndn-consumer-zipf-mandelbrot.cc
index 866eb48..3f863f5 100644
--- a/apps/ndn-consumer-zipf-mandelbrot.cc
+++ b/apps/ndn-consumer-zipf-mandelbrot.cc
@@ -176,7 +176,7 @@
 
   //
   Ptr<Name> nameWithSequence = Create<Name> (m_interestName);
-  (*nameWithSequence) (seq);
+  nameWithSequence->appendSeqNum (seq);
   //
 
   Ptr<Interest> interest = Create<Interest> ();
diff --git a/apps/ndn-consumer.cc b/apps/ndn-consumer.cc
index adbce0f..619e2f1 100644
--- a/apps/ndn-consumer.cc
+++ b/apps/ndn-consumer.cc
@@ -37,14 +37,9 @@
 #include "ns3/ndnSIM/utils/ndn-rtt-mean-deviation.h"
 
 #include <boost/ref.hpp>
-#include <boost/lexical_cast.hpp>
-#include <boost/lambda/lambda.hpp>
-#include <boost/lambda/bind.hpp>
 
 #include "ns3/names.h"
 
-namespace ll = boost::lambda;
-
 NS_LOG_COMPONENT_DEFINE ("ndn.Consumer");
 
 namespace ns3 {
@@ -200,7 +195,7 @@
 
   //
   Ptr<Name> nameWithSequence = Create<Name> (m_interestName);
-  (*nameWithSequence) (seq);
+  nameWithSequence->appendSeqNum (seq);
   //
 
   Ptr<Interest> interest = Create<Interest> ();
@@ -238,7 +233,7 @@
 
   // NS_LOG_INFO ("Received content object: " << boost::cref(*data));
 
-  uint32_t seq = boost::lexical_cast<uint32_t> (data->GetName ().GetComponents ().back ());
+  uint32_t seq = data->GetName ().get (-1).toSeqNum ();
   NS_LOG_INFO ("< DATA for " << seq);
 
   int hopCount = -1;
@@ -282,7 +277,7 @@
   // NS_LOG_FUNCTION (interest->GetName ());
 
   // NS_LOG_INFO ("Received NACK: " << boost::cref(*interest));
-  uint32_t seq = boost::lexical_cast<uint32_t> (interest->GetName ().GetComponents ().back ());
+  uint32_t seq = interest->GetName ().get (-1).toSeqNum ();
   NS_LOG_INFO ("< NACK for " << seq);
   // std::cout << Simulator::Now ().ToDouble (Time::S) << "s -> " << "NACK for " << seq << "\n";
 
diff --git a/apps/ndn-producer.cc b/apps/ndn-producer.cc
index 130b450..e8a66aa 100644
--- a/apps/ndn-producer.cc
+++ b/apps/ndn-producer.cc
@@ -129,7 +129,7 @@
 
   Ptr<ContentObject> data = Create<ContentObject> (Create<Packet> (m_virtualPayloadSize));
   Ptr<Name> dataName = Create<Name> (interest->GetName ());
-  dataName->Append (m_postfix);
+  dataName->append (m_postfix);
   data->SetName (dataName);
   data->SetFreshness (m_freshness);
 
diff --git a/examples/custom-apps/custom-app.cc b/examples/custom-apps/custom-app.cc
index 80652ba..4e83095 100644
--- a/examples/custom-apps/custom-app.cc
+++ b/examples/custom-apps/custom-app.cc
@@ -59,8 +59,8 @@
 
   // Create a name components object for name ``/prefix/sub``
   Ptr<ndn::Name> prefix = Create<ndn::Name> (); // now prefix contains ``/``
-  prefix->Add ("prefix"); // now prefix contains ``/prefix``
-  prefix->Add ("sub"); // now prefix contains ``/prefix/sub``
+  prefix->append ("prefix"); // now prefix contains ``/prefix``
+  prefix->append ("sub"); // now prefix contains ``/prefix/sub``
 
   /////////////////////////////////////////////////////////////////////////////
   // Creating FIB entry that ensures that we will receive incoming Interests //
diff --git a/examples/custom-apps/hijacker.cc b/examples/custom-apps/hijacker.cc
index a4d7601..a908dd0 100644
--- a/examples/custom-apps/hijacker.cc
+++ b/examples/custom-apps/hijacker.cc
@@ -21,6 +21,7 @@
 // hijacker.cc
 
 #include "hijacker.h"
+#include "ns3/ndn-name.h"
 
 NS_LOG_COMPONENT_DEFINE ("Hijacker");
 
@@ -60,7 +61,7 @@
 
   // equivalent to setting interest filter for "/" prefix
   Ptr<ndn::Fib> fib = GetNode ()->GetObject<ndn::Fib> ();
-  Ptr<ndn::fib::Entry> fibEntry = fib->Add ("/", m_face, 0);
+  Ptr<ndn::fib::Entry> fibEntry = fib->Add (ndn::Name ("/"), m_face, 0);
   fibEntry->UpdateStatus (m_face, ndn::fib::FaceMetric::NDN_FIB_GREEN);
 }
 
diff --git a/model/ndn-common.h b/model/ndn-common.h
index 3581a4c..de21c29 100644
--- a/model/ndn-common.h
+++ b/model/ndn-common.h
@@ -11,7 +11,29 @@
 #ifndef NDN_COMMON_H
 #define NDN_COMMON_H
 
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+
+#define NDNSIM_MODE 1
+
 #define NDN_NAMESPACE_BEGIN  namespace ns3 { namespace ndn {
 #define NDN_NAMESPACE_END    } /*ndn*/ } /*ns3*/ 
 
+NDN_NAMESPACE_BEGIN
+
+typedef Time TimeInterval;
+
+namespace time
+{
+
+inline Time
+NowUnixTimestamp ()
+{
+  return Simulator::Now ();
+}
+
+}
+
+NDN_NAMESPACE_END
+
 #endif // NDN_COMMON_H
diff --git a/model/ndn-name.cc b/model/ndn-name.cc
deleted file mode 100644
index 60d1b82..0000000
--- a/model/ndn-name.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- *         Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ndn-name.h"
-#include <boost/foreach.hpp>
-#include "ns3/log.h"
-
-#include <iostream>
-
-using namespace std;
-
-NS_LOG_COMPONENT_DEFINE ("ndn.Name");
-
-namespace ns3 {
-namespace ndn {
-
-ATTRIBUTE_HELPER_CPP (Name);
-
-Name::Name (/* root */)
-{
-}
-
-// Name::Name (const std::list<boost::reference_wrapper<const std::string> > &components)
-// {
-//   BOOST_FOREACH (const boost::reference_wrapper<const std::string> &component, components)
-//     {
-//       Add (component.get ());
-//     }
-// }
-
-Name::Name (const std::list<std::string> &components)
-{
-  BOOST_FOREACH (const std::string &component, components)
-    {
-      Add (component);
-    }
-}
-
-Name::Name (const std::string &prefix)
-{
-  istringstream is (prefix);
-  is >> *this;
-}
-
-Name::Name (const char *prefix)
-{
-  NS_ASSERT (prefix != 0);
-
-  istringstream is (prefix);
-  is >> *this;
-}
-
-const std::list<std::string> &
-Name::GetComponents () const
-{
-  return m_prefix;
-}
-
-std::string
-Name::GetLastComponent () const
-{
-  if (m_prefix.size () == 0)
-    {
-      return "";
-    }
-
-  return m_prefix.back ();
-}
-
-std::list<boost::reference_wrapper<const std::string> >
-Name::GetSubComponents (size_t num) const
-{
-  NS_ASSERT_MSG (0<=num && num<=m_prefix.size (), "Invalid number of subcomponents requested");
-
-  std::list<boost::reference_wrapper<const std::string> > subComponents;
-  std::list<std::string>::const_iterator component = m_prefix.begin();
-  for (size_t i=0; i<num; i++, component++)
-    {
-      subComponents.push_back (boost::ref (*component));
-    }
-
-  return subComponents;
-}
-
-Name
-Name::cut (size_t minusComponents) const
-{
-  Name retval;
-  std::list<std::string>::const_iterator component = m_prefix.begin ();
-  for (uint32_t i = 0; i < m_prefix.size () - minusComponents; i++, component++)
-    {
-      retval.Add (*component);
-    }
-
-  return retval;
-}
-
-void
-Name::Print (std::ostream &os) const
-{
-  for (const_iterator i=m_prefix.begin(); i!=m_prefix.end(); i++)
-    {
-      os << "/" << *i;
-    }
-  if (m_prefix.size ()==0) os << "/";
-}
-
-std::ostream &
-operator << (std::ostream &os, const Name &components)
-{
-  components.Print (os);
-  return os;
-}
-
-std::istream &
-operator >> (std::istream &is, Name &components)
-{
-  istream_iterator<char> eos; // end of stream
-
-  std::string component = "";
-  istream_iterator<char> it (is);
-  for (; it != eos; it++)
-    {
-      if (*it == '/')
-        {
-          if (component != "")
-              components.Add (component);
-          component = "";
-        }
-      else
-        component.push_back (*it);
-    }
-  if (component != "")
-      components.Add (component);
-
-  is.clear ();
-  // NS_LOG_ERROR (components << ", bad: " << is.bad () <<", fail: " << is.fail ());
-
-  return is;
-}
-
-} // ndn
-} // ns3
diff --git a/model/ndn-name.h b/model/ndn-name.h
index 3eb2021..797de98 100644
--- a/model/ndn-name.h
+++ b/model/ndn-name.h
@@ -1,315 +1,2 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- *         Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#ifndef _NDN_NAME_H_
-#define _NDN_NAME_H_
-
-#include "ns3/simple-ref-count.h"
-#include "ns3/attribute.h"
-#include "ns3/attribute-helper.h"
-
-#include <string>
-#include <algorithm>
-#include <list>
-#include "ns3/object.h"
-#include "ns3/buffer.h"
-
-#include <boost/ref.hpp>
-
-namespace ns3 {
-namespace ndn {
-
-/**
- * \ingroup ndn
- * \brief Hierarchical NDN name
- * A Name element represents a hierarchical name for Ndn content.
- * It simply contains a sequence of Component elements.
- * Each Component element contains a sequence of zero or more bytes.
- * There are no restrictions on what byte sequences may be used.
- * The Name element in an Interest is often referred to with the term name prefix or simply prefix.
- */
-class Name : public SimpleRefCount<Name>
-{
-public:
-  typedef std::list<std::string>::iterator       iterator;
-  typedef std::list<std::string>::const_iterator const_iterator;
-
-  /**
-   * \brief Constructor
-   * Creates a prefix with zero components (can be looked as root "/")
-   */
-  Name ();
-
-  // /**
-  //  * \brief Constructor
-  //  * Creates a prefix from a list of strings where every string represents a prefix component
-  //  * @param[in] components A list of strings
-  //  */
-  // Name (const std::list<boost::reference_wrapper<const std::string> > &components);
-
-  /**
-   * \brief Constructor
-   * Creates a prefix from a list of strings where every string represents a prefix component
-   * @param[in] components A list of strings
-   */
-  Name (const std::list<std::string> &components);
-  
-  /**
-   * @brief Constructor
-   * Creates a prefix from the string (string is parsed using operator>>)
-   * @param[in] prefix A string representation of a prefix
-   */
-  Name (const std::string &prefix);
-
-  /**
-   * @brief Constructor
-   * Creates a prefix from the string (string is parsed using operator>>)
-   * @param[in] prefix A string representation of a prefix
-   */
-  Name (const char *prefix);
-
-  /**
-   * \brief Generic Add method
-   * Appends object of type T to the list of components
-   * @param[in] value The object to be appended
-   */
-  template<class T>
-  inline Name&
-  Add (const T &value);
-
-  /**
-   * \brief Append components from another name
-   * @param otherName Name to add at the end
-   */
-  inline Name&
-  Append (const Name &otherName);
-  
-  /**
-   * \brief Generic constructor operator
-   * The object of type T will be appended to the list of components
-   */
-  template<class T>
-  inline Name&
-  operator () (const T &value);
-
-  /**
-   * \brief Get a name
-   * Returns a list of components (strings)
-   */
-  const std::list<std::string> &
-  GetComponents () const;
-
-  /**
-   * @brief Helper call to get the last component of the name
-   */
-  std::string
-  GetLastComponent () const;
-
-  /**
-   * \brief Get subcomponents of the name, starting with first component
-   * @param[in] num Number of components to return. Valid value is in range [1, GetComponents ().size ()]
-   */
-  std::list<boost::reference_wrapper<const std::string> >
-  GetSubComponents (size_t num) const;
-
-  /**
-   * @brief Get prefix of the name, containing less  minusComponents right components
-   */
-  Name
-  cut (size_t minusComponents) const;
-
-  /**
-   * \brief Print name
-   * @param[in] os Stream to print
-   */
-  void Print (std::ostream &os) const;
-
-  /**
-   * \brief Returns the size of Name
-   */
-  inline size_t
-  size () const;
-
-  /**
-   * @brief Get read-write begin() iterator
-   */
-  inline iterator
-  begin ();
-
-  /**
-   * @brief Get read-only begin() iterator
-   */
-  inline const_iterator
-  begin () const;
-
-  /**
-   * @brief Get read-write end() iterator
-   */
-  inline iterator
-  end ();
-
-  /**
-   * @brief Get read-only end() iterator
-   */
-  inline const_iterator
-  end () const;
-
-  /**
-   * \brief Equality operator for Name
-   */
-  inline bool
-  operator== (const Name &prefix) const;
-
-  /**
-   * \brief Less than operator for Name
-   */
-  inline bool
-  operator< (const Name &prefix) const;
-
-  typedef std::string partial_type;
-
-private:
-  std::list<std::string> m_prefix;                              ///< \brief a list of strings (components)
-};
-
-/**
- * \brief Print out name components separated by slashes, e.g., /first/second/third
- */
-std::ostream &
-operator << (std::ostream &os, const Name &components);
-
-/**
- * \brief Read components from input and add them to components. Will read input stream till eof
- * Substrings separated by slashes will become separate components
- */
-std::istream &
-operator >> (std::istream &is, Name &components);
-
-/**
- * \brief Returns the size of Name object
- */
-size_t
-Name::size () const
-{
-  return m_prefix.size ();
-}
-
-Name::iterator
-Name::begin ()
-{
-  return m_prefix.begin ();
-}
-
-/**
- * @brief Get read-only begin() iterator
- */
-Name::const_iterator
-Name::begin () const
-{
-  return m_prefix.begin ();
-}
-
-/**
- * @brief Get read-write end() iterator
- */
-Name::iterator
-Name::end ()
-{
-  return m_prefix.end ();
-}
-
-/**
- * @brief Get read-only end() iterator
- */
-Name::const_iterator
-Name::end () const
-{
-  return m_prefix.end ();
-}
-
-
-/**
- * \brief Generic constructor operator
- * The object of type T will be appended to the list of components
- */
-template<class T>
-Name&
-Name::operator () (const T &value)
-{
-  return Add (value);
-}
-
-/**
- * \brief Generic Add method
- * Appends object of type T to the list of components
- * @param[in] value The object to be appended
- */
-template<class T>
-Name&
-Name::Add (const T &value)
-{
-  std::ostringstream os;
-  os << value;
-  m_prefix.push_back (os.str ());
-
-  return *this;
-}
-
-inline Name&
-Name::Append (const Name &otherName)
-{
-  std::copy (otherName.begin (), otherName.end (), std::back_inserter (m_prefix));
-  return *this;
-}
-
-
-/**
- * \brief Equality operator for Name
- */
-bool
-Name::operator== (const Name &prefix) const
-{
-  if (m_prefix.size () != prefix.m_prefix.size ())
-    return false;
-
-  return std::equal (m_prefix.begin (), m_prefix.end (), prefix.m_prefix.begin ());
-}
-
-/**
- * \brief Less than operator for Name
- */
-bool
-Name::operator< (const Name &prefix) const
-{
-  return std::lexicographical_compare (m_prefix.begin (), m_prefix.end (),
-                                       prefix.m_prefix.begin (), prefix.m_prefix.end ());
-}
-
-ATTRIBUTE_HELPER_HEADER (Name);
-
-// for backwards compatibility
-typedef Name NameComponents;
-
-} // namespace ndn
-} // namespace ns3
-
-#endif // _NDN_NAME_H_
-
+// backwards compatibility header
+#include "ns3/ndnSIM/ndn.cxx/name.h"
diff --git a/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc b/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc
index 965b320..998e4e2 100644
--- a/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc
+++ b/model/wire/ccnb/ccnb-parser/visitors/name-visitor.cc
@@ -44,7 +44,7 @@
     case CCN_DTAG_Component:
       if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
         throw CcnbDecodingException ();
-      components.Add (
+      components.append (
                       boost::any_cast<std::string> ((*n.m_nestedTags.begin())->accept(
                                                                                       stringVisitor
                                                                                       )));
diff --git a/model/wire/ccnb/wire-ccnb.cc b/model/wire/ccnb/wire-ccnb.cc
index 9033d3f..e3a9ef1 100644
--- a/model/wire/ccnb/wire-ccnb.cc
+++ b/model/wire/ccnb/wire-ccnb.cc
@@ -191,10 +191,10 @@
 Ccnb::SerializeName (Buffer::Iterator &start, const Name &name)
 {
   size_t written = 0;
-  BOOST_FOREACH (const std::string &component, name.GetComponents())
+  BOOST_FOREACH (const name::Component &component, name)
     {
       written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Component,
-                                   reinterpret_cast<const uint8_t*>(component.c_str()), component.size());
+                                   reinterpret_cast<const uint8_t*>(component.buf ()), component.size());
     }
   return written;
 }
@@ -203,9 +203,9 @@
 Ccnb::SerializedSizeName (const Name &name)
 {
   size_t written = 0;
-  BOOST_FOREACH (const std::string &component, name.GetComponents())
+  BOOST_FOREACH (const name::Component &component, name)
     {
-      written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Component, component.size());
+      written += EstimateTaggedBlob (CcnbParser::CCN_DTAG_Component, component.size ());
     }
   return written;
 }
diff --git a/model/wire/ndnsim/wire-ndnsim.cc b/model/wire/ndnsim/wire-ndnsim.cc
index 7d383a4..8b4d81d 100644
--- a/model/wire/ndnsim/wire-ndnsim.cc
+++ b/model/wire/ndnsim/wire-ndnsim.cc
@@ -26,12 +26,12 @@
 
   i.WriteU16 (static_cast<uint16_t> (SerializedSizeName (name)-2));
 
-  for (std::list<std::string>::const_iterator item = name.begin ();
+  for (Name::const_iterator item = name.begin ();
        item != name.end ();
        item++)
     {
       i.WriteU16 (static_cast<uint16_t> (item->size ()));
-      i.Write (reinterpret_cast<const uint8_t*> (item->c_str ()), item->size ());
+      i.Write (reinterpret_cast<const uint8_t*> (item->buf ()), item->size ());
     }
 
   return i.GetDistanceFrom (start);
@@ -42,7 +42,7 @@
 {
   size_t nameSerializedSize = 2;
 
-  for (std::list<std::string>::const_iterator i = name.begin ();
+  for (Name::const_iterator i = name.begin ();
        i != name.end ();
        i++)
     {
@@ -67,7 +67,7 @@
       uint8_t tmp[length];
       i.Read (tmp, length);
 
-      name->Add (std::string (reinterpret_cast<const char*> (tmp), length));
+      name->append (std::string (reinterpret_cast<const char*> (tmp), length));
     }
 
   return name;
diff --git a/ndn.cxx/blob.h b/ndn.cxx/blob.h
new file mode 100644
index 0000000..f00d08e
--- /dev/null
+++ b/ndn.cxx/blob.h
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_BLOB_H
+#define NDN_BLOB_H
+
+#include "ns3/ndn-common.h"
+
+#include <vector>
+#include <cstddef>
+
+NDN_NAMESPACE_BEGIN
+
+/**
+ * @brief Class representing a general-use binary blob
+ */
+class Blob : public std::vector<char>
+{
+public:
+  /**
+   * @brief Creates an empty blob
+   */
+  Blob ()
+  {
+  }
+
+  Blob (const void *buf, size_t length)
+    : std::vector<char> (reinterpret_cast<const char*> (buf), reinterpret_cast<const char*> (buf) + length)
+  {
+  }
+  
+  /**
+   * @brief Get pointer to the first byte of the binary blob
+   */
+  inline char*
+  buf ()
+  {
+    return &front ();
+  }
+
+  /**
+   * @brief Get const pointer to the first byte of the binary blob
+   */
+  inline const char*
+  buf () const
+  {
+    return &front ();
+  }
+};
+
+NDN_NAMESPACE_END
+
+#endif // NDN_BLOB_H
diff --git a/ndn.cxx/detail/error.h b/ndn.cxx/detail/error.h
new file mode 100644
index 0000000..a1f1e34
--- /dev/null
+++ b/ndn.cxx/detail/error.h
@@ -0,0 +1,121 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+/**
+ * @file error.h
+ * @brief This file defines basic elements for the library reporting
+ *
+ * The library throws a number of exceptions.
+ * In general, the following example shows how to print out diagnostic information
+ * when one of the exceptions is thrown
+ * @code
+ *     try
+ *       {
+ *         ... operations with ndn::Name
+ *       }
+ *     catch (boost::exception &e)
+ *       {
+ *         std::cerr << boost::diagnostic_information (e) << std::endl;
+ *       }
+ * @endcode
+ */
+
+#ifndef NDN_ERROR2_H
+#define NDN_ERROR2_H
+
+#include "ns3/ndn-common.h"
+#include <boost/exception/all.hpp>
+
+NDN_NAMESPACE_BEGIN
+
+namespace error
+{
+
+struct Error           : public virtual boost::exception, public virtual std::exception {}; ///< @brief Some error with error reporting engine
+struct Uri             : public virtual boost::exception, public virtual std::exception {}; ///< @brief An error with URI processing
+struct StringTransform : public virtual boost::exception, public virtual std::exception {};
+struct Name            : public virtual boost::exception, public virtual std::exception {}; ///< @brief An error with Name
+namespace name {
+struct Component       : public virtual boost::exception, public virtual std::exception {}; ///< @brief An error with name::Component
+}
+struct Exclude         : public virtual boost::exception, public virtual std::exception {}; ///< @brief An error with Exclude
+struct KeyLocator      : public virtual boost::exception, public virtual std::exception {}; ///< @brief An error with KeyLocator
+namespace wire {
+struct Ccnb            : public virtual boost::exception, public virtual std::exception {}; ///< @brief An error with wire::Ccnb encoding
+}
+struct Keychain        : public virtual boost::exception, public virtual std::exception {}; ///< @brief An error with security::Keychain
+
+// Diagnostic information fields
+
+/**
+ * @brief Free-formatted text message explaining the error
+ *
+ * @code
+ * ...
+ * catch (boost::exception &e)
+ * {
+ *     if (const std::string *error = boost::get_error_info<error::msg> (e))
+ *          ...
+ * }
+ * @endcode
+ *
+ * @see get_msg
+ */
+typedef boost::error_info<struct tag_msg, std::string> msg;
+
+/**
+ * @brief Helper method to get error message from the exception
+ *
+ * Method assumes that message is present, if not, an exception will be thrown
+ */
+inline const std::string &
+get_msg (boost::exception &e)
+{
+  const std::string *error = boost::get_error_info<msg> (e);
+  if (error == 0)
+    BOOST_THROW_EXCEPTION (Error ());
+  return *error;
+}
+
+/**
+ * @brief Report of the position of the error (error-specific meaning)
+ *
+ * @code
+ * ...
+ * catch (boost::exception &e)
+ * {
+ *     if (const int *error = boost::get_error_info<error::pos> (e))
+ *          ...
+ * }
+ * @endcode
+ *
+ * @see get_pos
+ */
+typedef boost::error_info<struct tag_pos, int> pos;
+
+/**
+ * @brief Helper method to get position of the error from the exception
+ *
+ * Method assumes that position is present, if not, an exception will be thrown
+ */
+inline int
+get_pos (boost::exception &e)
+{
+  const int *position = boost::get_error_info<pos> (e);
+  if (position == 0)
+    BOOST_THROW_EXCEPTION (Error ());
+  return *position;
+}
+
+} // error
+
+NDN_NAMESPACE_END
+
+#endif // NDN_ERROR2_H
diff --git a/ndn.cxx/detail/uri.h b/ndn.cxx/detail/uri.h
new file mode 100644
index 0000000..ae3844e
--- /dev/null
+++ b/ndn.cxx/detail/uri.h
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_DETAIL_URI_H
+#define NDN_DETAIL_URI_H
+
+#include "ns3/ndn-common.h"
+
+#include "error.h"
+
+#include <boost/archive/iterators/transform_width.hpp>
+#include <boost/iterator/transform_iterator.hpp>
+
+NDN_NAMESPACE_BEGIN
+
+namespace detail
+{
+
+static const bool ESCAPE_CHARACTER [256] = {
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 26
+  1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 53
+  0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 107
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 134
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 161
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 188
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 215
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 242
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 255
+};
+
+/// @cond include_hidden
+template<class CharType>
+struct hex_from_4_bit
+{
+  typedef CharType result_type;
+  CharType operator () (CharType ch) const
+  {
+    const char lookup_table [16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+    // cout << "New character: " << (int) ch << " (" << (char) ch << ")" << "\n";
+    BOOST_ASSERT (ch < 16);
+    return lookup_table[static_cast<size_t>(ch)];
+  }
+};
+
+typedef boost::transform_iterator<hex_from_4_bit<std::string::const_iterator::value_type>,
+                                  boost::archive::iterators::transform_width<std::string::const_iterator, 4, 8, std::string::const_iterator::value_type> > string_from_binary;
+
+
+
+template<class CharType>
+struct hex_to_4_bit
+{
+  typedef CharType result_type;
+  CharType operator () (CharType ch) const
+  {
+    const signed char lookup_table [] = {
+      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
+      -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+      -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+      -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
+    };
+
+    signed char value = -1;
+    if ((unsigned)ch < 128)
+      value = lookup_table [(unsigned)ch];
+    if (value == -1)
+      boost::throw_exception (error::StringTransform ());
+
+    return value;
+  }
+};
+
+typedef boost::archive::iterators::transform_width<boost::transform_iterator<hex_to_4_bit<std::string::const_iterator::value_type>, std::string::const_iterator>, 8, 4> string_to_binary;
+/// @endcond
+
+} // detail
+
+/**
+ * @brief A helper class to convert to/from URI
+ */
+class Uri
+{
+public:
+  template<class Iterator1, class Iterator2>
+  inline static void
+  fromEscaped (Iterator1 begin, Iterator1 end, Iterator2 inserter)
+  {
+    Iterator1 i = begin;
+    while (i != end)
+      {
+        if (*i == '%')
+          {
+            try
+              {
+                ++i;
+                Iterator1 j = i;
+                advance (i, 2);
+              
+                std::copy (detail::string_to_binary (j), detail::string_to_binary (i), inserter);
+              }
+            catch (ndn::error::StringTransform &e)
+              {
+                BOOST_THROW_EXCEPTION (error::Uri ()
+                                       << error::pos (std::distance (i, begin)));
+              }
+          }
+        else if (!detail::ESCAPE_CHARACTER[static_cast<unsigned char> (*i)])
+          {
+            *inserter = *i;
+            ++inserter; ++i;
+          }
+        else
+          {
+            BOOST_THROW_EXCEPTION (error::Uri ()
+                                   << error::pos (std::distance (i, begin)));
+          }
+      }
+  }
+
+  template<class Iterator1, class Iterator2>
+  inline static void
+  toEscaped (Iterator1 begin, Iterator1 end, Iterator2 inserter)
+  {
+    const char lookup_table [16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+    
+    for (Iterator1 i = begin; i != end; i++)
+      {
+        if (detail::ESCAPE_CHARACTER[static_cast<unsigned char> (*i)])
+          {
+            *inserter = '%';         ++inserter;
+            *inserter = lookup_table [(*i >> 4) & 0x0F]; ++inserter;
+            *inserter = lookup_table [(*i & 0x0F)];      ++inserter;
+          }
+        else
+          {
+            *inserter = *i; ++inserter;
+          }
+      }
+  }
+};
+
+NDN_NAMESPACE_END
+
+#endif // NDN_DETAIL_URI_H
diff --git a/ndn.cxx/exclude.cc b/ndn.cxx/exclude.cc
new file mode 100644
index 0000000..16c78bc
--- /dev/null
+++ b/ndn.cxx/exclude.cc
@@ -0,0 +1,166 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "exclude.h"
+
+#include "detail/error.h"
+
+NDN_NAMESPACE_BEGIN
+
+Exclude::Exclude ()
+{
+}
+
+// example: ANY /b /d ANY /f
+//
+// ordered in map as:
+//
+// /f (false); /d (true); /b (false); / (true)
+//
+// lower_bound (/)  -> / (true) <-- excluded (equal)
+// lower_bound (/a) -> / (true) <-- excluded (any)
+// lower_bound (/b) -> /b (false) <--- excluded (equal)
+// lower_bound (/c) -> /b (false) <--- not excluded (not equal and no ANY)
+// lower_bound (/d) -> /d (true) <- excluded
+// lower_bound (/e) -> /d (true) <- excluded
+bool
+Exclude::isExcluded (const name::Component &comp) const
+{
+  const_iterator lowerBound = m_exclude.lower_bound (comp);
+  if (lowerBound == end ())
+    return false;
+
+  if (lowerBound->second)
+    return true;
+  else
+    return lowerBound->first == comp;
+
+  return false;
+}
+
+Exclude &
+Exclude::excludeOne (const name::Component &comp)
+{
+  if (!isExcluded (comp))
+    {
+      m_exclude.insert (std::make_pair (comp, false));
+    }
+  return *this;
+}
+
+
+// example: ANY /b0 /d0 ANY /f0
+//
+// ordered in map as:
+//
+// /f0 (false); /d0 (true); /b0 (false); / (true)
+//
+// lower_bound (/)  -> / (true) <-- excluded (equal)
+// lower_bound (/a0) -> / (true) <-- excluded (any)
+// lower_bound (/b0) -> /b0 (false) <--- excluded (equal)
+// lower_bound (/c0) -> /b0 (false) <--- not excluded (not equal and no ANY)
+// lower_bound (/d0) -> /d0 (true) <- excluded
+// lower_bound (/e0) -> /d0 (true) <- excluded
+
+
+// examples with desired outcomes
+// excludeRange (/, /f0) ->  ANY /f0
+//                          /f0 (false); / (true)
+// excludeRange (/, /f1) ->  ANY /f1
+//                          /f1 (false); / (true)
+// excludeRange (/a0, /e0) ->  ANY /f0
+//                          /f0 (false); / (true)
+// excludeRange (/a0, /e0) ->  ANY /f0
+//                          /f0 (false); / (true)
+
+// excludeRange (/b1, /c0) ->  ANY /b0 /b1 ANY /c0 /d0 ANY /f0
+//                          /f0 (false); /d0 (true); /c0 (false); /b1 (true); /b0 (false); / (true)
+
+Exclude &
+Exclude::excludeRange (const name::Component &from, const name::Component &to)
+{
+  if (from >= to)
+    {
+      BOOST_THROW_EXCEPTION (error::Exclude ()
+                             << error::msg ("Invalid exclude range (for single name exclude use Exclude::excludeOne)")
+                             << error::msg (from.toUri ())
+                             << error::msg (to.toUri ()));
+    }
+
+  iterator newFrom = m_exclude.lower_bound (from);
+  if (newFrom == end () || !newFrom->second /*without ANY*/)
+    {
+      std::pair<iterator, bool> fromResult = m_exclude.insert (std::make_pair (from, true));
+      newFrom = fromResult.first;
+      if (!fromResult.second)
+        {
+          // this means that the lower bound is equal to the item itself. So, just update ANY flag
+          newFrom->second = true;
+        }
+    }
+  // else
+  // nothing special if start of the range already exists with ANY flag set
+
+  iterator newTo = m_exclude.lower_bound (to); // !newTo cannot be end ()
+  if (newTo == newFrom || !newTo->second)
+    {
+      std::pair<iterator, bool> toResult = m_exclude.insert (std::make_pair (to, false));
+      newTo = toResult.first;
+      ++ newTo;
+    }
+  else
+    {
+      // nothing to do really
+    }
+
+  m_exclude.erase (newTo, newFrom); // remove any intermediate node, since all of the are excluded
+
+  return *this;
+}
+
+Exclude &
+Exclude::excludeAfter (const name::Component &from)
+{
+  iterator newFrom = m_exclude.lower_bound (from);
+  if (newFrom == end () || !newFrom->second /*without ANY*/)
+    {
+      std::pair<iterator, bool> fromResult = m_exclude.insert (std::make_pair (from, true));
+      newFrom = fromResult.first;
+      if (!fromResult.second)
+        {
+          // this means that the lower bound is equal to the item itself. So, just update ANY flag
+          newFrom->second = true;
+        }
+    }
+  // else
+  // nothing special if start of the range already exists with ANY flag set
+
+  if (newFrom != m_exclude.begin ())
+    {
+      m_exclude.erase (m_exclude.begin (), newFrom); // remove any intermediate node, since all of the are excluded
+    }
+
+  return *this;
+}
+
+
+std::ostream&
+operator << (std::ostream &os, const Exclude &exclude)
+{
+  for (Exclude::const_reverse_iterator i = exclude.rbegin (); i != exclude.rend (); i++)
+    {
+      os << i->first.toUri () << " ";
+      if (i->second)
+        os << "----> ";
+    }
+  return os;
+}
+
+NDN_NAMESPACE_END
diff --git a/ndn.cxx/exclude.h b/ndn.cxx/exclude.h
new file mode 100644
index 0000000..70b8f54
--- /dev/null
+++ b/ndn.cxx/exclude.h
@@ -0,0 +1,169 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_EXCLUDE_H
+#define NDN_EXCLUDE_H
+
+#include "name-component.h"
+
+#include <map>
+
+NDN_NAMESPACE_BEGIN
+
+/**
+ * @brief Class to represent Exclude component in NDN interests
+ */
+class Exclude
+{
+public:
+  typedef std::map< name::Component, bool /*any*/, std::greater<name::Component> > exclude_type;
+
+  typedef exclude_type::iterator iterator;
+  typedef exclude_type::const_iterator const_iterator;
+  typedef exclude_type::reverse_iterator reverse_iterator;
+  typedef exclude_type::const_reverse_iterator const_reverse_iterator;
+
+  /**
+   * @brief Default constructor an empty exclude
+   */
+  Exclude ();
+
+  /**
+   * @brief Check if name component is excluded
+   * @param comp Name component to check against exclude filter
+   */
+  bool
+  isExcluded (const name::Component &comp) const;
+
+  /**
+   * @brief Exclude specific name component
+   * @param comp component to exclude
+   * @returns *this to allow chaining
+   */
+  Exclude &
+  excludeOne (const name::Component &comp);
+
+  /**
+   * @brief Exclude components from range [from, to]
+   * @param from first element of the range
+   * @param to last element of the range
+   * @returns *this to allow chaining
+   */
+  Exclude &
+  excludeRange (const name::Component &from, const name::Component &to);
+
+  /**
+   * @brief Exclude all components from range [/, to]
+   * @param to last element of the range
+   * @returns *this to allow chaining
+   */
+  inline Exclude &
+  excludeBefore (const name::Component &to);
+
+  /**
+   * @brief Exclude all components from range [from, +Inf]
+   * @param to last element of the range
+   * @returns *this to allow chaining
+   */
+  Exclude &
+  excludeAfter (const name::Component &from);
+
+  /**
+   * @brief Method to directly append exclude element
+   * @param name excluded name component
+   * @param any  flag indicating if there is a postfix ANY component after the name
+   *
+   * This method is used during conversion from wire format of exclude filter
+   *
+   * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
+   */
+  void
+  appendExclude (const name::Component &name, bool any);
+
+  /**
+   * @brief Get number of exclude terms
+   */
+  inline size_t
+  size () const;
+
+  /**
+   * @brief Get begin iterator of the exclude terms
+   */
+  inline const_iterator
+  begin () const;
+
+  /**
+   * @brief Get end iterator of the exclude terms
+   */
+  inline const_iterator
+  end () const;
+
+  /**
+   * @brief Get begin iterator of the exclude terms
+   */
+  inline const_reverse_iterator
+  rbegin () const;
+
+  /**
+   * @brief Get end iterator of the exclude terms
+   */
+  inline const_reverse_iterator
+  rend () const;
+
+private:
+  Exclude &
+  excludeRange (iterator fromLowerBound, iterator toLowerBound);
+
+private:
+  exclude_type m_exclude;
+};
+
+std::ostream&
+operator << (std::ostream &os, const Exclude &name);
+
+inline Exclude &
+Exclude::excludeBefore (const name::Component &to)
+{
+  return excludeRange (name::Component (), to);
+}
+
+inline size_t
+Exclude::size () const
+{
+  return m_exclude.size ();
+}
+
+inline Exclude::const_iterator
+Exclude::begin () const
+{
+  return m_exclude.begin ();
+}
+
+inline Exclude::const_iterator
+Exclude::end () const
+{
+  return m_exclude.end ();
+}
+
+inline Exclude::const_reverse_iterator
+Exclude::rbegin () const
+{
+  return m_exclude.rbegin ();
+}
+
+inline Exclude::const_reverse_iterator
+Exclude::rend () const
+{
+  return m_exclude.rend ();
+}
+
+NDN_NAMESPACE_END
+
+#endif // NDN_EXCLUDE_H
diff --git a/ndn.cxx/name-component.cc b/ndn.cxx/name-component.cc
new file mode 100644
index 0000000..fed4bab
--- /dev/null
+++ b/ndn.cxx/name-component.cc
@@ -0,0 +1,167 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include "name-component.h"
+
+#include "detail/error.h"
+#include "detail/uri.h"
+
+NDN_NAMESPACE_BEGIN
+
+namespace name {
+  
+Component::Component ()
+{
+}
+
+Component::Component (const std::string &uri)
+{
+  try
+    {
+      Uri::fromEscaped (uri.begin (), uri.end (), back_inserter (*this));
+    }
+  catch (error::Uri &err)
+    {
+      // re-throwing different exception
+      BOOST_THROW_EXCEPTION (error::name::Component ()
+                             << error::msg (uri)
+                             << error::pos (error::get_pos (err)));
+    }
+}
+
+Component::Component (std::string::const_iterator begin, std::string::const_iterator end)
+{
+  try
+    {
+      Uri::fromEscaped (begin, end, back_inserter (*this));
+    }
+  catch (error::Uri &err)
+    {
+      // re-throwing different exception
+      BOOST_THROW_EXCEPTION (error::name::Component ()
+                             << error::msg (std::string (begin, end))
+                             << error::pos (error::get_pos (err)));
+    }
+}
+
+Component::Component (const void *buf, size_t length)
+{
+  copy (static_cast<const char*> (buf),
+        static_cast<const char*> (buf)+length,
+        back_inserter (*this));
+}
+
+int
+Component::compare (const Component &other) const
+{
+  if (size () < other.size ())
+    return -1;
+
+  if (size () > other.size ())
+    return +1;
+
+  // now we know that sizes are equal
+
+  std::pair<const_iterator, const_iterator> diff = mismatch (begin (), end (), other.begin ());
+  if (diff.first == end ()) // components are actually equal
+    return 0;
+
+  return (std::lexicographical_compare (diff.first, end (), diff.second, other.end ())) ? -1 : +1;    
+}
+
+Component
+Component::fromNumber (uint64_t number)
+{
+  Component comp;
+  while (number > 0)
+    {
+      comp.push_back (static_cast<unsigned char> (number & 0xFF));
+      number >>= 8;
+    }
+  std::reverse (comp.begin (), comp.end ());
+  return comp;
+}
+
+Component
+Component::fromNumberWithMarker (uint64_t number, unsigned char marker)
+{
+  Component comp;
+  comp.push_back (marker);
+
+  while (number > 0)
+    {
+      comp.push_back (static_cast<unsigned char> (number & 0xFF));
+      number >>= 8;
+    }
+
+  std::reverse (comp.begin () + 1, comp.end ());
+  return comp;
+}
+
+std::string
+Component::toBlob () const
+{
+  return std::string (begin (), end ());
+}
+
+void
+Component::toBlob (std::ostream &os) const
+{
+  os.write (buf (), size ());
+}
+
+std::string
+Component::toUri () const
+{
+  std::ostringstream os;
+  toUri (os);
+  return os.str ();  
+}
+
+void
+Component::toUri (std::ostream &os) const
+{
+  Uri::toEscaped (begin (), end (), std::ostream_iterator<char> (os));
+}
+
+uint64_t
+Component::toNumber () const
+{
+  uint64_t ret = 0;
+  for (const_iterator i = begin (); i != end (); i++)
+    {
+      ret <<= 8;
+      ret |= static_cast<unsigned char> (*i);
+    }
+  return ret;
+}
+
+uint64_t
+Component::toNumberWithMarker (unsigned char marker) const
+{
+  if (empty () ||
+      static_cast<unsigned char> (*(begin ())) != marker)
+    {
+      BOOST_THROW_EXCEPTION (error::name::Component ()
+                             << error::msg ("Name component does not have required marker [" + toUri () + "]"));
+    }
+
+  uint64_t ret = 0;
+  for (const_iterator i = begin () + 1; i != end (); i++)
+    {
+      ret <<= 8;
+      ret |= static_cast<unsigned char> (*i);
+    }
+  return ret;
+}
+
+} // name
+
+NDN_NAMESPACE_END
diff --git a/ndn.cxx/name-component.h b/ndn.cxx/name-component.h
new file mode 100644
index 0000000..56291ea
--- /dev/null
+++ b/ndn.cxx/name-component.h
@@ -0,0 +1,282 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef NDN_NAME_COMPONENT_H
+#define NDN_NAME_COMPONENT_H
+
+#include <string>
+#include <vector>
+
+#include "blob.h"
+#include <stdint.h>
+
+NDN_NAMESPACE_BEGIN
+
+namespace name {
+
+/**
+ * @brief Class to representing binary blob of NDN name component
+ *
+ * This class is based on std::vector<char> and just provides several helpers
+ * to work with name components, as well as operator to apply canonical
+ * ordering on name components
+ */
+class Component : public Blob
+{
+public:
+  /**
+   * @brief Default constructor an empty exclude
+   */
+  Component ();
+
+  /**
+   * @brief Create component from URI encoded string
+   * @param uri URI encoded name component (convert escaped with % characters)
+   */
+  Component (const std::string &uri);
+
+  /**
+   * @brief Create component from URI encoded string, with string specified by a pair of iterators
+   * @param begin begin iterator pointing to the URI encoded name
+   * @param end end iterator
+   */
+  Component (std::string::const_iterator begin, std::string::const_iterator end);
+  
+  /**
+   * @brief Create component using a binary blob
+   * @param buf pointer to first byte of binary blob to store as a name component
+   * @param length length of the binary blob
+   */
+  Component (const void *buf, size_t length);
+
+  /**
+   * @brief Apply canonical ordering on component comparison
+   * @return 0  They compare equal
+   *         <0 If *this comes before other in the canonical ordering
+   *         >0 If *this comes after in the canonical ordering
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  int
+  compare (const Component &other) const;
+  
+  /**
+   * @brief Apply canonical ordering on component comparison (less or equal)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator <= (const Component &other) const;
+
+  /**
+   * @brief Apply canonical ordering on component comparison (less)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator < (const Component &other) const;
+
+  /**
+   * @brief Apply canonical ordering on component comparison (greater or equal)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator >= (const Component &other) const;
+
+  /**
+   * @brief Apply canonical ordering on component comparison (greater)
+   *
+   * @see http://www.ccnx.org/releases/latest/doc/technical/CanonicalOrder.html
+   */
+  inline bool
+  operator > (const Component &other) const;
+
+  ////////////////////////////////////
+  // Component construction helpers //
+  ////////////////////////////////////
+
+  /**
+   * @brief Create network-ordered numeric component
+   *
+   * @param number number to be encoded and added as a component
+   *
+   * Number is encoded and added in network order. Tail zero-bytes are not included.
+   * For example, if the number is 1, then 1-byte binary blob will be added  0x01.
+   * If the number is 256, then 2 binary blob will be added: 0x01 0x01
+   *
+   * If the number is zero, an empty component will be created
+   */
+  static Component
+  fromNumber (uint64_t number);
+
+  /**
+   * @brief Create network-ordered numeric component to the name with marker
+   *
+   * @param number number to be encoded and added as a component
+   * @param marker byte marker, specified by the desired naming convention
+   *
+   * Currently defined naming conventions of the marker:
+   * - 0x00  sequence number
+   * - 0xC1  control number
+   * - 0xFB  block id
+   * - 0xFD  version number
+   *
+   * This version is almost exactly as appendNumber, with exception that it adds initial marker.
+   * The number is formatted in the exactly the same way.
+   *
+   * @see fromNumber
+   */
+  static Component
+  fromNumberWithMarker (uint64_t number, unsigned char marker);
+  
+  //////////////////////////////////////////////////////////////////////////////////
+  // helpers
+  //////////////////////////////////////////////////////////////////////////////////
+  
+  /**
+   * @brief Convert binary blob name component to std::string (no conversion is made)
+   * @param comp name component to be converted
+   * @see asUriString
+   */  
+  std::string
+  toBlob () const;
+
+  /**
+   * @brief Write blob of the name component to the specified output stream
+   * @param os output stream
+   */
+  void
+  toBlob (std::ostream &os) const;
+
+  /**
+   * @brief Convert binary blob name component to std::string, escaping all non-printable characters in URI format
+   * @param comp name component to be converted
+   * @see asString
+   */
+  std::string
+  toUri () const;
+
+  /**
+   * @brief Write name as URI to the specified output stream
+   * @param os output stream
+   */
+  void
+  toUri (std::ostream &os) const;
+  
+  /**
+   * @brief Convert binary blob name component (network-ordered number) to number
+   * @param comp name component to be converted
+   */  
+  uint64_t
+  toNumber () const;
+
+  /**
+   * @brief Convert binary blob name component (network-ordered number) to number, using appropriate marker from the naming convention
+   * @param comp name component to be converted
+   * @param marker required marker from the naming convention
+   *
+   * If the required marker does not exist, an exception will be thrown
+   */  
+  uint64_t
+  toNumberWithMarker (unsigned char marker) const;
+
+  /**
+   * @brief Convert binary blob name component, assuming sequence number naming convention (marker = 0x00)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toSeqNum () const;
+  
+  /**
+   * @brief Convert binary blob name component, assuming control number naming convention (marker = 0xC1)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toControlNum () const;
+
+  /**
+   * @brief Convert binary blob name component, assuming block ID naming convention (marker = 0xFB)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toBlkId () const;
+
+  /**
+   * @brief Convert binary blob name component, assuming time-stamping version naming convention (marker = 0xFD)
+   * @param comp name component to be converted
+   * @see asNumberWithMarker
+   */
+  inline uint64_t
+  toVersion () const;
+};
+
+bool
+Component::operator <= (const Component &other) const
+{
+  return (compare (other) <= 0);
+}
+
+bool
+Component::operator < (const Component &other) const
+{
+  return (compare (other) < 0);
+}
+
+bool
+Component::operator >= (const Component &other) const
+{
+  return (compare (other) >= 0);
+}
+
+bool
+Component::operator > (const Component &other) const
+{
+  return (compare (other) > 0);
+}
+
+inline uint64_t
+Component::toSeqNum () const
+{
+  return toNumberWithMarker (0x00);
+}
+  
+inline uint64_t
+Component::toControlNum () const
+{
+  return toNumberWithMarker (0xC1);
+}
+
+inline uint64_t
+Component::toBlkId () const
+{
+  return toNumberWithMarker (0xFB);
+}
+
+inline uint64_t
+Component::toVersion () const
+{
+  return toNumberWithMarker (0xFD);
+}
+
+/**
+ * @brief Stream output operator (output in escaped URI format)
+ */
+std::ostream&
+operator <<(std::ostream &os, const Component &name);
+
+} // name
+
+NDN_NAMESPACE_END
+
+#endif // NDN_NAME_COMPONENT_H
diff --git a/ndn.cxx/name.cc b/ndn.cxx/name.cc
new file mode 100644
index 0000000..3bb2416
--- /dev/null
+++ b/ndn.cxx/name.cc
@@ -0,0 +1,272 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *         Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ */
+
+#include "name.h"
+
+#include "detail/error.h"
+#include <boost/algorithm/string.hpp>
+
+#include <ctype.h>
+
+using namespace std;
+
+NDN_NAMESPACE_BEGIN
+
+ATTRIBUTE_HELPER_CPP (Name);
+
+///////////////////////////////////////////////////////////////////////////////
+//                              CONSTRUCTORS                                 //
+///////////////////////////////////////////////////////////////////////////////
+
+Name::Name ()
+{
+}
+
+Name::Name (const string &uri)
+{ 
+  string::const_iterator i = uri.begin ();
+  string::const_iterator end = uri.end ();
+
+  string::const_iterator firstSlash = std::find (i, end, '/');
+  if (firstSlash == end)
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Name should include at least one slash (did you forget to specify initial /?)"));
+    }
+
+  if (firstSlash != i)
+    {
+      string schema (i, firstSlash);
+      if (*schema.rbegin () != ':')
+        {
+          BOOST_THROW_EXCEPTION (error::Name ()
+                                 << error::msg ("First component of the name does not start with a slash (did you forget to specify initial /?)"));
+        }
+
+      i = firstSlash;
+
+      if (!boost::iequals (schema, "ccnx:") &&
+          !boost::iequals (schema, "ndn:"))
+        {
+          BOOST_THROW_EXCEPTION (error::Name ()
+                                 << error::msg ("URI schema is not supported (only ccnx: or ndn: is allowed)")
+                                 << error::msg (schema));
+        }
+    }
+
+  string::const_iterator secondSlash = i;
+  secondSlash ++;
+  if (secondSlash != end && *secondSlash == '/')
+    {
+      // The authority component (the part after the initial "//" in the familiar http and ftp URI schemes) is present,
+      // but it is not relevant to NDN name.
+      // skipping it
+      secondSlash ++;
+      i = std::find (secondSlash, end, '/');
+    }
+  
+  if (i == end)
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Invalid URI")
+                             << error::msg (uri));
+    }
+
+  while (i != end)
+    {
+      // skip any extra slashes
+      while (i != end && *i == '/')
+        {
+          i ++;
+        }
+      if (i == end)
+        break;
+      
+      string::const_iterator endOfComponent = std::find (i, end, '/');
+      append (name::Component (i, endOfComponent));
+
+      i = endOfComponent;
+    }
+}
+
+Name::Name (const Name &other)
+{
+  m_comps = other.m_comps;
+}
+
+Name &
+Name::operator= (const Name &other)
+{
+  m_comps = other.m_comps;
+  return *this;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//                                SETTERS                                    //
+///////////////////////////////////////////////////////////////////////////////
+
+Name &
+Name::appendVersion (uint64_t version/* = Name::nversion*/)
+{
+  if (version != Name::nversion)
+    return appendNumberWithMarker (version, 0xFD);
+  else
+    {
+      TimeInterval now = time::NowUnixTimestamp ();
+#ifdef NDNSIM_MODE
+      int64_t seconds = now.GetSeconds ();
+      int64_t microseconds = now.GetMicroSeconds () - seconds * 1000000;
+      
+      version = (seconds << 12) | (0xFFF & (microseconds / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
+#else
+      version = (now.total_seconds () << 12) | (0xFFF & (now.fractional_seconds () / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
+#endif
+      return appendNumberWithMarker (version, 0xFD);
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                                GETTERS                                    //
+///////////////////////////////////////////////////////////////////////////////
+
+const name::Component &
+Name::get (int index) const
+{
+  if (index < 0)
+    {
+      index = size () - (-index);
+    }
+
+  if (static_cast<unsigned int> (index) >= size ())
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Index out of range")
+                             << error::pos (index));
+    }
+  return m_comps [index];
+}
+
+name::Component &
+Name::get (int index)
+{
+  if (index < 0)
+    {
+      index = size () - (-index);
+    }
+
+  if (static_cast<unsigned int> (index) >= size())
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("Index out of range")
+                             << error::pos (index));
+    }
+  return m_comps [index];
+}
+
+
+/////
+///// Static helpers to convert name component to appropriate value
+/////
+
+
+Name
+Name::getSubName (size_t pos/* = 0*/, size_t len/* = Name::npos*/) const
+{
+  Name retval;
+
+  if (len == npos)
+    {
+      len = size () - pos;
+    }
+
+  if (pos + len > size ())
+    {
+      BOOST_THROW_EXCEPTION (error::Name ()
+                             << error::msg ("getSubName parameter out of range")
+                             << error::pos (pos)
+                             << error::pos (len));
+    }
+
+  for (size_t i = pos; i < pos + len; i++)
+    {
+      retval.append (get (i));
+    }
+
+  return retval;
+}
+
+Name
+Name::operator+ (const Name &name) const
+{
+  Name newName;
+  newName
+    .append (*this)
+    .append (name);
+
+  return newName;
+}
+
+std::string
+Name::toUri () const
+{
+  ostringstream os;
+  toUri (os);
+  return os.str ();
+}
+
+void
+Name::toUri (std::ostream &os) const
+{
+  for (Name::const_iterator comp = begin (); comp != end (); comp++)
+    {
+      os << "/";
+      comp->toUri (os);
+    }
+  if (size () == 0)
+    os << "/";
+}
+
+// ostream &
+// operator << (ostream &os, const Name &name)
+// {
+//   for (Name::const_iterator comp = name.begin (); comp != name.end (); comp++)
+//     {
+//       os << "/" << *comp;
+//     }
+//   if (name.size () == 0)
+//     os << "/";
+//   return os;
+// }
+
+int
+Name::compare (const Name &name) const
+{
+  Name::const_iterator i = this->begin ();
+  Name::const_iterator j = name.begin ();
+
+  for (; i != this->end () && j != name.end (); i++, j++)
+    {
+      int res = i->compare (*j);
+      if (res == 0)
+        continue;
+      else
+        return res;
+    }
+
+  if (i == this->end () && j == name.end ())
+    return 0; // prefixes are equal
+
+  return (i == this->end ()) ? -1 : +1;
+}
+
+NDN_NAMESPACE_END
diff --git a/ndn.cxx/name.h b/ndn.cxx/name.h
new file mode 100644
index 0000000..b456bc7
--- /dev/null
+++ b/ndn.cxx/name.h
@@ -0,0 +1,650 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ *                     Alexander Afanasyev
+ *                     Zhenkai Zhu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *         Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ */
+
+#ifndef NDN_NAME_H
+#define NDN_NAME_H
+
+#include "ns3/ndn-common.h"
+#include "ns3/simple-ref-count.h"
+#include "ns3/attribute.h"
+#include "ns3/attribute-helper.h"
+
+#include "name-component.h"
+
+NDN_NAMESPACE_BEGIN
+
+/**
+ * @brief Class for NDN Name
+ */
+class Name : public SimpleRefCount<Name>
+{
+public:
+  typedef std::vector<name::Component>::iterator iterator;
+  typedef std::vector<name::Component>::const_iterator const_iterator;
+  typedef std::vector<name::Component>::reverse_iterator reverse_iterator;
+  typedef std::vector<name::Component>::const_reverse_iterator const_reverse_iterator;
+  typedef std::vector<name::Component>::reference reference;
+  typedef std::vector<name::Component>::const_reference const_reference;
+
+  typedef name::Component partial_type;
+  
+  ///////////////////////////////////////////////////////////////////////////////
+  //                              CONSTRUCTORS                                 //
+  ///////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief Default constructor to create an empty name (zero components, or "/")
+   */
+  Name ();
+
+  /**
+   * @brief Copy constructor
+   *
+   * @param other reference to a NDN name object
+   */
+  Name (const Name &other);
+
+  /**
+   * @brief Create a name from URL string
+   *
+   * @param url URI-represented name
+   */
+  Name (const std::string &url);
+
+  /**
+   * @brief Create a name from a container of elements [begin, end)
+   *
+   * @param begin begin iterator of the container
+   * @param end end iterator of the container
+   */
+  template<class Iterator>
+  Name (Iterator begin, Iterator end);
+
+  /**
+   * @brief Assignment operator
+   */
+  Name &
+  operator= (const Name &other);
+
+
+  ///////////////////////////////////////////////////////////////////////////////
+  //                                SETTERS                                    //
+  ///////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief Append a binary blob as a name component
+   *
+   * @param comp a binary blob
+   * @returns reference to self (to allow chaining of append methods)
+   */
+  inline Name &
+  append (const name::Component &comp);
+
+  /**
+   * @brief Append a binary blob as a name component
+   * @param comp a binary blob
+   *
+   * This version is a little bit more efficient, since it swaps contents of comp and newly added component
+   *
+   * Attention!!! This method has an intended side effect: content of comp becomes empty
+   */
+  inline Name &
+  appendBySwap (name::Component &comp);
+  
+  /**
+   * @brief Append components a container of elements [begin, end)
+   *
+   * @param begin begin iterator of the container
+   * @param end end iterator of the container
+   * @returns reference to self (to allow chaining of append methods)
+   */
+  template<class Iterator>
+  inline Name &
+  append (Iterator begin, Iterator end);
+
+  /**
+   * @brief Append components from another ndn::Name object
+   *
+   * @param comp reference to Name object
+   * @returns reference to self (to allow chaining of append methods)
+   */
+  inline Name &
+  append (const Name &comp);
+
+  /**
+   * @brief Append a string as a name component
+   *
+   * @param compStr a string
+   * @returns reference to self (to allow chaining of append methods)
+   *
+   * No conversions will be done to the string.  The string is included in raw form,
+   * without any leading '\0' symbols.
+   */
+  inline Name &
+  append (const std::string &compStr);
+
+  /**
+   * @brief Append a binary blob as a name component
+   *
+   * @param buf pointer to the first byte of the binary blob
+   * @param size length of the binary blob
+   * @returns reference to self (to allow chaining of append methods)
+   */
+  inline Name &
+  append (const void *buf, size_t size);
+
+  /**
+   * @brief Append network-ordered numeric component to the name
+   *
+   * @param number number to be encoded and added as a component
+   *
+   * Number is encoded and added in network order. Tail zero-bytes are not included.
+   * For example, if the number is 1, then 1-byte binary blob will be added  0x01.
+   * If the number is 256, then 2 binary blob will be added: 0x01 0x01
+   *
+   * If the number is zero, an empty component will be added
+   */
+  inline Name &
+  appendNumber (uint64_t number);
+
+  /**
+   * @brief Append network-ordered numeric component to the name with marker
+   *
+   * @param number number to be encoded and added as a component
+   * @param marker byte marker, specified by the desired naming convention
+   *
+   * Currently defined naming conventions of the marker:
+   * - 0x00  sequence number
+   * - 0xC1  control number
+   * - 0xFB  block id
+   * - 0xFD  version number
+   *
+   * This version is almost exactly as appendNumber, with exception that it adds initial marker.
+   * The number is formatted in the exactly the same way.
+   *
+   * @see appendNumber
+   */
+  inline Name &
+  appendNumberWithMarker (uint64_t number, unsigned char marker);
+
+  /**
+   * @brief Helper method to add sequence number to the name (marker = 0x00)
+   * @param seqno sequence number
+   * @see appendNumberWithMarker
+   */
+  inline Name &
+  appendSeqNum (uint64_t seqno);
+
+  /**
+   * @brief Helper method to add control number to the name (marker = 0xC1)
+   * @param control control number
+   * @see appendNumberWithMarker
+   */
+  inline Name &
+  appendControlNum (uint64_t control);
+
+  /**
+   * @brief Helper method to add block ID to the name (marker = 0xFB)
+   * @param blkid block ID
+   * @see appendNumberWithMarker
+   */
+  inline Name &
+  appendBlkId (uint64_t blkid);
+
+  /**
+   * @brief Helper method to add version to the name (marker = 0xFD)
+   * @param version fully formatted version in a desired format (e.g., timestamp).
+   *                If version is Name::nversion, then the version number is automatically
+   *                assigned based on UTC timestamp
+   * @see appendNumberWithMarker
+   */
+  Name &
+  appendVersion (uint64_t version = Name::nversion);
+
+  ///////////////////////////////////////////////////////////////////////////////
+  //                                GETTERS                                    //
+  ///////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief Get number of the name components
+   * @return number of name components
+   */
+  inline size_t
+  size () const;
+
+  /**
+   * @brief Get binary blob of name component
+   * @param index index of the name component.  If less than 0, then getting component from the back:
+   *              get(-1) getting the last component, get(-2) is getting second component from back, etc.
+   * @returns const reference to binary blob of the requested name component
+   *
+   * If index is out of range, an exception will be thrown
+   */
+  const name::Component &
+  get (int index) const;
+
+  /**
+   * @brief Get binary blob of name component
+   * @param index index of the name component.  If less than 0, then getting component from the back
+   * @returns reference to binary blob of the requested name component
+   *
+   * If index is out of range, an exception will be thrown
+   */
+  name::Component &
+  get (int index);
+
+  /////
+  ///// Iterator interface to name components
+  /////
+  inline Name::const_iterator
+  begin () const;           ///< @brief Begin iterator (const)
+
+  inline Name::iterator
+  begin ();                 ///< @brief Begin iterator
+
+  inline Name::const_iterator
+  end () const;             ///< @brief End iterator (const)
+
+  inline Name::iterator
+  end ();                   ///< @brief End iterator
+
+  inline Name::const_reverse_iterator
+  rbegin () const;          ///< @brief Reverse begin iterator (const)
+
+  inline Name::reverse_iterator
+  rbegin ();                ///< @brief Reverse begin iterator
+
+  inline Name::const_reverse_iterator
+  rend () const;            ///< @brief Reverse end iterator (const)
+
+  inline Name::reverse_iterator
+  rend ();                  ///< @brief Reverse end iterator
+
+
+  /////
+  ///// Static helpers to convert name component to appropriate value
+  /////
+
+  /**
+   * @brief Get a new name, constructed as a subset of components
+   * @param pos Position of the first component to be copied to the subname
+   * @param len Number of components to be copied. Value Name::npos indicates that all components till the end of the name.
+   */
+  Name
+  getSubName (size_t pos = 0, size_t len = npos) const;
+
+  /**
+   * @brief Get prefix of the name
+   * @param len length of the prefix
+   * @param skip number of components to skip from beginning of the name
+   */
+  inline Name
+  getPrefix (size_t len, size_t skip = 0) const;
+
+  /**
+   * @brief Get postfix of the name
+   * @param len length of the postfix
+   * @param skip number of components to skip from end of the name
+   */
+  inline Name
+  getPostfix (size_t len, size_t skip = 0) const;
+
+  /**
+   * @brief Get text representation of the name (URI)
+   */
+  std::string
+  toUri () const;
+
+  /**
+   * @brief Write name as URI to the specified output stream
+   * @param os output stream
+   */
+  void
+  toUri (std::ostream &os) const;
+
+  /////////////////////////////////////////////////
+  // Helpers and compatibility wrappers
+  /////////////////////////////////////////////////
+
+  /**
+   * @brief Compare two names, using canonical ordering for each component
+   * @return 0  They compare equal
+   *         <0 If *this comes before other in the canonical ordering
+   *         >0 If *this comes after in the canonical ordering
+   */
+  int
+  compare (const Name &name) const;
+
+  /**
+   * @brief Check if to Name objects are equal (have the same number of components with the same binary data)
+   */
+  inline bool
+  operator == (const Name &name) const;
+
+  /**
+   * @brief Check if two Name objects are not equal
+   */
+  inline bool
+  operator != (const Name &name) const;
+
+  /**
+   * @brief Less or equal comparison of two name objects
+   */
+  inline bool
+  operator <= (const Name &name) const;
+
+  /**
+   * @brief Less comparison of two name objects
+   */
+  inline bool
+  operator < (const Name &name) const;
+
+  /**
+   * @brief Great or equal comparison of two name objects
+   */
+  inline bool
+  operator >= (const Name &name) const;
+
+  /**
+   * @brief Great comparison of two name objects
+   */
+  inline bool
+  operator > (const Name &name) const;
+
+  /**
+   * @brief Operator [] to simplify access to name components
+   * @see get
+   */
+  inline name::Component &
+  operator [] (int index);
+
+  /**
+   * @brief Operator [] to simplify access to name components
+   * @see get
+   */
+  inline const name::Component &
+  operator [] (int index) const;
+
+  /**
+   * @brief Create a new Name object, by copying components from first and second name
+   */
+  Name
+  operator + (const Name &name) const;
+
+  /**
+   * @brief A wrapper for append method
+   */
+  template<class T>
+  inline void
+  push_back (const T &comp);
+
+public:
+  // Data Members (public):
+  ///  Value returned by various member functions when they fail.
+  const static size_t npos = static_cast<size_t> (-1);
+  const static uint64_t nversion = static_cast<uint64_t> (-1);
+
+private:
+  std::vector<name::Component> m_comps;
+};
+
+inline std::ostream &
+operator << (std::ostream &os, const Name &name)
+{
+  name.toUri (os);
+  return os;
+}
+
+inline std::istream &
+operator >> (std::istream &is, Name &name)
+{
+  std::string line;
+  is >> line;
+  name = Name (line);
+
+  return is;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Definition of inline methods
+/////////////////////////////////////////////////////////////////////////////////////
+
+template<class Iterator>
+Name::Name (Iterator begin, Iterator end)
+{
+  append (begin, end);
+}
+
+inline Name &
+Name::append (const name::Component &comp)
+{
+  if (comp.size () != 0)
+    m_comps.push_back (comp);
+  return *this;
+}
+
+inline Name &
+Name::appendBySwap (name::Component &comp)
+{
+  if (comp.size () != 0)
+    {
+      Name::iterator newComp = m_comps.insert (end (), name::Component ());
+      newComp->swap (comp);
+    }
+  return *this;
+}
+
+template<class Iterator>
+inline Name &
+Name::append (Iterator begin, Iterator end)
+{
+  for (Iterator i = begin; i != end; i++)
+    {
+      append (*i);
+    }
+  return *this;
+}
+
+Name &
+Name::append (const Name &comp)
+{
+  if (this == &comp)
+    {
+      // have to double-copy if the object is self, otherwise results very frustrating (because we use vector...)
+      return append (Name (comp.begin (), comp.end ()));
+    }
+  return append (comp.begin (), comp.end ());
+}
+
+Name &
+Name::append (const std::string &compStr)
+{
+  name::Component comp (compStr);
+  return appendBySwap (comp);
+}
+
+Name &
+Name::append (const void *buf, size_t size)
+{
+  name::Component comp (buf, size);
+  return appendBySwap (comp);
+}
+
+Name &
+Name::appendNumber (uint64_t number)
+{
+  name::Component comp;
+  name::Component::fromNumber (number).swap (comp);
+  return appendBySwap (comp);
+}
+
+Name &
+Name::appendNumberWithMarker (uint64_t number, unsigned char marker)
+{
+  name::Component comp;
+  name::Component::fromNumberWithMarker (number, marker).swap (comp);
+  return appendBySwap (comp);
+}
+
+inline Name &
+Name::appendSeqNum (uint64_t seqno)
+{
+  return appendNumberWithMarker (seqno, 0x00);
+}
+
+inline Name &
+Name::appendControlNum (uint64_t control)
+{
+  return appendNumberWithMarker (control, 0xC1);
+}
+
+inline Name &
+Name::appendBlkId (uint64_t blkid)
+{
+  return appendNumberWithMarker (blkid, 0xFB);
+}
+
+inline size_t
+Name::size () const
+{
+  return m_comps.size ();
+}
+
+/////
+///// Iterator interface to name components
+/////
+inline Name::const_iterator
+Name::begin () const
+{
+  return m_comps.begin ();
+}
+
+inline Name::iterator
+Name::begin ()
+{
+  return m_comps.begin ();
+}
+
+inline Name::const_iterator
+Name::end () const
+{
+  return m_comps.end ();
+}
+
+inline Name::iterator
+Name::end ()
+{
+  return m_comps.end ();
+}
+
+inline Name::const_reverse_iterator
+Name::rbegin () const
+{
+  return m_comps.rbegin ();
+}
+
+inline Name::reverse_iterator
+Name::rbegin ()
+{
+  return m_comps.rbegin ();
+}
+
+inline Name::const_reverse_iterator
+Name::rend () const
+{
+  return m_comps.rend ();
+}
+
+
+inline Name::reverse_iterator
+Name::rend ()
+{
+  return m_comps.rend ();
+}
+
+
+//// helpers
+
+
+inline Name
+Name::getPrefix (size_t len, size_t skip/* = 0*/) const
+{
+  return getSubName (skip, len);
+}
+
+inline Name
+Name::getPostfix (size_t len, size_t skip/* = 0*/) const
+{
+  return getSubName (size () - len - skip, len);
+}
+
+
+template<class T>
+inline void
+Name::push_back (const T &comp)
+{
+  append (comp);
+}
+
+inline bool
+Name::operator ==(const Name &name) const
+{
+  return (compare (name) == 0);
+}
+
+inline bool
+Name::operator !=(const Name &name) const
+{
+  return (compare (name) != 0);
+}
+
+inline bool
+Name::operator <= (const Name &name) const
+{
+  return (compare (name) <= 0);
+}
+
+inline bool
+Name::operator < (const Name &name) const
+{
+  return (compare (name) < 0);
+}
+
+inline bool
+Name::operator >= (const Name &name) const
+{
+  return (compare (name) >= 0);
+}
+
+inline bool
+Name::operator > (const Name &name) const
+{
+  return (compare (name) > 0);
+}
+
+inline name::Component &
+Name::operator [] (int index)
+{
+  return get (index);
+}
+
+inline const name::Component &
+Name::operator [] (int index) const
+{
+  return get (index);
+}
+
+ATTRIBUTE_HELPER_HEADER (Name);
+
+NDN_NAMESPACE_END
+
+#endif
diff --git a/utils/trie/trie-with-policy.h b/utils/trie/trie-with-policy.h
index 2d175a0..2e1f883 100644
--- a/utils/trie/trie-with-policy.h
+++ b/utils/trie/trie-with-policy.h
@@ -48,7 +48,7 @@
 
   inline
   trie_with_policy (size_t bucketSize = 10, size_t bucketIncrement = 10)
-    : trie_ ("", bucketSize, bucketIncrement)
+    : trie_ (name::Component (), bucketSize, bucketIncrement)
     , policy_ (*this)
   {
   }
diff --git a/wscript b/wscript
index ff2b7f3..fb00647 100644
--- a/wscript
+++ b/wscript
@@ -137,6 +137,12 @@
         "model/ndn-name-components.h",
         "model/ndn-name.h",
 
+        "ndn.cxx/name.h",
+        "ndn.cxx/name-component.h",
+        "ndn.cxx/blob.h",
+        "ndn.cxx/exclude.h",
+        "ndn.cxx/ndn-api-face.h",
+
         "model/cs/ndn-content-store.h",
 
         "model/fib/ndn-fib.h",
@@ -155,7 +161,6 @@
         "utils/ndn-limits.h",
         "utils/ndn-rtt-estimator.h",
 
-        "ndn.cxx/ndn-api-face.h",
         "apps/callback-based-app.h",
         ]
 
@@ -186,7 +191,7 @@
 
     bld.recurse ('tools')
 
-    bld.ns3_python_bindings()
+    # bld.ns3_python_bindings()
 
 
 @TaskGen.feature('ns3fullmoduleheaders')