Merge remote-tracking branch 'git.irl/master'
diff --git a/examples/ccnx-test.cc b/examples/ccnx-test.cc
index 626a2f5..0d32793 100644
--- a/examples/ccnx-test.cc
+++ b/examples/ccnx-test.cc
@@ -2,9 +2,7 @@
 
 #include "ns3/core-module.h"
 #include "ns3/network-module.h"
-#include "ns3/internet-module.h"
 #include "ns3/point-to-point-module.h"
-#include "ns3/applications-module.h"
 #include "ns3/NDNabstraction-module.h"
 
 using namespace ns3;
@@ -15,18 +13,23 @@
 main (int argc, char *argv[])
 {
   LogComponentEnable ("CcnxTest", LOG_ALL);
+  LogComponentEnable ("CcnxStackHelper", LOG_ALL);
   
-  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
-  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
+  // Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
+  // Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
+
+  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("10Mbps"));
+  Config::SetDefault ("ns3::PointToPointChannel::Delay", StringValue ("1ms"));
   
   CommandLine cmd;
   cmd.Parse (argc, argv);
   
   // Here, we will explicitly create seven nodes. 
   NodeContainer c;
-  c.Create (2);
+  c.Create (3);
   
-  NodeContainer n = NodeContainer (c.Get (0), c.Get (2));
+  NodeContainer n1 = NodeContainer (c.Get (0), c.Get (1));
+  NodeContainer n2 = NodeContainer (c.Get (1), c.Get (2));
   
   // Ipv4StaticRoutingHelper staticRouting;
   
@@ -35,16 +38,16 @@
 
   NS_LOG_INFO ("Create channels.");
   PointToPointHelper p2p;
-  p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
-  p2p.SetChannelAttribute ("Delay", StringValue ("1ms"));
-  NetDeviceContainer nd = p2p.Install (n);
+  // NetDeviceContainer nd =
+  p2p.Install (n1);
+  p2p.Install (n2);
 
   NS_LOG_INFO ("Installing NDN stack");
   CcnxStackHelper ccnx;
+  Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
 
   // ? set up forwarding
   
-  //  ccnx.Install (c);
   
   //Add static routing
   // InternetStackHelper internet;
diff --git a/helper/ccnb-parser/ccnb-parser-common.h b/helper/ccnb-parser/ccnb-parser-common.h
new file mode 100644
index 0000000..4e4eb12
--- /dev/null
+++ b/helper/ccnb-parser/ccnb-parser-common.h
@@ -0,0 +1,178 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_COMMON_H_
+#define _CCNB_PARSER_COMMON_H_
+
+namespace ns3 {
+
+/**
+ * \ingroup ccnx
+ * \defgroup ccnx-ccnb CCNB decoding routines
+ */
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Namespace for ccnb parer
+ */
+namespace CcnbParser {
+
+// forward declarations
+class Block;
+class Blob;
+class Udata;
+class Tag;
+class Attr;
+class Dtag;
+class Dattr;
+class Ext;
+
+
+/**
+ * \brief Exception thrown if there is a parsing error
+ *
+ * \todo inherit this class from some exception class and provide meaningful error messages
+ */
+class CcnbDecodingException {};
+
+/**
+ * \brief Type tag for a ccnb start marker.
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/DTAG.html
+ */
+enum ccn_tt {
+  CCN_EXT,        /**< starts composite extension - numval is subtype */
+  CCN_TAG,        /**< starts composite - numval is tagnamelen-1 */ 
+  CCN_DTAG,       /**< starts composite - numval is tagdict index (enum ccn_dtag) */
+  CCN_ATTR,       /**< attribute - numval is attrnamelen-1, value follows */
+  CCN_DATTR,      /**< attribute numval is attrdict index */
+  CCN_BLOB,       /**< opaque binary data - numval is byte count */
+  CCN_UDATA,      /**< UTF-8 encoded character data - numval is byte count */
+  CCN_NO_TOKEN    /**< should not occur in encoding */
+};
+
+/** \brief CCN_CLOSE terminates composites */
+enum {CCN_CLOSE = 0};
+
+/**
+ * \brief DTAG identifies ccnb-encoded elements.
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/DTAG.html
+ */
+enum ccn_dtag {
+  CCN_DTAG_Any = 13,
+  CCN_DTAG_Name = 14,
+  CCN_DTAG_Component = 15,
+  CCN_DTAG_Certificate = 16,
+  CCN_DTAG_Collection = 17,
+  CCN_DTAG_CompleteName = 18,
+  CCN_DTAG_Content = 19,
+  CCN_DTAG_SignedInfo = 20,
+  CCN_DTAG_ContentDigest = 21,
+  CCN_DTAG_ContentHash = 22,
+  CCN_DTAG_Count = 24,
+  CCN_DTAG_Header = 25,
+  CCN_DTAG_Interest = 26,	/* 20090915 */
+  CCN_DTAG_Key = 27,
+  CCN_DTAG_KeyLocator = 28,
+  CCN_DTAG_KeyName = 29,
+  CCN_DTAG_Length = 30,
+  CCN_DTAG_Link = 31,
+  CCN_DTAG_LinkAuthenticator = 32,
+  CCN_DTAG_NameComponentCount = 33,	/* DeprecatedInInterest */
+  CCN_DTAG_RootDigest = 36,
+  CCN_DTAG_Signature = 37,
+  CCN_DTAG_Start = 38,
+  CCN_DTAG_Timestamp = 39,
+  CCN_DTAG_Type = 40,
+  CCN_DTAG_Nonce = 41,
+  CCN_DTAG_Scope = 42,
+  CCN_DTAG_Exclude = 43,
+  CCN_DTAG_Bloom = 44,
+  CCN_DTAG_BloomSeed = 45,
+  CCN_DTAG_AnswerOriginKind = 47,
+  CCN_DTAG_InterestLifetime = 48,
+  CCN_DTAG_Witness = 53,
+  CCN_DTAG_SignatureBits = 54,
+  CCN_DTAG_DigestAlgorithm = 55,
+  CCN_DTAG_BlockSize = 56,
+  CCN_DTAG_FreshnessSeconds = 58,
+  CCN_DTAG_FinalBlockID = 59,
+  CCN_DTAG_PublisherPublicKeyDigest = 60,
+  CCN_DTAG_PublisherCertificateDigest = 61,
+  CCN_DTAG_PublisherIssuerKeyDigest = 62,
+  CCN_DTAG_PublisherIssuerCertificateDigest = 63,
+  CCN_DTAG_ContentObject = 64,	/* 20090915 */
+  CCN_DTAG_WrappedKey = 65,
+  CCN_DTAG_WrappingKeyIdentifier = 66,
+  CCN_DTAG_WrapAlgorithm = 67,
+  CCN_DTAG_KeyAlgorithm = 68,
+  CCN_DTAG_Label = 69,
+  CCN_DTAG_EncryptedKey = 70,
+  CCN_DTAG_EncryptedNonceKey = 71,
+  CCN_DTAG_WrappingKeyName = 72,
+  CCN_DTAG_Action = 73,
+  CCN_DTAG_FaceID = 74,
+  CCN_DTAG_IPProto = 75,
+  CCN_DTAG_Host = 76,
+  CCN_DTAG_Port = 77,
+  CCN_DTAG_MulticastInterface = 78,
+  CCN_DTAG_ForwardingFlags = 79,
+  CCN_DTAG_FaceInstance = 80,
+  CCN_DTAG_ForwardingEntry = 81,
+  CCN_DTAG_MulticastTTL = 82,
+  CCN_DTAG_MinSuffixComponents = 83,
+  CCN_DTAG_MaxSuffixComponents = 84,
+  CCN_DTAG_ChildSelector = 85,
+  CCN_DTAG_RepositoryInfo = 86,
+  CCN_DTAG_Version = 87,
+  CCN_DTAG_RepositoryVersion = 88,
+  CCN_DTAG_GlobalPrefix = 89,
+  CCN_DTAG_LocalName = 90,
+  CCN_DTAG_Policy = 91,
+  CCN_DTAG_Namespace = 92,
+  CCN_DTAG_GlobalPrefixName = 93,
+  CCN_DTAG_PolicyVersion = 94,
+  CCN_DTAG_KeyValueSet = 95,
+  CCN_DTAG_KeyValuePair = 96,
+  CCN_DTAG_IntegerValue = 97,
+  CCN_DTAG_DecimalValue = 98,
+  CCN_DTAG_StringValue = 99,
+  CCN_DTAG_BinaryValue = 100,
+  CCN_DTAG_NameValue = 101,
+  CCN_DTAG_Entry = 102,
+  CCN_DTAG_ACL = 103,
+  CCN_DTAG_ParameterizedName = 104,
+  CCN_DTAG_Prefix = 105,
+  CCN_DTAG_Suffix = 106,
+  CCN_DTAG_Root = 107,
+  CCN_DTAG_ProfileName = 108,
+  CCN_DTAG_Parameters = 109,
+  CCN_DTAG_InfoString = 110,
+  CCN_DTAG_StatusResponse = 112,
+  CCN_DTAG_StatusCode = 113,
+  CCN_DTAG_StatusText = 114,
+  CCN_DTAG_SequenceNumber = 256,
+  CCN_DTAG_CCNProtocolDataUnit = 17702112
+};
+
+} // namespace CcnxParser
+} // namespace ns3
+
+#endif // _CCNB_PARSER_COMMON_H_
diff --git a/helper/ccnb-parser/ccnx-decoding-helper.h b/helper/ccnb-parser/ccnx-decoding-helper.h
new file mode 100644
index 0000000..375a57a
--- /dev/null
+++ b/helper/ccnb-parser/ccnx-decoding-helper.h
@@ -0,0 +1,46 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNX_DECODING_HELPER_H_
+#define _CCNX_DECODING_HELPER_H_
+
+namespace ns3 {
+
+class CcnxInterestHeader;
+class CcnxContentObjectHeader;
+
+/**
+ * \brief Helper class to decode ccnb formatted CCNx message
+ */
+class CcnxDecodingHelper
+{
+public:
+  static size_t
+  Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
+
+  static size_t
+  Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
+  
+private:
+};
+
+} // namespace ns3
+
+#endif // _CCNX_DECODING_HELPER_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
new file mode 100644
index 0000000..397e940
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.cc
@@ -0,0 +1,41 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-attr.h"
+#include "ns3/ccnb-parser-common.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+// length length in octets of UTF-8 encoding of tag name - 1 (minimum tag name length is 1) 
+Attr::Attr (Buffer::Iterator &start, uint32_t length)
+{
+  m_attr.reserve (length+2); // extra byte for potential \0 at the end
+  for (uint32_t i = 0; i < (length+1); i++)
+    {
+      m_attr.push_back (start.ReadU8 ());
+    }
+  m_value = DynamicCast<Udata> (Block::ParseBlock (start));
+  if (m_value == 0)
+    throw CcnbDecodingException (); // "ATTR must be followed by UDATA field"
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.h
new file mode 100644
index 0000000..1b7d5e8
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-attr.h
@@ -0,0 +1,60 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_ATTR_H_
+#define _CCNB_PARSER_ATTR_H_
+
+#include "ccnb-parser-base-attr.h"
+#include <string>
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Class to represent ATTR ccnb-encoded node
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class Attr : public BaseAttr
+{
+public:
+  /**
+   * \brief Constructor that actually parsed ccnb-encoded ATTR block
+   *
+   * \param start  buffer iterator pointing to the first byte of ATTR block name
+   * \param length length of ATTR name (extracted from the value field)
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  Attr (Buffer::Iterator &start, uint32_t length);
+  
+  virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
+  virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
+  virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
+  virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
+
+  std::string m_attr; ///< field holding name of the attribute
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_ATTR_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-base-attr.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-base-attr.h
new file mode 100644
index 0000000..9b20073
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-base-attr.h
@@ -0,0 +1,45 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_BASE_ATTR_H_
+#define _CCNB_PARSER_BASE_ATTR_H_
+
+#include "ccnb-parser-udata.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Virtual base class providing a common storage for ATTR
+ * and DATTR ccnb-encoded blocks
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class BaseAttr : public Block
+{
+public:
+  Ptr<Udata> m_value; ///< \brief Value of the attribute
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_BASE_ATTR_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-base-tag.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-base-tag.h
new file mode 100644
index 0000000..6b7fe76
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-base-tag.h
@@ -0,0 +1,54 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_BASE_TAG_H_
+#define _CCNB_PARSER_BASE_TAG_H_
+
+#include "ccnb-parser-block.h"
+#include <list>
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Virtual base class providing a common storage for TAG
+ * and DTAG ccnb-encoded blocks
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class BaseTag : public Block
+{
+public:
+  std::list<Ptr<Block> > m_attrs;      ///< \brief List of attributes, associated with this tag
+  std::list<Ptr<Block> > m_nestedTags; ///< \brief List of nested tags
+
+protected:
+  /**
+   * \brief Default constructor
+   */
+  BaseTag() { }
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_BASE_TAG_H_
+
diff --git a/in-progress/ccn/ccn_name_util.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
similarity index 76%
copy from in-progress/ccn/ccn_name_util.h
copy to helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
index 6e5fda7..0928eb8 100644
--- a/in-progress/ccn/ccn_name_util.h
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.cc
@@ -15,5 +15,18 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
+
+#include "ccnb-parser-blob.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+Blob::Blob (Buffer::Iterator &start, uint32_t length)
+{
+  start.Read (m_blob.Begin (), length);
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
new file mode 100644
index 0000000..4b22d62
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-blob.h
@@ -0,0 +1,60 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_BLOB_H_
+#define _CCNB_PARSER_BLOB_H_
+
+#include "ccnb-parser-block.h"
+#include "ns3/buffer.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Class to represent BLOB ccnb-encoded node
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class Blob : public Block
+{
+public:
+  /**
+   * \brief Constructor that actually parsed ccnb-encoded BLOB block
+   *
+   * \param start  buffer iterator pointing to the first byte of BLOB data in ccnb-encoded block 
+   * \param length length of data in BLOB block (extracted from the value field)
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  Blob (Buffer::Iterator &start, uint32_t length);
+  
+  virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
+  virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
+  virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
+  virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
+
+  Buffer m_blob; ///< \brief field holding a parsed BLOB value of the block
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_BLOB_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
new file mode 100644
index 0000000..e1e09fd
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.cc
@@ -0,0 +1,76 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-block.h"
+
+#include "ccnb-parser-blob.h"
+#include "ccnb-parser-udata.h"
+#include "ccnb-parser-tag.h"
+#include "ccnb-parser-dtag.h"
+#include "ccnb-parser-attr.h"
+#include "ccnb-parser-dattr.h"
+#include "ccnb-parser-ext.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+const uint8_t CCN_TT_BITS = 3;
+const uint8_t CCN_TT_MASK = ((1 << CCN_TT_BITS) - 1);
+const uint8_t CCN_MAX_TINY= ((1 << (7-CCN_TT_BITS)) - 1);
+const uint8_t CCN_TT_HBIT = ((uint8_t)(1 << 7));
+
+Ptr<Block> Block::ParseBlock (Buffer::Iterator &start)
+{
+  uint32_t value = 0;
+
+  // We will have problems if length field is more than 32 bits. Though it's really impossible
+  uint8_t byte = 0;
+  while (!(byte & CCN_TT_HBIT))
+    {
+      value <<= 8;
+      value += byte;
+      byte = start.ReadU8 ();
+    }
+  value <<= 4;
+  value += ( (byte&(~CCN_TT_HBIT)) >> 3);
+
+  switch (byte & CCN_TT_MASK)
+    {
+    case CCN_BLOB:
+      return Create<Blob> (start, value);
+    case CCN_UDATA:
+      return Create<Udata> (start, value);
+    case CCN_TAG:
+      return Create<Tag> (start, value);
+    case CCN_ATTR:
+      return Create<Attr> (start, value);
+    case CCN_DTAG:
+      return Create<Dtag> (start, value);
+    case CCN_DATTR:
+      return Create<Dattr> (start, value);
+    case CCN_EXT:
+      return Create<Ext> (start, value);
+    default:
+      throw CcnbDecodingException ();
+    }
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-block.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.h
new file mode 100644
index 0000000..1ff614b
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-block.h
@@ -0,0 +1,68 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_BLOCK_H_
+#define _CCNB_PARSER_BLOCK_H_
+
+#include "ns3/simple-ref-count.h"
+#include "ns3/buffer.h"
+#include "ns3/ptr.h"
+
+// visitors
+#include "ns3/ccnb-parser-void-no-argu-visitor.h"
+#include "ns3/ccnb-parser-void-visitor.h"
+#include "ns3/ccnb-parser-no-argu-visitor.h"
+#include "ns3/ccnb-parser-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Base class for ccnb-encoded node
+ *
+ * This class provides a static method to create a new block
+ * (recursively) from the stream
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class Block : public SimpleRefCount<Block>
+{
+public:
+  /**
+   * \brief Parsing stream (recursively) and creating a parsed BLOCK
+   * object
+   *
+   * \param start buffer iterator pointing to the start position for parsing 
+   * \returns parsed ccnb-encoded block, that could contain more block inside
+   */
+  static Ptr<Block>
+  ParseBlock (Buffer::Iterator &start);
+  
+  virtual void accept( VoidNoArguVisitor &v )               = 0;
+  virtual void accept( VoidVisitor &v, boost::any param )   = 0;
+  virtual boost::any accept( NoArguVisitor &v )             = 0;
+  virtual boost::any accept( Visitor &v, boost::any param ) = 0;
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_BLOCK_H_
diff --git a/in-progress/ccn/ccn_name_util.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-dattr.cc
similarity index 64%
copy from in-progress/ccn/ccn_name_util.h
copy to helper/ccnb-parser/syntax-tree/ccnb-parser-dattr.cc
index 6e5fda7..bb6be82 100644
--- a/in-progress/ccn/ccn_name_util.h
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dattr.cc
@@ -15,5 +15,22 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
+
+#include "ccnb-parser-dattr.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+// dictionary attributes are not used (yet?) in CCNx 
+Dattr::Dattr (Buffer::Iterator &start, uint32_t dattr)
+{
+  m_dattr = dattr;
+  m_value = DynamicCast<Udata> (Block::ParseBlock (start));
+  if (m_value == 0)
+    throw CcnbDecodingException (); // "ATTR must be followed by UDATA field"
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-dattr.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-dattr.h
new file mode 100644
index 0000000..6775017
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dattr.h
@@ -0,0 +1,59 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_DATTR_H_
+#define _CCNB_PARSER_DATTR_H_
+
+#include "ccnb-parser-base-attr.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Class to represent DATTR ccnb-encoded node
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class Dattr : public BaseAttr
+{
+public:
+  /**
+   * \brief Constructor that actually parsed ccnb-encoded DATTR block
+   *
+   * \param start buffer iterator pointing to the first byte of attribute value (UDATA block)
+   * \param dattr dictionary code of DATTR (extracted from the value field)
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  Dattr (Buffer::Iterator &start, uint32_t dattr);
+
+  virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
+  virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
+  virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
+  virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
+
+  uint32_t m_dattr; ///< \brief Dictionary code of DATTR
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_DATTR_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc
new file mode 100644
index 0000000..8d9ecf7
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.cc
@@ -0,0 +1,76 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-dtag.h"
+
+#include "ccnb-parser-base-attr.h"
+#include "ccnb-parser-base-tag.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+Dtag::Dtag (Buffer::Iterator &start, uint32_t dtag)
+{
+  m_dtag = dtag;
+
+  /**
+   * Hack
+   *
+   * Stop processing after encountering <Content> dtag.  Actual
+   * content (including virtual payload) will be stored in Packet
+   * buffer
+   */
+  if (dtag == CCN_DTAG_Content)
+    return; // hack #1. Do not process nesting block for <Content>
+  
+  // parse attributes until first nested block reached
+  while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+    {
+      Ptr<Block> block = Block::ParseBlock (start);
+      if (DynamicCast<BaseAttr> (block)!=0)
+		m_attrs.push_back (block);
+	  else
+		{
+		  m_nestedTags.push_back (block);
+		  break;
+		}
+	}
+
+  // parse the rest of nested blocks
+  while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+    {
+      // hack #2. Stop processing nested blocks if last block was <Content>
+      if (m_dtag == CCN_DTAG_ContentObject && // we are in <ContentObject>
+          DynamicCast<Dtag> (m_nestedTags.back())!=0 && // last block is DTAG
+          DynamicCast<Dtag> (m_nestedTags.back())->m_dtag == CCN_DTAG_Content) 
+        {
+          return; 
+        }
+
+      m_nestedTags.push_back (Block::ParseBlock (start));
+    }
+  if (start.IsEnd ())
+      throw CcnbDecodingException ();
+
+  start.ReadU8 (); // read CCN_CLOSE
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.h
new file mode 100644
index 0000000..1ff75e3
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-dtag.h
@@ -0,0 +1,64 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_DTAG_H_
+#define _CCNB_PARSER_DTAG_H_
+
+#include "ccnb-parser-base-tag.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Class to represent DTAG ccnb-encoded node
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class Dtag : public BaseTag
+{
+public:
+  /**
+   * \brief Constructor that actually parsed ccnb-encoded DTAG block
+   *
+   * \param start buffer iterator pointing to the first nesting block or closing tag
+   * \param dtag  dictionary code of DTAG (extracted from the value field)
+   *
+   * DTAG parsing is slightly hacked to provide memory optimization
+   * for NS-3 simulations.  Parsing will be stopped after encountering
+   * <Content> dtag.  Actual content (including virtual payload) will
+   * be stored in Packet buffer
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  Dtag (Buffer::Iterator &start, uint32_t dtag);
+
+  virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
+  virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
+  virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
+  virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
+
+  uint32_t m_dtag; ///< \brief Dictionary code for DTAG
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_DTAG_H_
diff --git a/in-progress/ccn/ccn_name_util.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-ext.cc
similarity index 76%
rename from in-progress/ccn/ccn_name_util.h
rename to helper/ccnb-parser/syntax-tree/ccnb-parser-ext.cc
index 6e5fda7..7d90019 100644
--- a/in-progress/ccn/ccn_name_util.h
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-ext.cc
@@ -15,5 +15,18 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
+
+#include "ccnb-parser-ext.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+Ext::Ext (Buffer::Iterator &start, uint32_t extSubtype)
+{
+  m_extSubtype = extSubtype;
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-ext.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-ext.h
new file mode 100644
index 0000000..568706b
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-ext.h
@@ -0,0 +1,59 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_EXT_H_
+#define _CCNB_PARSER_EXT_H_
+
+#include "ccnb-parser-block.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Class to represent EXT ccnb-encoded node
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class Ext : public Block
+{
+public:
+  /**
+   * \brief Constructor that actually parsed ccnb-encoded DTAG block
+   *
+   * \param start buffer iterator pointing to the next byte past EXT block
+   * \param extSubtype extension type (extracted from the value field)
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  Ext (Buffer::Iterator &start, uint32_t extSubtype);
+
+  virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
+  virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
+  virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
+  virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
+
+  uint64_t m_extSubtype; ///< \brief Extension type
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_EXT_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
new file mode 100644
index 0000000..c288be9
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.cc
@@ -0,0 +1,63 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-tag.h"
+
+#include "ccnb-parser-base-attr.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+Tag::Tag (Buffer::Iterator &start, uint32_t length)
+{
+  m_tag.reserve (length+2); // extra byte for potential \0 at the end
+  for (uint32_t i = 0; i < (length+1); i++)
+    {
+      m_tag.push_back (start.ReadU8 ());
+    }
+  
+  // parse attributes until first nested block reached
+  while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+    {
+      Ptr<Block> block = Block::ParseBlock (start);
+      if (DynamicCast<BaseAttr> (block)!=0)
+		m_attrs.push_back (block);
+	  else
+		{
+		  m_nestedTags.push_back (block);
+		  break;
+		}
+	}
+
+  // parse the rest of nested blocks
+  while (!start.IsEnd () && start.PeekU8 ()!=CCN_CLOSE)
+    {
+      Ptr<Block> block = Block::ParseBlock (start);
+	  m_nestedTags.push_back (block);
+    }
+  
+  if (start.IsEnd ()) //should not be the end
+      throw CcnbDecodingException ();
+
+  start.ReadU8 (); // read CCN_CLOSE
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.h
new file mode 100644
index 0000000..c80581d
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-tag.h
@@ -0,0 +1,60 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_TAG_H_
+#define _CCNB_PARSER_TAG_H_
+
+#include "ccnb-parser-base-tag.h"
+#include <string>
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Class to represent TAG ccnb-encoded node
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ */
+class Tag : public BaseTag
+{
+public:
+  /**
+   * \brief Constructor that actually parsed ccnb-encoded TAG block
+   *
+   * \param start  buffer iterator pointing to the first byte of TAG block name
+   * \param length length of TAG name - 1 byte (i.e., minimum tag name is 1 byte)
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  Tag (Buffer::Iterator &start, uint32_t length);
+
+  virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
+  virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
+  virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
+  virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
+
+  std::string m_tag; ///< \brief Name of TAG block
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_TAG_H_
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
new file mode 100644
index 0000000..39217fd
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.cc
@@ -0,0 +1,42 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-udata.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+Udata::Udata (Buffer::Iterator &start, uint32_t length)
+{
+  // Ideally, the code should look like this. Unfortunately, we don't have normal compatible iterators
+  // Buffer::Iterator realStart = start;
+  // start.Next (length); // advancing forward
+  // m_udata.assign (realStart, start/*actually, it is the end*/);
+
+  m_udata.reserve (length+1); //just in case we will need \0 at the end later
+  // this is actually the way Read method is implemented in network/src/buffer.cc
+  for (uint32_t i = 0; i < length; i++)
+    {
+      m_udata.push_back (start.ReadU8 ());
+    }
+}
+
+}
+}
diff --git a/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.h b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.h
new file mode 100644
index 0000000..b6ef2c2
--- /dev/null
+++ b/helper/ccnb-parser/syntax-tree/ccnb-parser-udata.h
@@ -0,0 +1,58 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_UDATA_H_
+#define _CCNB_PARSER_UDATA_H_
+
+#include "ccnb-parser-block.h"
+#include <string>
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Class to represent UDATA ccnb-encoded node
+ */
+class Udata : public Block
+{
+public:
+  /**
+   * \brief Constructor that actually parsed ccnb-encoded UDATA block
+   *
+   * \param start  buffer iterator pointing to the first byte of string in ccnb-encoded block 
+   * \param length length of data in UDATA block (extracted from the value field)
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  Udata (Buffer::Iterator &start, uint32_t length);
+  
+  virtual void accept( VoidNoArguVisitor &v )               { v.visit( *this ); }
+  virtual void accept( VoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
+  virtual boost::any accept( NoArguVisitor &v )             { return v.visit( *this ); }
+  virtual boost::any accept( Visitor &v, boost::any param ) { return v.visit( *this, param ); }
+
+  std::string m_udata; ///< \brief field holding a parsed UDATA value of the block
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_UDATA_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
new file mode 100644
index 0000000..d694f11
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.cc
@@ -0,0 +1,79 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-content-object-visitor.h"
+#include "ccnb-parser-name-components-visitor.h"
+
+#include "ns3/ccnb-parser-block.h"
+#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/name-components.h"
+#include "ns3/assert.h"
+
+#include "ns3/ccnx-content-object-header.h"
+
+#include <boost/foreach.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+// We don't really care about any other fields
+void
+ContentObjectVisitor::visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/)
+{
+  // uint32_t n.m_dtag;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  static NameComponentsVisitor nameComponentsVisitor;
+  
+  CcnxContentObjectHeader &contentObject = boost::any_cast<CcnxContentObjectHeader&> (param);
+  
+  switch (n.m_dtag)
+    {
+    case CCN_DTAG_ContentObject:
+      // process nested blocks
+      BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+        {
+          block->accept (*this, param);
+        }
+      break;
+    case CCN_DTAG_Name:
+      {
+        // process name components
+        Ptr<Name::Components> name = Create<Name::Components> ();
+        
+        BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+          {
+            block->accept (nameComponentsVisitor, *name);
+          }
+        contentObject.SetName (name);
+        break;
+      }
+    case CCN_DTAG_Signature: // ignoring
+      break;
+    case CCN_DTAG_SignedInfo: // ignoring
+      break;
+    case CCN_DTAG_Content: // !!! HACK
+      // This hack was necessary for memory optimizations (i.e., content is virtual payload)
+      NS_ASSERT_MSG (n.m_nestedTags.size() == 0, "Parser should have stopped just after processing <Content> tag");
+      break;
+    }
+}
+
+} // namespace CcnbParser
+} // namespace ns3
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
new file mode 100644
index 0000000..e15e290
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-content-object-visitor.h
@@ -0,0 +1,50 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_CONTENT_OBJECT_VISITOR_H_
+#define _CCNB_PARSER_CONTENT_OBJECT_VISITOR_H_
+
+#include "ccnb-parser-void-depth-first-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor that fills fields in CcnxContentObjectHeader
+ *
+ * Usage example:
+ * \code
+ *   Ptr<CcnxContentObjectHeader> header = Create<CcnxContentObjectHeader> ();
+ *   Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
+ *   ContentObjectVisitor visitor;
+ *   root->accept (visitor, *header); 
+ * \endcode
+ */
+class ContentObjectVisitor : public VoidDepthFirstVisitor
+{
+public:
+  virtual void visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/);
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_CONTENT_OBJECT_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-depth-first-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-depth-first-visitor.cc
new file mode 100644
index 0000000..514f444
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-depth-first-visitor.cc
@@ -0,0 +1,108 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-depth-first-visitor.h"
+
+#include "ns3/ccnb-parser-blob.h"
+#include "ns3/ccnb-parser-udata.h"
+#include "ns3/ccnb-parser-tag.h"
+#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/ccnb-parser-attr.h"
+#include "ns3/ccnb-parser-dattr.h"
+#include "ns3/ccnb-parser-ext.h"
+
+#include <boost/foreach.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+boost::any
+DepthFirstVisitor::visit (Blob &n, boost::any param)
+{
+  // Buffer n.m_blob;
+  return n.m_blob;
+}
+ 
+boost::any
+DepthFirstVisitor::visit (Udata &n, boost::any param)
+{
+  // std::string n.m_udata;
+  return n.m_udata;
+}
+ 
+boost::any
+DepthFirstVisitor::visit (Tag &n, boost::any param)
+{
+  // std::string n.m_tag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this, param);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this, param);
+    }
+  return boost::any();
+}
+
+boost::any
+DepthFirstVisitor::visit (Dtag &n, boost::any param)
+{
+  // std::string n.m_tag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this, param);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this, param);
+    }
+  return boost::any ();
+}
+
+boost::any
+DepthFirstVisitor::visit (Attr &n, boost::any param)
+{
+  // std::string n.m_attr;
+  // Ptr<Udata> n.m_value;
+  return boost::any ();
+}
+
+boost::any
+DepthFirstVisitor::visit (Dattr &n, boost::any param)
+{
+  // uint32_t n.m_dattr;
+  // Ptr<Udata> n.m_value;
+  return boost::any ();
+}
+ 
+boost::any
+DepthFirstVisitor::visit (Ext &n, boost::any param)
+{
+  // uint64_t n.m_extSubtype;
+  return n.m_extSubtype;
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-depth-first-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-depth-first-visitor.h
new file mode 100644
index 0000000..d68b4ad
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-depth-first-visitor.h
@@ -0,0 +1,48 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_DEPTH_FIRST_VISITOR_H_
+#define _CCNB_PARSER_DEPTH_FIRST_VISITOR_H_
+
+#include "ccnb-parser-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingrou ccnx-ccnb
+ * \brief Depth-first visitor that takes boot::any as argument and returns boost::any value
+ */
+class DepthFirstVisitor : public Visitor
+{
+public:
+  virtual boost::any visit (Blob&,  boost::any);
+  virtual boost::any visit (Udata&, boost::any);
+  virtual boost::any visit (Tag&,   boost::any);
+  virtual boost::any visit (Attr&,  boost::any);
+  virtual boost::any visit (Dtag&,  boost::any);
+  virtual boost::any visit (Dattr&, boost::any);
+  virtual boost::any visit (Ext&,   boost::any);
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_DEPTH_FIRST_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
new file mode 100644
index 0000000..70578e7
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.cc
@@ -0,0 +1,157 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-interest-visitor.h"
+
+#include "ns3/ccnb-parser-block.h"
+#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/name-components.h"
+#include "ns3/assert.h"
+#include "ns3/nstime.h"
+
+#include "ns3/ccnx-interest-header.h"
+#include "ccnb-parser-name-components-visitor.h"
+#include "ccnb-parser-non-negative-integer-visitor.h"
+#include "ccnb-parser-timestamp-visitor.h"
+#include "ccnb-parser-nonce-visitor.h"
+
+#include <boost/foreach.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+// We don't care about any other fields
+void
+InterestVisitor::visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/)
+{
+  // uint32_t n.m_dtag;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+
+  static NonNegativeIntegerVisitor nonNegativeIntegerVisitor;
+  static NameComponentsVisitor     nameComponentsVisitor;
+  static TimestampVisitor          timestampVisitor;
+  static NonceVisitor              nonceVisitor;
+  
+  CcnxInterestHeader &interest = boost::any_cast<CcnxInterestHeader&> (param);
+  
+  switch (n.m_dtag)
+    {
+    case CCN_DTAG_Interest:
+      // process nested blocks
+      BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+        {
+          block->accept (*this, param);
+        }
+      break;
+    case CCN_DTAG_Name:
+      {
+        // process name components
+        Ptr<Name::Components> name = Create<Name::Components> ();
+        
+        BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+          {
+            block->accept (nameComponentsVisitor, *name);
+          }
+        interest.SetName (name);
+        break;
+      }
+    case CCN_DTAG_MinSuffixComponents:
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+      interest.SetMinSuffixComponents (
+               boost::any_cast<uint32_t> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           nonNegativeIntegerVisitor
+                                                                           )));
+      break;
+    case CCN_DTAG_MaxSuffixComponents:
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+      interest.SetMaxSuffixComponents (
+               boost::any_cast<uint32_t> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           nonNegativeIntegerVisitor
+                                                                           )));
+      break;
+    case CCN_DTAG_Exclude:
+      {
+        // process exclude components
+        Ptr<Name::Components> exclude = Create<Name::Components> ();
+        
+        BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+          {
+            block->accept (nameComponentsVisitor, *exclude);
+          }
+        interest.SetExclude (exclude);
+        break;
+      }
+    case CCN_DTAG_ChildSelector:
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+
+      interest.SetChildSelector (
+               1 == boost::any_cast<uint32_t> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           nonNegativeIntegerVisitor
+                                                                           )));
+      break;
+    case CCN_DTAG_AnswerOriginKind:
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+      interest.SetAnswerOriginKind (
+               1 == boost::any_cast<uint32_t> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           nonNegativeIntegerVisitor
+                                                                           )));
+      break;
+    case CCN_DTAG_Scope: 
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+      interest.SetScope (
+               boost::any_cast<uint32_t> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           nonNegativeIntegerVisitor
+                                                                           )));
+      break;
+    case CCN_DTAG_InterestLifetime:
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+
+      interest.SetInterestLifetime (
+               boost::any_cast<Time> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           timestampVisitor
+                                                                           )));
+      break;
+    case CCN_DTAG_Nonce:
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+
+      interest.SetNonce (
+               boost::any_cast<uint32_t> (
+                                          (*n.m_nestedTags.begin())->accept(
+                                                                           nonceVisitor
+                                                                           )));
+      break;
+    }
+}
+
+} // namespace CcnbParser
+} // namespace ns3
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
new file mode 100644
index 0000000..136b173
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-interest-visitor.h
@@ -0,0 +1,50 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_INTEREST_VISITOR_H_
+#define _CCNB_PARSER_INTEREST_VISITOR_H_
+
+#include "ccnb-parser-void-depth-first-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor that fills fields in CcnxInterestHeader
+ *
+ * Usage example:
+ * \code
+ *   Ptr<CcnxInterestHeader> header = Create<CcnxInterestHeader> ();
+ *   Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
+ *   InterestVisitor visitor;
+ *   root->accept (visitor, *header); 
+ * \endcode
+ */
+class InterestVisitor : public VoidDepthFirstVisitor
+{
+public:
+  virtual void visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/);
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_INTEREST_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
new file mode 100644
index 0000000..3138be1
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.cc
@@ -0,0 +1,57 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-name-components-visitor.h"
+
+#include "ccnb-parser-string-visitor.h"
+#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/name-components.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+void
+NameComponentsVisitor::visit (Dtag &n, boost::any param/*should be Name::Components&*/)
+{
+  // uint32_t n.m_dtag;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  static StringVisitor stringVisitor; 
+ 
+  Name::Components &components = boost::any_cast<Name::Components&> (param);
+
+  switch (n.m_dtag)
+    {
+    case CCN_DTAG_Component:
+      if (n.m_nestedTags.size()!=1) // should be exactly one UDATA inside this tag
+        throw CcnbDecodingException ();
+      components.Add (
+                      boost::any_cast<std::string> ((*n.m_nestedTags.begin())->accept(
+                                                                                        stringVisitor
+                                                                                        )));
+      break;
+    default:
+      // ignore any other components
+      // when parsing Exclude, there could be <Any /> and <Bloom /> tags
+      break;
+    }
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
new file mode 100644
index 0000000..c68eb56
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-name-components-visitor.h
@@ -0,0 +1,43 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_NAME_COMPONENTS_VISITOR_H_
+#define _CCNB_PARSER_NAME_COMPONENTS_VISITOR_H_
+
+#include "ccnb-parser-void-depth-first-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor to obtain fill Name::Components object with name components
+ */
+class NameComponentsVisitor : public VoidDepthFirstVisitor
+{
+public:
+  virtual void visit (Dtag &n, boost::any param/*should be Name::Components&*/);
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_NAME_COMPONENTS_VISITOR_H_
+
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-no-argu-depth-first-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-depth-first-visitor.cc
new file mode 100644
index 0000000..f81a350
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-depth-first-visitor.cc
@@ -0,0 +1,108 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-no-argu-depth-first-visitor.h"
+
+#include "ns3/ccnb-parser-blob.h"
+#include "ns3/ccnb-parser-udata.h"
+#include "ns3/ccnb-parser-tag.h"
+#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/ccnb-parser-attr.h"
+#include "ns3/ccnb-parser-dattr.h"
+#include "ns3/ccnb-parser-ext.h"
+
+#include <boost/foreach.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+boost::any
+NoArguDepthFirstVisitor::visit (Blob &n)
+{
+  // Buffer n.m_blob;
+  return n.m_blob;
+}
+ 
+boost::any
+NoArguDepthFirstVisitor::visit (Udata &n)
+{
+  // std::string n.m_udata;
+  return n.m_udata;
+}
+ 
+boost::any
+NoArguDepthFirstVisitor::visit (Tag &n)
+{
+  // uint32_t n.m_dtag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this);
+    }
+  return boost::any ();
+}
+ 
+boost::any
+NoArguDepthFirstVisitor::visit (Dtag &n)
+{
+  // uint32_t n.m_dtag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this);
+    }
+  return boost::any();
+}
+ 
+boost::any
+NoArguDepthFirstVisitor::visit (Attr &n)
+{
+  // std::string n.m_attr;
+  // Ptr<Udata> n.m_value;
+  return boost::any ();
+}
+ 
+boost::any
+NoArguDepthFirstVisitor::visit (Dattr &n)
+{
+  // uint32_t n.m_dattr;
+  // Ptr<Udata> n.m_value;
+  return boost::any ();
+}
+ 
+boost::any
+NoArguDepthFirstVisitor::visit (Ext &n)
+{
+  // uint64_t n.m_extSubtype;
+  return n.m_extSubtype;
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-no-argu-depth-first-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-depth-first-visitor.h
new file mode 100644
index 0000000..1990d87
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-depth-first-visitor.h
@@ -0,0 +1,48 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_NO_ARGU_DEPTH_FIRST_VISITOR_H_
+#define _CCNB_PARSER_NO_ARGU_DEPTH_FIRST_VISITOR_H_
+
+#include "ccnb-parser-no-argu-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingrou ccnx-ccnb
+ * \brief Depth-first visitor that takes no arguments and returns boost::any value
+ */
+class NoArguDepthFirstVisitor : public NoArguVisitor
+{
+public:
+  virtual boost::any visit (Blob& );
+  virtual boost::any visit (Udata&);
+  virtual boost::any visit (Tag&  );
+  virtual boost::any visit (Attr& );
+  virtual boost::any visit (Dtag& );
+  virtual boost::any visit (Dattr&);
+  virtual boost::any visit (Ext&  );
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_NO_ARGU_DEPTH_FIRST_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-no-argu-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-visitor.h
new file mode 100644
index 0000000..3e1750f
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-no-argu-visitor.h
@@ -0,0 +1,52 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_NO_ARGU_VISITOR_H_
+#define _CCNB_PARSER_NO_ARGU_VISITOR_H_
+
+#include "ns3/ccnb-parser-commoh.h"
+#include <boost/any.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor interface that takes no arguments and returns boost::any
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ * for ccnb encoding format help
+ */
+class NoArguVisitor
+{
+public:
+  virtual boost::any visit (Blob& )=0; ///< \brief Method accepting BLOB block  
+  virtual boost::any visit (Udata&)=0; ///< \brief Method accepting UDATA block 
+  virtual boost::any visit (Tag&  )=0; ///< \brief Method accepting TAG block   
+  virtual boost::any visit (Attr& )=0; ///< \brief Method accepting ATTR block  
+  virtual boost::any visit (Dtag& )=0; ///< \brief Method accepting DTAG block  
+  virtual boost::any visit (Dattr&)=0; ///< \brief Method accepting DATTR block 
+  virtual boost::any visit (Ext&  )=0; ///< \brief Method accepting EXT block
+};
+  
+}
+}
+
+#endif // _CCNB_PARSER_NO_ARGU_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-non-negative-integer-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-non-negative-integer-visitor.cc
new file mode 100644
index 0000000..e393770
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-non-negative-integer-visitor.cc
@@ -0,0 +1,51 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-non-negative-integer-visitor.h"
+
+#include "ns3/ccnb-parser-blob.h"
+#include "ns3/ccnb-parser-udata.h"
+#include <sstream>
+
+namespace ns3 {
+namespace CcnbParser {
+
+boost::any
+NonNegativeIntegerVisitor::visit (Blob &n) //to throw parsing error
+{
+  // Buffer n.m_blob;
+  throw CcnbDecodingException ();
+}
+
+boost::any
+NonNegativeIntegerVisitor::visit (Udata &n)
+{
+  // std::string n.m_udata;
+  std::istringstream is (n.m_udata);
+  int32_t value;
+  is >> value;
+  if (value<0) // value should be non-negative
+    throw CcnbDecodingException ();
+
+  return static_cast<uint32_t> (value);
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-non-negative-integer-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-non-negative-integer-visitor.h
new file mode 100644
index 0000000..7ecc3a9
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-non-negative-integer-visitor.h
@@ -0,0 +1,45 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_NON_NEGATIVE_INTEGER_VISITOR_H_
+#define _CCNB_PARSER_NON_NEGATIVE_INTEGER_VISITOR_H_
+
+#include "ccnb-parser-no-argu-depth-first-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor to obtain non-negative integer value from UDATA block
+ *
+ * Will return empty boost::any() if called on anything except UDATA block
+ */
+class NonNegativeIntegerVisitor : public NoArguDepthFirstVisitor
+{
+public:
+  virtual boost::any visit (Blob &n); ///< Throws an exception if BLOB object is encountered
+  virtual boost::any visit (Udata &n);
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_NON_NEGATIVE_INTEGER_VISITOR_H_
diff --git a/in-progress/ccn/ccn_name_util.h b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
similarity index 61%
copy from in-progress/ccn/ccn_name_util.h
copy to helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
index 6e5fda7..7492adf 100644
--- a/in-progress/ccn/ccn_name_util.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.cc
@@ -15,5 +15,31 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
+
+#include "ccnb-parser-nonce-visitor.h"
+#include "ns3/ccnb-parser-blob.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+boost::any
+NonceVisitor::visit (Blob &n) 
+{
+  // Buffer n.m_blob;
+  if (n.m_blob.GetSize ()<4)
+    throw CcnbDecodingException ();
+     
+  return boost::any (n.m_blob.Begin ().ReadU32 ());
+}
+
+boost::any
+NonceVisitor::visit (Udata &n)
+{
+  // std::string n.m_udata;
+  throw CcnbDecodingException ();
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.h
new file mode 100644
index 0000000..c4912aa
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-nonce-visitor.h
@@ -0,0 +1,48 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_NONCE_VISITOR_H_
+#define _CCNB_PARSER_NONCE_VISITOR_H_
+
+#include "ccnb-parser-no-argu-depth-first-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor to obtain nonce value from BLOB block
+ *
+ * Note, only first 32 bits will be actually parsed into nonce. If
+ * original Nonce contains more, the rest will be ignored
+ *
+ * Will return empty boost::any() if called on anything except BLOB block
+ */
+class NonceVisitor : public NoArguDepthFirstVisitor
+{
+public:
+  virtual boost::any visit (Blob &n); 
+  virtual boost::any visit (Udata &n); ///< Throws parsing error if BLOB object is encountered
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_NONCE_VISITOR_H_
diff --git a/in-progress/ccn/ccn_name_util.h b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
similarity index 66%
copy from in-progress/ccn/ccn_name_util.h
copy to helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
index 6e5fda7..33c9465 100644
--- a/in-progress/ccn/ccn_name_util.h
+++ b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.cc
@@ -15,5 +15,28 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
+
+#include "ccnb-parser-string-visitor.h"
+#include "ns3/ccnb-parser-udata.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+boost::any
+StringVisitor::visit (Blob &n) 
+{
+  // Buffer n.m_blob;
+  throw CcnbDecodingException ();
+}
+
+boost::any
+StringVisitor::visit (Udata &n)
+{
+  // std::string n.m_udata;
+  return n.m_udata;
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
new file mode 100644
index 0000000..b2a2a29
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-string-visitor.h
@@ -0,0 +1,45 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_STRING_VISITOR_H_
+#define _CCNB_PARSER_STRING_VISITOR_H_
+
+#include "ccnb-parser-no-argu-depth-first-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor to obtain string value from UDATA block
+ *
+ * Will return empty boost::any() if called on anything except UDATA block
+ */
+class StringVisitor : public NoArguDepthFirstVisitor
+{
+public:
+  virtual boost::any visit (Blob &n); ///< Throws parsing error if BLOB object is encountered
+  virtual boost::any visit (Udata &n);
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_STRING_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
new file mode 100644
index 0000000..4724bb4
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.cc
@@ -0,0 +1,63 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-timestamp-visitor.h"
+#include "ns3/ccnb-parser-blob.h"
+
+#include "ns3/nstime.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+boost::any/*Time*/
+TimestampVisitor::visit (Blob &n) 
+{
+  // Buffer n.m_blob;
+  if (n.m_blob.GetSize ()<2)
+    throw CcnbDecodingException ();
+
+  Buffer::Iterator start = n.m_blob.Begin ();
+  
+  intmax_t seconds = 0;
+  intmax_t nanoseconds = 0;
+
+  for (uint32_t i=0; i < n.m_blob.GetSize ()-2; i++)
+    {
+      seconds = (seconds << 8) | start.ReadU8 ();
+    }
+  uint8_t combo = start.ReadU8 (); // 4 most significant bits hold 4 least significant bits of number of seconds
+  seconds = (seconds << 8) | (combo >> 4);
+
+  nanoseconds = combo & 0x0F; /*00001111*/ // 4 least significant bits hold 4 most significant bits of number of
+  nanoseconds = (nanoseconds << 8) | start.ReadU8 ();
+  nanoseconds = (intmax_t) ((nanoseconds / 4096.0/*2^12*/) * 1000000000 /*up-convert nanoseconds*/);
+
+  return boost::any (Time::FromInteger (seconds, Time::S) + Time::FromInteger (nanoseconds, Time::NS));
+}
+
+boost::any
+TimestampVisitor::visit (Udata &n)
+{
+  // std::string n.m_udata;
+  throw CcnbDecodingException ();
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.h
new file mode 100644
index 0000000..ff7e8c8
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-timestamp-visitor.h
@@ -0,0 +1,45 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_TIMESTAMP_VISITOR_H_
+#define _CCNB_PARSER_TIMESTAMP_VISITOR_H_
+
+#include "ccnb-parser-no-argu-depth-first-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor to obtain timestamp value from BLOB block
+ *
+ * Will return empty boost::any() if called on anything except BLOB block
+ */
+class TimestampVisitor : public NoArguDepthFirstVisitor
+{
+public:
+  virtual boost::any visit (Blob &n); 
+  virtual boost::any/*Time*/ visit (Udata &n); ///< Throws parsing error if UDATA object is encountered
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_TIMESTAMP_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-visitor.h
new file mode 100644
index 0000000..aa6911b
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-visitor.h
@@ -0,0 +1,52 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_VISITOR_H_
+#define _CCNB_PARSER_VISITOR_H_
+
+#include "ns3/ccnb-parser-commoh.h"
+#include <boost/any.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor interface that takes one boost::any argument and returns boost::any
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ * for ccnb encoding format help
+ */
+class Visitor
+{
+public:
+  virtual boost::any visit (Blob&,  boost::any)=0; ///< \brief Method accepting BLOB block  
+  virtual boost::any visit (Udata&, boost::any)=0; ///< \brief Method accepting UDATA block 
+  virtual boost::any visit (Tag&,   boost::any)=0; ///< \brief Method accepting TAG block   
+  virtual boost::any visit (Attr&,  boost::any)=0; ///< \brief Method accepting ATTR block  
+  virtual boost::any visit (Dtag&,  boost::any)=0; ///< \brief Method accepting DTAG block  
+  virtual boost::any visit (Dattr&, boost::any)=0; ///< \brief Method accepting DATTR block 
+  virtual boost::any visit (Ext&,   boost::any)=0; ///< \brief Method accepting EXT block
+};                                                
+                                                  
+}                                                 
+}                                                 
+                                                  
+#endif // _CCNB_PARSER_VISITOR_H_                             
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-depth-first-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-void-depth-first-visitor.cc
new file mode 100644
index 0000000..1c9a28a
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-depth-first-visitor.cc
@@ -0,0 +1,101 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-void-depth-first-visitor.h"
+
+#include "ns3/ccnb-parser-blob.h"
+#include "ns3/ccnb-parser-udata.h"
+#include "ns3/ccnb-parser-tag.h"
+#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/ccnb-parser-attr.h"
+#include "ns3/ccnb-parser-dattr.h"
+#include "ns3/ccnb-parser-ext.h"
+
+#include <boost/foreach.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+void
+VoidDepthFirstVisitor::visit (Blob &n, boost::any param)
+{
+  // Buffer n.m_blob;
+}
+ 
+void
+VoidDepthFirstVisitor::visit (Udata &n, boost::any param)
+{
+  // std::string n.m_udata;
+}
+ 
+void
+VoidDepthFirstVisitor::visit (Tag &n, boost::any param)
+{
+  // std::string n.m_tag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this, param);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this, param);
+    }
+}
+ 
+void
+VoidDepthFirstVisitor::visit (Dtag &n, boost::any param)
+{
+  // std::string n.m_tag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this, param);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this, param);
+    }
+}
+ 
+void
+VoidDepthFirstVisitor::visit (Attr &n, boost::any param)
+{
+  // std::string n.m_attr;
+  // Ptr<Udata> n.m_value;
+}
+ 
+void
+VoidDepthFirstVisitor::visit (Dattr &n, boost::any param)
+{
+  // uint32_t n.m_dattr;
+  // Ptr<Udata> n.m_value;
+}
+ 
+void
+VoidDepthFirstVisitor::visit (Ext &n, boost::any param)
+{
+  // uint64_t n.m_extSubtype;
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-depth-first-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-void-depth-first-visitor.h
new file mode 100644
index 0000000..f2b78e3
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-depth-first-visitor.h
@@ -0,0 +1,48 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_VOID_DEPTH_FIRST_VISITOR_H_
+#define _CCNB_PARSER_VOID_DEPTH_FIRST_VISITOR_H_
+
+#include "ccnb-parser-void-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingrou ccnx-ccnb
+ * \brief Depth-first visitor that takes one argument and returns nothing
+ */
+class VoidDepthFirstVisitor : public VoidVisitor
+{
+public:
+  virtual void visit (Blob&,  boost::any);
+  virtual void visit (Udata&, boost::any);
+  virtual void visit (Tag&,   boost::any);
+  virtual void visit (Attr&,  boost::any);
+  virtual void visit (Dtag&,  boost::any);
+  virtual void visit (Dattr&, boost::any);
+  virtual void visit (Ext&,   boost::any);
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_VOID_DEPTH_FIRST_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-depth-first-visitor.cc b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-depth-first-visitor.cc
new file mode 100644
index 0000000..1944b2a
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-depth-first-visitor.cc
@@ -0,0 +1,101 @@
+/* -*- 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>
+ */
+
+#include "ccnb-parser-void-no-argu-depth-first-visitor.h"
+
+#include "ns3/ccnb-parser-blob.h"
+#include "ns3/ccnb-parser-udata.h"
+#include "ns3/ccnb-parser-tag.h"
+#include "ns3/ccnb-parser-dtag.h"
+#include "ns3/ccnb-parser-attr.h"
+#include "ns3/ccnb-parser-dattr.h"
+#include "ns3/ccnb-parser-ext.h"
+
+#include <boost/foreach.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+void
+VoidNoArguDepthFirstVisitor::visit (Blob &n)
+{
+  // Buffer n.m_blob;
+}
+ 
+void
+VoidNoArguDepthFirstVisitor::visit (Udata &n)
+{
+  // std::string n.m_udata;
+}
+ 
+void
+VoidNoArguDepthFirstVisitor::visit (Tag &n)
+{
+  // std::string n.m_tag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this);
+    }
+}
+ 
+void
+VoidNoArguDepthFirstVisitor::visit (Dtag &n)
+{
+  // uint32_t n.m_dtag;
+  // std::list<Ptr<Block> > n.m_attrs;
+  // std::list<Ptr<Block> > n.m_nestedBlocks;
+  BOOST_FOREACH (Ptr<Block> block, n.m_attrs)
+    {
+      block->accept (*this);
+    }
+  BOOST_FOREACH (Ptr<Block> block, n.m_nestedTags)
+    {
+      block->accept (*this);
+    }
+}
+ 
+void
+VoidNoArguDepthFirstVisitor::visit (Attr &n)
+{
+  // std::string n.m_attr;
+  // Ptr<Udata> n.m_value;
+}
+ 
+void
+VoidNoArguDepthFirstVisitor::visit (Dattr &n)
+{
+  // uint32_t n.m_dattr;
+  // Ptr<Udata> n.m_value;
+}
+ 
+void
+VoidNoArguDepthFirstVisitor::visit (Ext &n)
+{
+  // uint64_t n.m_extSubtype;
+}
+
+}
+}
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-depth-first-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-depth-first-visitor.h
new file mode 100644
index 0000000..9237c2c
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-depth-first-visitor.h
@@ -0,0 +1,48 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_VOID_NO_ARGU_DEPTH_FIRST_VISITOR_H_
+#define _CCNB_PARSER_VOID_NO_ARGU_DEPTH_FIRST_VISITOR_H_
+
+#include "ccnb-parser-void-no-argu-visitor.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingrou ccnx-ccnb
+ * \brief Depth-first visitor that takes no arguments and returns nothing
+ */
+class VoidNoArguDepthFirstVisitor : public VoidNoArguVisitor
+{
+public:
+  virtual void visit (Blob& );
+  virtual void visit (Udata&);
+  virtual void visit (Tag&  );
+  virtual void visit (Attr& );
+  virtual void visit (Dtag& );
+  virtual void visit (Dattr&);
+  virtual void visit (Ext&  );
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_VOID_NO_ARGU_DEPTH_FIRST_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-visitor.h
new file mode 100644
index 0000000..5941350
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-no-argu-visitor.h
@@ -0,0 +1,51 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_VOID_NO_ARGU_VISITOR_H_
+#define _CCNB_PARSER_VOID_NO_ARGU_VISITOR_H_
+
+#include "ns3/ccnb-parser-commoh.h"
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor interface that takes no arguments and returns nothing
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ * for ccnb encoding format help
+ */
+class VoidNoArguVisitor
+{
+public:
+  virtual void visit (Blob& )=0; ///< \brief Method accepting BLOB block
+  virtual void visit (Udata&)=0; ///< \brief Method accepting UDATA block
+  virtual void visit (Tag&  )=0; ///< \brief Method accepting TAG block
+  virtual void visit (Attr& )=0; ///< \brief Method accepting ATTR block
+  virtual void visit (Dtag& )=0; ///< \brief Method accepting DTAG block
+  virtual void visit (Dattr&)=0; ///< \brief Method accepting DATTR block
+  virtual void visit (Ext&  )=0; ///< \brief Method accepting EXT block
+};
+  
+}
+}
+
+#endif // _CCNB_PARSER_VOID_NO_ARGU_VISITOR_H_
diff --git a/helper/ccnb-parser/visitors/ccnb-parser-void-visitor.h b/helper/ccnb-parser/visitors/ccnb-parser-void-visitor.h
new file mode 100644
index 0000000..9ef1e3c
--- /dev/null
+++ b/helper/ccnb-parser/visitors/ccnb-parser-void-visitor.h
@@ -0,0 +1,52 @@
+/* -*- 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>
+ */
+
+#ifndef _CCNB_PARSER_VOID_VISITOR_H_
+#define _CCNB_PARSER_VOID_VISITOR_H_
+
+#include "ns3/ccnb-parser-commoh.h"
+#include <boost/any.hpp>
+
+namespace ns3 {
+namespace CcnbParser {
+
+/**
+ * \ingroup ccnx-ccnb
+ * \brief Visitor interface that takes one boost::any argument and returns nothing
+ *
+ * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+ * for ccnb encoding format help
+ */
+class VoidVisitor
+{
+public:
+  virtual void visit (Blob&,  boost::any)=0; ///< \brief Method accepting BLOB block  
+  virtual void visit (Udata&, boost::any)=0; ///< \brief Method accepting UDATA block 
+  virtual void visit (Tag&,   boost::any)=0; ///< \brief Method accepting TAG block   
+  virtual void visit (Attr&,  boost::any)=0; ///< \brief Method accepting ATTR block  
+  virtual void visit (Dtag&,  boost::any)=0; ///< \brief Method accepting DTAG block  
+  virtual void visit (Dattr&, boost::any)=0; ///< \brief Method accepting DATTR block 
+  virtual void visit (Ext&,   boost::any)=0; ///< \brief Method accepting EXT block
+};
+
+}
+}
+
+#endif // _CCNB_PARSER_VOID_VISITOR_H_
diff --git a/helper/ccnx-decoding-helper.cc b/helper/ccnx-decoding-helper.cc
index 0dabb66..1ebb0e8 100644
--- a/helper/ccnx-decoding-helper.cc
+++ b/helper/ccnx-decoding-helper.cc
@@ -20,25 +20,23 @@
 
 #include "ccnx-decoding-helper.h"
 
-#include "ns3/ccnx.h"
-#include "ns3/name-components.h"
 #include "ns3/ccnx-interest-header.h"
 #include "ns3/ccnx-content-object-header.h"
 
-#include <sstream>
-#include <boost/foreach.hpp>
+#include "ns3/ccnb-parser-interest-visitor.h"
+#include "ns3/ccnb-parser-content-object-visitor.h"
+#include "ns3/ccnb-parser-block.h"
 
 namespace ns3 {
 
-CcnxParser::InterestVisitor CcnxDecodingHelper::m_interestVisitor;
-CcnxParser::ContentObjectVisitor CcnxDecodingHelper::m_contentObjectVisitor;
-
 size_t
 CcnxDecodingHelper::Deserialize (Buffer::Iterator start, const CcnxInterestHeader &interest)
 {
+  static CcnbParser::InterestVisitor interestVisitor;
+
   Buffer::Iterator i = start;
-  Ptr<CcnxParser::Block> root = CcnxParser::Block::ParseBlock (i);
-  root->accept (m_interestVisitor, interest);
+  Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
+  root->accept (interestVisitor, interest);
 
   return i.GetDistanceFrom (start);
 }
@@ -46,622 +44,13 @@
 size_t
 CcnxDecodingHelper::Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject)
 {
+  static CcnbParser::ContentObjectVisitor contentObjectVisitor;
+
   Buffer::Iterator i = start;
-  Ptr<CcnxParser::Block> root = CcnxParser::Block::ParseBlock (i);
-  root->accept (m_contentObjectVisitor, contentObject);
+  Ptr<CcnbParser::Block> root = CcnbParser::Block::ParseBlock (i);
+  root->accept (contentObjectVisitor, contentObject);
 
   return i.GetDistanceFrom (start);
 }
 
-
-//////////////////////////////////////////////////////////////////////
-
-const uint8_t CCN_TT_BITS = 3;
-const uint8_t CCN_TT_MASK = ((1 << CCN_TT_BITS) - 1);
-const uint8_t CCN_MAX_TINY= ((1 << (7-CCN_TT_BITS)) - 1);
-const uint8_t CCN_TT_HBIT = ((uint8_t)(1 << 7));
-
-namespace CcnxParser {
-
-Ptr<Block> Block::ParseBlock (Buffer::Iterator &start)
-{
-  uint32_t value = 0;
-
-  // We will have problems if length field is more than 32 bits. Though it's really impossible
-  uint8_t byte = 0;
-  while (!(byte & CCN_TT_HBIT))
-    {
-      value <<= 8;
-      value += byte;
-      byte = start.ReadU8 ();
-    }
-  value <<= 4;
-  value += ( (byte&(~CCN_TT_HBIT)) >> 3);
-
-  switch (byte & CCN_TT_MASK)
-    {
-    case Ccnx::CCN_BLOB:
-      return Create<Blob> (start, value);
-    case Ccnx::CCN_UDATA:
-      return Create<Udata> (start, value);
-    case Ccnx::CCN_TAG:
-      return Create<Tag> (start, value);
-    case Ccnx::CCN_ATTR:
-      return Create<Attr> (start, value);
-    case Ccnx::CCN_DTAG:
-      return Create<Dtag> (start, value);
-    case Ccnx::CCN_DATTR:
-      return Create<Dattr> (start, value);
-    case Ccnx::CCN_EXT:
-      return Create<Ext> (start, value);
-    default:
-      throw CcnxDecodingException ();
-    }
-}
-
-Blob::Blob (Buffer::Iterator &start, uint32_t length)
-{
-  start.Read (m_blob.Begin (), length);
-}
-
-Udata::Udata (Buffer::Iterator &start, uint32_t length)
-{
-  // Ideally, the code should look like this. Unfortunately, we don't have normal compatible iterators
-  // Buffer::Iterator realStart = start;
-  // start.Next (length); // advancing forward
-  // m_udata.assign (realStart, start/*actually, it is the end*/);
-
-  m_udata.reserve (length+1); //just in case we will need \0 at the end later
-  // this is actually the way Read method is implemented in network/src/buffer.cc
-  for (uint32_t i = 0; i < length; i++)
-    {
-      m_udata.push_back (start.ReadU8 ());
-    }
-}
-
-// length length in octets of UTF-8 encoding of tag name - 1 (minimum tag name length is 1) 
-Tag::Tag (Buffer::Iterator &start, uint32_t length)
-{
-  m_tag.reserve (length+2); // extra byte for potential \0 at the end
-  for (uint32_t i = 0; i < (length+1); i++)
-    {
-      m_tag.push_back (start.ReadU8 ());
-    }
-  
-  while (!start.IsEnd () && start.PeekU8 ()!=Ccnx::CCN_CLOSE)
-    {
-      m_nestedBlocks.push_back (Block::ParseBlock (start));
-    }
-  if (start.IsEnd ())
-      throw CcnxDecodingException ();
-
-  start.ReadU8 (); // read CCN_CLOSE
-}
-
-// length length in octets of UTF-8 encoding of tag name - 1 (minimum tag name length is 1) 
-Attr::Attr (Buffer::Iterator &start, uint32_t length)
-{
-  m_attr.reserve (length+2); // extra byte for potential \0 at the end
-  for (uint32_t i = 0; i < (length+1); i++)
-    {
-      m_attr.push_back (start.ReadU8 ());
-    }
-  m_value = DynamicCast<Udata> (Block::ParseBlock (start));
-  if (m_value == 0)
-    throw CcnxDecodingException (); // "ATTR must be followed by UDATA field"
-}
-
-Dtag::Dtag (Buffer::Iterator &start, uint32_t dtag)
-{
-  m_dtag = dtag;
-
-  /**
-   * Hack
-   *
-   * Stop processing after encountering <Content> dtag.  Actual
-   * content (including virtual payload) will be stored in Packet
-   * buffer
-   */
-  if (dtag == Ccnx::CCN_DTAG_Content)
-    return; // hack #1. Do not process nesting block for <Content>
-  
-  while (!start.IsEnd () && start.PeekU8 ()!=Ccnx::CCN_CLOSE)
-    {
-      m_nestedBlocks.push_back (Block::ParseBlock (start));
-
-      // hack #2. Stop processing nested blocks if last block was <Content>
-      if (m_dtag == Ccnx::CCN_DTAG_ContentObject && // we are in <ContentObject>
-          DynamicCast<Dtag> (m_nestedBlocks.back())!=0 && // last block is DTAG
-          DynamicCast<Dtag> (m_nestedBlocks.back())->m_dtag == Ccnx::CCN_DTAG_Content) 
-        {
-          return; 
-        }
-    }
-  if (start.IsEnd ())
-      throw CcnxDecodingException ();
-
-  start.ReadU8 (); // read CCN_CLOSE
-}
-
-// dictionary attributes are not used (yet?) in CCNx 
-Dattr::Dattr (Buffer::Iterator &start, uint32_t dattr)
-{
-  m_dattr = dattr;
-  m_value = DynamicCast<Udata> (Block::ParseBlock (start));
-  if (m_value == 0)
-    throw CcnxDecodingException (); // "ATTR must be followed by UDATA field"
-}
-
-Ext::Ext (Buffer::Iterator &start, uint32_t extSubtype)
-{
-  m_extSubtype = extSubtype;
-}
-
-void
-DepthFirstVisitor::visit (Blob &n)
-{
-  // Buffer n.m_blob;
-}
- 
-void
-DepthFirstVisitor::visit (Udata &n)
-{
-  // std::string n.m_udata;
-}
- 
-void
-DepthFirstVisitor::visit (Tag &n)
-{
-  // std::string n.m_tag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this);
-    }
-}
- 
-void
-DepthFirstVisitor::visit (Attr &n)
-{
-  // std::string n.m_attr;
-  // Ptr<Udata> n.m_value;
-}
- 
-void
-DepthFirstVisitor::visit (Dtag &n)
-{
-  // uint32_t n.m_dtag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this);
-    }
-}
- 
-void
-DepthFirstVisitor::visit (Dattr &n)
-{
-  // uint32_t n.m_dattr;
-  // Ptr<Udata> n.m_value;
-}
- 
-void
-DepthFirstVisitor::visit (Ext &n)
-{
-  // uint64_t n.m_extSubtype;
-}
-
-//////////////////////////////////////////////////////////////////////
- 
-boost::any
-GJNoArguDepthFirstVisitor::visit (Blob &n)
-{
-  // Buffer n.m_blob;
-  return n.m_blob;
-}
- 
-boost::any
-GJNoArguDepthFirstVisitor::visit (Udata &n)
-{
-  // std::string n.m_udata;
-  return n.m_udata;
-}
- 
-boost::any
-GJNoArguDepthFirstVisitor::visit (Tag &n)
-{
-  // std::string n.m_tag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this);
-    }
-  return boost::any();
-}
- 
-boost::any
-GJNoArguDepthFirstVisitor::visit (Attr &n)
-{
-  // std::string n.m_attr;
-  // Ptr<Udata> n.m_value;
-  return boost::any(
-                    std::pair<std::string,std::string> (
-                                                        n.m_attr,
-                                                        boost::any_cast<std::string> (n.m_value->accept (*this))
-                                                        ));
-}
- 
-boost::any
-GJNoArguDepthFirstVisitor::visit (Dtag &n)
-{
-  // uint32_t n.m_dtag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this);
-    }
-  return boost::any();
-}
- 
-boost::any
-GJNoArguDepthFirstVisitor::visit (Dattr &n)
-{
-  // uint32_t n.m_dattr;
-  // Ptr<Udata> n.m_value;
-  return boost::any(
-                    std::pair<uint32_t,std::string> (
-                                                     n.m_dattr,
-                                                     boost::any_cast<std::string> (n.m_value->accept (*this))
-                                                     ));
-}
- 
-boost::any
-GJNoArguDepthFirstVisitor::visit (Ext &n)
-{
-  // uint64_t n.m_extSubtype;
-  return n.m_extSubtype;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-void
-GJVoidDepthFirstVisitor::visit (Blob &n, boost::any param)
-{
-  // Buffer n.m_blob;
-}
- 
-void
-GJVoidDepthFirstVisitor::visit (Udata &n, boost::any param)
-{
-  // std::string n.m_udata;
-}
- 
-void
-GJVoidDepthFirstVisitor::visit (Tag &n, boost::any param)
-{
-  // std::string n.m_tag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this, param);
-    }
-}
- 
-void
-GJVoidDepthFirstVisitor::visit (Attr &n, boost::any param)
-{
-  // std::string n.m_attr;
-  // Ptr<Udata> n.m_value;
-}
- 
-void
-GJVoidDepthFirstVisitor::visit (Dtag &n, boost::any param)
-{
-  // uint32_t n.m_dtag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this, param);
-    }
-}
- 
-void
-GJVoidDepthFirstVisitor::visit (Dattr &n, boost::any param)
-{
-  // uint32_t n.m_dattr;
-  // Ptr<Udata> n.m_value;
-}
- 
-void
-GJVoidDepthFirstVisitor::visit (Ext &n, boost::any param)
-{
-  // uint64_t n.m_extSubtype;
-}
-
-//////////////////////////////////////////////////////////////////////
- 
-boost::any
-GJDepthFirstVisitor::visit (Blob &n, boost::any param)
-{
-  // Buffer n.m_blob;
-  return n.m_blob;
-}
- 
-boost::any
-GJDepthFirstVisitor::visit (Udata &n, boost::any param)
-{
-  // std::string n.m_udata;
-  return n.m_udata;
-}
- 
-boost::any
-GJDepthFirstVisitor::visit (Tag &n, boost::any param)
-{
-  // std::string n.m_tag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this, param);
-    }
-  return boost::any();
-}
- 
-boost::any
-GJDepthFirstVisitor::visit (Attr &n, boost::any param)
-{
-  // std::string n.m_attr;
-  // Ptr<Udata> n.m_value;
-  return boost::any(
-                    std::pair<std::string,std::string> (
-                                                        n.m_attr,
-                                                        boost::any_cast<std::string> (n.m_value->accept (*this,param))
-                                                        ));
-}
- 
-boost::any
-GJDepthFirstVisitor::visit (Dtag &n, boost::any param)
-{
-  // uint32_t n.m_dtag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-    {
-      block->accept (*this, param);
-    }
-  return boost::any();
-}
- 
-boost::any
-GJDepthFirstVisitor::visit (Dattr &n, boost::any param)
-{
-  // uint32_t n.m_dattr;
-  // Ptr<Udata> n.m_value;
-  return boost::any(
-                    std::pair<uint32_t,std::string> (
-                                                     n.m_dattr,
-                                                     boost::any_cast<std::string> (n.m_value->accept (*this,param))
-                                                     ));
-}
- 
-boost::any
-GJDepthFirstVisitor::visit (Ext &n, boost::any param)
-{
-  // uint64_t n.m_extSubtype;
-  return n.m_extSubtype;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-boost::any
-NonNegativeIntegerVisitor::visit (Blob &n) //to throw parsing error
-{
-  // Buffer n.m_blob;
-  throw CcnxDecodingException ();
-}
-
-boost::any
-NonNegativeIntegerVisitor::visit (Udata &n)
-{
-  // std::string n.m_udata;
-  std::istringstream is (n.m_udata);
-  int32_t value;
-  is >> value;
-  if (value<0) // value should be non-negative
-    throw CcnxDecodingException ();
-
-  return static_cast<uint32_t> (value);
-}
-
-
-//////////////////////////////////////////////////////////////////////
-
-boost::any
-StringVisitor::visit (Blob &n) //to throw parsing error
-{
-  // Buffer n.m_blob;
-  throw CcnxDecodingException ();
-}
-
-boost::any
-StringVisitor::visit (Udata &n)
-{
-  // std::string n.m_udata;
-  return n.m_udata;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-StringVisitor NameComponentsVisitor::m_stringVisitor; 
-
-void
-NameComponentsVisitor::visit (Dtag &n, boost::any param/*should be Name::Components&*/)
-{
-  // uint32_t n.m_dtag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  Name::Components &components = boost::any_cast<Name::Components&> (param);
-
-  switch (n.m_dtag)
-    {
-    case Ccnx::CCN_DTAG_Component:
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-      components.Add (
-                      boost::any_cast<std::string> ((*n.m_nestedBlocks.begin())->accept(
-                                                                                        m_stringVisitor
-                                                                                        )));
-      break;
-    default:
-      // ignore any other components
-      // when parsing Exclude, there could be <Any /> and <Bloom /> tags
-      break;
-    }
-}
- 
-//////////////////////////////////////////////////////////////////////
-
-NonNegativeIntegerVisitor InterestVisitor::m_nonNegativeIntegerVisitor;
-NameComponentsVisitor     InterestVisitor::m_nameComponentsVisitor;
-
-// We don't really care about any other fields
-void
-InterestVisitor::visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/)
-{
-  // uint32_t n.m_dtag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  CcnxInterestHeader &interest = boost::any_cast<CcnxInterestHeader&> (param);
-  
-  switch (n.m_dtag)
-    {
-    case Ccnx::CCN_DTAG_Interest:
-      // process nested blocks
-      BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-        {
-          block->accept (*this, param);
-        }
-      break;
-    case Ccnx::CCN_DTAG_Name:
-      {
-        // process name components
-        Ptr<Name::Components> name = Create<Name::Components> ();
-        
-        BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-          {
-            block->accept (m_nameComponentsVisitor, *name);
-          }
-        interest.SetName (name);
-        break;
-      }
-    case Ccnx::CCN_DTAG_MinSuffixComponents:
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-      interest.SetMinSuffixComponents (
-               boost::any_cast<uint32_t> (
-                                          (*n.m_nestedBlocks.begin())->accept(
-                                                                           m_nonNegativeIntegerVisitor
-                                                                           )));
-      break;
-    case Ccnx::CCN_DTAG_MaxSuffixComponents:
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-      interest.SetMaxSuffixComponents (
-               boost::any_cast<uint32_t> (
-                                          (*n.m_nestedBlocks.begin())->accept(
-                                                                           m_nonNegativeIntegerVisitor
-                                                                           )));
-      break;
-    case Ccnx::CCN_DTAG_Exclude:
-      {
-        // process exclude components
-        Ptr<Name::Components> exclude = Create<Name::Components> ();
-        
-        BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-          {
-            block->accept (m_nameComponentsVisitor, *exclude);
-          }
-        interest.SetExclude (exclude);
-        break;
-      }
-    case Ccnx::CCN_DTAG_ChildSelector:
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-
-      interest.SetChildSelector (
-               1 == boost::any_cast<uint32_t> (
-                                          (*n.m_nestedBlocks.begin())->accept(
-                                                                           m_nonNegativeIntegerVisitor
-                                                                           )));
-      break;
-    case Ccnx::CCN_DTAG_AnswerOriginKind:
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-      interest.SetAnswerOriginKind (
-               1 == boost::any_cast<uint32_t> (
-                                          (*n.m_nestedBlocks.begin())->accept(
-                                                                           m_nonNegativeIntegerVisitor
-                                                                           )));
-      break;
-    case Ccnx::CCN_DTAG_Scope: 
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-      interest.SetScope (
-               boost::any_cast<uint32_t> (
-                                          (*n.m_nestedBlocks.begin())->accept(
-                                                                           m_nonNegativeIntegerVisitor
-                                                                           )));
-      break;
-    case Ccnx::CCN_DTAG_InterestLifetime:
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-      break;
-    case Ccnx::CCN_DTAG_Nonce:
-      if (n.m_nestedBlocks.size()!=1) // should be exactly one UDATA inside this tag
-        throw CcnxDecodingException ();
-      break;
-    }
-}
-
-//////////////////////////////////////////////////////////////////////
-
-NameComponentsVisitor ContentObjectVisitor::m_nameComponentsVisitor;
-
-// We don't really care about any other fields
-void
-ContentObjectVisitor::visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/)
-{
-  // uint32_t n.m_dtag;
-  // std::list<Ptr<Block> > n.m_nestedBlocks;
-  CcnxContentObjectHeader &contentObject = boost::any_cast<CcnxContentObjectHeader&> (param);
-  
-  switch (n.m_dtag)
-    {
-    case Ccnx::CCN_DTAG_ContentObject:
-      // process nested blocks
-      BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-        {
-          block->accept (*this, param);
-        }
-      break;
-    case Ccnx::CCN_DTAG_Name:
-      {
-        // process name components
-        Ptr<Name::Components> name = Create<Name::Components> ();
-        
-        BOOST_FOREACH (Ptr<Block> block, n.m_nestedBlocks)
-          {
-            block->accept (m_nameComponentsVisitor, *name);
-          }
-        contentObject.SetName (name);
-        break;
-      }
-    case Ccnx::CCN_DTAG_Signature: // ignoring
-      break;
-    case Ccnx::CCN_DTAG_SignedInfo: // ignoring
-      break;
-    case Ccnx::CCN_DTAG_Content: // !!! HACK
-      // This hack was necessary for memory optimizations (i.e., content is virtual payload)
-      NS_ASSERT_MSG (n.m_nestedBlocks.size() == 0, "Parser should have stopped just after processing <Content> tag");
-      break;
-    }
-}
-
-} // namespace CcnxParser
 } // namespace ns3
diff --git a/helper/ccnx-decoding-helper.h b/helper/ccnx-decoding-helper.h
index e89766c..2e41769 100644
--- a/helper/ccnx-decoding-helper.h
+++ b/helper/ccnx-decoding-helper.h
@@ -15,37 +15,22 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: 
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
 
 #ifndef _CCNX_DECODING_HELPER_H_
 #define _CCNX_DECODING_HELPER_H_
 
-#include <sys/types.h>
-#include <boost/any.hpp>
-#include <list>
-
-#include "ns3/ptr.h"
-#include "ns3/nstime.h"
+#include <cstring>
 #include "ns3/buffer.h"
-#include "ns3/simple-ref-count.h"
-
 
 namespace ns3 {
 
-namespace Name{ class Components; }
-
 class CcnxInterestHeader;
 class CcnxContentObjectHeader;
 
-namespace CcnxParser {
-class InterestVisitor;
-class ContentObjectVisitor;
-}
-
 /**
- * Helper to encode/decode ccnb formatted CCNx message
- *
+ * \brief Helper class to decode ccnb formatted CCNx message
  */
 class CcnxDecodingHelper
 {
@@ -57,276 +42,8 @@
   Deserialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
   
 private:
-  static CcnxParser::InterestVisitor m_interestVisitor;
-  static CcnxParser::ContentObjectVisitor m_contentObjectVisitor;
 };
 
-namespace CcnxParser {
-
-class Block;
-class Blob;
-class Udata;
-class Tag;
-class Attr;
-class Dtag;
-class Dattr;
-class Ext;
-
-class Visitor
-{
-public:
-  virtual void visit (Blob& )=0;
-  virtual void visit (Udata&)=0;
-  virtual void visit (Tag&  )=0;
-  virtual void visit (Attr& )=0;
-  virtual void visit (Dtag& )=0;
-  virtual void visit (Dattr&)=0;
-  virtual void visit (Ext&  )=0;
-};
-  
-class GJVisitor
-{
-public:
-  virtual boost::any visit (Blob&,  boost::any)=0;
-  virtual boost::any visit (Udata&, boost::any)=0;
-  virtual boost::any visit (Tag&,   boost::any)=0;
-  virtual boost::any visit (Attr&,  boost::any)=0;
-  virtual boost::any visit (Dtag&,  boost::any)=0;
-  virtual boost::any visit (Dattr&, boost::any)=0;
-  virtual boost::any visit (Ext&,   boost::any)=0;
-};
-  
-class GJNoArguVisitor
-{
-public:
-  virtual boost::any visit (Blob& )=0;
-  virtual boost::any visit (Udata&)=0;
-  virtual boost::any visit (Tag&  )=0;
-  virtual boost::any visit (Attr& )=0;
-  virtual boost::any visit (Dtag& )=0;
-  virtual boost::any visit (Dattr&)=0;
-  virtual boost::any visit (Ext&  )=0;
-};
-
-class GJVoidVisitor
-{
-public:
-  virtual void visit (Blob&,  boost::any)=0;
-  virtual void visit (Udata&, boost::any)=0;
-  virtual void visit (Tag&,   boost::any)=0;
-  virtual void visit (Attr&,  boost::any)=0;
-  virtual void visit (Dtag&,  boost::any)=0;
-  virtual void visit (Dattr&, boost::any)=0;
-  virtual void visit (Ext&,   boost::any)=0;
-};
-
-class Block : public SimpleRefCount<Block>
-{
-public:
-  /**
-   * Parsing block header and creating an appropriate object
-   */
-  static Ptr<Block>
-  ParseBlock (Buffer::Iterator &start);
-  
-  virtual void accept( Visitor &v )                           =0;
-  virtual void accept (GJVoidVisitor &v, boost::any param)    =0;
-  virtual boost::any accept( GJNoArguVisitor &v )             =0;
-  virtual boost::any accept( GJVisitor &v, boost::any param ) =0;
-};
-
-class Blob : public Block
-{
-public:
-  Blob (Buffer::Iterator &start, uint32_t length);
-  
-  virtual void accept( Visitor &v )                           { v.visit( *this ); }
-  virtual void accept( GJVoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
-  virtual boost::any accept( GJNoArguVisitor &v )             { return v.visit( *this ); }
-  virtual boost::any accept( GJVisitor &v, boost::any param ) { return v.visit( *this, param ); }
-
-  Buffer m_blob;
-};
-
-class Udata : public Block
-{
-public:
-  Udata (Buffer::Iterator &start, uint32_t length);
-  
-  virtual void accept( Visitor &v )                           { v.visit( *this ); }
-  virtual void accept( GJVoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
-  virtual boost::any accept( GJNoArguVisitor &v )             { return v.visit( *this ); }
-  virtual boost::any accept( GJVisitor &v, boost::any param ) { return v.visit( *this, param ); }
-
-  std::string m_udata;
-};
-
-class Tag : public Block
-{
-public:
-  Tag (Buffer::Iterator &start, uint32_t length);
-
-  virtual void accept( Visitor &v )                           { v.visit( *this ); }
-  virtual void accept( GJVoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
-  virtual boost::any accept( GJNoArguVisitor &v )             { return v.visit( *this ); }
-  virtual boost::any accept( GJVisitor &v, boost::any param ) { return v.visit( *this, param ); }
-
-  std::string m_tag;
-  std::list<Ptr<Block> > m_nestedBlocks;
-};
-
-class Attr : public Block
-{
-public:
-  Attr (Buffer::Iterator &start, uint32_t length);
-  
-  virtual void accept( Visitor &v )                           { v.visit( *this ); }
-  virtual void accept( GJVoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
-  virtual boost::any accept( GJNoArguVisitor &v )             { return v.visit( *this ); }
-  virtual boost::any accept( GJVisitor &v, boost::any param ) { return v.visit( *this, param ); }
-
-  std::string m_attr;
-  Ptr<Udata> m_value;
-};
-
-class Dtag : public Block
-{
-public:
-  Dtag (Buffer::Iterator &start, uint32_t dtag);
-
-  virtual void accept( Visitor &v )                           { v.visit( *this ); }
-  virtual void accept( GJVoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
-  virtual boost::any accept( GJNoArguVisitor &v )             { return v.visit( *this ); }
-  virtual boost::any accept( GJVisitor &v, boost::any param ) { return v.visit( *this, param ); }
-
-  uint32_t m_dtag;
-  std::list<Ptr<Block> > m_nestedBlocks;
-};
-
-class Dattr : public Block
-{
-public:
-  Dattr (Buffer::Iterator &start, uint32_t dattr);
-
-  virtual void accept( Visitor &v )                           { v.visit( *this ); }
-  virtual void accept( GJVoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
-  virtual boost::any accept( GJNoArguVisitor &v )             { return v.visit( *this ); }
-  virtual boost::any accept( GJVisitor &v, boost::any param ) { return v.visit( *this, param ); }
-
-  uint32_t m_dattr;
-  Ptr<Udata> m_value;
-};
-
-class Ext : public Block
-{
-public:
-  Ext (Buffer::Iterator &start, uint32_t extSubtype);
-
-  virtual void accept( Visitor &v )                           { v.visit( *this ); }
-  virtual void accept( GJVoidVisitor &v, boost::any param )   { v.visit( *this, param ); }
-  virtual boost::any accept( GJNoArguVisitor &v )             { return v.visit( *this ); }
-  virtual boost::any accept( GJVisitor &v, boost::any param ) { return v.visit( *this, param ); }
-
-  uint64_t m_extSubtype;
-};
-
-class DepthFirstVisitor : public Visitor
-{
-public:
-  virtual void visit (Blob& );
-  virtual void visit (Udata&);
-  virtual void visit (Tag&  );
-  virtual void visit (Attr& );
-  virtual void visit (Dtag& );
-  virtual void visit (Dattr&);
-  virtual void visit (Ext&  );
-};
-
-class GJDepthFirstVisitor : public GJVisitor
-{
-public:
-  virtual boost::any visit (Blob&,  boost::any);
-  virtual boost::any visit (Udata&, boost::any);
-  virtual boost::any visit (Tag&,   boost::any);
-  virtual boost::any visit (Attr&,  boost::any);
-  virtual boost::any visit (Dtag&,  boost::any);
-  virtual boost::any visit (Dattr&, boost::any);
-  virtual boost::any visit (Ext&,   boost::any);
-};
-
-class GJNoArguDepthFirstVisitor : public GJNoArguVisitor
-{
-public:
-  virtual boost::any visit (Blob& );
-  virtual boost::any visit (Udata&);
-  virtual boost::any visit (Tag&  );
-  virtual boost::any visit (Attr& );
-  virtual boost::any visit (Dtag& );
-  virtual boost::any visit (Dattr&);
-  virtual boost::any visit (Ext&  );
-};
-
-class GJVoidDepthFirstVisitor : public GJVoidVisitor
-{
-public:
-  virtual void visit (Blob&,  boost::any);
-  virtual void visit (Udata&, boost::any);
-  virtual void visit (Tag&,   boost::any);
-  virtual void visit (Attr&,  boost::any);
-  virtual void visit (Dtag&,  boost::any);
-  virtual void visit (Dattr&, boost::any);
-  virtual void visit (Ext&,   boost::any);
-};
-
-// class NameComponentsVisitor : public 
-
-class NonNegativeIntegerVisitor : public GJNoArguDepthFirstVisitor
-{
-public:
-  virtual boost::any visit (Blob &n); //to throw parsing error
-  virtual boost::any visit (Udata &n);
-};
-
-class StringVisitor : public GJNoArguDepthFirstVisitor
-{
-public:
-  virtual boost::any visit (Blob &n); //to throw parsing error
-  virtual boost::any visit (Udata &n);
-};
-
-class NameComponentsVisitor : public GJVoidDepthFirstVisitor
-{
-public:
-  virtual void visit (Dtag &n, boost::any param/*should be Name::Components*/);
-private:
-  static StringVisitor m_stringVisitor; 
-};
-
-class InterestVisitor : public GJVoidDepthFirstVisitor
-{
-public:
-  virtual void visit (Dtag &n, boost::any param/*should be CcnxInterestHeader&*/);
-  
-private:
-  static NonNegativeIntegerVisitor m_nonNegativeIntegerVisitor;
-  static NameComponentsVisitor     m_nameComponentsVisitor;
-};
-
-class ContentObjectVisitor : public GJVoidDepthFirstVisitor
-{
-public:
-  virtual void visit (Dtag &n, boost::any param/*should be CcnxContentObjectHeader&*/);
-  
-private:
-  static NameComponentsVisitor     m_nameComponentsVisitor;
-};
-
-
-class CcnxDecodingException {};
-
-} // namespace CcnxParser
-
 } // namespace ns3
 
 #endif // _CCNX_DECODING_HELPER_H_
-
diff --git a/helper/ccnx-encoding-helper.cc b/helper/ccnx-encoding-helper.cc
index 21ca9ae..7783d7a 100644
--- a/helper/ccnx-encoding-helper.cc
+++ b/helper/ccnx-encoding-helper.cc
@@ -35,17 +35,17 @@
 #define CCN_TT_HBIT ((unsigned char)(1 << 7))
 
 size_t
-CcnxEncodingHelper::AppendBlockHeader (Buffer::Iterator start, size_t val, Ccnx::ccn_tt tt)
+CcnxEncodingHelper::AppendBlockHeader (Buffer::Iterator start, size_t val, CcnbParser::ccn_tt tt)
 {
   unsigned char buf[1+8*((sizeof(val)+6)/7)];
   unsigned char *p = &(buf[sizeof(buf)-1]);
   size_t n = 1;
-  p[0] = (CCN_TT_HBIT & ~Ccnx::CCN_CLOSE) |
+  p[0] = (CCN_TT_HBIT & ~CcnbParser::CCN_CLOSE) |
   ((val & CCN_MAX_TINY) << CCN_TT_BITS) |
   (CCN_TT_MASK & tt);
   val >>= (7-CCN_TT_BITS);
   while (val != 0) {
-    (--p)[0] = (((unsigned char)val) & ~CCN_TT_HBIT) | Ccnx::CCN_CLOSE;
+    (--p)[0] = (((unsigned char)val) & ~CCN_TT_HBIT) | CcnbParser::CCN_CLOSE;
     n++;
     val >>= 7;
   }
@@ -60,7 +60,7 @@
   os << number;
 
   size_t written = 0;
-  written += AppendBlockHeader (start, os.str().size(), Ccnx::CCN_UDATA);
+  written += AppendBlockHeader (start, os.str().size(), CcnbParser::CCN_UDATA);
   written += os.str().size();
   start.Write (reinterpret_cast<const unsigned char*>(os.str().c_str()), os.str().size());
 
@@ -71,7 +71,7 @@
 size_t
 CcnxEncodingHelper::CcnxEncodingHelper::AppendCloser (Buffer::Iterator start)
 {
-  start.WriteU8 (Ccnx::CCN_CLOSE);
+  start.WriteU8 (CcnbParser::CCN_CLOSE);
   return 1;
 }
 
@@ -81,7 +81,7 @@
   size_t written = 0;
   BOOST_FOREACH (const std::string &component, name.GetComponents())
     {
-      written += AppendTaggedBlob (start, Ccnx::CCN_DTAG_Component,
+      written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Component,
                                    reinterpret_cast<const uint8_t*>(component.c_str()), component.size());
     }
   return written;
@@ -98,7 +98,7 @@
   for (;  required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
      required_bytes++;
   
-  size_t len = AppendBlockHeader(start, required_bytes, Ccnx::CCN_BLOB);
+  size_t len = AppendBlockHeader(start, required_bytes, CcnbParser::CCN_BLOB);
 
   // write part with seconds
   ts = time.ToInteger (Time::S) >> 4;
@@ -114,13 +114,13 @@
 }
 
 size_t
-CcnxEncodingHelper::AppendTaggedBlob (Buffer::Iterator start, Ccnx::ccn_dtag dtag,
+CcnxEncodingHelper::AppendTaggedBlob (Buffer::Iterator start, CcnbParser::ccn_dtag dtag,
                   const uint8_t *data, size_t size)
 {
-  size_t written = AppendBlockHeader (start, dtag, Ccnx::CCN_DTAG);
+  size_t written = AppendBlockHeader (start, dtag, CcnbParser::CCN_DTAG);
   if (size>0)
     {
-      written += AppendBlockHeader (start, size, Ccnx::CCN_BLOB);
+      written += AppendBlockHeader (start, size, CcnbParser::CCN_BLOB);
       start.Write (data, size);
       written += size;
     }
@@ -134,58 +134,58 @@
 CcnxEncodingHelper::Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest)
 {
   size_t written = 0;
-  written += AppendBlockHeader (start, Ccnx::CCN_DTAG_Interest, Ccnx::CCN_DTAG); // <Interest>
+  written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Interest, CcnbParser::CCN_DTAG); // <Interest>
   
-  written += AppendBlockHeader (start, Ccnx::CCN_DTAG_Name, Ccnx::CCN_DTAG); // <Name>
+  written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG); // <Name>
   written += AppendNameComponents (start, interest.GetName());                // <Component>...</Component>...
   written += AppendCloser (start);                               // </Name>
 
   if (interest.GetMinSuffixComponents() >= 0)
     {
-      written += AppendBlockHeader (start, Ccnx::CCN_DTAG_MinSuffixComponents, Ccnx::CCN_DTAG);
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_MinSuffixComponents, CcnbParser::CCN_DTAG);
       written += AppendNumber (start, interest.GetMinSuffixComponents ());
       written += AppendCloser (start);
     }
   if (interest.GetMaxSuffixComponents() >= 0)
     {
-      written += AppendBlockHeader (start, Ccnx::CCN_DTAG_MaxSuffixComponents, Ccnx::CCN_DTAG);
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_MaxSuffixComponents, CcnbParser::CCN_DTAG);
       written += AppendNumber (start, interest.GetMaxSuffixComponents ());
       written += AppendCloser (start);
     }
   if (interest.GetExclude().size() > 0)
     {
-      written += AppendBlockHeader (start, Ccnx::CCN_DTAG_Exclude, Ccnx::CCN_DTAG); // <Exclude>
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Exclude, CcnbParser::CCN_DTAG); // <Exclude>
       written += AppendNameComponents (start, interest.GetExclude());                // <Component>...</Component>...
       written += AppendCloser (start);                                  // </Exclude>
     }
   if (interest.IsEnabledChildSelector())
     {
-      written += AppendBlockHeader (start, Ccnx::CCN_DTAG_ChildSelector, Ccnx::CCN_DTAG);
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_ChildSelector, CcnbParser::CCN_DTAG);
       written += AppendNumber (start, 1);
       written += AppendCloser (start);
     }
   if (interest.IsEnabledAnswerOriginKind())
     {
-      written += AppendBlockHeader (start, Ccnx::CCN_DTAG_AnswerOriginKind, Ccnx::CCN_DTAG);
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_AnswerOriginKind, CcnbParser::CCN_DTAG);
       written += AppendNumber (start, 1);
       written += AppendCloser (start);
     }
   if (interest.GetScope() >= 0)
     {
-      written += AppendBlockHeader (start, Ccnx::CCN_DTAG_Scope, Ccnx::CCN_DTAG);
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Scope, CcnbParser::CCN_DTAG);
       written += AppendNumber (start, interest.GetScope ());
       written += AppendCloser (start);
     }
   if (!interest.GetInterestLifetime().IsZero())
     {
-      written += AppendBlockHeader (start, Ccnx::CCN_DTAG_InterestLifetime, Ccnx::CCN_DTAG);
+      written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_InterestLifetime, CcnbParser::CCN_DTAG);
       written += AppendTimestampBlob (start, interest.GetInterestLifetime());
       written += AppendCloser (start);
     }
   if (interest.GetNonce()>0)
     {
       uint32_t nonce = interest.GetNonce();
-      written += AppendTaggedBlob (start, Ccnx::CCN_DTAG_Nonce,
+      written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_Nonce,
                                    reinterpret_cast<const uint8_t*>(&nonce),
                                    sizeof(nonce));
     }
@@ -198,32 +198,32 @@
 CcnxEncodingHelper::Serialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject)
 {
   size_t written = 0;
-  written += AppendBlockHeader (start, Ccnx::CCN_DTAG_ContentObject, Ccnx::CCN_DTAG); // <ContentObject>
+  written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_ContentObject, CcnbParser::CCN_DTAG); // <ContentObject>
 
   // fake signature
-  written += AppendBlockHeader (start, Ccnx::CCN_DTAG_Signature, Ccnx::CCN_DTAG); // <Signature>
+  written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Signature, CcnbParser::CCN_DTAG); // <Signature>
   // Signature ::= DigestAlgorithm? 
   //               Witness?         
   //               SignatureBits   
-  written += AppendTaggedBlob (start, Ccnx::CCN_DTAG_SignatureBits, 0, 0);      // <SignatureBits />
+  written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_SignatureBits, 0, 0);      // <SignatureBits />
   written += AppendCloser (start);                                    // </Signature>  
 
-  written += AppendBlockHeader (start, Ccnx::CCN_DTAG_Name, Ccnx::CCN_DTAG);    // <Name>
+  written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Name, CcnbParser::CCN_DTAG);    // <Name>
   written += AppendNameComponents (start, contentObject.GetName()); //   <Component>...</Component>...
   written += AppendCloser (start);                                  // </Name>  
 
   // fake signature
-  written += AppendBlockHeader (start, Ccnx::CCN_DTAG_SignedInfo, Ccnx::CCN_DTAG); // <SignedInfo>
+  written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_SignedInfo, CcnbParser::CCN_DTAG); // <SignedInfo>
   // SignedInfo ::= PublisherPublicKeyDigest
   //                Timestamp
   //                Type?
   //                FreshnessSeconds?
   //                FinalBlockID?
   //                KeyLocator?
-  written += AppendTaggedBlob (start, Ccnx::CCN_DTAG_PublisherPublicKeyDigest, 0, 0); // <PublisherPublicKeyDigest />
+  written += AppendTaggedBlob (start, CcnbParser::CCN_DTAG_PublisherPublicKeyDigest, 0, 0); // <PublisherPublicKeyDigest />
   written += AppendCloser (start);                                     // </SignedInfo>
 
-  written += AppendBlockHeader (start, Ccnx::CCN_DTAG_Content, Ccnx::CCN_DTAG); // <Content>
+  written += AppendBlockHeader (start, CcnbParser::CCN_DTAG_Content, CcnbParser::CCN_DTAG); // <Content>
 
   // there is no closing tag !!!
   return written;
diff --git a/helper/ccnx-encoding-helper.h b/helper/ccnx-encoding-helper.h
index 90fad22..da5066a 100644
--- a/helper/ccnx-encoding-helper.h
+++ b/helper/ccnx-encoding-helper.h
@@ -23,7 +23,7 @@
 
 #include <sys/types.h>
 
-#include "ns3/ccnx.h"
+#include "ns3/ccnb-parser-common.h"
 #include "ns3/ptr.h"
 #include "ns3/nstime.h"
 #include "ns3/buffer.h"
@@ -50,7 +50,7 @@
 
 private:
   static size_t
-  AppendBlockHeader (Buffer::Iterator start, size_t value, Ccnx::ccn_tt block_type);
+  AppendBlockHeader (Buffer::Iterator start, size_t value, CcnbParser::ccn_tt block_type);
 
   static size_t
   AppendNumber (Buffer::Iterator start, uint32_t number);
@@ -86,7 +86,7 @@
    * @returns written length
    */
   static size_t
-  AppendTaggedBlob (Buffer::Iterator start, Ccnx::ccn_dtag dtag,
+  AppendTaggedBlob (Buffer::Iterator start, CcnbParser::ccn_dtag dtag,
                     const uint8_t *data, size_t size);
   
 };
diff --git a/helper/ccnx-face-container.cc b/helper/ccnx-face-container.cc
index 956614d..ce595bb 100644
--- a/helper/ccnx-face-container.cc
+++ b/helper/ccnx-face-container.cc
@@ -19,8 +19,7 @@
  */
 
 #include "ccnx-face-container.h"
-// #include "ns3/node-list.h"
-// #include "ns3/names.h"
+
 #include <algorithm>
 
 #include "ns3/ccnx-face.h"
@@ -47,6 +46,12 @@
 
   
 void
+CcnxFaceContainer::AddAll (Ptr<CcnxFaceContainer> other)
+{
+  AddAll (*other);
+}
+
+void
 CcnxFaceContainer::AddAll (const CcnxFaceContainer &other)
 {
   m_faces.insert (m_faces.end (),
diff --git a/helper/ccnx-face-container.h b/helper/ccnx-face-container.h
index 4426449..ecb29d9 100644
--- a/helper/ccnx-face-container.h
+++ b/helper/ccnx-face-container.h
@@ -23,20 +23,24 @@
 
 #include <stdint.h>
 #include <vector>
-#include "ns3/ccnx.h"
+
+#include "ns3/ptr.h"
+#include "ns3/simple-ref-count.h"
 
 namespace ns3 {
 
+class CcnxFace;
+
 /**
- * \ingroup ccnx
+ * \ingroup ccnx-helpers
  * \brief A pool for CCNx faces
  * 
  * Provides tools to perform basic manipulation on faces, such as
  * setting metrics and states on faces
  *
- * \see Ccnx
+ * \see CcnxStackHelper
  */
-class CcnxFaceContainer
+class CcnxFaceContainer : public SimpleRefCount<CcnxFaceContainer>
 {
 private:
   typedef std::vector<Ptr<CcnxFace> > FaceContainer;
@@ -67,6 +71,13 @@
   /**
    * \brief Add all entries from other container
    *
+   * \param other smart pointer to a container
+   */
+  void AddAll (Ptr<CcnxFaceContainer> other);
+
+  /**
+   * \brief Add all entries from other container
+   *
    * \param other container
    */
   void AddAll (const CcnxFaceContainer &other);
diff --git a/helper/ccnx-forwarding-helper.h b/helper/ccnx-forwarding-helper.h
index a7d0bf8..8ac041e 100644
--- a/helper/ccnx-forwarding-helper.h
+++ b/helper/ccnx-forwarding-helper.h
@@ -30,13 +30,11 @@
 class Node;
 
 /**
+ * \ingroup ccnx-helpers
+ *
  * \brief a factory to create ns3::CcnxForwardingStrategy objects
  *
- * For each new forwarding protocol created as a subclass of 
- * ns3::CcnxForwardingStrategy, you need to create a subclass of 
- * ns3::CcnxForwardingHelper which can be used by 
- * ns3::InternetStackHelper::SetForwardingHelper and 
- * ns3::InternetStackHelper::Install.
+ * \todo Document this class
  */
 class CcnxForwardingHelper
 {
@@ -53,7 +51,7 @@
    * This method is mainly for internal use by the other helpers;
    * clients are expected to free the dynamic memory allocated by this method
    */
-  virtual CcnxForwardingHelper* Copy (void) const = 0;
+  virtual CcnxForwardingHelper* Copy () const = 0;
 
   /**
    * \param node the node within which the new forwarding protocol will run
diff --git a/helper/ccnx-header-helper.h b/helper/ccnx-header-helper.h
index 35aeab8..72d030c 100644
--- a/helper/ccnx-header-helper.h
+++ b/helper/ccnx-header-helper.h
@@ -30,7 +30,9 @@
 class Packet;
 
 /**
- * Class implementing functionality to detect CCNx packet type and
+ * \ingroup ccnx-helpers
+ *
+ * \brief Class implementing functionality to detect CCNx packet type and
  * create the corresponding object
  *
  * CCNx doesn't really have a header, so we need this class to
@@ -68,6 +70,15 @@
   CreateCorrectCcnxHeader (Ptr<const Packet> packet);
 };
 
+  /**
+   * \ingroup ccnx
+   * \defgroup ccnx-exceptions Exceptions
+   */
+  /**
+   * \ingroup ccnx-exceptions
+   * \brief Exception thrown if CCNx stack receives unrecognized
+   * message type
+   */
 class CcnxUnknownHeaderException {};
 
 } // namespace ns3
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 50839a3..d59827e 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -1,4 +1,4 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
 /*
  * Copyright (c) 2011 UCLA
  *
@@ -15,7 +15,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * Author: 
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
 
 /**
@@ -67,7 +67,10 @@
 #include "ns3/node.h"
 #include "ns3/core-config.h"
 #include "ns3/ccnx-forwarding-strategy.h"
+#include "ns3/ccnx-net-device-face.h"
+#include "ns3/ccnx-l3-protocol.h"
 
+#include "ccnx-face-container.h"
 #include "ccnx-stack-helper.h"
 #include "ccnx-forwarding-helper.h"
 
@@ -175,19 +178,21 @@
   m_ccnxEnabled = enable;
 }
 
-void 
+Ptr<CcnxFaceContainer>
 CcnxStackHelper::Install (NodeContainer c) const
 {
+  Ptr<CcnxFaceContainer> faces = Create<CcnxFaceContainer> ();
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Install (*i);
+      faces->AddAll (Install (*i));
     }
+  return faces;
 }
 
-void 
+Ptr<CcnxFaceContainer>
 CcnxStackHelper::InstallAll (void) const
 {
-  Install (NodeContainer::GetGlobal ());
+  return Install (NodeContainer::GetGlobal ());
 }
 
 void
@@ -199,10 +204,11 @@
   node->AggregateObject (protocol);
 }
 
-void
+Ptr<CcnxFaceContainer>
 CcnxStackHelper::Install (Ptr<Node> node) const
 {
-  NS_ASSERT_MSG (m_forwarding, "CcnxForwarding should be set prior calling Install() method");
+  // NS_ASSERT_MSG (m_forwarding, "SetForwardingHelper() should be set prior calling Install() method");
+  Ptr<CcnxFaceContainer> faces = Create<CcnxFaceContainer> ();
   
   if (m_ccnxEnabled)
     {
@@ -210,22 +216,32 @@
         {
           NS_FATAL_ERROR ("CcnxStackHelper::Install (): Installing " 
                           "a CcnxStack to a node with an existing Ccnx object");
-          return;
+          return 0;
         }
 
       CreateAndAggregateObjectFromTypeId (node, "ns3::CcnxL3Protocol");
       // Set forwarding
       Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
-      Ptr<CcnxForwardingStrategy> ccnxForwarding = m_forwarding->Create (node);
-      ccnx->SetForwardingStrategy (ccnxForwarding);
+      for (uint32_t index=0; index < node->GetNDevices (); index++)
+        {
+          Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node->GetDevice (index));
+          uint32_t __attribute__ ((unused)) face_id = ccnx->AddFace (face);
+          NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcxnNetDeviceFace as face #" << face_id);
+
+          faces->Add (face);
+        }
+      // Ptr<CcnxForwardingStrategy> ccnxForwarding = m_forwarding->Create (node);
+      // ccnx->SetForwardingStrategy (ccnxForwarding);
     }
+
+  return faces;
 }
 
-void
+Ptr<CcnxFaceContainer>
 CcnxStackHelper::Install (std::string nodeName) const
 {
   Ptr<Node> node = Names::Find<Node> (nodeName);
-  Install (node);
+  return Install (node);
 }
 
 static void
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index 3d0b3a4..7308241 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -21,12 +21,9 @@
 #ifndef CCNX_STACK_HELPER_H
 #define CCNX_STACK_HELPER_H
 
-#include "ns3/node-container.h"
-#include "ns3/net-device-container.h"
 #include "ns3/packet.h"
 #include "ns3/ptr.h"
 #include "ns3/object-factory.h"
-#include "ns3/ccnx-l3-protocol.h"
 
 #include "ccnx-trace-helper.h"
 
@@ -34,8 +31,14 @@
 
 class Node;
 class CcnxForwardingHelper;
+class CcnxFaceContainer;
 
 /**
+ * \ingroup ccnx
+ * \defgroup ccnx-helpers Helpers
+ */
+/**
+ * \ingroup ccnx-helpers
  * \brief Adding CCNx functionality to existing Nodes.
  *
  * This helper enables pcap and ascii tracing of events in the ccnx stack
@@ -55,25 +58,27 @@
 {
 public:
   /**
-   * Create a new CcnxStackHelper which <empty> forwarding by default.
+   * \brief Create a new CcnxStackHelper which <empty> forwarding by default.
    *
    * \todo set non-empty default forwarding
    */
   CcnxStackHelper ();
 
   /**
-   * Destroy the CcnxStackHelper
+   * \brief Destroy the CcnxStackHelper
    */
   virtual ~CcnxStackHelper ();
   CcnxStackHelper (const CcnxStackHelper &);
   CcnxStackHelper &operator = (const CcnxStackHelper &o);
 
   /**
-   * Return helper internal state to that of a newly constructed one
+   * \brief Return helper internal state to that of a newly constructed one
    */
   void Reset ();
 
   /**
+   * Set forwarding strategy helper
+   *
    * \param forwarding a new forwarding helper
    *
    * Set the forwarding helper to use during Install. The forwarding helper is
@@ -81,50 +86,68 @@
    * ns3::CcnxFrProtocol per node. This forwarding object is then associated to
    * a single ns3::Ccnx object through its ns3::Ccnx::SetforwardingProtocol.
    */
-  void SetForwardingHelper (const CcnxForwardingHelper &forwarding);
+  void
+  SetForwardingHelper (const CcnxForwardingHelper &forwarding);
 
   /**
-   * Install CCNx stack on the node
+   * \brief Install CCNx stack on the node
    *
    * This method will assert if called on a node that already has Ccnx object
    * installed on it
    * 
    * \param nodeName The name of the node on which to install the stack.
+   *
+   * \returns list of installed faces in the form of a smart pointer
+   * to CcnxFaceContainer object
    */
-  void Install (std::string nodeName) const;
+  Ptr<CcnxFaceContainer>
+  Install (std::string nodeName) const;
 
   /**
-   * Install CCNx stack on the node
+   * \brief Install CCNx stack on the node
    *
    * This method will assert if called on a node that already has Ccnx object
    * installed on it
    * 
    * \param node The node on which to install the stack.
+   *
+   * \returns list of installed faces in the form of a smart pointer
+   * to CcnxFaceContainer object
    */
-  void Install (Ptr<Node> node) const;
+  Ptr<CcnxFaceContainer>
+  Install (Ptr<Node> node) const;
 
   /**
-   * Install CCNx stack on each node in the input container
+   * \brief Install CCNx stack on each node in the input container
    *
    * The program will assert if this method is called on a container with a node
    * that already has an ccnx object aggregated to it.
    * 
    * \param c NodeContainer that holds the set of nodes on which to install the
    * new stacks.
+   *
+   * \returns list of installed faces in the form of a smart pointer
+   * to CcnxFaceContainer object
    */
-  void Install (NodeContainer c) const;
+  Ptr<CcnxFaceContainer>
+  Install (NodeContainer c) const;
 
   /**
-   * Install CCNx stack on all nodes in the simulation
+   * \brief Install CCNx stack on all nodes in the simulation
+   *
+   * \returns list of installed faces in the form of a smart pointer
+   * to CcnxFaceContainer object
    */
-  void 
+  Ptr<CcnxFaceContainer>
   InstallAll () const;
 
   /**
    * \brief Enable/disable ccnx stack install.
+   *
    * \param enable enable state
    */
-  void SetCcnxStackInstall (bool enable);
+  void
+  SetCcnxStackInstall (bool enable);
 
 private:
   /**
diff --git a/helper/ccnx-trace-helper.h b/helper/ccnx-trace-helper.h
index a0390e7..49ad8e0 100644
--- a/helper/ccnx-trace-helper.h
+++ b/helper/ccnx-trace-helper.h
@@ -14,6 +14,8 @@
  * 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
+ *
+ * Authors: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
 
 #ifndef CCNX_TRACE_HELPER_H
@@ -27,6 +29,8 @@
 namespace ns3 {
 
 /**
+ * \ingroup ccnx-helpers
+ *
  * @brief Base class providing common user-level pcap operations for helpers
  * representing Ccnx protocols .
  */
@@ -119,6 +123,8 @@
 };
 
 /**
+ * \ingroup ccnx-helpers
+ *
  * @brief Base class providing common user-level ascii trace operations for 
  * helpers representing Ccnx protocols .
  */
diff --git a/in-progress/ccn/README b/in-progress/ccn/README
deleted file mode 100644
index 6b9ef69..0000000
--- a/in-progress/ccn/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory contains files borrowed and adapted from CCNx implementation
-
diff --git a/in-progress/ccn/ccn.h b/in-progress/ccn/ccn.h
deleted file mode 100644
index af9dcae..0000000
--- a/in-progress/ccn/ccn.h
+++ /dev/null
@@ -1,407 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/*
- *  ccn_ccn.h
- *  Abstraction
- *
- *  Created by Ilya on 7/29/11.
- *  Copyright 2011 __MyCompanyName__. All rights reserved.
- *
- */
-
-#ifndef CCN_CCN_DEFINED
-#define CCN_CCN_DEFINED
-
-#include <stdint.h>
-#include "ccn_coding.h"
-#include "ccn_charbuf.h"
-#include "ccn_indexbuf.h"
-
-/***********************************
- * Writing Names
- * Names for interests are constructed in charbufs using 
- * the following routines.
- */
-
-/*
- * ccn_name_init: reset charbuf to represent an empty Name in binary format
- * Return value is 0, or -1 for error.
- */
-int ccn_name_init(struct ccn_charbuf *c);
-
-/*
- * ccn_name_append: add a Component to a Name
- * The component is an arbitrary string of n octets, no escaping required.
- * Return value is 0, or -1 for error.
- */
-int ccn_name_append(struct ccn_charbuf *c, const void *component, size_t n);
-
-/*
- * ccn_name_append_str: add a Component that is a \0 terminated string.
- * The component added is the bytes of the string without the \0.
- * This function is convenient for those applications that construct 
- * component names from simple strings.
- * Return value is 0, or -1 for error
- */
-int ccn_name_append_str(struct ccn_charbuf *c, const char *s);
-
-/*
- * ccn_name_append_components: add sequence of ccnb-encoded Components
- *    to a ccnb-encoded Name
- * start and stop are offsets from ccnb
- * Return value is 0, or -1 for obvious error
- */
-int ccn_name_append_components(struct ccn_charbuf *c,
-                               const unsigned char *ccnb,
-                               size_t start, size_t stop);
-
-enum ccn_marker {
-    CCN_MARKER_NONE = -1,
-    CCN_MARKER_SEQNUM  = 0x00, /**< consecutive block sequence numbers */
-    CCN_MARKER_CONTROL = 0xC1, /**< commands, etc. */ 
-    CCN_MARKER_OSEQNUM = 0xF8, /**< deprecated */
-    CCN_MARKER_BLKID   = 0xFB, /**< nonconsecutive block ids */
-    CCN_MARKER_VERSION = 0xFD  /**< timestamp-based versioning */
-};
-
-/*
- * ccn_name_append_numeric: add binary Component to ccnb-encoded Name
- * These are special components used for marking versions, fragments, etc.
- * Return value is 0, or -1 for error
- * see doc/technical/NameConventions.html
- */
-int ccn_name_append_numeric(struct ccn_charbuf *c,
-                            enum ccn_marker tag, uintmax_t value);
-
-/*
- * ccn_name_append_nonce: add nonce Component to ccnb-encoded Name
- * Uses %C1.N.n marker.
- * see doc/technical/NameConventions.html
- */
-int ccn_name_append_nonce(struct ccn_charbuf *c);
-
-/*
- * ccn_name_split: find Component boundaries in a ccnb-encoded Name
- * Thin veneer over ccn_parse_Name().
- * returns -1 for error, otherwise the number of Components
- * components arg may be NULL to just do a validity check
- */
-int ccn_name_split(const struct ccn_charbuf *c,
-                   struct ccn_indexbuf* components);
-
-/*
- * ccn_name_chop: Chop the name down to n components.
- * returns -1 for error, otherwise the new number of Components
- * components arg may be NULL; if provided it must be consistent with
- * some prefix of the name, and is updated accordingly.
- * n may be negative to say how many components to remove instead of how
- * many to leave, e.g. -1 will remove just the last component.
- */
-int ccn_name_chop(struct ccn_charbuf *c,
-                  struct ccn_indexbuf* components, int n);
-
-
-
-
-/*********** Interest parsing ***********/
-
-/*
- * The parse of an interest results in an array of offsets into the 
- * wire representation, with the start and end of each major element and
- * a few of the inportant sub-elements.  The following enum allows those
- * array items to be referred to symbolically.  The *_B_* indices correspond
- * to beginning offsets and the *_E_* indices correspond to ending offsets.
- * An omitted element has its beginning and ending offset equal to each other.
- * Normally these offsets will end up in non-decreasing order.
- * Some aliasing tricks may be played here, e.g. since
- * offset[CCN_PI_E_ComponentLast] is always equal to
- * offset[CCN_PI_E_LastPrefixComponent],
- * we may define CCN_PI_E_ComponentLast = CCN_PI_E_LastPrefixComponent.
- * However, code should not rely on that,
- * since it may change from time to time as the
- * interest schema evolves.
- */
-enum ccn_parsed_interest_offsetid {
-  CCN_PI_B_Name,
-  CCN_PI_B_Component0,
-  CCN_PI_B_LastPrefixComponent,
-  CCN_PI_E_LastPrefixComponent,
-  CCN_PI_E_ComponentLast = CCN_PI_E_LastPrefixComponent,
-  CCN_PI_E_Name,
-  CCN_PI_B_MinSuffixComponents,
-  CCN_PI_E_MinSuffixComponents,
-  CCN_PI_B_MaxSuffixComponents,
-  CCN_PI_E_MaxSuffixComponents,
-  CCN_PI_B_PublisherID, // XXX - rename
-  CCN_PI_B_PublisherIDKeyDigest,
-  CCN_PI_E_PublisherIDKeyDigest,
-  CCN_PI_E_PublisherID,
-  CCN_PI_B_Exclude,
-  CCN_PI_E_Exclude,
-  CCN_PI_B_ChildSelector,
-  CCN_PI_E_ChildSelector,
-  CCN_PI_B_AnswerOriginKind,
-  CCN_PI_E_AnswerOriginKind,
-  CCN_PI_B_Scope,
-  CCN_PI_E_Scope,
-  CCN_PI_B_InterestLifetime,
-  CCN_PI_E_InterestLifetime,
-  CCN_PI_B_Nonce,
-  CCN_PI_E_Nonce,
-  CCN_PI_B_OTHER,
-  CCN_PI_E_OTHER,
-  CCN_PI_E
-};
-
-
-struct ccn_parsed_interest {
-  int magic;
-  int prefix_comps;
-  int min_suffix_comps;
-  int max_suffix_comps;
-  int orderpref;
-  int answerfrom;
-  int scope;
-  unsigned short offset[CCN_PI_E+1];
-};
-
-/*
- * Bitmasks for AnswerOriginKind
- */
-#define CCN_AOK_CS      0x1     /* Answer from content store */
-#define CCN_AOK_NEW     0x2     /* OK to produce new content */
-#define CCN_AOK_DEFAULT (CCN_AOK_CS | CCN_AOK_NEW)
-#define CCN_AOK_STALE   0x4     /* OK to answer with stale data */
-#define CCN_AOK_EXPIRE  0x10    /* Mark as stale (must have Scope 0) */
-
-/***********************************
- * Low-level binary formatting
- */
-
-/*
- * Append a ccnb start marker
- *
- * This forms the basic building block of ccnb-encoded data.
- * c is the buffer to append to.
- * Return value is 0, or -1 for error.
- */
-int ccn_charbuf_append_tt(struct ccn_charbuf *c, size_t val, enum ccn_tt tt);
-
-/**
- * Append a CCN_CLOSE
- *
- * Use this to close off an element in ccnb-encoded data.
- * @param c is the buffer to append to.
- * @returns 0 for success or -1 for error.
- */
-int ccn_charbuf_append_closer(struct ccn_charbuf *c);
-
-/***********************************
- * Slightly higher level binary formatting
- */
-
-/*
- * Append a non-negative integer as a UDATA.
- */
-int ccnb_append_number(struct ccn_charbuf *c, int nni);
-
-/*
- * Append a binary timestamp
- * as a BLOB using the ccn binary Timestamp representation (12-bit fraction).
- */
-int ccnb_append_timestamp_blob(struct ccn_charbuf *c,
-                               enum ccn_marker marker,
-                               long long secs, int nsecs);
-
-/*
- * Append a binary timestamp, using the current time.
- */
-int ccnb_append_now_blob(struct ccn_charbuf *c, enum ccn_marker marker);
-
-/*
- * Append a start-of-element marker.
- */
-int ccnb_element_begin(struct ccn_charbuf *c, enum ccn_dtag dtag);
-
-/*
- * Append an end-of-element marker.
- * This is the same as ccn_charbuf_append_closer()
- */
-int ccnb_element_end(struct ccn_charbuf *c);
-
-/*
- * Append a tagged BLOB
- */
-int ccnb_append_tagged_blob(struct ccn_charbuf *c, enum ccn_dtag dtag,
-                            const void *data, size_t size);
-
-/*
- * Append a tagged UDATA string, with printf-style formatting
- */
-int ccnb_tagged_putf(struct ccn_charbuf *c, enum ccn_dtag dtag,
-                     const char *fmt, ...);
-
-
-
-/***********************************
- * Binary decoding
- * These routines require that the whole binary object be buffered.
- */
-
-struct ccn_buf_decoder {
-  struct ccn_skeleton_decoder decoder;
-  const unsigned char *buf;
-  size_t size;
-};
-
-struct ccn_buf_decoder *ccn_buf_decoder_start(struct ccn_buf_decoder *d,
-                                              const unsigned char *buf, size_t size);
-
-void ccn_buf_advance(struct ccn_buf_decoder *d);
-int ccn_buf_advance_past_element(struct ccn_buf_decoder *d);
-
-/* The match routines return a boolean - true for match */
-int ccn_buf_match_dtag(struct ccn_buf_decoder *d, enum ccn_dtag dtag);
-
-int ccn_buf_match_some_dtag(struct ccn_buf_decoder *d);
-
-int ccn_buf_match_some_blob(struct ccn_buf_decoder *d);
-int ccn_buf_match_blob(struct ccn_buf_decoder *d,
-                       const unsigned char **bufp, size_t *sizep);
-
-int ccn_buf_match_udata(struct ccn_buf_decoder *d, const char *s);
-
-int ccn_buf_match_attr(struct ccn_buf_decoder *d, const char *s);
-
-/* On error, the parse routines enter an error state and return a negative value. */
-/*int ccn_parse_required_tagged_BLOB(struct ccn_buf_decoder *d,
-                                   enum ccn_dtag dtag,
-                                   int minlen, int maxlen);
-int ccn_parse_optional_tagged_BLOB(struct ccn_buf_decoder *d,
-                                   enum ccn_dtag dtag,
-                                   int minlen, int maxlen);
-int ccn_parse_nonNegativeInteger(struct ccn_buf_decoder *d);
-int ccn_parse_optional_tagged_nonNegativeInteger(struct ccn_buf_decoder *d,
-                                                 enum ccn_dtag dtag);
-int ccn_parse_uintmax(struct ccn_buf_decoder *d, uintmax_t *result);
-int ccn_parse_tagged_string(struct ccn_buf_decoder *d,
-                            enum ccn_dtag dtag, struct ccn_charbuf *store);*/
-/* check the decoder error state for these two - result can't be negative */
-/*uintmax_t ccn_parse_required_tagged_binary_number(struct ccn_buf_decoder *d,
-                                                  enum ccn_dtag dtag,
-                                                  int minlen, int maxlen);
-uintmax_t ccn_parse_optional_tagged_binary_number(struct ccn_buf_decoder *d,
-                                                  enum ccn_dtag dtag,
-                                                  int minlen, int maxlen,
-                                                  uintmax_t default_value);*/
-
-/**
- * Enter an error state if element closer not found.
- */
-void ccn_buf_check_close(struct ccn_buf_decoder *d);
-
-/*
- * ccn_ref_tagged_BLOB: Get address & size associated with blob-valued element
- * Returns 0 for success, negative value for error.
- */
-int ccn_ref_tagged_BLOB(enum ccn_dtag tt,
-                        const unsigned char *buf,
-                        size_t start, size_t stop,
-                        const unsigned char **presult, size_t *psize);
-
-/*
- * ccn_parse_Name: Parses a ccnb-encoded name
- * components may be NULL, otherwise is filled in with Component boundary offsets
- * Returns the number of Components in the Name, or -1 if there is an error.
- */
-int ccn_parse_Name(struct ccn_buf_decoder *d, struct ccn_indexbuf *components);
-
-/***********************************
- * Authenticators and signatures for content are constructed in charbufs
- * using the following routines.
- */
-
-enum ccn_content_type {
-  CCN_CONTENT_DATA = 0x0C04C0,
-  CCN_CONTENT_ENCR = 0x10D091,
-  CCN_CONTENT_GONE = 0x18E344,
-  CCN_CONTENT_KEY  = 0x28463F,
-  CCN_CONTENT_LINK = 0x2C834A,
-  CCN_CONTENT_NACK = 0x34008A
-};
-
-
-/*********** ContentObject parsing ***********/
-/* Analogous to enum ccn_parsed_interest_offsetid, but for content */
-enum ccn_parsed_content_object_offsetid {
-  CCN_PCO_B_Signature,
-  CCN_PCO_B_DigestAlgorithm,
-  CCN_PCO_E_DigestAlgorithm,
-  CCN_PCO_B_Witness,
-  CCN_PCO_E_Witness,
-  CCN_PCO_B_SignatureBits,
-  CCN_PCO_E_SignatureBits,
-  CCN_PCO_E_Signature,
-  CCN_PCO_B_Name,
-  CCN_PCO_B_Component0,
-  CCN_PCO_E_ComponentN,
-  CCN_PCO_E_ComponentLast = CCN_PCO_E_ComponentN,
-  CCN_PCO_E_Name,
-  CCN_PCO_B_SignedInfo,
-  CCN_PCO_B_PublisherPublicKeyDigest,
-  CCN_PCO_E_PublisherPublicKeyDigest,
-  CCN_PCO_B_Timestamp,
-  CCN_PCO_E_Timestamp,
-  CCN_PCO_B_Type,
-  CCN_PCO_E_Type,
-  CCN_PCO_B_FreshnessSeconds,
-  CCN_PCO_E_FreshnessSeconds,
-  CCN_PCO_B_FinalBlockID,
-  CCN_PCO_E_FinalBlockID,
-  CCN_PCO_B_KeyLocator,
-  /* Exactly one of Key, Certificate, or KeyName will be present */
-  CCN_PCO_B_Key_Certificate_KeyName,
-  CCN_PCO_B_KeyName_Name,
-  CCN_PCO_E_KeyName_Name,
-  CCN_PCO_B_KeyName_Pub,
-  CCN_PCO_E_KeyName_Pub,
-  CCN_PCO_E_Key_Certificate_KeyName,
-  CCN_PCO_E_KeyLocator,
-  CCN_PCO_E_SignedInfo,
-  CCN_PCO_B_Content,
-  CCN_PCO_E_Content,
-  CCN_PCO_E
-};
-
-struct ccn_parsed_ContentObject {
-  int magic;
-  enum ccn_content_type type;
-  int name_ncomps;
-  unsigned short offset[CCN_PCO_E+1];
-  unsigned char digest[32];	/* Computed only when needed */
-  int digest_bytes;
-};
-
-int ccn_encode_ContentObject(struct ccn_charbuf *buf,
-                             const struct ccn_charbuf *Name,
-                             const void *data,
-                             size_t size);
-#endif
diff --git a/in-progress/ccn/ccn_buf_decoder.cc b/in-progress/ccn/ccn_buf_decoder.cc
deleted file mode 100644
index eeb51fa..0000000
--- a/in-progress/ccn/ccn_buf_decoder.cc
+++ /dev/null
@@ -1,930 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include "ccn.h"
-#include "ccn_charbuf.h"
-#include "ccn_coding.h"
-#include "ccn_indexbuf.h"
-
-
-struct ccn_buf_decoder *
-ccn_buf_decoder_start(struct ccn_buf_decoder *d,
-                      const unsigned char *buf, size_t size)
-{
-  memset(&d->decoder, 0, sizeof(d->decoder));
-  d->decoder.state |= CCN_DSTATE_PAUSE;
-  d->buf = buf;
-  d->size = size;
-  ccn_skeleton_decode(&d->decoder, buf, size);
-  return(d);
-}
-
-void
-ccn_buf_advance(struct ccn_buf_decoder *d)
-{
-  ccn_skeleton_decode(&d->decoder,
-                      d->buf + d->decoder.index,
-                      d->size - d->decoder.index);
-}
-
-int
-ccn_buf_match_dtag(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
-  return (d->decoder.state >= 0 &&
-          CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG &&
-          (int)d->decoder.numval == dtag);
-}
-
-int
-ccn_buf_match_some_dtag(struct ccn_buf_decoder *d)
-{
-  return(d->decoder.state >= 0 &&
-         CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG);
-}
-
-int
-ccn_buf_match_some_blob(struct ccn_buf_decoder *d)
-{
-  return(d->decoder.state >= 0 &&
-         CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB);
-}
-
-int
-ccn_buf_match_blob(struct ccn_buf_decoder *d,
-                   const unsigned char **bufp, size_t *sizep)
-{
-  if (ccn_buf_match_some_blob(d)) {
-    if (bufp != NULL)
-      *bufp = d->buf + d->decoder.index;
-    if (sizep != NULL)
-      *sizep = d->decoder.numval;
-    return (1);
-  }
-  if (bufp != NULL)
-    *bufp = d->buf + d->decoder.token_index;
-  if (sizep != NULL)
-    *sizep = 0;
-  return(0);
-}
-
-int
-ccn_buf_match_udata(struct ccn_buf_decoder *d, const char *s)
-{
-  size_t len = strlen(s);
-  return (d->decoder.state >= 0 &&
-          CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA &&
-          d->decoder.numval == len &&
-          0 == memcmp(d->buf + d->decoder.index, s, len));
-}
-
-int
-ccn_buf_match_attr(struct ccn_buf_decoder *d, const char *s)
-{
-  size_t len = strlen(s);
-  return (d->decoder.state >= 0 &&
-          CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_ATTR &&
-          d->decoder.numval == len &&
-          0 == memcmp(d->buf + d->decoder.index, s, len));
-}
-
-void
-ccn_buf_check_close(struct ccn_buf_decoder *d)
-{
-  if (d->decoder.state >= 0) {
-    if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) != CCN_NO_TOKEN)
-      d->decoder.state = CCN_DSTATE_ERR_NEST;
-    else
-      ccn_buf_advance(d);
-  }
-}
-
-int
-ccn_buf_advance_past_element(struct ccn_buf_decoder *d)
-{
-  enum ccn_tt tt;
-  int nest;
-  if (d->decoder.state < 0)
-    return(d->decoder.state);
-  tt = (ccn_tt)CCN_GET_TT_FROM_DSTATE(d->decoder.state);
-  if (tt == CCN_DTAG || tt == CCN_TAG) {
-    nest = d->decoder.nest;
-    ccn_buf_advance(d);
-    while (d->decoder.state >= 0 && d->decoder.nest >= nest)
-      ccn_buf_advance(d);
-    /* The nest decrements before the closer is consumed */
-    ccn_buf_check_close(d);
-  }
-  else
-    return(-1);
-  if (d->decoder.state < 0)
-    return(d->decoder.state);
-  return (0);
-}
-
-int
-ccn_parse_required_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
-                               int minlen, int maxlen)
-{
-  int res = -1;
-  size_t len = 0;
-  if (ccn_buf_match_dtag(d, dtag)) {
-    res = d->decoder.element_index;
-    ccn_buf_advance(d);
-    if (ccn_buf_match_some_blob(d)) {
-      len = d->decoder.numval;
-      ccn_buf_advance(d);
-    }
-    ccn_buf_check_close(d);
-    if ((int)len < minlen || (maxlen >= 0 && (int)len > maxlen)) {
-      d->decoder.state = -__LINE__;
-    }
-  }
-  else
-    d->decoder.state = -__LINE__;
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  return(res);
-}
-
-int
-ccn_parse_optional_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
-                               int minlen, int maxlen)
-{
-  if (ccn_buf_match_dtag(d, dtag))
-    return(ccn_parse_required_tagged_BLOB(d, dtag, minlen, maxlen));
-  return(-1);
-}
-
-uintmax_t
-ccn_parse_required_tagged_binary_number(struct ccn_buf_decoder *d,
-                                        enum ccn_dtag dtag,
-                                        int minlen, int maxlen)
-{
-  uintmax_t value = 0;
-  const unsigned char *p = NULL;
-  size_t len = 0;
-  int i;
-  if (0 <= minlen && minlen <= maxlen && maxlen <= (int)sizeof(value) &&
-      ccn_buf_match_dtag(d, dtag)) {
-    ccn_buf_advance(d);
-    if (ccn_buf_match_blob(d, &p, &len))
-      ccn_buf_advance(d);
-    ccn_buf_check_close(d);
-    if (d->decoder.state < 0)
-      return(value);
-    if (minlen <= (int)len && (int)len <= maxlen)
-      for (i = 0; i < (int)len; i++)
-        value = (value << 8) + p[i];
-    else
-      d->decoder.state = -__LINE__;
-  }
-  else
-    d->decoder.state = -__LINE__;
-  return(value);
-}
-
-uintmax_t
-ccn_parse_optional_tagged_binary_number(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
-                                        int minlen, int maxlen, uintmax_t default_value)
-{
-  if (ccn_buf_match_dtag(d, dtag))
-    return(ccn_parse_required_tagged_binary_number(d, dtag, minlen, maxlen));
-  return(default_value);
-}
-
-int
-ccn_parse_required_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
-  int res = -1;
-  if (ccn_buf_match_dtag(d, dtag)) {
-    res = d->decoder.element_index;
-    ccn_buf_advance(d);
-    if (d->decoder.state >= 0 &&
-        CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA)
-      ccn_buf_advance(d);
-    else
-      d->decoder.state = -__LINE__;
-    ccn_buf_check_close(d);
-  }
-  else
-    d->decoder.state = -__LINE__;
-  if (d->decoder.state < 0)
-    return (-1);
-  return(res);
-}
-
-int
-ccn_parse_optional_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
-  if (ccn_buf_match_dtag(d, dtag))
-    return(ccn_parse_required_tagged_UDATA(d, dtag));
-  return(-1);
-}
-
-/**
- * Parses a ccnb-encoded element expected to contain a UDATA string.
- * @param d is the decoder
- * @param dtag is the expected dtag value
- * @param store - on success, the string value is appended to store,
- *        with null termination.
- * @returns the offset into the store buffer of the copied value, or -1 for error.
- *        If a parse error occurs, d->decoder.state is set to a negative value.
- *        If the element is not present, -1 is returned but no parse error
- *        is indicated.
- */
-int
-ccn_parse_tagged_string(struct ccn_buf_decoder *d, enum ccn_dtag dtag, struct ccn_charbuf *store)
-{
-  const unsigned char *p = NULL;
-  size_t size = 0;
-  int res;
-  
-  if (ccn_buf_match_dtag(d, dtag)) {
-    ccn_buf_advance(d);
-    if (d->decoder.state >= 0 &&
-        CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
-      res = store->length;
-      p = d->buf + d->decoder.index;
-      size = d->decoder.numval;
-      ccn_buf_advance(d);
-    }
-    ccn_buf_check_close(d);
-    if (d->decoder.state >= 0) {
-      // XXX - should check for valid utf-8 data.
-      res = store->length;
-      if (size > 0)
-        ccn_charbuf_append(store, p, size);
-      ccn_charbuf_append_value(store, 0, 1);
-      return(res);
-    }
-  }
-  return(-1);
-}
-
-/**
- * Parses a ccnb-encoded name
- * @param d is the decoder
- * @param components may be NULL, otherwise is filled in with the 
- *        Component boundary offsets
- * @returns the number of Components in the Name, or -1 if there is an error.
- */
-int
-ccn_parse_Name(struct ccn_buf_decoder *d, struct ccn_indexbuf *components)
-{
-  int ncomp = 0;
-  if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
-    if (components != NULL) components->n = 0;
-    ccn_buf_advance(d);
-    while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
-      if (components != NULL)
-        ccn_indexbuf_append_element(components, d->decoder.token_index);
-      ncomp += 1;
-      ccn_buf_advance(d);
-      if (ccn_buf_match_blob(d, NULL, NULL))
-        ccn_buf_advance(d);
-      ccn_buf_check_close(d);
-    }
-    if (components != NULL)
-      ccn_indexbuf_append_element(components, d->decoder.token_index);
-    ccn_buf_check_close(d);
-  }
-  else
-    d->decoder.state = -__LINE__;
-  if (d->decoder.state < 0)
-    return(-1);
-  else
-    return(ncomp);
-}
-
-int
-ccn_parse_PublisherID(struct ccn_buf_decoder *d, struct ccn_parsed_interest *pi)
-{
-  int res = -1;
-  int iskey = 0;
-  unsigned pubstart = d->decoder.token_index;
-  unsigned keystart = pubstart;
-  unsigned keyend = pubstart;
-  unsigned pubend = pubstart;
-  iskey = ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest);
-  if (iskey                                                          ||
-      ccn_buf_match_dtag(d, CCN_DTAG_PublisherCertificateDigest)     ||
-      ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerKeyDigest)       ||
-      ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerCertificateDigest)) {
-    res = d->decoder.element_index;
-    ccn_buf_advance(d);
-    keystart = d->decoder.token_index;
-    if (!ccn_buf_match_some_blob(d))
-      return (d->decoder.state = -__LINE__);
-    ccn_buf_advance(d);
-    keyend = d->decoder.token_index;
-    ccn_buf_check_close(d);
-    pubend = d->decoder.token_index;
-  }
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  if (pi != NULL) {
-    pi->offset[CCN_PI_B_PublisherID] = pubstart;
-    pi->offset[CCN_PI_B_PublisherIDKeyDigest] = keystart;
-    pi->offset[CCN_PI_E_PublisherIDKeyDigest] = iskey ? keyend : keystart;
-    pi->offset[CCN_PI_E_PublisherID] = pubend;
-  }
-  return(res);
-}
-
-static int
-ccn_parse_optional_Any_or_Bloom(struct ccn_buf_decoder *d)
-{
-  int res;
-  res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Bloom, 1, 1024+8);
-  if (res >= 0)
-    return(res);
-  if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
-    ccn_buf_advance(d);
-    ccn_buf_check_close(d);
-    res = 0;
-  }
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  return(res);
-}
-
-int
-ccn_parse_Exclude(struct ccn_buf_decoder *d)
-{
-  int res = -1;
-  if (ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) {
-    res = d->decoder.element_index;
-    ccn_buf_advance(d);
-    ccn_parse_optional_Any_or_Bloom(d);
-    while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
-      ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1);
-      ccn_parse_optional_Any_or_Bloom(d);
-    }
-    ccn_buf_check_close(d);
-  }
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  return(res);
-}
-
-
-
-int
-ccn_parse_nonNegativeInteger(struct ccn_buf_decoder *d)
-{
-  const unsigned char *p;
-  int i;
-  int n;
-  int val;
-  int newval;
-  unsigned char c;
-  if (d->decoder.state < 0)
-    return(d->decoder.state);
-  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
-    p = d->buf + d->decoder.index;
-    n = d->decoder.numval;
-    if (n < 1)
-      return(d->decoder.state = -__LINE__);
-    val = 0;
-    for (i = 0; i < n; i++) {
-      c = p[i];
-      if ('0' <= c && c <= '9') {
-        newval = val * 10 + (c - '0');
-        if (newval < val)
-          return(d->decoder.state = -__LINE__);
-        val = newval;
-      }
-      else
-        return(d->decoder.state = -__LINE__);
-    }
-    ccn_buf_advance(d);
-    return(val);
-  }
-  return(d->decoder.state = -__LINE__);
-}
-
-/**
- * Parse a potentially large non-negative integer.
- *
- * @returns 0 for success, and the value is place in *result; for an error
- * a negative value is returned and *result is unchanged.
- */
-int
-ccn_parse_uintmax(struct ccn_buf_decoder *d, uintmax_t *result)
-{
-  const unsigned char *p;
-  int i;
-  int n;
-  uintmax_t val;
-  uintmax_t newval;
-  unsigned char c;
-  if (d->decoder.state < 0)
-    return(d->decoder.state);
-  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
-    p = d->buf + d->decoder.index;
-    n = d->decoder.numval;
-    if (n < 1)
-      return(d->decoder.state = -__LINE__);
-    val = 0;
-    for (i = 0; i < n; i++) {
-      c = p[i];
-      if ('0' <= c && c <= '9') {
-        newval = val * 10 + (c - '0');
-        if (newval < val)
-          return(d->decoder.state = -__LINE__);
-        val = newval;
-      }
-      else
-        return(d->decoder.state = -__LINE__);
-    }
-    ccn_buf_advance(d);
-    *result = val;
-    return(0);
-  }
-  return(d->decoder.state = -__LINE__);
-}
-
-int
-ccn_parse_timestamp(struct ccn_buf_decoder *d)
-{
-  const unsigned char dlm[] = "--T::.Z";
-  const unsigned char *p;
-  int i;
-  int k;
-  int n;
-  if (d->decoder.state < 0)
-    return(d->decoder.state);
-  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB) {
-    /* New-style binary timestamp, 12-bit fraction */
-    n = d->decoder.numval;
-    if (n < 3 || n > 7)
-      return(d->decoder.state = -__LINE__);
-    ccn_buf_advance(d);
-    return(0);
-  }
-  if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
-    /* This is for some temporary back-compatibility */
-    p = d->buf + d->decoder.index;
-    n = d->decoder.numval;
-    if (n < 8 || n > 40)
-      return(d->decoder.state = -__LINE__);
-    if (p[n - 1] != 'Z')
-      return(d->decoder.state = -__LINE__);
-    for (i = 0, k = 0; i < n && '0' <= p[i] && p[i] <= '9';) {
-      i++;
-      if (i < n && p[i] == dlm[k]) {
-        if (dlm[k++] == 0)
-          return(d->decoder.state = -__LINE__);
-        i++;
-      }
-    }
-    if (k < 5)
-      return(d->decoder.state = -__LINE__);
-    if (!(i == n || i == n - 1))
-      return(d->decoder.state = -__LINE__);
-    ccn_buf_advance(d);
-    return(0);
-  }
-  return(d->decoder.state = -__LINE__);
-}
-
-int
-ccn_parse_required_tagged_timestamp(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
-  int res = -1;
-  if (ccn_buf_match_dtag(d, dtag)) {
-    res = d->decoder.element_index;
-    ccn_buf_advance(d);
-    ccn_parse_timestamp(d);
-    ccn_buf_check_close(d);
-  }
-  else
-    d->decoder.state = -__LINE__;
-  if (d->decoder.state < 0)
-    return (-1);
-  return(res);
-}
-
-int
-ccn_parse_optional_tagged_nonNegativeInteger(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
-{
-  int res = -1;
-  if (ccn_buf_match_dtag(d, dtag)) {
-    ccn_buf_advance(d);
-    res = ccn_parse_nonNegativeInteger(d);
-    ccn_buf_check_close(d);
-  }
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  return(res);
-}
-
-int
-ccn_fetch_tagged_nonNegativeInteger(enum ccn_dtag tt,
-                                    const unsigned char *buf,
-                                    size_t start, size_t stop)
-{
-  struct ccn_buf_decoder decoder;
-  struct ccn_buf_decoder *d;
-  int result = -1;
-  if (stop < start) return(-1);
-  d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
-  if (ccn_buf_match_dtag(d, tt)) {
-    ccn_buf_advance(d);
-    result = ccn_parse_nonNegativeInteger(d);
-    ccn_buf_check_close(d);
-  }
-  if (result < 0)
-    return(-1);
-  return(result);
-}
-
-
-int
-ccn_parse_interest(const unsigned char *msg, size_t size,
-                   struct ccn_parsed_interest *interest,
-                   struct ccn_indexbuf *components)
-{
-  struct ccn_buf_decoder decoder;
-  struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
-  int magic = 0;
-  int ncomp = 0;
-  int res;
-  if (ccn_buf_match_dtag(d, CCN_DTAG_Interest)) {
-    if (components == NULL) {
-      /* We need to have the component offsets. */
-      components = ccn_indexbuf_create();
-      if (components == NULL) return(-1);
-      res = ccn_parse_interest(msg, size, interest, components);
-      ccn_indexbuf_destroy(&components);
-      return(res);
-    }
-    ccn_buf_advance(d);
-    interest->offset[CCN_PI_B_Name] = d->decoder.element_index;
-    interest->offset[CCN_PI_B_Component0] = d->decoder.index;
-    ncomp = ccn_parse_Name(d, components);
-    if (d->decoder.state < 0) {
-      memset(interest->offset, 0, sizeof(interest->offset));
-      return(d->decoder.state);
-    }
-    interest->offset[CCN_PI_E_ComponentLast] = d->decoder.token_index - 1;
-    interest->offset[CCN_PI_E_Name] = d->decoder.token_index;
-    interest->prefix_comps = ncomp;
-    interest->offset[CCN_PI_B_LastPrefixComponent] = components->buf[(ncomp > 0) ? (ncomp - 1) : 0];
-    interest->offset[CCN_PI_E_LastPrefixComponent] = components->buf[ncomp];
-    /* optional MinSuffixComponents, MaxSuffixComponents */
-    interest->min_suffix_comps = 0;
-    interest->max_suffix_comps = 32767;
-    interest->offset[CCN_PI_B_MinSuffixComponents] = d->decoder.token_index;
-    res = ccn_parse_optional_tagged_nonNegativeInteger(d,
-                                                       CCN_DTAG_MinSuffixComponents);
-    interest->offset[CCN_PI_E_MinSuffixComponents] = d->decoder.token_index;
-    if (res >= 0)
-      interest->min_suffix_comps = res;
-    interest->offset[CCN_PI_B_MaxSuffixComponents] = d->decoder.token_index;
-    res = ccn_parse_optional_tagged_nonNegativeInteger(d,
-                                                       CCN_DTAG_MaxSuffixComponents);
-    interest->offset[CCN_PI_E_MaxSuffixComponents] = d->decoder.token_index;
-    if (res >= 0)
-      interest->max_suffix_comps = res;
-    if (interest->max_suffix_comps < interest->min_suffix_comps)
-      return (d->decoder.state = -__LINE__);
-    /* optional PublisherID */
-    res = ccn_parse_PublisherID(d, interest);
-    /* optional Exclude element */
-    interest->offset[CCN_PI_B_Exclude] = d->decoder.token_index;
-    res = ccn_parse_Exclude(d);
-    interest->offset[CCN_PI_E_Exclude] = d->decoder.token_index;
-    /* optional ChildSelector */
-    interest->offset[CCN_PI_B_ChildSelector] = d->decoder.token_index;
-    res = ccn_parse_optional_tagged_nonNegativeInteger(d,
-                                                       CCN_DTAG_ChildSelector);
-    if (res < 0)
-      res = 0;
-    interest->orderpref = res;
-    interest->offset[CCN_PI_E_ChildSelector] = d->decoder.token_index;
-    if (interest->orderpref > 5)
-      return (d->decoder.state = -__LINE__);        
-    /* optional AnswerOriginKind */
-    interest->offset[CCN_PI_B_AnswerOriginKind] = d->decoder.token_index;
-    interest->answerfrom = ccn_parse_optional_tagged_nonNegativeInteger(d,
-                                                                        CCN_DTAG_AnswerOriginKind);
-    interest->offset[CCN_PI_E_AnswerOriginKind] = d->decoder.token_index;
-    if (interest->answerfrom == -1)
-      interest->answerfrom = CCN_AOK_DEFAULT;
-    else if ((interest->answerfrom & CCN_AOK_NEW) != 0 &&
-             (interest->answerfrom & CCN_AOK_CS) == 0)
-      return (d->decoder.state = -__LINE__);
-    /* optional Scope */
-    interest->offset[CCN_PI_B_Scope] = d->decoder.token_index;
-    interest->scope = ccn_parse_optional_tagged_nonNegativeInteger(d,
-                                                                   CCN_DTAG_Scope);
-    interest->offset[CCN_PI_E_Scope] = d->decoder.token_index;
-    if (interest->scope > 9)
-      return (d->decoder.state = -__LINE__);
-    if ((interest->answerfrom & CCN_AOK_EXPIRE) != 0 &&
-        interest->scope != 0)
-      return (d->decoder.state = -__LINE__);
-    /* optional InterestLifetime */
-    interest->offset[CCN_PI_B_InterestLifetime] = d->decoder.token_index;
-    res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_InterestLifetime, 1, 8);
-    if (res >= 0)
-      magic |= 20100401;
-    interest->offset[CCN_PI_E_InterestLifetime] = d->decoder.token_index;
-    /* optional Nonce */
-    interest->offset[CCN_PI_B_Nonce] = d->decoder.token_index;
-    res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Nonce, 4, 64);
-    interest->offset[CCN_PI_E_Nonce] = d->decoder.token_index;
-    /* Allow for no experimental stuff */
-    interest->offset[CCN_PI_B_OTHER] = d->decoder.token_index;
-    interest->offset[CCN_PI_E_OTHER] = d->decoder.token_index;
-    ccn_buf_check_close(d);
-    interest->offset[CCN_PI_E] = d->decoder.index;
-  }
-  else
-    return (d->decoder.state = -__LINE__);
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  if (d->decoder.index != (int)size || !CCN_FINAL_DSTATE(d->decoder.state))
-    return (CCN_DSTATE_ERR_CODING);
-  if (magic == 0)
-    magic = 20090701;
-  if (!(magic == 20090701 || magic == 20100401))
-    return (d->decoder.state = -__LINE__);
-  interest->magic = magic;
-  return (ncomp);
-}
-
-struct parsed_KeyName {
-  int Name;
-  int endName;
-  int PublisherID;
-  int endPublisherID;
-};
-
-static int
-ccn_parse_KeyName(struct ccn_buf_decoder *d, struct parsed_KeyName *x)
-{
-  int res = -1;
-  if (ccn_buf_match_dtag(d, CCN_DTAG_KeyName)) {
-    res = d->decoder.element_index;
-    ccn_buf_advance(d);
-    x->Name = d->decoder.token_index;
-    ccn_parse_Name(d, NULL);
-    x->endName = d->decoder.token_index;
-    x->PublisherID = ccn_parse_PublisherID(d, NULL);
-    x->endPublisherID = d->decoder.token_index;
-    ccn_buf_check_close(d);
-  }
-  else
-    d->decoder.state = -__LINE__;
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  return(res);
-}
-
-static int
-ccn_parse_Signature(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
-{
-  int res = -1;
-  int i;
-  struct ccn_parsed_ContentObject dummy;
-  if (x == NULL)
-    x = &dummy;
-  for (i = CCN_PCO_B_Signature; i <= CCN_PCO_E_Signature; i++) {
-    x->offset[i] = d->decoder.token_index;
-  }
-  if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) {
-    res = d->decoder.element_index;
-    ccn_buf_advance(d);
-    x->offset[CCN_PCO_B_DigestAlgorithm] = d->decoder.token_index;
-    ccn_parse_optional_tagged_UDATA(d, CCN_DTAG_DigestAlgorithm);
-    x->offset[CCN_PCO_E_DigestAlgorithm] = d->decoder.token_index;
-    x->offset[CCN_PCO_B_Witness] = d->decoder.token_index;
-    ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 8, -1);
-    x->offset[CCN_PCO_E_Witness] = d->decoder.token_index;
-    x->offset[CCN_PCO_B_SignatureBits] = d->decoder.token_index;
-    ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 16, -1);
-    x->offset[CCN_PCO_E_SignatureBits] = d->decoder.token_index;
-    ccn_buf_check_close(d);
-    x->offset[CCN_PCO_E_Signature] = d->decoder.token_index;
-  }
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  return(res);
-}
-
-static int
-ccn_parse_SignedInfo(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
-{
-  x->offset[CCN_PCO_B_SignedInfo] = d->decoder.token_index;
-  if (ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) {
-    ccn_buf_advance(d);
-    x->offset[CCN_PCO_B_PublisherPublicKeyDigest] = d->decoder.token_index;
-    ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest, 16, 64);
-    x->offset[CCN_PCO_E_PublisherPublicKeyDigest] = d->decoder.token_index;
-    
-    x->offset[CCN_PCO_B_Timestamp] = d->decoder.token_index;
-    ccn_parse_required_tagged_timestamp(d, CCN_DTAG_Timestamp);
-    x->offset[CCN_PCO_E_Timestamp] = d->decoder.token_index;
-    
-    x->offset[CCN_PCO_B_Type] = d->decoder.token_index;
-    x->type = CCN_CONTENT_DATA;
-    x->type = (ccn_content_type)ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA);
-    x->offset[CCN_PCO_E_Type] = d->decoder.token_index;
-    
-    x->offset[CCN_PCO_B_FreshnessSeconds] = d->decoder.token_index;
-    ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
-    x->offset[CCN_PCO_E_FreshnessSeconds] = d->decoder.token_index;
-    
-    x->offset[CCN_PCO_B_FinalBlockID] = d->decoder.token_index;
-    ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1);
-    x->offset[CCN_PCO_E_FinalBlockID] = d->decoder.token_index;
-    
-    x->offset[CCN_PCO_B_KeyLocator] = d->decoder.token_index;
-    x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
-    x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
-    x->offset[CCN_PCO_B_KeyName_Name] = d->decoder.token_index;
-    x->offset[CCN_PCO_E_KeyName_Name] = d->decoder.token_index;
-    x->offset[CCN_PCO_B_KeyName_Pub] = d->decoder.token_index;
-    x->offset[CCN_PCO_E_KeyName_Pub] = d->decoder.token_index;
-    if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) {
-      ccn_buf_advance(d);
-      x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
-      if (ccn_buf_match_dtag(d, CCN_DTAG_Key)) {
-        (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Key, 0, -1);
-      }
-      else if (ccn_buf_match_dtag(d, CCN_DTAG_Certificate)) {
-        (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Certificate, 0, -1);
-      }
-      else {
-        struct parsed_KeyName keyname = {-1, -1, -1, -1};
-        if (ccn_parse_KeyName(d, &keyname) >= 0) {
-          if (keyname.Name >= 0) {
-            x->offset[CCN_PCO_B_KeyName_Name] = keyname.Name;
-            x->offset[CCN_PCO_E_KeyName_Name] = keyname.endName;
-          }
-          if (keyname.PublisherID >= 0) {
-            x->offset[CCN_PCO_B_KeyName_Pub] = keyname.PublisherID;
-            x->offset[CCN_PCO_E_KeyName_Pub] = keyname.endPublisherID;
-          }
-        }
-      }
-      x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
-      ccn_buf_check_close(d);
-    }
-    x->offset[CCN_PCO_E_KeyLocator] = d->decoder.token_index;
-    ccn_buf_check_close(d);
-  }
-  else
-    d->decoder.state = -__LINE__;
-  x->offset[CCN_PCO_E_SignedInfo] = d->decoder.token_index;
-  if (d->decoder.state < 0)
-    return (d->decoder.state);
-  return(0);
-}
-
-int
-ccn_parse_ContentObject(const unsigned char *msg, size_t size,
-                        struct ccn_parsed_ContentObject *x,
-                        struct ccn_indexbuf *components)
-{
-  struct ccn_buf_decoder decoder;
-  struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
-  int res;
-  x->magic = 20090415;
-  x->digest_bytes = 0;
-  if (ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) {
-    ccn_buf_advance(d);
-    res = ccn_parse_Signature(d, x);
-    x->offset[CCN_PCO_B_Name] = d->decoder.token_index;
-    x->offset[CCN_PCO_B_Component0] = d->decoder.index;
-    res = ccn_parse_Name(d, components);
-    if (res < 0)
-      d->decoder.state = -__LINE__;
-    x->name_ncomps = res;
-    x->offset[CCN_PCO_E_ComponentLast] = d->decoder.token_index - 1;
-    x->offset[CCN_PCO_E_Name] = d->decoder.token_index;
-    ccn_parse_SignedInfo(d, x);
-    x->offset[CCN_PCO_B_Content] = d->decoder.token_index;
-    ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Content, 0, -1);
-    x->offset[CCN_PCO_E_Content] = d->decoder.token_index;
-    ccn_buf_check_close(d);
-    x->offset[CCN_PCO_E] = d->decoder.index;
-  }
-  else
-    d->decoder.state = -__LINE__;
-  if (d->decoder.index != (int)size || !CCN_FINAL_DSTATE(d->decoder.state))
-    return (CCN_DSTATE_ERR_CODING);
-  return(0);
-}
-
-int
-ccn_ref_tagged_BLOB(enum ccn_dtag tt,
-                    const unsigned char *buf, size_t start, size_t stop,
-                    const unsigned char **presult, size_t *psize)
-{
-  struct ccn_buf_decoder decoder;
-  struct ccn_buf_decoder *d;
-  if (stop < start) return(-1);
-  d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
-  if (ccn_buf_match_dtag(d, tt)) {
-    ccn_buf_advance(d);
-    if (ccn_buf_match_blob(d, presult, psize))
-      ccn_buf_advance(d);
-    ccn_buf_check_close(d);
-  }
-  else
-    return(-1);
-  if (d->decoder.index != (int)d->size || !CCN_FINAL_DSTATE(d->decoder.state))
-    return (CCN_DSTATE_ERR_CODING);
-  return(0);
-}
-
-static struct ccn_buf_decoder *
-ccn_buf_decoder_start_at_components(struct ccn_buf_decoder *d,
-                                    const unsigned char *buf, size_t buflen)
-{
-  ccn_buf_decoder_start(d, buf, buflen);
-  while (ccn_buf_match_dtag(d, CCN_DTAG_Name) ||
-         ccn_buf_match_dtag(d, CCN_DTAG_Interest) ||
-         ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)
-         ) {
-    ccn_buf_advance(d);
-    ccn_parse_Signature(d, NULL);
-  }
-  return(d);
-}
-
-int
-ccn_content_get_value(const unsigned char *data, size_t data_size,
-                      const struct ccn_parsed_ContentObject *content,
-                      const unsigned char **value, size_t *value_size)
-{
-  int res;
-  res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, data,
-                            content->offset[CCN_PCO_B_Content],
-                            content->offset[CCN_PCO_E_Content],
-                            value, value_size);
-  return(res);
-}
-
-int
-ccn_compare_names(const unsigned char *a, size_t asize,
-                  const unsigned char *b, size_t bsize)
-{
-  struct ccn_buf_decoder a_decoder;
-  struct ccn_buf_decoder b_decoder;
-  struct ccn_buf_decoder *aa =
-  ccn_buf_decoder_start_at_components(&a_decoder, a, asize);
-  struct ccn_buf_decoder *bb =
-  ccn_buf_decoder_start_at_components(&b_decoder, b, bsize);
-  const unsigned char *acp = NULL;
-  const unsigned char *bcp = NULL;
-  size_t acsize;
-  size_t bcsize;
-  int cmp = 0;
-  int more_a;
-  for (;;) {
-    more_a = ccn_buf_match_dtag(aa, CCN_DTAG_Component);
-    cmp = more_a - ccn_buf_match_dtag(bb, CCN_DTAG_Component);
-    if (more_a == 0 || cmp != 0)
-      break;
-    ccn_buf_advance(aa);
-    ccn_buf_advance(bb);
-    acsize = bcsize = 0;
-    if (ccn_buf_match_blob(aa, &acp, &acsize))
-      ccn_buf_advance(aa);
-    if (ccn_buf_match_blob(bb, &bcp, &bcsize))
-      ccn_buf_advance(bb);
-    cmp = acsize - bcsize;
-    if (cmp != 0)
-      break;
-    cmp = memcmp(acp, bcp, acsize);
-    if (cmp != 0)
-      break;
-    ccn_buf_check_close(aa);
-    ccn_buf_check_close(bb);
-  }
-  return (cmp);
-}
-
diff --git a/in-progress/ccn/ccn_buf_encoder.cc b/in-progress/ccn/ccn_buf_encoder.cc
deleted file mode 100644
index d0d157b..0000000
--- a/in-progress/ccn/ccn_buf_encoder.cc
+++ /dev/null
@@ -1,91 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include "ccn.h"
-#include "ccn_charbuf.h"
-#include "ccn_coding.h"
-#include "ccn_indexbuf.h"
-
-/**
- * Encode and sign a ContentObject.
- * @param buf is the output buffer where encoded object is written.
- * @param Name is the ccnb-encoded name from ccn_name_init and friends.
- * @param SignedInfo is the ccnb-encoded info from ccn_signed_info_create.
- * @param data pintes to the raw data to be encoded.
- * @param size is the size, in bytes, of the raw data to be encoded.
- * @param digest_algorithm may be NULL for default.
- * @param private_key is the private key to use for signing.
- * @returns 0 for success or -1 for error.
- */
-int
-ccn_encode_ContentObject(struct ccn_charbuf *buf,
-                         const struct ccn_charbuf *Name,
-                         /*const struct ccn_charbuf *SignedInfo,*/
-                         const void *data,
-                         size_t size
-                         /*const char *digest_algorithm,
-                         const struct ccn_pkey *private_key*/
-                         )
-{
-    int res = 0;
-    
-    res |= ccn_charbuf_append_tt(buf, CCN_DTAG_ContentObject, CCN_DTAG);
-    //res |= ccn_encode_Signature(buf, digest_algorithm,
-    //                            NULL, 0, signature, signature_size);
-    res |= ccn_charbuf_append_charbuf(buf, Name);
-    //res |= ccn_charbuf_append_charbuf(buf, SignedInfo);
-    res |= ccnb_append_tagged_blob(buf, CCN_DTAG_Content, data, size);
-    res |= ccn_charbuf_append_closer(buf);
-    //free(signature);
-    ccn_charbuf_destroy(&content_header);
-    return(res == 0 ? 0 : -1);
-}
-
-/**
- * Append a tagged BLOB
- *
- * This is a ccnb-encoded element with containing the BLOB as content
- * @param c is the buffer to append to.
- * @param dtag is the element's dtab
- * @param data points to the binary data
- * @param size is the size of the data, in bytes
- * @returns 0 for success or -1 for error.
- */
-int
-ccnb_append_tagged_blob(struct ccn_charbuf *c,
-                        enum ccn_dtag dtag,
-                        const void *data,
-                        size_t size)
-{
-    int res;
-    
-    res = ccn_charbuf_append_tt(c, dtag, CCN_DTAG);
-    if (size != 0) {
-        res |= ccn_charbuf_append_tt(c, size, CCN_BLOB);
-        res |= ccn_charbuf_append(c, data, size);
-    }
-    res |= ccn_charbuf_append_closer(c);
-    return(res == 0 ? 0 : -1);
-}
diff --git a/in-progress/ccn/ccn_charbuf.cc b/in-progress/ccn/ccn_charbuf.cc
deleted file mode 100644
index 06c6544..0000000
--- a/in-progress/ccn/ccn_charbuf.cc
+++ /dev/null
@@ -1,215 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_charbuf.h"
-
-/**
- * @file ccn_charbuf.c
- * @brief Support expandable buffer for counted sequences of arbitrary bytes.
- * 
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library 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
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include "ccn_coding.h"
-
-struct ccn_charbuf *
-ccn_charbuf_create(void)
-{
-  struct ccn_charbuf *c;
-  c = (ccn_charbuf*)calloc(1, sizeof(*c));
-  return(c);
-}
-
-void
-ccn_charbuf_destroy(struct ccn_charbuf **cbp)
-{
-  struct ccn_charbuf *c = *cbp;
-  if (c != NULL) {
-    if (c->buf != NULL)
-      free(c->buf);
-    free(c);
-    *cbp = NULL;
-  }
-}
-
-/*
- * ccn_charbuf_reserve: expand buffer as necessary to hold n more chars
- */
-unsigned char *
-ccn_charbuf_reserve(struct ccn_charbuf *c, size_t n)
-{
-  size_t newsz = n + c->length;
-  unsigned char *buf = c->buf;
-  if (newsz < n)
-    return(NULL);
-  if (newsz > c->limit) {
-    if (2 * c->limit > newsz)
-      newsz = 2 * c->limit;
-    buf = (unsigned char*)realloc(c->buf, newsz);
-    if (buf == NULL)
-      return(NULL);
-    memset(buf + c->limit, 0, newsz - c->limit);
-    c->buf = buf;
-    c->limit = newsz;
-  }
-  buf += c->length;
-  return(buf);
-}
-
-void ccn_charbuf_reset(struct ccn_charbuf *c)
-{
-  if (c == NULL) {
-    return;
-  } 
-  c->length = 0;
-}
-
-int
-ccn_charbuf_append(struct ccn_charbuf *c, const void *p, size_t n)
-{
-  unsigned char *dst = ccn_charbuf_reserve(c, n);
-  if (dst == NULL)
-    return(-1);
-  memcpy(dst, p, n);
-  c->length += n;
-  return(0);
-}
-
-int
-ccn_charbuf_append_value(struct ccn_charbuf *c, unsigned val, unsigned n)
-{
-  unsigned char *dst;
-  unsigned i;
-  if (n > sizeof(val))
-    return(-1);
-  dst = ccn_charbuf_reserve(c, n);
-  if (dst == NULL)
-    return(-1);
-  for (i = 0; i < n; i++)
-    dst[i] = (unsigned char)(val >> (8 * (n-1-i)));
-  c->length += n;
-  return(0);
-}
-
-int
-ccn_charbuf_append_charbuf(struct ccn_charbuf *c, const struct ccn_charbuf *in)
-{
-  return(ccn_charbuf_append(c, in->buf, in->length));
-}
-
-int
-ccn_charbuf_append_string(struct ccn_charbuf *c, const char *s)
-{
-  return(ccn_charbuf_append(c, s, strlen(s)));
-}
-
-int
-ccn_charbuf_putf(struct ccn_charbuf *c, const char *fmt, ...)
-{
-  int sz;
-  va_list ap;
-  char *buf;
-  buf = (char *)ccn_charbuf_reserve(c, strlen(fmt) + 10); /* estimate */
-  if (buf == NULL) return(-1);
-  va_start(ap, fmt);
-  sz = vsnprintf(buf, c->limit - c->length, fmt, ap);
-  va_end(ap);
-  if (sz < 0)
-    return(sz);
-  if (c->length + sz < c->limit) {
-    c->length += sz;
-    return(sz);
-  }
-  va_end(ap);
-  buf = (char *)ccn_charbuf_reserve(c, sz + 1); /* accurate */
-  if (buf == NULL) return(-1);
-  va_start(ap, fmt);
-  sz = vsnprintf(buf, c->limit - c->length, fmt, ap);
-  va_end(ap);
-  if (c->length + sz < c->limit) {
-    c->length += sz;
-    return(sz);
-  }
-  return(-1);
-}
-
-/* This formats time into xs:dateTime format */
-int
-ccn_charbuf_append_datetime(struct ccn_charbuf *c, time_t secs, int nsecs)
-{
-  char timestring[32];
-  int timelen;
-  struct tm time_tm;
-  int res;
-  
-  timelen = strftime(timestring, sizeof(timestring),
-                     "%FT%T", gmtime_r(&secs, &time_tm));
-  if (timelen >= (int)sizeof(timestring))
-    return(-1);
-  if (nsecs != 0) {
-    if (nsecs < 0 || nsecs >= 1000000000)
-      return(-1);
-    timelen += snprintf(&timestring[timelen], sizeof(timestring) - timelen,
-                        ".%09d", nsecs);
-    if (timelen >= (int)sizeof(timestring))
-      return(-1);
-    while (timestring[timelen - 1] == '0') timelen--;
-  }
-  timestring[timelen++] = 'Z';
-  res = ccn_charbuf_append(c, timestring, timelen);
-  return (res);
-}
-
-char *
-ccn_charbuf_as_string(struct ccn_charbuf *c)
-{
-  unsigned char *r;
-  r = ccn_charbuf_reserve(c, 1);
-  if (r == NULL)
-    return(NULL);
-  r[0] = 0;
-  return((char *)c->buf);
-}
-
-int
-ccn_charbuf_append_closer(struct ccn_charbuf *c)
-{
-  int res;
-  const unsigned char closer = CCN_CLOSE;
-  res = ccn_charbuf_append(c, &closer, 1);
-  return(res);
-}
diff --git a/in-progress/ccn/ccn_charbuf.h b/in-progress/ccn/ccn_charbuf.h
deleted file mode 100644
index 066eda2..0000000
--- a/in-progress/ccn/ccn_charbuf.h
+++ /dev/null
@@ -1,137 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/**
- * @file ccn/charbuf.h
- * 
- * Expandable character buffer for counted sequences of arbitrary octets.
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library 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
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef CCN_CHARBUF_DEFINED
-#define CCN_CHARBUF_DEFINED
-
-#include <stddef.h>
-#include <time.h>
-
-struct ccn_charbuf {
-  size_t length;
-  size_t limit;
-  unsigned char *buf;
-};
-
-/*
- * ccn_charbuf_create:  allocate a new charbuf
- * ccn_charbuf_destroy: destroy a charbuf
- */
-struct ccn_charbuf *ccn_charbuf_create(void);
-void ccn_charbuf_destroy(struct ccn_charbuf **cbp);
-
-/*
- * ccn_charbuf_reserve: reserve some space in the buffer
- * Grows c->buf if needed and returns a pointer to the new region.
- * Does not modify c->length
- */ 
-unsigned char *ccn_charbuf_reserve(struct ccn_charbuf *c, size_t n);
-
-/*
- * ccn_charbuf_reset: reset to empty for reuse
- * Sets c->length to 0
- */
-void ccn_charbuf_reset(struct ccn_charbuf *c);
-
-/*
- * ccn_charbuf_append: append character content
- */ 
-int ccn_charbuf_append(struct ccn_charbuf *c, const void *p, size_t n);
-
-/*
- * ccn_charbuf_append: append n bytes of val
- * The n low-order bytes are appended in network byte order (big-endian) 
- */ 
-int ccn_charbuf_append_value(struct ccn_charbuf *c, unsigned val, unsigned n);
-
-
-/*
- * ccn_charbuf_append_charbuf: append content from another charbuf
- */ 
-int ccn_charbuf_append_charbuf(struct ccn_charbuf *c, const struct ccn_charbuf *i);
-
-/*
- * ccn_charbuf_append: append a string
- * Sometimes you have a null-terminated string in hand...
- */ 
-int ccn_charbuf_append_string(struct ccn_charbuf *c, const char *s);
-
-/*
- * ccn_charbuf_putf: formatting output
- * Use this in preference to snprintf to simplify bookkeeping.
- */ 
-int ccn_charbuf_putf(struct ccn_charbuf *c, const char *fmt, ...);
-
-/*
- * ccn_charbuf_append_datetime: append a date/time string
- * Appends a dateTime string in canonical form according to
- * http://www.w3.org/TR/xmlschema-2/
- * Return value is 0, or -1 for error.
- * example: 2008-07-22T17:33:14.109Z
- */ 
-int ccn_charbuf_append_datetime(struct ccn_charbuf *c, time_t secs, int nsecs);
-
-/*
- * ccn_charbuf_append_datetime_now: append a date/time string
- * Appends a dateTime string representing the current date and time
- * in canonical form according to
- * http://www.w3.org/TR/xmlschema-2/
- * precision, a non-negative number, indicates the maximum number
- * of fractional digits in the seconds.  Only values 0..6 have
- * any effect, at this times, since the gettimeofday() function
- * is defined to return microsecond resolution.
- * Return value is 0, or -1 for error.
- * example: 2008-07-22T17:33:14.109Z
- */ 
-#define CCN_DATETIME_PRECISION_USEC 6
-#define CCN_DATETIME_PRECISION_MAX 6
-int ccn_charbuf_append_datetime_now(struct ccn_charbuf *c, int precision);
-
-/*
- * ccn_charbuf_as_string: view charbuf contents as a string
- * This assures that c->buf has a null termination, and simply
- * returns the pointer into the buffer.  If the result needs to
- * persist beyond the next operation on c, the caller is
- * responsible for copying it.
- */ 
-char *ccn_charbuf_as_string(struct ccn_charbuf *c);
-
-#endif
diff --git a/in-progress/ccn/ccn_indexbuf.cc b/in-progress/ccn/ccn_indexbuf.cc
deleted file mode 100644
index 034c5db..0000000
--- a/in-progress/ccn/ccn_indexbuf.cc
+++ /dev/null
@@ -1,247 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_indexbuf.h"
-
-/**
- * @file ccn_indexbuf.c
- * @brief Support for expandable buffer of non-negative values.
- * 
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library 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
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define ELEMENT size_t
-
-/**
- * Create a new indexbuf.
- */
-struct ccn_indexbuf *
-ccn_indexbuf_create(void)
-{
-  struct ccn_indexbuf *c;
-  c = (ccn_indexbuf*)calloc(1, sizeof(*c));
-  return(c);
-}
-
-/**
- * Deallocate indexbuf.
- */
-void
-ccn_indexbuf_destroy(struct ccn_indexbuf **cbp)
-{
-  struct ccn_indexbuf *c = *cbp;
-  if (c != NULL) {
-    if (c->buf != NULL) {
-      free(c->buf);
-    }
-    free(c);
-    *cbp = NULL;
-  }
-}
-
-/**
- * Expand buffer as necessary to hold at least n more values.
- * @returns pointer to reserved space
- */
-ELEMENT *
-ccn_indexbuf_reserve(struct ccn_indexbuf *c, size_t n)
-{
-  size_t newlim = n + c->n;
-  size_t oldlim = c->limit;
-  ELEMENT *buf = c->buf;
-  if (newlim < n)
-    return(NULL);
-  if (newlim > oldlim) {
-    if (2 * oldlim > newlim)
-      newlim = 2 * oldlim;
-    buf = (size_t*)realloc(c->buf, newlim * sizeof(ELEMENT));
-    if (buf == NULL)
-      return(NULL);
-    memset(buf + oldlim, 0, (newlim - oldlim) * sizeof(ELEMENT));
-    c->buf = buf;
-    c->limit = newlim;
-  }
-  buf += c->n;
-  return(buf);
-}
-
-/**
- * Append multiple elements to the indexbuf.
- * @returns 0 for success, -1 for failure.
- */
-int
-ccn_indexbuf_append(struct ccn_indexbuf *c, const ELEMENT *p, size_t n)
-{
-  ELEMENT *dst = ccn_indexbuf_reserve(c, n);
-  if (dst == NULL)
-    return(-1);
-  memcpy(dst, p, n * sizeof(ELEMENT));
-  c->n += n;
-  return(0);
-}
-
-/**
- * Append v to the indexbuf
- * @returns 0 for success, -1 for failure.
- */
-int
-ccn_indexbuf_append_element(struct ccn_indexbuf *c, ELEMENT v)
-{
-  ELEMENT *dst = ccn_indexbuf_reserve(c, 1);
-  if (dst == NULL)
-    return(-1);
-  *dst = v;
-  c->n += 1;
-  return(0);
-}
-
-/**
- * @returns index at which the element was found or appended, or -1 if not found.
- */
-int
-ccn_indexbuf_member(struct ccn_indexbuf *x, ELEMENT val)
-{
-  int i;
-  if (x == NULL)
-    return (-1);
-  for (i = x->n - 1; i >= 0; i--)
-    if (x->buf[i] == val)
-      return(i);
-  return(-1);
-}
-
-/**
- * Removes up to one instance of val from the indexbuf.
- * Order of elements not preserved.
- */
-void
-ccn_indexbuf_remove_element(struct ccn_indexbuf *x, ELEMENT val)
-{
-  int i;
-  if (x == NULL) return;
-  for (i = x->n - 1; i >= 0; i--)
-    if (x->buf[i] == val) {
-      x->buf[i] = x->buf[--x->n]; /* move last element into vacant spot */
-      return;
-    }
-}
-
-/**
- * @returns index at which the element was found or appended,
- *          or -1 in case of error.
- */
-int
-ccn_indexbuf_set_insert(struct ccn_indexbuf *x, ELEMENT val)
-{
-  int i;
-  if (x == NULL)
-    return (-1);
-  for (i = 0; i < (int)x->n; i++)
-    if (x->buf[i] == val)
-      return(i);
-  if (ccn_indexbuf_append_element(x, val) < 0)
-    return(-1);
-  return(i);
-}
-
-/**
- * Removes first occurrence of val, preserving order
- * @returns index at which the element was found,
- *          or -1 if the element was not found.
- */
-int
-ccn_indexbuf_remove_first_match(struct ccn_indexbuf *x, ELEMENT val)
-{
-  int i;
-  int n;
-  if (x == NULL)
-    return (-1);
-  for (i = 0, n = x->n; i < n; i++) {
-    if (x->buf[i] == val) {
-      if (i + 1 < n)
-        memmove(&(x->buf[i]),
-                &(x->buf[i + 1]),
-                sizeof(x->buf[i]) * (n - i - 1));
-      x->n--;
-      return(i);
-    }
-  }
-  return(-1);
-}
-
-/**
- * If val is present in the indexbuf, move it to the final place.
- */
-void
-ccn_indexbuf_move_to_end(struct ccn_indexbuf *x, ELEMENT val)
-{
-  int i;
-  int n;
-  if (x == NULL)
-    return;
-  for (i = 0, n = x->n; i + 1 < n; i++) {
-    if (x->buf[i] == val) {
-      memmove(&(x->buf[i]),
-              &(x->buf[i + 1]),
-              sizeof(x->buf[i]) * (n - i - 1));
-      x->buf[n - 1] = val;
-      return;
-    }
-  }
-}
-
-/**
- * If val is present in the indexbuf, move it to the first place.
- */
-void
-ccn_indexbuf_move_to_front(struct ccn_indexbuf *x, ELEMENT val)
-{
-  int i;
-  int n;
-  if (x == NULL)
-    return;
-  for (i = 0, n = x->n; i < n; i++) {
-    if (x->buf[i] == val) {
-      memmove(&(x->buf[1]),
-              &(x->buf[0]),
-              sizeof(x->buf[i]) * i);
-      x->buf[0] = val;
-      return;
-    }
-  }
-  
-}
-
diff --git a/in-progress/ccn/ccn_indexbuf.h b/in-progress/ccn/ccn_indexbuf.h
deleted file mode 100644
index 3e133c3..0000000
--- a/in-progress/ccn/ccn_indexbuf.h
+++ /dev/null
@@ -1,65 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/**
- * @file ccn/indexbuf.h
- * 
- * Expandable buffer of non-negative values.
- *
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library 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
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef CCN_INDEXBUF_DEFINED
-#define CCN_INDEXBUF_DEFINED
-
-#include <stddef.h>
-
-struct ccn_indexbuf {
-  size_t n;
-  size_t limit;
-  size_t *buf;
-};
-
-struct ccn_indexbuf *ccn_indexbuf_create(void);
-void ccn_indexbuf_destroy(struct ccn_indexbuf **cbp);
-size_t *ccn_indexbuf_reserve(struct ccn_indexbuf *c, size_t n);
-int ccn_indexbuf_append(struct ccn_indexbuf *c, const size_t *p, size_t n);
-int ccn_indexbuf_append_element(struct ccn_indexbuf *c, size_t v);
-int ccn_indexbuf_member(struct ccn_indexbuf *x, size_t val);
-void ccn_indexbuf_remove_element(struct ccn_indexbuf *x, size_t val);
-int ccn_indexbuf_set_insert(struct ccn_indexbuf *x, size_t val);
-int ccn_indexbuf_remove_first_match(struct ccn_indexbuf *x, size_t val);
-void ccn_indexbuf_move_to_end(struct ccn_indexbuf *x, size_t val);
-void ccn_indexbuf_move_to_front(struct ccn_indexbuf *x, size_t val);
-
-#endif
diff --git a/in-progress/ccn/ccn_name_util.cc b/in-progress/ccn/ccn_name_util.cc
deleted file mode 100644
index 64405ce..0000000
--- a/in-progress/ccn/ccn_name_util.cc
+++ /dev/null
@@ -1,326 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_name_util.h"
-#include "ccn_coding.h"
-#include "ccn_charbuf.h"
-#include "ccn_indexbuf.h"
-#include <string.h>
-#include <stdlib.h>
-#include "ccn_random.h"
-#include "ccn.h"
-
-/**
- * @file ccn_name_util.c
- * @brief Support for manipulating ccnb-encoded Names.
- * 
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008-2010 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library 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
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-//#include <ccn/ccn.h>
-
-/**
- * Reset charbuf to represent an empty Name in binary format.
- * @returns 0, or -1 for error.
- */
-int
-ccn_name_init(struct ccn_charbuf *c)
-{
-  int res;
-  c->length = 0;
-  res = ccn_charbuf_append_tt(c, CCN_DTAG_Name, CCN_DTAG);
-  if (res == -1) return(res);
-  res = ccn_charbuf_append_closer(c);
-  return(res);
-}
-
-/**
- * Add a Component to a Name.
- *
- * The component is an arbitrary string of n octets, no escaping required.
- * @returns 0, or -1 for error.
- */
-int
-ccn_name_append(struct ccn_charbuf *c, const void *component, size_t n)
-{
-  int res;
-  const unsigned char closer[2] = {CCN_CLOSE, CCN_CLOSE};
-  if (c->length < 2 || c->buf[c->length-1] != closer[1])
-    return(-1);
-  c->length -= 1;
-  ccn_charbuf_reserve(c, n + 8);
-  res = ccn_charbuf_append_tt(c, CCN_DTAG_Component, CCN_DTAG);
-  if (res == -1) return(res);
-  res = ccn_charbuf_append_tt(c, n, CCN_BLOB);
-  if (res == -1) return(res);
-  res = ccn_charbuf_append(c, component, n);
-  if (res == -1) return(res);
-  res = ccn_charbuf_append(c, closer, sizeof(closer));
-  return(res);
-}
-
-/**
- * Add a Component that is a NUL-terminated string.
- *
- * The component added consists of the bytes of the string without the NUL.
- * This function is convenient for those applications that construct 
- * component names from simple strings.
- * @returns 0, or -1 for error.
- */
-int 
-ccn_name_append_str(struct ccn_charbuf *c, const char *s)
-{
-  return(ccn_name_append(c, s, strlen(s)));
-}
-
-/**
- * Add a binary Component to a ccnb-encoded Name
- *
- * These are special components used for marking versions, fragments, etc.
- * @returns 0, or -1 for error
- * see doc/technical/NameConventions.html
- */
-int
-ccn_name_append_numeric(struct ccn_charbuf *c,
-                        enum ccn_marker marker, unsigned long long value)
-{
-  //uintmax_t v;
-  unsigned long long v;
-  int i;
-  char b[32];
-  
-  for (v = value, i = sizeof(b); v != 0 && i > 0; i--, v >>= 8)
-    b[i-1] = v & 0xff;
-  if (i < 1)
-    return(-1);
-  if (marker >= 0)
-    b[--i] = marker;
-  return(ccn_name_append(c, b + i, sizeof(b) - i));
-}
-
-/**
- * Add nonce Component to ccnb-encoded Name
- *
- * Uses %C1.N namespace.
- * @returns 0, or -1 for error
- * see doc/technical/NameConventions.html
- */
-int
-ccn_name_append_nonce(struct ccn_charbuf *c)
-{
-  const unsigned char pre[4] = { CCN_MARKER_CONTROL, '.', 'N', 0 };
-  unsigned char b[15];
-  
-  memcpy(b, pre, sizeof(pre));
-  ccn_random_bytes(b + sizeof(pre), sizeof(b) - sizeof(pre));
-  return(ccn_name_append(c, b, sizeof(b)));
-}
-
-/**
- * Add sequence of ccnb-encoded Components to a ccnb-encoded Name.
- *
- * start and stop are offsets from ccnb
- * @returns 0, or -1 for obvious error
- */
-int
-ccn_name_append_components(struct ccn_charbuf *c,
-                           const unsigned char *ccnb,
-                           size_t start, size_t stop)
-{
-  int res;
-  if (c->length < 2 || start > stop)
-    return(-1);
-  c->length -= 1;
-  ccn_charbuf_reserve(c, stop - start + 1);
-  res = ccn_charbuf_append(c, ccnb + start, stop - start);
-  if (res == -1) return(res);
-  res = ccn_charbuf_append_closer(c);
-  return(res);
-}
-
-/**
- * Extract a pointer to and size of component at
- * given index i.  The first component is index 0.
- * @returns 0, or -1 for error.
- */
-int
-ccn_name_comp_get(const unsigned char *data,
-                  const struct ccn_indexbuf *indexbuf,
-                  unsigned int i,
-                  const unsigned char **comp, size_t *size)
-{
-  int len;
-  struct ccn_buf_decoder decoder;
-  struct ccn_buf_decoder *d;
-  /* indexbuf should have an extra value marking end of last component,
-   so we need to use last 2 values */
-  if (indexbuf->n < 2 || i > indexbuf->n - 2) {
-    /* There isn't a component at this index */
-    return(-1);
-  }
-  len = indexbuf->buf[i + 1]-indexbuf->buf[i];
-  d = ccn_buf_decoder_start(&decoder, data + indexbuf->buf[i], len);
-  if (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
-    ccn_buf_advance(d);
-    if (ccn_buf_match_blob(d, comp, size))
-	    return(0);
-    *comp = d->buf + d->decoder.index;
-    *size = 0;
-    ccn_buf_check_close(d);
-    if (d->decoder.state >= 0)
-      return(0);
-  }
-  return(-1);
-}
-
-int
-ccn_name_comp_strcmp(const unsigned char *data,
-                     const struct ccn_indexbuf *indexbuf,
-                     unsigned int i, const char *val)
-{
-  const unsigned char *comp_ptr;
-  size_t comp_size;
-  
-  // XXX - We probably want somewhat different semantics in the API -
-  // comparing a string against a longer string with a 0 byte should
-  // not claim equality.
-  if (ccn_name_comp_get(data, indexbuf, i, &comp_ptr, &comp_size) == 0)
-    return(strncmp(val, (const char *)comp_ptr, comp_size));
-  /* Probably no such component, say query is greater-than */
-  return(1);
-}
-
-/**
- * Find Component boundaries in a ccnb-encoded Name.
- *
- * Thin veneer over ccn_parse_Name().
- * components arg may be NULL to just do a validity check
- *
- * @returns -1 for error, otherwise the number of Components.
- */
-int
-ccn_name_split(const struct ccn_charbuf *c, struct ccn_indexbuf *components)
-{
-  struct ccn_buf_decoder decoder;
-  struct ccn_buf_decoder *d;
-  d = ccn_buf_decoder_start(&decoder, c->buf, c->length);
-  return(ccn_parse_Name(d, components));
-}
-
-/**
- * Chop the name down to n components.
- * @param c contains a ccnb-encoded Name
- * @param components may be NULL; if provided it must be consistent with
- *        some prefix of the name, and is updated accordingly.
- * @param n is the number or components to leave, or, if negative, specifies
- *        how many components to remove,
- e.g. -1 will remove just the last component.
- * @returns -1 for error, otherwise the new number of Components
- */
-int
-ccn_name_chop(struct ccn_charbuf *c, struct ccn_indexbuf *components, int n)
-{
-  if (components == NULL) {
-    int res;
-    components = ccn_indexbuf_create();
-    if (components == NULL)
-      return(-1);
-    res = ccn_name_split(c, components);
-    if (res >= 0)
-      res = ccn_name_chop(c, components, n);
-    ccn_indexbuf_destroy(&components);
-    return(res);
-  }
-  /* Fix up components if needed. We could be a little smarter about this. */
-  if (components->n == 0 || components->buf[components->n-1] + 1 != c->length)
-    if (ccn_name_split(c, components) < 0)
-      return(-1);
-  if (n < 0)
-    n += (components->n - 1); /* APL-style indexing */
-  if (n < 0)
-    return(-1);
-  if (n < (int)(components->n)) {
-    c->length = components->buf[n];
-    ccn_charbuf_append_value(c, CCN_CLOSE, 1);
-    components->n = n + 1;
-    return(n);
-  }
-  return(-1);
-}
-
-/**
- * Advance the last Component of a Name to the next possible value.
- * @param c contains a ccnb-encoded Name to be updated.
- * @returns -1 for error, otherwise the number of Components
- */
-int
-ccn_name_next_sibling(struct ccn_charbuf *c)
-{
-  int res = -1;
-  struct ccn_indexbuf *ndx;
-  unsigned char *lastcomp = NULL;
-  size_t lastcompsize = 0;
-  size_t i;
-  int carry;
-  struct ccn_charbuf *newcomp;
-  
-  ndx = ccn_indexbuf_create();
-  if (ndx == NULL) goto Finish;
-  res = ccn_name_split(c, ndx);
-  if (res <= 0) {
-    res = -1;
-    goto Finish;
-  }
-  res = ccn_ref_tagged_BLOB(CCN_DTAG_Component, c->buf,
-                            ndx->buf[res-1], ndx->buf[res],
-                            (const unsigned char **)&lastcomp,
-                            &lastcompsize);
-  if (res < 0) goto Finish;
-  for (carry = 1, i = lastcompsize; carry && i > 0; i--) {
-    carry = (((++lastcomp[i-1]) & 0xFF) == 0x00);
-  }
-  if (carry) {
-    newcomp = ccn_charbuf_create();
-    res |= ccn_charbuf_append_value(newcomp, 0, 1);
-    res |= ccn_charbuf_append(newcomp, lastcomp, lastcompsize);
-    res |= ccn_name_chop(c, ndx, ndx->n - 2);
-    res |= ccn_name_append(c, newcomp->buf, newcomp->length);
-    ccn_charbuf_destroy(&newcomp);
-    if (res < 0) goto Finish;
-  }
-  res = ndx->n - 1;
-Finish:
-  ccn_indexbuf_destroy(&ndx);
-  return(res);
-}
-
diff --git a/in-progress/ccn/ccn_random.cc b/in-progress/ccn/ccn_random.cc
deleted file mode 100644
index 6176c79..0000000
--- a/in-progress/ccn/ccn_random.cc
+++ /dev/null
@@ -1,59 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ccn_random.h"
-#include <openssl/rand.h>
-//#include <openssl/rand.c>
-
-/**
- * Generate pseudo-random bytes.
- *
- * @param buf is the destination buffer
- * @param size is in bytes
- */
-void
-ccn_random_bytes(unsigned char *buf, size_t size)
-{
-  int num = size;
-  
-  if (num < 0 || num != (int)size)
-    abort();
-  RAND_bytes(buf, num);
-}
-
-/**
- * Feed some entropy to the random number generator.
- * 
- * @param buf is the source buffer
- * @param size is in bytes
- * @param bits_of_entropy is an estimate; use 0 to make me guess
- */
-void
-ccn_add_entropy(const void *buf, size_t size, int bits_of_entropy)
-{
-  int num = size;
-  
-  if (num < 0 || num != (int)size)
-    abort();
-  /* Supply a hopefully conservative estimate of entropy. */
-  if (bits_of_entropy <= 0)
-    bits_of_entropy = (num < 32) ? 1 : num / 32;
-  RAND_add((unsigned char *)buf, num, bits_of_entropy * 0.125);
-}
diff --git a/in-progress/ccn/ccn_random.h b/in-progress/ccn/ccn_random.h
deleted file mode 100644
index ddd0a38..0000000
--- a/in-progress/ccn/ccn_random.h
+++ /dev/null
@@ -1,50 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-/**
- * @file random.h
- * @brief Pseudo-random number generation
- * 
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2010 Palo Alto Research Center, Inc.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
- * This library 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
- * Lesser General Public License for more details. You should have received
- * a copy of the GNU Lesser General Public License along with this library;
- * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
- * Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef CCN_RANDOM_DEFINED
-#define CCN_RANDOM_DEFINED
-
-#include <stddef.h>
-#include <openssl/rand.h>
-
-void ccn_random_bytes(unsigned char *buf, size_t size);
-void ccn_add_entropy(const void *buf, size_t size, int bits_of_entropy);
-
-#endif
diff --git a/in-progress/ccnx-contentstore.cc b/in-progress/ccnx-contentstore.cc
deleted file mode 100644
index 61d6452..0000000
--- a/in-progress/ccnx-contentstore.cc
+++ /dev/null
@@ -1,123 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#include "ndn_contentstore.h"
-
-namespace ns3
-{
-namespace NDNabstraction
-{
-    
-ContentStore::ContentStore( int maxSize )
-: m_maxSize(maxSize) { }
-
-
-ContentStore::~ContentStore( ) 
-{ }
-
-//Find corresponding CS entry for the given content name
-CsEntry* 
-ContentStore::Lookup(const char *prefix )
-{
-	CriticalSection section(m_csMutex);
-    
-    struct CsEntry *result = NULL;
-    
-    HASH_FIND_STR (m_contentStore, prefix, result);
-    
-    if(result != NULL)
-        Promote (*result);
-    
-	return result;
-}
-
-
-
-//Add entry to content store, if content store is full, use LRU replacement
-void 
-ContentStore::Add( const char *contentName, int contentSize )
-{
-    CriticalSection section(m_csMutex);
-    
-    // removing the old record
-    struct CsEntry *tmp = NULL;
-    HASH_FIND_STR (m_contentStore, contentName, tmp);
-    HASH_DELETE (hh, m_contentStore,tmp);
-    //free(tmp);
-    
-    int size = (int)HASH_COUNT(m_contentStore);
-    
-	if(size == m_maxSize )
-	{
-		CsEntry *entry = m_LRU.back();
-        HASH_DELETE (hh, m_contentStore,entry);//_cs.erase( entry->contentName );
-		m_LRU.pop_back( );
-	}
-    
-	struct CsEntry *ce = (struct CsEntry*)malloc(sizeof(struct CsEntry));
-	ce->contentName = (char*)contentName;
-	ce->contentSize = contentSize;
-    
-	//_cs[ contentName ] = ce;
-    HASH_ADD_KEYPTR (hh, m_contentStore, ce->contentName, strlen(ce->contentName), ce);
-    
-	//CsEntry *ce_in_hash = &(_cs[ contentName ]);
-    struct CsEntry *ce_in_hash = NULL;
-    HASH_FIND_STR (m_contentStore, contentName, ce_in_hash);
-	m_LRU.push_front( ce_in_hash );
-	ce_in_hash->lruPosition = m_LRU.begin( );
-}
-
-
-//move the given CS entry to the head of the list
-void 
-ContentStore::Promote(CsEntry &ce )
-{
-	// should not lock mutex. Otherwise deadlocks will be welcome
-	if( m_LRU.front() == &ce ) return;
-    
-	//assert( *(ce.lruPosition)==&ce ); // should point to the same object
-    
-	// swaping positions in _lru
-	m_LRU.erase( ce.lruPosition );
-	m_LRU.push_front( &ce );
-	ce.lruPosition = m_LRU.begin( );
-    
-	//assert( *(ce.lruPosition)==&ce ); // should point to the same object
-}
-
-void 
-ContentStore::Dump()
-{
-	CriticalSection section(m_csMutex);
-    
-    struct CsEntry *s, *tmp;
-    
-    HASH_ITER(hh, m_contentStore, s, tmp) 
-    {
-        printf("-%s-", s->contentName);
-        /* ... it is safe to delete and free s here */
-    }
-    
-    printf("\n");
-    
-}
-}
-}
diff --git a/in-progress/ccnx-contentstore.h b/in-progress/ccnx-contentstore.h
deleted file mode 100644
index 7e49fb6..0000000
--- a/in-progress/ccnx-contentstore.h
+++ /dev/null
@@ -1,83 +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: Ilya Moiseenko <iliamo@cs.ucla.edu>
- */
-
-#ifndef ndn_contentstore_h
-#define	ndn_contentstore_h
-
-#include <ns3/system-mutex.h>
-#include <list>
-#include <string>
-#include "uthash.h"
-
-using namespace std;
-
-//size of content store
-#define NDN_CONTENT_STORE_SIZE 100
-
-namespace  ns3
-{
-namespace NDNabstraction
-{
-    
-class CsEntry;
-typedef list<CsEntry*>::iterator CsLruIterator;
-    
-//structure for CS entry
-struct CsEntry
-{
-    char *contentName;
-    int contentSize;
-    
-	CsLruIterator lruPosition;
-    UT_hash_handle hh;         /* makes this structure hashable */
-};
-
-
-class ContentStore
-{
-public:
-	ContentStore( int max_size=NDN_CONTENT_STORE_SIZE );
-	virtual ~ContentStore( );
-    
-	// Find corresponding CS entry for the given content name
-	CsEntry* Lookup( const char *prefix );
-	//bool isValid( const CsIterator &it ) { return it!=_cs.end(); }
-	
-	// Add new content to the content store. Old content will be replaced
-	void Add( const char *contentName, int contentSize );
-    
-	// Dump content store entries
-	void Dump( );
-    
-protected:
-	//move the given CS entry to the head of the list
-	void Promote( CsEntry &entry );
-    
-private:
-	int                   m_maxSize; // maximum number of entries in cache
-    
-    struct CsEntry  *m_contentStore;     // actual content store
-	list<CsEntry*>			  m_LRU;	// LRU index of the content store
-	SystemMutex				m_csMutex;   // just to make sure we are not
-};
-    
-}
-}
-#endif
diff --git a/in-progress/ccnx-cs.cpp b/in-progress/ccnx-cs.cpp
deleted file mode 100644
index c102cd5..0000000
--- a/in-progress/ccnx-cs.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* 
- * File:   ndn_cs.cpp
- * Author: cawka
- * 
- * Created on December 15, 2010, 2:17 PM
- */
-
-#include "ndn_cs.h"
-
-NdnCs::NdnCs( int maxSize )
-: _maxSize(maxSize) { }
-
-//NdnCs::NdnCs( constNdnCs& orig ) { }
-
-NdnCs::~NdnCs( ) { }
-
-//Find corresponding CS entry for the given content name
-CsIterator NdnCs::lookup( const string &prefix )
-{
-	QNThreadLock lock( &_csMutex );
-
-	CsIterator entry=_cs.find( prefix );
-	if( entry!=_cs.end() ) promote( entry->second );
-	return entry;
-}
-
-
-
-//Add entry to content store, if content store is full, use LRU replacement
-void NdnCs::add( const string &contentName, int contentSize )
-{
-	QNThreadLock lock( &_csMutex );
-
-	_cs.erase( contentName ); // removing the old record
-
-	if( _cs.size()==_maxSize )
-	{
-		CsEntry *entry=_lru.back();
-		_cs.erase( entry->contentName );
-		_lru.pop_back( );
-	}
-
-	CsEntry ce;
-	ce.contentName = contentName;
-	ce.contentSize = contentSize;
-
-	_cs[ contentName ] = ce;
-
-	CsEntry *ce_in_hash = &(_cs[ contentName ]);
-	_lru.push_front( ce_in_hash );
-	ce_in_hash->lruPosition = _lru.begin( );
-}
-
-
-//move the given CS entry to the head of the list
-void NdnCs::promote( CsEntry &ce )
-{
-	// should not lock mutex. Otherwise deadlocks will be welcome
-	if( _lru.front() == &ce ) return;
-
-	assert( *(ce.lruPosition)==&ce ); // should point to the same object
-
-	// swaping positions in _lru
-	_lru.erase( ce.lruPosition );
-	_lru.push_front( &ce );
-	ce.lruPosition = _lru.begin( );
-
-	assert( *(ce.lruPosition)==&ce ); // should point to the same object
-}
-
-void NdnCs::dump()
-{
-	QNThreadLock lock( &_csMutex );
-
-	for( CsRangeIterator it=_cs.begin(); it!=_cs.end(); ++it )
-	{
-		printf("-%s-", it->second.contentName.c_str() );
-	}
-
-    printf("\n");
-//    list<CsEntry *>::reverse_iterator rit;
-//
-//    for (rit = contentList->rbegin(); rit != contentList->rend(); rit ++)
-//    {
-//        temp = *rit;
-//        printf("=%s=", temp->contentName);
-//    }
-//
-//    printf("\n");
-}
diff --git a/in-progress/ccnx-cs.h b/in-progress/ccnx-cs.h
deleted file mode 100644
index 096b0c0..0000000
--- a/in-progress/ccnx-cs.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* 
- * File:   ndn_cs.h
- * Author: cawka
- *
- * Created on December 15, 2010, 2:17 PM
- */
-
-#ifndef NDN_CS_H
-#define	NDN_CS_H
-
-#include "ndn_common.h"
-#include "hash_helper.h"
-#include <qualnet_mutex.h>
-#include <list>
-#include <string>
-
-using namespace std;
-
-class CsEntry;
-typedef list<CsEntry*>::iterator CsLruIterator;
-
-//structure for CS entry
-struct CsEntry
-{
-    string contentName;
-    int contentSize;
-
-	CsLruIterator lruPosition;
-};
-
-typedef string_key_hash_t<CsEntry>::point_iterator CsIterator;
-typedef string_key_hash_t<CsEntry>::iterator CsRangeIterator;
-
-// class implementing NDN content store
-class NdnCs
-{
-public:
-	NdnCs( int max_size=NDN_CONTENT_STORE_SIZE );
-	virtual ~NdnCs( );
-
-	// Find corresponding CS entry for the given content name
-	CsIterator lookup( const string &prefix );
-	bool isValid( const CsIterator &it ) { return it!=_cs.end(); }
-	
-	// Add new content to the content store. Old content will be replaced
-	void add( const string &contentName, int contentSize );
-
-	// Dump content store entries
-	void dump( );
-
-protected:
-	//move the given CS entry to the head of the list
-	void promote( CsEntry &entry );
-
-private:
-	int							_maxSize; // maximum number of entries in cache
-
-	string_key_hash_t<CsEntry>	_cs;	// actual content store
-
-	list<CsEntry*>				_lru;	// LRU index of the content store
-	QNThreadMutex				_csMutex; // just to make sure we are not
-										  // getting problems with multiple threads
-};
-
-#endif	/* NDN_CS_H */
diff --git a/in-progress/ccnx-fib.cpp b/in-progress/ccnx-fib.cpp
deleted file mode 100644
index a8adbd0..0000000
--- a/in-progress/ccnx-fib.cpp
+++ /dev/null
@@ -1,300 +0,0 @@
-/* 
- * File:   ndn_fib.cpp
- * Author: cawka
- * 
- * Created on December 15, 2010, 1:54 PM
- */
-
-#include "ndn.h"
-#include "ndn_fib.h"
-
-#include <node.h>
-#include <buffer.h>
-#include <network_ip.h>
-#include <partition.h>
-#include <routing_ospfv2.h>
-#include <routing_bgp.h>
-
-//#define NDN_DEBUG_OSPF	0
-//#define NDN_DEBUG_OSPF_NODES 0
-
-//#define NDN_DUMP_FIB		0
-
-
-NdnFib::NdnFib( Ndn &node ) : _node(node) { }
-
-NdnFib::~NdnFib( ) { }
-
-
-//Find corresponding FIB entry for the given content name
-//Longest match is performed
-FibIterator NdnFib::lookup( const string &name )
-{
-	string prefix=name;
-
-	FibIterator entry;
-	do
-	{
-		entry=_fib.find( prefix );
-
-		prefix = GetLongestNamePrefix( prefix );
-	} while( !isValid(entry) && prefix.size()>0 );
-
-	return entry;
-}
-
-bool NdnFibNexthopSorter::operator()( const FibNexthop &first, const FibNexthop &second )
-{
-	// Right now is a very simple logic.
-	// Probably this logic should be changed later
-	if( first. cost==NETWORK_UNREACHABLE && second.cost>=0 ) return false;
-	if( second.cost==NETWORK_UNREACHABLE && first. cost>=0 ) return true;
-	return  first.cost < second.cost;
-}
-
-/**
- * Update FIB entry
- * If the entry exists, metric will be updated. Otherwise, new entry will be created
- * 
- * @param name				Prefix
- * @param interfaceIndex	Forwarding interface
- * @param metric			Routing metric
- * @param nextHop			Nexthop node address (IPv4)
- * @return true if a new entry created, false otherwise
- */
-bool NdnFib::update( const string &name, int interfaceIndex, int metric, NodeAddress nextHop )
-{
-	FibIterator entry = _fib.find( name );
-	if( isValid(entry) )
-	{
-		FibNexthopIterator nh = VALUE(entry).findNexthop( interfaceIndex );
-
-		if( !VALUE(entry).isValid(nh) )
-		{
-			nh = VALUE(entry).forwardingList.insert( VALUE(entry).forwardingList.begin(),
-											 FibNexthop(interfaceIndex,nextHop,metric) );
-		}
-		else
-		{
-			nh->cost = metric;
-			nh->nextHop = nextHop;
-		}
-
-		VALUE(entry).forwardingList.sort( NdnFibNexthopSorter() );
-
-		return false;
-	}
-
-	FibEntry &new_entry = _fib[name];
-	new_entry.forwardingList.push_back( FibNexthop(interfaceIndex,nextHop,metric) );
-
-	for( int interface=0; interface < _node.getNode()->numberInterfaces; interface++ )
-	{
-		NodeAddress src = NetworkIpGetInterfaceAddress( _node.getNode(), interface );
-
-		if( isValidLink(src) && interface!=interfaceIndex )
-		{
-			new_entry.forwardingList.push_back( FibNexthop(interface,0,NETWORK_UNREACHABLE) );
-		}
-	}
-
-	return true;
-}
-
-// helper for update call
-bool NdnFib::update( NodeAddress nodeId, int metric, NodeAddress nextHop )
-{
-	ostringstream os;
-	os << (int)nodeId;
-
-	int interface = NetworkIpGetInterfaceIndexForNextHop( _node.getNode(), nextHop );
-
-	return update( os.str(), interface, metric, nextHop );
-}
-
-// helper for update call
-bool NdnFib::update( NodeAddress nodeId, int interfaceIndex, int metric, NodeAddress nextHop )
-{
-	ostringstream os;
-	os << (int)nodeId;
-
-	int interface = NetworkIpGetInterfaceIndexForNextHop( _node.getNode(), nextHop );
-
-	return update( os.str(), interface, metric, nextHop ); //unknown metric
-}
-
-/**
- * Invalidate entries in FIB
- */
-void NdnFib::invalidate( )
-{
-	for( FibRangeIterator fib=_fib.begin(); fib!=_fib.end(); fib++ )
-	{
-		for( FibNexthopIterator nh=VALUE(fib).forwardingList.begin(); nh!=VALUE(fib).forwardingList.end(); nh++ )
-		{
-			nh->cost = NETWORK_UNREACHABLE;
-		}
-	}
-}
-
-//compute and update STO value for Fib Entry (similar to RFC 2988)
-//for now we pick the maximum rto of all forwardings
-void FibEntry::updateSto( )
-{
-    assert( forwardingList.size() > 0 );
-
-    clocktype max = 0;
-
-    for( FibNexthopIterator it = forwardingList.begin();
-		 it != forwardingList.end();
-		 it++ )
-    {
-        clocktype sto = it->srtt + NDN_RTO_K * it->rttvar;
-
-        if( sto > max )
-			max = sto;
-    }
-
-    this->sto = max;
-}
-
-
-/**
- * Updating FIB using data from OSPF
- * @param node
- * @param interface	-2	Invalid OSPF (to purge FIB)
- *					-1	Normal OSPF
- *					0-N	SPF was calcylated using only interface `interface'
- *
- * @bug	All local networks will always appear in routing table with cost == 1
- */
-void NdnFib::updateFibFromOSPFv2( int interface )
-{
-    Ospfv2Data* ospf = (Ospfv2Data*)NetworkIpGetRoutingProtocol(_node.getNode(), ROUTING_PROTOCOL_OSPFv2);
-
-	if( interface==-2 ) invalidate( );
-
-#ifdef NDN_DEBUG_OSPF
-	if( interface==-1 ) printf( "Routing/interface costs\n" );
-#endif // NDN_DEBUG_OSPF
-
-#ifdef NDN_DEBUG_OSPF_NODES
-	printf( "-- Node %d (interface %d) --\n", _node.getNode()->nodeId, interface );
-#endif // NDN_DEBUG_OSPF_NODES
-
-    Ospfv2RoutingTableRow* rowPtr = (Ospfv2RoutingTableRow*)
-            BUFFER_GetData(&ospf->routingTable.buffer);
-
-    for (int i = 0; i < ospf->routingTable.numRows; i++)
-    {
-		NodeAddress destNodeId = Ipv4ToNodeId( rowPtr[i].destAddr );
-
-		if( destNodeId!=-1 ) update( destNodeId, rowPtr[i].metric, rowPtr[i].nextHop );
-    }
-
-#ifdef NDN_DUMP_FIB
-	if( interface==-1 ) dump( );
-#endif
-}
-
-void NdnFib::updateFibFromBGP( )
-{
-	BgpData* bgp=(BgpData*)_node.getNode()->appData.exteriorGatewayVar;
-
-	assert( bgp->ip_version == NETWORK_IPV4 );
-
-	invalidate( );
-
-	int i=0;
-	int numEntriesInAdjRibIn=BUFFER_GetCurrentSize( &( bgp->adjRibIn ) )
-			/ sizeof(BgpRoutingInformationBase );
-
-	BgpRoutingInformationBase* adjRibInPtr=(BgpRoutingInformationBase*)
-			BUFFER_GetData( &( bgp->adjRibIn ) );
-
-	for( i=0; i < numEntriesInAdjRibIn; i++ )
-	{
-		assert( adjRibInPtr[i].nextHop.networkType == NETWORK_IPV4 );
-
-		NodeAddress destNodeId = Ipv4ToNodeId( GetIPv4Address(adjRibInPtr[i].destAddress.prefix) );
-
-		if( destNodeId!=-1 && adjRibInPtr[i].isValid != FALSE )
-		{
-			char destNodeStr[NDN_MAX_NAME_LENGTH];
-			memset(destNodeStr, 0, NDN_MAX_NAME_LENGTH);
-			sprintf(destNodeStr, "%d", destNodeId);
-
-			update( destNodeId,
-					adjRibInPtr[i].asPathList->pathSegmentLength / 2,
-					GetIPv4Address(adjRibInPtr[i].nextHop) );
-		}
-	}
-
-#ifdef NDN_DUMP_FIB
-	dump( );
-#endif
-}
-
-void NdnFib::updateFibFromIpRouting( )
-{
-	invalidate( );
-
-	for (int i = 0; i < _node.getNode()->partitionData->numNodes; i ++)
-    {
-		if( !_node.getNode()->networkData.networkVar->ndnEnabled ) continue;
-
-        NodeAddress destNode = _node.getNode()->partitionData->nodeData[i]->nodeId;
-		NodeAddress ipv4subnet = NodeIdToIpv4( destNode );
-
-		int interfaceIndex;
-		NodeAddress nextHopAddr;
-        NetworkGetInterfaceAndNextHopFromForwardingTable(
-			_node.getNode(), ipv4subnet, &interfaceIndex, &nextHopAddr );
-
-        if( interfaceIndex != NETWORK_UNREACHABLE )
-        {
-			update( destNode, interfaceIndex, 1, nextHopAddr );
-        }
-    }
-}
-
-
-
-void NdnFib::dump( )
-{
-	if( _node.getNode()->numberInterfaces==1 ) return;  // do not dump FIB for `virtual' nodes
-
-	printf( "Node %s: FIB\n", _node.getPrefix().c_str() );
-	printf( "  Dest prefix      Interfaces(Costs)                  \n" );
-	printf( "+-------------+--------------------------------------+\n" );
-
-	for( FibRangeIterator fib=_fib.begin(); fib!=_fib.end(); fib++ )
-	{
-		dump( fib );
-	}
-}
-
-void NdnFib::dump( const FibIterator &fib )
-{
-	printf( " %8s ", fib->first.c_str() );
-	for( FibNexthopIterator nh=VALUE(fib).forwardingList.begin(); nh!=VALUE(fib).forwardingList.end(); nh++ )
-	{
-		if( nh!=VALUE(fib).forwardingList.begin() ) printf( "," );
-		printf( "i%d(%d)", nh->interfaceIndex, nh->cost );
-	}
-	printf( "\n" );
-}
-
-void NdnFib::resetProbing()
-{
-    for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
-        VALUE(fib).needsProbing = true;
-}
-
-void NdnFib::updateInterfaceStatus( int interface, int status )
-{
-	for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
-	{
-		VALUE(fib).updateStatus( interface, status );
-	}
-}
\ No newline at end of file
diff --git a/in-progress/ccnx-fib.h b/in-progress/ccnx-fib.h
deleted file mode 100644
index 9a1c3d6..0000000
--- a/in-progress/ccnx-fib.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* 
- * File:   ndn_fib.h
- * Author: cawka
- *
- * Created on December 15, 2010, 1:54 PM
- */
-
-#ifndef NDN_FIB_H
-#define	NDN_FIB_H
-
-#include "hash_helper.h"
-#include <clock.h>
-#include <main.h>
-
-class Ndn;
-
-const int NDN_FIB_GREEN = 1;
-const int NDN_FIB_YELLOW = 2;
-const int NDN_FIB_RED = 3;
-
-//structure for Fib outgoing interface
-struct FibNexthop
-{
-    int interfaceIndex;     //interface index of the node
-	NodeAddress nextHop;	//next-hop
-	int cost;				//routing protocol cost to route an interest via this interface
-    int packetCount;        //record the number of packets forwarded using this interface
-
-	clocktype srtt;         //smoothed round-trip time
-    clocktype rttvar;       //round-trip time variation
-	
-	int status;				// Status of the next hop: 
-							//		- #NDN_FIB_GREEN
-							//		- #NDN_FIB_YELLOW
-							//		- #NDN_FIB_RED
-
-	bool operator==( int interface ) const { return interfaceIndex==interface; }
-	FibNexthop( ) {}
-	FibNexthop( int _interface, int _nextHop, int _cost )
-			: interfaceIndex(_interface), nextHop(_nextHop), cost(_cost)
-			, packetCount(1), srtt(0), rttvar(0), status(NDN_FIB_YELLOW) { }
-};
-
-typedef list<FibNexthop>::iterator FibNexthopIterator;
-typedef list<FibNexthop>::const_iterator FibNexthopConstIterator;
-
-//structure for FIB table entry
-struct FibEntry
-{
-    list<FibNexthop> forwardingList;
-    clocktype sto;	  //retransmission time out
-
-	bool needsProbing;      //set to true when probing timer goes out
-
-	FibEntry( ) : sto(0), needsProbing(false) { }
-
-	// Find nexthop record
-	inline FibNexthopIterator findNexthop( int interfaceIndex );
-	bool isValid( const FibNexthopIterator &nh )
-		{ return nh!=forwardingList.end(); }
-
-	// Compute and update RTO value for Fib Entry (RFC 2988)
-	// (for now we pick the maximum RTO of all forwardings)
-	void updateSto( );
-	
-	// Update status of FIB next hop
-	inline void updateStatus( int interface, int status );
-};
-
-typedef string_key_hash_t<FibEntry>::point_iterator FibIterator;
-typedef string_key_hash_t<FibEntry>::iterator FibRangeIterator;
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-// Class implementing FIB functionality
-class NdnFib
-{
-public:
-	NdnFib( Ndn &node );
-	virtual ~NdnFib( );
-
-	// Invalidate entries in FIB
-	// Will leave FIB records in hash, but assign metric=NETWORK_UNREACHABLE
-	void invalidate( );
-
-	//Find corresponding FIB entry for the given content name
-	//Longest match is performed
-	FibIterator lookup( const string &name );
-	bool isValid( const FibIterator &it ) { return it!=_fib.end(); }
-
-	/**
-	 * Update FIB entry
-	 * If the entry exists, metric will be updated. Otherwise, new entry will be created
-	 *
-	 * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
-	 *
-	 * @param name				Prefix
-	 * @param interfaceIndex	Forwarding interface
-	 * @param metric			Routing metric
-	 * @param nextHop			Nexthop node address (IPv4)
-	 * @return true if a new entry created, false otherwise
-	 */
-	bool update( const string &name, int interfaceIndex, int metric, NodeAddress nextHop );
-	bool update( NodeAddress nodeId, int interfaceIndex, int metric, NodeAddress nextHop );
-	bool update( NodeAddress nodeId, int metric, NodeAddress nextHop );
-
-	// Update Fib from OSPF routing table (through a hack in OSPF algorithm)
-	void updateFibFromOSPFv2( int interface );
-
-	// Update Fib from BGP routing table (using info from RibIn)
-	void updateFibFromBGP( );
-
-	// Update Fib from IP routing table
-	void updateFibFromIpRouting( );
-
-	// Update the status for all FIB records for the specified interface
-	void updateInterfaceStatus( int interface, int status );
-	
-	void dump( );
-	void dump( const FibIterator &fib );
-
-    void resetProbing();    //reset needsProbing field for every FibEntry
-private:
-
-private:
-	Ndn &_node;
-
-	string_key_hash_t<FibEntry> _fib;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-class NdnFibNexthopSorter
-{
-public:
-	bool operator()( const FibNexthop &first, const FibNexthop &second );
-};
-
-FibNexthopIterator FibEntry::findNexthop( int interfaceIndex )
-{
-	return find( forwardingList.begin( ),
-				 forwardingList.end( ),
-				 interfaceIndex );
-}
-
-//inline FibNexthopIterator FibEntry::findBestNexthop( int bestNum, int excludeInterface )
-//{
-//	// First adjust number of available interfaces (to make sure we have correct ranking function)
-//	int num_valid_interfaces = forwardingList.size();
-//	FibNexthopIterator nh;
-//	for( nh=forwardingList.begin(); nh!=forwardingList.end(); nh++ )
-//	{
-//		if( nh->interfaceIndex==excludeInterface ) num_valid_interfaces--;
-//	}
-//
-//	if( num_valid_interfaces==0 ) return forwardingList.end();
-//
-//	bestNum = bestNum % num_valid_interfaces;
-//	int i=0;
-//	for( nh=forwardingList.begin(); nh!=forwardingList.end(); nh++ ) // skip bestNum % size() FIB records
-//	{
-//		if( nh->interfaceIndex==excludeInterface ) continue;
-//		if( i==bestNum ) break;
-//
-//		i++;
-//	}
-//
-//	if( nh!=forwardingList.end() )
-//	{
-//		assert( nh->interfaceIndex!=excludeInterface );
-//// 		printf( "%d best => i%d\n", bestNum, nh->interfaceIndex );
-//	}
-//// 	else
-//// 	{
-//// 		printf( "No other hops available\n" );
-//// 	}
-//
-//
-//	return nh;
-//}
-
-void FibEntry::updateStatus( int interface, int status )
-{
-	FibNexthopIterator nh = findNexthop( interface );
-	if( isValid(nh) )
-	{
-		nh->status = status;
-	}
-}
-
-#endif	/* NDN_FIB_H */
diff --git a/in-progress/ccnx-pit.cpp b/in-progress/ccnx-pit.cpp
deleted file mode 100644
index 5d10b90..0000000
--- a/in-progress/ccnx-pit.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-//
-// Copyright (c) 2010,2011 UCLA
-//
-// 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: 
-//
-
-#include "ccnx-pit.h"
-#include <algorithm>
-
-CcnxPit::CcnxPit( Ccnx &node )
-: _node(node)
-{
-};
-
-CcnxPit::~CcnxPit( ) { }
-
-//Find corresponding CS entry for the given content name
-PitIterator CcnxPit::lookup( const string &prefix )
-{
-	QNThreadLock lock( &_pitMutex );
-
-	PitIterator entry=_pit.find( prefix );
-	return entry;
-}
-
-// add new PIT entry
-bool CcnxPit::add( const string &name, const PitIncomingInterest &interest )
-{
-	QNThreadLock lock( &_pitMutex );
-
-	PitEntry *entry=NULL;
-
-	PitIterator existent_entry = _pit.find( name );
-	if( isValid(existent_entry) )
-	{
-		if( VALUE(existent_entry).timerExpired )
-		{
-			_node.fillAvailableInterfacesInPitEntry( VALUE(existent_entry) );
-		}
-
-		add( VALUE(existent_entry), interest );
-	}
-	else
-	{
-		PitEntry &entry = _pit[ name ];
-		entry.contentName  = name;
-
-		_node.fillAvailableInterfacesInPitEntry( entry );
-
-		add( entry, interest );
-	}
-}
-
-// Remove expired records from PIT
-void CcnxPit::cleanExpired( clocktype time )
-{
-	QNThreadLock lock( &_pitMutex );
-
-    while( !_pitExpirationList.empty() )
-    {
-		PitExpirationIterator entry = _pitExpirationList.begin( );
-
-        if( VALUE(entry)->expireTime <= time )
-        {
-			deleteIncomingInterest( *(KEY(entry)), VALUE(entry)->interfaceIndex );
-
-			// delete entry if all incoming interests expired
-			if( KEY(entry)->incomingInterests.size()==0 )
-			{
-				_pit.erase( KEY(entry)->contentName );
-			}
-        }
-        else
-            break;
-    }
-}
-
-//delete PIT entry
-void CcnxPit::erase( const string &name )
-{
-	// should not call `lookup' method !!!
-	
-	QNThreadLock lock( &_pitMutex );
-
-    PitIterator pe = _pit.find( name );
-	
-	if( !isValid(pe) ) return;
-
-	if( VALUE(pe).timerMsg ) MESSAGE_CancelSelfMsg( _node.getNode(), VALUE(pe).timerMsg );
-
-	PitIncomingIterator it = VALUE(pe).incomingInterests.begin();
-	while( it!=VALUE(pe).incomingInterests.end() )
-	{
-		deleteIncomingInterest( VALUE(pe), it );
-
-		it = VALUE(pe).incomingInterests.begin();
-	}
-
-	resetPendingState( VALUE(pe) );
-
-	_pit.erase( name );
-}
-
-//delete incoming interest from PIT entry
-//return 0 if interest does not exist, 1 otherwise
-bool CcnxPit::deleteIncomingInterest( PitEntry &pe, int interfaceIndex )
-{
-	// should not lock thread !!! Otherwise there will be a deadlock
-    if( pe.incomingInterests.size()==0 ) return false; //nothing to delete. Can happen when duplicate data arrives to the node
-
-    PitIncomingIterator it = findIncoming( pe, interfaceIndex );
-
-	if( !isValid(pe, it) ) return false;
-
-	deleteIncomingInterest( pe, it );
-
-    return true;
-}
-
-void CcnxPit::deleteAllIncomingInterests( PitEntry &pe )
-{
-	PitIncomingIterator it = pe.incomingInterests.begin();
-	while( it!=pe.incomingInterests.end() )
-	{
-		deleteIncomingInterest( pe, it );
-
-		it = pe.incomingInterests.begin();
-	}
-}
-
-void CcnxPit::deleteIncomingInterest( PitEntry &pe, PitIncomingIterator it )
-{
-	assert( KEY(it->expirationPosition)==&pe );
-	assert( VALUE(it->expirationPosition)->interfaceIndex==it->interfaceIndex );
-
-	_pitExpirationList.erase( it->expirationPosition );
-	pe.incomingInterests.erase( it );
-}
-
-//add new incoming interest to PIT entry
-//returns false if interface already exists, true otherwise
-bool CcnxPit::add( PitEntry &pe, const PitIncomingInterest &interest )
-{
-	pe.availableInterfaces.remove( interest.interfaceIndex );
-
-    PitIncomingIterator it=findIncoming( pe, interest.interfaceIndex );
-
-	if( isValid(pe, it) )
-	{
-		//update expiration time
-		it->expireTime = interest.expireTime;
-		it->nonce = interest.nonce;
-
-		//move Interest to the end of the node's Interest list
-		_pitExpirationList.erase( it->expirationPosition );
-		_pitExpirationList.push_back( PitExpirationEntry(&pe,&(*it)) );
-		
-		it->expirationPosition = --_pitExpirationList.end();
-		return false;
-	}
-
-	pe.incomingInterests.push_back( interest );
-	PitIncomingInterest *incoming = &pe.incomingInterests.back();
-
-    //Add to the end of the node's Interest list
-	_pitExpirationList.push_back( PitExpirationEntry(&pe,incoming) );
-	incoming->expirationPosition = -- _pitExpirationList.end();
-
-    return true;
-}
-
-//add new outgoing interest to PIT entry
-//returns false  interface limit reached or interest exists and is still marked as outstanding (nonce will not be changed)
-//		  true otherwise
-int CcnxPit::add( PitEntry &pe, const PitOutgoingInterest &interest )
-{
-	if( _node.isRateLimit && _bucketsPerInterface[interest.interfaceIndex]+1.0 >= maxBucketsPerInterface[interest.interfaceIndex] )
-	{
-//		printf( "DEBUG: bucket overflow. Should not forward anything to interface %d\n", interest.interfaceIndex );
-		return false;
-	}
-
-	_bucketsPerInterface[interest.interfaceIndex] = _bucketsPerInterface[interest.interfaceIndex] + 1.0;
-	pe.availableInterfaces.remove( interest.interfaceIndex );
-
-	PitOutgoingIterator it = findOutgoing(pe, interest.interfaceIndex);
-	if( isValid(pe, it) )
-    {
-		if( it->outstanding ) return false;
-
-        it->retxNum ++;
-        it->nonce = interest.nonce;
-		it->outstanding = true;
-		it->waitingInVain = false;
-    }
-	else
-	{
-		//add to the head of the list
-		pe.outgoingInterests.push_front( interest );
-	}
-	
-    return true;
-}
-
-void CcnxPit::resetPendingState( PitEntry &pe )
-{
-	for( PitOutgoingIterator it = pe.outgoingInterests.begin();
-		 it != pe.outgoingInterests.end();
-		 it++ )
-	{
-		it->outstanding = false;
-	}
-}
-
-void CcnxPit::leakBuckets( )
-{
-	for( PitBucketIterator it=_bucketsPerInterface.begin(); 
-		 it != _bucketsPerInterface.end();
-		 it++ )
-	{
-		it->second = max( 0.0, it->second - leakSize[it->first] );
-	}
-}
-
-void CcnxPit::leakBucket( int interface, int amount )
-{
-	_bucketsPerInterface[interface] = 
-			max( 0.0, _bucketsPerInterface[interface] - amount );
-}
diff --git a/in-progress/ccnx-pit.h b/in-progress/ccnx-pit.h
deleted file mode 100644
index 83fad09..0000000
--- a/in-progress/ccnx-pit.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-//
-// Copyright (c) 2010,2011 UCLA
-//
-// 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: 
-//
-
-#ifndef CCNX_PIT_H
-#define	CCNX_PIT_H
-
-#include "ns3/nstime.h"
-#include "hash-helper.h"
-#include <list>
-
-namespace ns3 {
-
-class Ccnx;
-class PitEntry;
-class PitIncomingInterest;
-typedef pair<PitEntry*,PitIncomingInterest*> PitExpirationEntry;
-typedef list<PitExpirationEntry>::iterator PitExpirationIterator;
-
-struct PitIncomingInterest
-{
-  int interfaceIndex;     // interface index of the incoming Interest
-  Time expireTime;        // life time of the incoming Interest
-  int nonce;				// nonce of the last received incoming Interest on this interface
-
-  PitExpirationIterator expirationPosition;
-
-public:
-PitIncomingInterest( int _interface, clocktype _expire, int _nonce )
-: interfaceIndex(_interface)
-, expireTime(_expire)
-	, nonce(_nonce)
-  { };
-
-  bool operator==( const PitIncomingInterest &dst ) { return interfaceIndex==dst.interfaceIndex; }
-  bool operator==( int interface ) { return interfaceIndex==interface; }
-};
-
-struct PitOutgoingInterest
-{
-  int interfaceIndex;
-  clocktype sendTime;     //time when the first outgoing interest is sent
-  int retxNum;            //number of retransmission
-  int nonce;              //nonce of the outgoing Interest
-  bool outstanding;		//flag to indicate that this interest is currently pending
-  bool waitingInVain;		//when flag is set, we do not expect data for this interest, only a small hope that it will happen
-	
-public:
-PitOutgoingInterest( int interface, clocktype time, int nonce )
-: interfaceIndex(interface)
-, sendTime( time )
-	, retxNum( 0 )
-	, nonce( nonce )
-	, outstanding( true )
-	, waitingInVain( false )
-  { };
-
-  bool operator==( const PitIncomingInterest &dst ) { return interfaceIndex==dst.interfaceIndex; }
-  bool operator==( int interface ) { return interfaceIndex==interface; }
-};
-
-
-//structure for PIT entry
-struct PitEntry
-{
-  string contentName;
-  list<PitIncomingInterest> incomingInterests;
-  list<PitOutgoingInterest> outgoingInterests;
-	
-  bool timerExpired;      
-  int  counterExpirations; //whether timer is expired (+ number of times timer expired)
-
-  /**
-   * This variable provides a list of interfaces that will be tried to propagate interest
-   *
-   * It should be initialized with all available interfaces upon reception of first or
-   * any retransmitted (i.e., after STO expired), but not duplicate interests
-   *  
-   * Reaction to duplicate interests depends on strategy. 
-   * 
-   * In case of flooding, this variable should always be empty (it is filled initially with
-   * all avaialble interfaces and then immediately emptied by interest flooding)
-   * 
-   * In case of routing strategies, this list will guide (and limit) the local recovery process
-   */
-  list<int> availableInterfaces;
-
-  Message *timerMsg;      //the timer message, used to cancel message if data is received
-
-  // Changing PIT removal policy. From now on it will be deleted only when all outgoing
-  // interests are satisfied
-  //
-  //	bool dontDeleteOnFirstData;	//don't delete when first data packet comes 
-  //								//(PIT will be deleted only upon timeout or reception data
-  //								//packets or prunes for all outgoing interests)
-
-public:
-PitEntry()
-: timerExpired( false )
-, counterExpirations( 0 )
-	, timerMsg( NULL )
-  { }
-	
-  inline void fillAvailableInterfacesFromFIB( const FibEntry &fe );
-
-  // Find best candidate, skipping `skip' first candidates (modulo availableInterfaces.size())
-  // !!! assert( availableInterfaces.size()>0 ) !!!
-  inline int findBestCandidate( int skip = 0 );
-	
-  // Get number of outgoing interests that we're expecting data from
-  inline size_t numberOfPromisingInterests( ) const; 
-};
-
-typedef string_key_hash_t<PitEntry>::point_iterator PitIterator;
-typedef string_key_hash_t<PitEntry>::iterator PitRangeIterator;
-
-typedef list<PitIncomingInterest>::iterator PitIncomingIterator;
-typedef list<PitOutgoingInterest>::iterator PitOutgoingIterator;
-typedef list<PitOutgoingInterest>::const_iterator PitOutgoingConstIterator;
-
-typedef map<int,int> PitCounter;
-typedef map<int,int>::iterator PitCounterIterator;
-
-typedef map<int,double> PitBucket;
-typedef map<int,double>::iterator PitBucketIterator;
-
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-// class implementing Pending Interests Table
-class CcnxPit
-{
- public:
-  /**
-   * PIT constructor
-   */
-  CcnxPit( Ccnx &node );
-  virtual ~CcnxPit( );
-
-  //Find corresponding PIT entry for the given content name
-  PitIterator lookup( const string &prefix );
-  bool isValid( const PitIterator &it ) { return it!=_pit.end(); }
-
-  inline PitIncomingIterator findIncoming( PitEntry &pe, int interfaceIndex );
-  inline bool isValid( PitEntry &pe, PitIncomingIterator it );
-  inline PitOutgoingIterator findOutgoing( PitEntry &pe, int interfaceIndex );
-  inline bool isValid( PitEntry &pe, PitOutgoingIterator it );
-
-  // Add a new PIT entry and a correspondent new incoming interest
-  bool add( const string &contentName, const PitIncomingInterest &interest );
-
-  // Add a new outgoing interest
-  int  add( PitEntry &pe, const PitOutgoingInterest &interest );
-
-  // remove a PIT entry
-  void erase( const string &contentName );
-	
-  //	inline bool InterestAlreadyForwarded( PitEntry &pe, int interfaceIndex );
-
-  // Remove expired records from PIT
-  void cleanExpired( clocktype time );
-
-  // Dump content store entries
-  void dump( );
-
-  // Reset pending state in outgoing interests
-  void resetPendingState( PitEntry &pe );
-
-  //	// Check if there are any interfaces that we haven't sent data to yet
-  //	bool areFreeInterfaces( PitEntry &pe, int interface );
-
-  // Periodically generate pre-calculated number of tokens (leak buckets)
-  void leakBuckets( );
-	
-  // Selectively leak a bucket
-  void leakBucket( int interface, int amount );
-
-  // Delete incoming interest for the interface
-  bool deleteIncomingInterest( PitEntry &pe, int interfaceIndex );
-
-  // Remove all incoming interests
-  void deleteAllIncomingInterests( PitEntry &pe );
-	
- public:
-  PitBucket				 maxBucketsPerInterface; // maximum number of buckets. Automatically computed based on link capacity
-  // averaging over 1 second (bandwidth * 1second)
-  PitBucket				 leakSize;				 // size of a periodic bucket leak
-	
- private:
-  bool add( PitEntry &pe, const PitIncomingInterest &interest );
-  void deleteIncomingInterest( PitEntry &pe, PitIncomingIterator it );
-
- private:
-  Ccnx &_node;
-
-  string_key_hash_t<PitEntry> _pit;
-
-  list<PitExpirationEntry> _pitExpirationList;  //list of incoming Interests sorted by expiration time
-
-  PitBucket				 _bucketsPerInterface;	// pending interface counter per interface
-	
-  QNThreadMutex			 _pitMutex; // just to make sure
-};
-
-////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-PitIncomingIterator CcnxPit::findIncoming( PitEntry &pe, int interfaceIndex )
-{
-  return find( pe.incomingInterests.begin( ),
-			   pe.incomingInterests.end( ),
-			   interfaceIndex );
-}
-
-PitOutgoingIterator CcnxPit::findOutgoing( PitEntry &pe, int interfaceIndex )
-{
-  return find( pe.outgoingInterests.begin( ),
-			   pe.outgoingInterests.end( ),
-			   interfaceIndex );
-}
-
-bool CcnxPit::isValid( PitEntry &pe, PitIncomingIterator it )
-{
-  return it!=pe.incomingInterests.end( );
-}
-
-bool CcnxPit::isValid( PitEntry &pe, PitOutgoingIterator it )
-{
-  return it!=pe.outgoingInterests.end( );
-}
-
-int PitEntry::findBestCandidate( int skip/* = 0*/ )
-{
-  assert( availableInterfaces.size()>0 );
-
-  skip = skip % availableInterfaces.size();
-  list<int>::iterator candidate = availableInterfaces.begin( );
-  while( skip>0 /* && candidate!=availableInterfaces.end() */ ) { skip--; candidate++; }
-
-  return *candidate;
-}
-
-size_t PitEntry::numberOfPromisingInterests( ) const
-{
-  size_t count = 0;
-	
-  for( PitOutgoingConstIterator i = outgoingInterests.begin();
-	   i!=outgoingInterests.end();
-	   i++ )
-	{
-	  if( !i->waitingInVain ) count++;
-	}
-
-  return count;
-}
-
-} // namespace ns3
-
-#endif	/* CCNX_PIT_H */
diff --git a/in-progress/ccnx-rit.cpp b/in-progress/ccnx-rit.cpp
deleted file mode 100644
index b84f9d0..0000000
--- a/in-progress/ccnx-rit.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 
- * File:   ndn_rit.cpp
- * Author: cawka
- * 
- * Created on December 15, 2010, 2:02 PM
- */
-
-#include "ndn_rit.h"
-
-NdnRit::NdnRit( ) { }
-
-NdnRit::~NdnRit( ) { }
-
-
-//find corresponding RIT entry for the given nonce
-RitIterator NdnRit::lookup( int nonce )
-{
-	QNThreadLock lock( &_ritMutex );
-
-	RitIterator entry=_rit.find( nonce );
-	return entry;
-}
-
-
-// add new RIT entry
-// returns false if entry already exists, otherwise returns true
-bool NdnRit::add( int nonce, clocktype expire )
-{
-	QNThreadLock lock( &_ritMutex );
-
-	RitIterator entry=_rit.find( nonce );
-	if( isValid(entry) ) return false;
-
-    RitEntry re;
-    re.nonce = nonce;
-	re.expireTime = expire;
-
-	_rit[ nonce ] = re;
-
-	_ritExpirationList.push_back( &(_rit[nonce]) );
-}
-
-
-void NdnRit::cleanExpired( clocktype time )
-{
-	QNThreadLock lock( &_ritMutex );
-
-	while( !_ritExpirationList.empty() )
-    {
-        RitEntry *head = _ritExpirationList.front( );
-
-        if( head->expireTime <= time )
-		{
-			//delete the head RIT entry
-			_rit.erase( head->nonce );
-			_ritExpirationList.pop_front( );
-		}
-        else
-            break;
-    }
-    //printf("Node %d: RIT entries\n", node->nodeId);
-    //PrintRitEntries(ndn->riList);
-}
-
diff --git a/in-progress/ccnx-rit.h b/in-progress/ccnx-rit.h
deleted file mode 100644
index 4a03bda..0000000
--- a/in-progress/ccnx-rit.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* 
- * File:   ndn_rit.h
- * Author: cawka
- *
- * Created on December 15, 2010, 2:02 PM
- */
-
-#ifndef NDN_RIT_H
-#define	NDN_RIT_H
-
-#include "hash_helper.h"
-#include <qualnet_mutex.h>
-#include <clock.h>
-#include <list>
-using namespace std;
-
-//recent interest
-struct RitEntry
-{
-    int nonce;
-    clocktype expireTime;  //RIT entries will stay in the table for a while before being cleaned out
-};
-
-typedef int_key_hash_t<RitEntry>::point_iterator RitIterator;
-typedef int_key_hash_t<RitEntry>::iterator RitRangeIterator;
-
-class NdnRit
-{
-public:
-	NdnRit( );
-	virtual ~NdnRit( );
-
-	//Find corresponding RIT entry for the given content name
-	RitIterator lookup( int nonce );
-	bool isValid( const RitIterator &it ) { return it!=_rit.end(); }
-
-	//add new RIT entry
-	bool add( int nonce, clocktype expireTime );
-
-	// Delete expired records
-	void cleanExpired( clocktype time );
-	
-private:
-	int_key_hash_t<RitEntry> _rit;
-
-	list<RitEntry*> _ritExpirationList;
-
-	QNThreadMutex   _ritMutex;
-};
-
-#endif	/* NdnRit_H */
-
diff --git a/model/ccnx-content-object-header.cc b/model/ccnx-content-object-header.cc
index e567207..d1ad0cf 100644
--- a/model/ccnx-content-object-header.cc
+++ b/model/ccnx-content-object-header.cc
@@ -37,6 +37,7 @@
 CcnxContentObjectHeader::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxContentObjectHeader")
+    .SetGroupName ("Ccnx")
     .SetParent<Header> ()
     .AddConstructor<CcnxContentObjectHeader> ()
     ;
diff --git a/model/ccnx-content-object-header.h b/model/ccnx-content-object-header.h
index c26052b..97a8d3d 100644
--- a/model/ccnx-content-object-header.h
+++ b/model/ccnx-content-object-header.h
@@ -24,6 +24,7 @@
 
 #include "ns3/integer.h"
 #include "ns3/header.h"
+#include "ns3/trailer.h"
 
 #include <string>
 #include <vector>
@@ -101,7 +102,7 @@
  * ContentObjectTail should always be 2 bytes, representing two closing tags:
  * "</Content><ContentObject>"
  */
-class CcnxContentObjectTail : public Header
+class CcnxContentObjectTail : public Trailer
 {
 public:
   CcnxContentObjectTail ();
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index 31a9fb3..b526308 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -16,88 +16,137 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
  */
 
 #include "ccnx-content-store.h"
 #include "ns3/log.h"
-
+#include "ns3/packet.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+#include "ns3/uinteger.h"
 
 NS_LOG_COMPONENT_DEFINE ("CcnxContentStore");
 
 namespace ns3
 {
-        
-CcnxContentStore::CcnxContentStore( int maxSize )
-    : m_maxSize(maxSize) { }
+
+NS_OBJECT_ENSURE_REGISTERED (CcnxContentStore);
+
+using namespace __ccnx_private;
+
+TypeId 
+CcnxContentStore::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CcnxContentStore")
+    .SetGroupName ("Ccnx")
+    .SetParent<Object> ()
+    .AddConstructor<CcnxContentStore> ()
+    .AddAttribute ("Size",
+                   "Maximum number of packets that content storage can hold",
+                   UintegerValue (100),
+                   MakeUintegerAccessor (&CcnxContentStore::SetMaxSize,
+                                         &CcnxContentStore::GetMaxSize),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+
+  return tid;
+}
+
+CcnxContentObjectTail CcnxContentStoreEntry::m_tail;
+
+CcnxContentStoreEntry::CcnxContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
+  : m_header (header)
+{
+  m_packet = packet->Copy ();
+  m_packet->RemoveHeader (*header);
+  m_packet->RemoveTrailer (m_tail);
+}
+
+Ptr<Packet>
+CcnxContentStoreEntry::GetFullyFormedCcnxPacket () const
+{
+  Ptr<Packet> packet = m_packet->Copy ();
+  packet->AddHeader (*m_header);
+  packet->AddTrailer (m_tail);
+  return packet;
+}
+
+// /// Disabled copy constructor
+// CcnxContentStoreEntry::CcnxContentStoreEntry (const CcnxContentStoreEntry &o)
+// {
+// }
+
+// /// Disables copy operator
+// CcnxContentStoreEntry& CcnxContentStoreEntry::operator= (const CcnxContentStoreEntry &o)
+// {
+//   return *this;
+// }
+
+
+
+CcnxContentStore::CcnxContentStore( )
+  : m_maxSize(100) { } // this value shouldn't matter, NS-3 should call SetSize with default value specified in AddAttribute earlier
         
 CcnxContentStore::~CcnxContentStore( ) 
-    { }
+{ }
 
-//Find corresponding CS entry for the given content name
-CsEntry* 
-CcnxContentStore::Lookup(const string prefix )
+/// Disabled copy constructor
+CcnxContentStore::CcnxContentStore (const CcnxContentStore &o)
 {
-    CriticalSection section(m_csMutex);
-        
-    CsEntry *result = &(m_contentStore.at(prefix));
-    
-    if(result != NULL)
-        Promote (*result);
-        
-    return result;
+}
+
+/// Disables copy operator
+CcnxContentStore& CcnxContentStore::operator= (const CcnxContentStore &o)
+{
+  return *this;
+}
+
+
+Ptr<Packet>
+CcnxContentStore::Lookup (Ptr<const CcnxInterestHeader> interest)
+{
+  CcnxContentStoreContainer::type::iterator it = m_contentStore.get<hash> ().find (interest->GetName ());
+  if (it != m_contentStore.end ())
+    {
+      // promote entry to the top
+      m_contentStore.get<mru> ().relocate (m_contentStore.get<mru> ().begin (),
+                                           m_contentStore.project<mru> (it));
+
+      // return fully formed CCNx packet
+      return it->GetFullyFormedCcnxPacket ();
+    }
+  return 0;
 }   
     
-//move the given CS entry to the head of the list
 void 
-CcnxContentStore::Promote(CsEntry &ce )
+CcnxContentStore::Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet)
 {
-    // should not lock mutex. Otherwise deadlocks will be welcome
-    if( m_LRU.front() == &ce ) return;
-        
-    //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-        
-    // swaping positions in _lru
-    m_LRU.erase( ce.lruPosition );
-    m_LRU.push_front( &ce );
-    ce.lruPosition = m_LRU.begin( );
-        
-    //assert( *(ce.lruPosition)==&ce ); // should point to the same object
-}
-    
-//Add entry to content store, if content store is full, use LRU replacement
-void 
-CcnxContentStore::Add( const string contentName, int contentSize )
-{
-    CriticalSection section(m_csMutex);
-        
-    m_contentStore.erase(m_contentStore.find(contentName));
-    
-    if((int)m_contentStore.size() == m_maxSize )
-    {
-        CsEntry *entry = m_LRU.back();
-        m_contentStore.erase(m_contentStore.find(entry->contentName));
-        m_LRU.pop_back( );
+  CcnxContentStoreContainer::type::iterator it = m_contentStore.get<hash> ().find (header->GetName ());
+  if (it == m_contentStore.end ())
+    { // add entry to the top
+      m_contentStore.get<mru> ().push_front (CcnxContentStoreEntry (header, packet));
+      if (m_contentStore.size () > m_maxSize)
+        m_contentStore.get<mru> ().pop_back ();
     }
-        
-    CsEntry ce;
-    ce.contentName = contentName;
-    ce.contentSize = contentSize;
-    
-    m_contentStore[contentName] = ce;
-    
-    CsEntry *ce_in_hash = &(m_contentStore.at(contentName));
-    m_LRU.push_front( ce_in_hash );
-    ce_in_hash->lruPosition = m_LRU.begin( );
-}
-    
-void 
-CcnxContentStore::Dump()
-{
-    CriticalSection section(m_csMutex);
-        
-    BOOST_FOREACH(string_key_hash_t<CsEntry>::value_type i, m_contentStore) 
+  else
     {
-        NS_LOG_INFO ("Key = " << i.first << " Value = " << i.second.contentName);
+      // promote entry to the top
+      m_contentStore.get<mru> ().relocate (m_contentStore.get<mru> ().begin (),
+                                           m_contentStore.project<mru> (it));
     }
 }
-}
\ No newline at end of file
+    
+void 
+CcnxContentStore::Print() const
+{
+  for( DUMP_INDEX::type::iterator it=m_contentStore.get<DUMP_INDEX_TAG> ().begin ();
+       it != m_contentStore.get<DUMP_INDEX_TAG> ().end ();
+       it++
+       )
+    {
+      NS_LOG_INFO (it->GetName ());
+    }
+}
+
+} // namespace ns3
diff --git a/model/ccnx-content-store.h b/model/ccnx-content-store.h
index 58e060e..29b838a 100644
--- a/model/ccnx-content-store.h
+++ b/model/ccnx-content-store.h
@@ -18,60 +18,327 @@
  * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
  */
 
-#ifndef ccnx_content_store_h
-#define	ccnx_content_store_h
+#ifndef CCNX_CONTENT_STORE_H
+#define	CCNX_CONTENT_STORE_H
 
-#include <ns3/system-mutex.h>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
 #include <list>
 #include <string>
-#include "hash-helper.h"
+#include <iostream>
 
-using namespace std;
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/tag.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/mem_fun.hpp>
+
+#include "hash-helper.h"
+#include "ccnx-content-object-header.h"
+#include "ccnx-interest-header.h"
+#include "name-components.h"
 
 namespace  ns3
 {
-    
-class CsEntry;
-typedef list<CsEntry*>::iterator CsLruIterator;
-        
-//structure for CS entry
-struct CsEntry
-{
-    string contentName;
-    int contentSize;
-            
-    CsLruIterator lruPosition;
-};
-        
-typedef string_key_hash_t<CsEntry>::iterator CsIterator;
-typedef string_key_hash_t<CsEntry>::iterator CsRangeIterator;
-    
-class CcnxContentStore
+class Packet;
+
+/**
+ * \ingroup ccnx
+ * \brief NDN content store entry
+ *
+ * Content store entry stores separately pseudo header and content of
+ * ContentObject packet.  It is responsibility of the caller to
+ * construct a fully formed CcnxPacket by calling Copy(), AddHeader(),
+ * AddTail() on the packet received by GetPacket() method.
+ *
+ * GetFullyFormedCcnxPacket method provided as a convenience
+ */
+class CcnxContentStoreEntry
 {
 public:
-    CcnxContentStore( int max_size=NDN_CONTENT_STORE_SIZE );
-    virtual ~CcnxContentStore( );
+  /**
+   * \brief Construct content store entry
+   *
+   * \param header Parsed CcnxContentObject header
+   * \param packet Original CCNx packet
+   *
+   * The constructor will make a copy of the supplied packet and calls
+   * RemoveHeader and RemoveTail on the copy.
+   */
+  CcnxContentStoreEntry (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
+
+  /**
+   * \brief Get prefix of the stored entry
+   * \returns prefix of the stored entry
+   */
+  inline const Name::Components&
+  GetName () const;
+
+  /**
+   * \brief Get CcnxContentObjectHeader of the stored entry
+   * \returns CcnxContentObjectHeader of the stored entry
+   */
+  inline Ptr<const CcnxContentObjectHeader>
+  GetHeader () const;
+
+  /**
+   * \brief Get content of the stored entry
+   * \returns content of the stored entry
+   */
+  inline Ptr<const Packet>
+  GetPacket () const;
+
+  /**
+   * \brief Convenience method to create a fully formed CCNx packet from stored header and content
+   * \returns A read-write copy of the packet with CcnxContentObjectHeader and CcxnContentObjectTail
+   */
+  Ptr<Packet>
+  GetFullyFormedCcnxPacket () const;
+
+// Copy constructor is required by the container. Though, we're
+// storing only two pointers, so shouldn't be a problem
+// private:
+//   CcnxContentStoreEntry (const CcnxContentStoreEntry &); ///< disabled copy constructor
+//   CcnxContentStoreEntry& operator= (const CcnxContentStoreEntry&); ///< disabled copy operator
+  
+private:
+  Ptr<CcnxContentObjectHeader> m_header; ///< \brief non-modifiable CcnxContentObjectHeader
+  Ptr<Packet> m_packet; ///< \brief non-modifiable content of the ContentObject packet
+
+  static CcnxContentObjectTail m_tail; ///< \internal for optimization purposes
+};
+
+/// \brief Private namespace for CCNx implementation
+namespace __ccnx_private
+{
+class hash {}; ///< tag for Boost.Multiindex container (hashed prefix)
+class mru {}; ///< tag for Boost.Multiindex container (most recent used index)
+#ifdef _DEBUG
+class ordered {}; ///< tag for Boost.MultiIndex container (ordered by prefix)
+#endif
+};
+
+/**
+ * \ingroup ccnx
+ * \brief Typedef for content store container implemented as a Boost.MultiIndex container
+ *
+ * - First index (tag<prefix>) is a unique hash index based on NDN prefix of the stored content.
+ * - Second index (tag<mru>) is a sequential index used to maintain up to m_maxSize most recent used (MRU) entries in the content store
+ * - Third index (tag<ordered>) is just a helper to provide stored prefixes in ordered way. Should be disabled in production build
+ *
+ * \see http://www.boost.org/doc/libs/1_46_1/libs/multi_index/doc/ for more information on Boost.MultiIndex library
+ */
+struct CcnxContentStoreContainer
+{
+  typedef
+  boost::multi_index::multi_index_container<
+    CcnxContentStoreEntry,
+    boost::multi_index::indexed_by<
+      boost::multi_index::hashed_unique<
+        boost::multi_index::tag<__ccnx_private::hash>,
+        boost::multi_index::const_mem_fun<CcnxContentStoreEntry,
+                                          const Name::Components&,
+                                          &CcnxContentStoreEntry::GetName>,
+        CcnxPrefixHash>,
+      boost::multi_index::sequenced<boost::multi_index::tag<__ccnx_private::mru> >
+#ifdef _DEBUG
+      ,
+      boost::multi_index::ordered_unique<
+        boost::multi_index::tag<__ccnx_private::ordered>,
+        boost::multi_index::const_mem_fun<CcnxContentStoreEntry,
+                                          const Name::Components&,
+                                          &CcnxContentStoreEntry::GetName>
+          >
+#endif
+      >
+    > type;
+};
+
+/**
+ * \ingroup ccnx
+ * \brief Typedef for hash index of content store container
+ */
+struct CcnxContentStoreByPrefix
+{
+  typedef
+  CcnxContentStoreContainer::type::index<__ccnx_private::hash>::type
+  type;
+};
+
+/**
+ * \ingroup ccnx
+ * \brief Typedef for MRU index of content store container
+ */
+struct CcnxContentStoreByMru
+{
+  typedef
+  CcnxContentStoreContainer::type::index<__ccnx_private::mru>::type
+  type;
+};
+
+#ifdef _DEBUG
+#define DUMP_INDEX_TAG ordered
+#define DUMP_INDEX     CcnxContentStoreOrderedPrefix
+/**
+ * \ingroup ccnx
+ * \brief Typedef for ordered index of content store container
+ */
+struct CcnxContentStoreOrderedPrefix
+{
+  typedef
+  CcnxContentStoreContainer::type::index<__ccnx_private::ordered>::type
+  type;
+};
+#else
+#define DUMP_INDEX_TAG mru
+#define DUMP_INDEX     CcnxContentStoreByMru
+#endif
+  
+/**
+ * \ingroup ccnx
+ * \brief NDN content store entry
+ */
+class CcnxContentStore : public Object
+{
+public:
+  /**
+   * \brief Interface ID
+   *
+   * \return interface ID
+   */
+  static TypeId GetTypeId ();
+  
+  // typedef string_key_hash_t<CsEntry>::iterator CsIterator;
+  // typedef string_key_hash_t<CsEntry>::iterator CsRangeIterator;
+
+  /**
+   * Default constructor
+   */
+  CcnxContentStore( );
+  virtual ~CcnxContentStore( );
             
-    // Find corresponding CS entry for the given content name
-    CsEntry* Lookup( const string prefix );
-    //bool isValid( const CsIterator &it ) { return it!=_cs.end(); }
+  /**
+   * \brief Find corresponding CS entry for the given interest
+   *
+   * \param interest Interest for which matching content store entry
+   * will be searched
+   *
+   * If an entry is found, it is promoted to the top of most recent
+   * used entries index, \see m_contentStore
+   */
+  Ptr<Packet>
+  Lookup (Ptr<const CcnxInterestHeader> interest);
             
-    // Add new content to the content store. Old content will be replaced
-    void Add( const string contentName, int contentSize );
-            
-    // Dump content store entries
-    void Dump( );
+  /**
+   * \brief Add a new content to the content store.
+   *
+   * \param header Fully parsed CcnxContentObjectHeader
+   * \param packet Fully formed CCNx packet to add to content store
+   * (will be copied and stripped down of headers)
+   *
+   * If entry with the same prefix exists, the old entry will be
+   * promoted to the top of the MRU hash
+   */
+  void
+  Add (Ptr<CcnxContentObjectHeader> header, Ptr<const Packet> packet);
+
+  /**
+   * \brief Set maximum size of content store
+   *
+   * \param size size in packets
+   */
+  inline void
+  SetMaxSize (uint32_t maxSize);
+
+  /**
+   * \brief Get maximum size of content store
+   *
+   * \returns size in packets
+   */
+  inline uint32_t
+  GetMaxSize () const;
+  
+  /**
+   * \brief Print out content store entries
+   *
+   * Debug build provides dumping of content store entries in
+   * lexicographical order of corresponding prefixes
+   *
+   * Release build dumps everything in MRU order
+   */
+  void Print () const;
             
 protected:
-    //move the given CS entry to the head of the list
-    void Promote( CsEntry &entry );
-            
+  // /**
+  //  * \brief Move the given CS entry to the head of the list
+  //  *
+  //  * \param entry Content Store entry
+  //  */
+  // void Promote( CsEntry &entry );
+
+  /**
+   * \todo Alex: DoDispose and NotifyNewAggregate are seem to be very
+   * important, but I'm not yet sure what exactly they are supposed to
+   * do
+   */
+  // virtual void DoDispose ();
+  // virtual void NotifyNewAggregate ();
+
 private:
-    int                   m_maxSize; // maximum number of entries in cache
-            
-    string_key_hash_t<CsEntry>  m_contentStore;     // actual content store
-    list<CsEntry*>			  m_LRU;	// LRU index of the content store
-    SystemMutex				m_csMutex;   // just to make sure we are not
+  CcnxContentStore (const CcnxContentStore &o); ///< Disabled copy constructor
+  CcnxContentStore& operator= (const CcnxContentStore &o); ///< Disabled copy operator
+ 
+private:
+  size_t m_maxSize; ///< \brief maximum number of entries in cache \internal
+  // string_key_hash_t<CsEntry>  m_contentStore;     ///< \brief actual content store \internal
+
+  /**
+   * \brief Content store implemented as a Boost.MultiIndex container
+   * \internal
+   */
+    CcnxContentStoreContainer::type m_contentStore;
 };
+
+inline std::ostream&
+operator<< (std::ostream &os, const CcnxContentStore &cs)
+{
+  cs.Print ();
+  return os;
 }
-#endif
+
+const Name::Components&
+CcnxContentStoreEntry::GetName () const
+{
+  return m_header->GetName ();
+}
+
+Ptr<const CcnxContentObjectHeader>
+CcnxContentStoreEntry::GetHeader () const
+{
+  return m_header;
+}
+
+Ptr<const Packet>
+CcnxContentStoreEntry::GetPacket () const
+{
+  return m_packet;
+}
+
+
+inline void
+CcnxContentStore::SetMaxSize (uint32_t maxSize)
+{
+  m_maxSize = maxSize;
+}
+
+inline uint32_t
+CcnxContentStore::GetMaxSize () const
+{
+  return m_maxSize;
+}
+
+} //namespace ns3
+
+#endif // CCNX_CONTENT_STORE_H
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index e19dc57..3250355 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -34,6 +34,7 @@
 CcnxFace::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxFace")
+    .SetGroupName ("Ccnx")
     .SetParent<Object> ()
   ;
   return tid;
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index 787bfa0..4370ab9 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -31,9 +31,10 @@
 class Packet;
 class Node;
 
+  
 /**
  * \ingroup ccnx
- * \defgroup ccnx-face
+ * \defgroup ccnx-face Faces
  */
 /**
  * \ingroup ccnx-face
@@ -54,7 +55,7 @@
    * \param face Face from which packet has been received
    * \param packet Received packet
    */
-  typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<Packet>& > ProtocolHandler;
+  typedef Callback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>& > ProtocolHandler;
   
   /**
    * \brief Interface ID
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 6d4b045..7159109 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -28,6 +28,7 @@
 TypeId CcnxForwardingStrategy::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxForwardingStrategy")
+    .SetGroupName ("Ccnx")
     .SetParent<Object> ()
   ;
   return tid;
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index 02ad9af..330e2f4 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.cc
@@ -40,6 +40,7 @@
 CcnxInterestHeader::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxInterestHeader")
+    .SetGroupName ("Ccnx")
     .SetParent<Header> ()
     .AddConstructor<CcnxInterestHeader> ()
     ;
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 07bf848..8b7cccd 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -37,6 +37,7 @@
 #include "ccnx-forwarding-strategy.h"
 #include "ccnx-interest-header.h"
 #include "ccnx-content-object-header.h"
+#include "ccnx-content-store.h"
 
 #include <boost/foreach.hpp>
 
@@ -53,6 +54,7 @@
 {
   static TypeId tid = TypeId ("ns3::CcnxL3Protocol")
     .SetParent<Ccnx> ()
+    .SetGroupName ("Ccnx")
     .AddConstructor<CcnxL3Protocol> ()
     // .AddTraceSource ("Tx", "Send ccnx packet to outgoing interface.",
     //                  MakeTraceSourceAccessor (&CcnxL3Protocol::m_txTrace))
@@ -155,7 +157,7 @@
 
   m_faces.push_back (face);
   m_faceCounter ++;
-  return m_faceCounter;
+  return face->GetId ();
 }
 
 Ptr<CcnxFace>
@@ -177,8 +179,14 @@
 
 // Callback from lower layer
 void 
-CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<Packet> &p)
+CcnxL3Protocol::Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p)
 {
+  if (face->IsUp ())
+    {
+      NS_LOG_LOGIC ("Dropping received packet -- interface is down");
+      // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
+      return;
+    }
   NS_LOG_LOGIC ("Packet from face " << &face << " received on node " <<  m_node->GetId ());
 
   Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
@@ -198,16 +206,11 @@
                                         const Ptr<CcnxInterestHeader> &header,
                                         const Ptr<Packet> &packet)
 {
-  if (incomingFace->IsUp ())
-    {
-      NS_LOG_LOGIC ("Dropping received packet -- interface is down");
-      // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
-      return;
-    }
-
-  NS_LOG_LOGIC ("Receiving interest from " << incomingFace);
+  NS_LOG_LOGIC ("Receiving interest from " << &incomingFace);
   // m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
 
+  /// \todo Processing of Interest packets
+  
   // NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
   // if (!m_forwardingStrategy->RouteInput (packet, incomingFace,
   //                                     MakeCallback (&CcnxL3Protocol::Send, this),
@@ -224,14 +227,9 @@
                                         const Ptr<CcnxContentObjectHeader> &header,
                                         const Ptr<Packet> &packet)
 {
-  if (incomingFace->IsUp ())
-    {
-      NS_LOG_LOGIC ("Dropping received packet -- interface is down");
-      // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
-      return;
-    }
+  NS_LOG_LOGIC ("Receiving contentObject from " << &incomingFace);
 
-  NS_LOG_LOGIC ("Receiving contentObject from " << incomingFace);
+  /// \todo Processing of ContentObject packets
 }
 
 // fake method
@@ -245,27 +243,21 @@
 void
 CcnxL3Protocol::Send (const Ptr<CcnxFace> &face, const Ptr<Packet> &packet)
 {
-  // NS_LOG_FUNCTION (this << "packet: " << packet << ", route: "<< route);
-  
-  // if (route == 0)
-  //   {
-  //     NS_LOG_WARN ("No route to host.  Drop.");
-  //     // m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), 0);
-  //     return;
-  //   }
-  // Ptr<CcnxFace> outFace = route->GetOutputFace ();
+  NS_LOG_FUNCTION (this << "packet: " << &packet << ", face: "<< &face); //
 
-  // if (outFace->IsUp ())
-  //   {
-  //     NS_LOG_LOGIC ("Sending via face " << *outFace);
-  //     // m_txTrace (packet, m_node->GetObject<Ccnx> (), outFace);
-  //     outFace->Send (packet);
-  //   }
-  // else
-  //   {
-  //     NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << *outFace);
-  //     // m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), outFace);
-  //   }
+  NS_ASSERT_MSG (face != 0, "Face should never be NULL");
+
+  if (face->IsUp ())
+    {
+      NS_LOG_LOGIC ("Sending via face " << &face); //
+      m_txTrace (packet, m_node->GetObject<Ccnx> (), face);
+      face->Send (packet);
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Dropping -- outgoing interface is down: " << &face);
+      m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), face);
+    }
 }
 
 
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 4743bdd..6167fd0 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -41,7 +41,8 @@
 class Header;
 class CcnxInterestHeader;
 class CcnxContentObjectHeader;
-  
+class CcnxContentStore;
+
 /**
  * \ingroup ccnx
  * \brief Actual implementation of the Ccnx network layer
@@ -105,7 +106,7 @@
   Ptr<CcnxForwardingStrategy> GetForwardingStrategy () const;
 
   virtual void Send (const Ptr<CcnxFace> &face, const Ptr<Packet> &packet);
-  virtual void Receive (const Ptr<CcnxFace> &device, const Ptr<Packet> &p);
+  virtual void Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p);
 
   virtual uint32_t AddFace (const Ptr<CcnxFace> &face);
   virtual uint32_t GetNFaces () const;
@@ -113,7 +114,7 @@
 
 protected:
   /**
-   * Actual processing of incoming CCNx packets. Also processing packets coming from local apps
+   * \brief Actual processing of incoming CCNx interests
    * 
    * Processing Interest packets
    */
@@ -124,7 +125,7 @@
 
   
   /**
-   * Actual processing of incoming CCNx packets. Also processing packets coming from local apps
+   * \brief Actual processing of incoming CCNx content objects
    * 
    * Processing ContentObject packets
    */
@@ -153,22 +154,32 @@
   ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p);
 
 private:
-  uint32_t m_faceCounter; ///< counter of faces. Increased every time a new face is added to the stack
+  uint32_t m_faceCounter; ///< \brief counter of faces. Increased every time a new face is added to the stack
   typedef std::vector<Ptr<CcnxFace> > CcnxFaceList;
-  CcnxFaceList m_faces;
+  CcnxFaceList m_faces; ///< \brief list of faces that belongs to ccnx stack on this node
 
-  Ptr<Node> m_node;
-  Ptr<CcnxForwardingStrategy> m_forwardingStrategy;
+  Ptr<Node> m_node; ///< \brief node on which ccnx stack is installed
+  Ptr<CcnxForwardingStrategy> m_forwardingStrategy; ///< \brief smart pointer to the selected forwarding strategy
 
-  // TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_sendOutgoingTrace;
-  // TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_unicastForwardTrace;
-  // TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_localDeliverTrace;
+  Ptr<CcnxContentStore> m_contentStore;
+  
+  /**
+   * \brief Trace of transmitted packets, including all headers
+   * \internal
+   */
+  TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_txTrace;
 
-  // // The following two traces pass a packet with an IP header
-  // TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_txTrace;
-  // TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_rxTrace;
-  // // <ip-header, payload, reason, ifindex> (ifindex not valid if reason is DROP_NO_ROUTE)
-  // TracedCallback<Ptr<const Packet>, DropReason, Ptr<const Ccnx>, Ptr<const CcnxFace> > m_dropTrace;
+  /**
+   * \brief Trace of received packets, including all headers
+   * \internal
+   */
+  TracedCallback<Ptr<const Packet>, Ptr<Ccnx>, Ptr<const CcnxFace> > m_rxTrace;
+
+  /**
+   * \brief Trace of dropped packets, including reason and all headers
+   * \internal
+   */
+  TracedCallback<Ptr<const Packet>, DropReason, Ptr<const Ccnx>, Ptr<const CcnxFace> > m_dropTrace;
 };
   
 } // Namespace ns3
diff --git a/model/ccnx-local-face.cc b/model/ccnx-local-face.cc
index ea2a84b..80b0b52 100644
--- a/model/ccnx-local-face.cc
+++ b/model/ccnx-local-face.cc
@@ -37,6 +37,7 @@
 CcnxLocalFace::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxLocalFace")
+    .SetGroupName ("Ccnx")
     .SetParent<CcnxFace> ()
   ;
   return tid;
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index 37a3555..9bdcd43 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -38,20 +38,21 @@
 CcnxNetDeviceFace::GetTypeId ()
 {
   static TypeId tid = TypeId ("ns3::CcnxNetDeviceFace")
+    .SetGroupName ("Ccnx")
     .SetParent<CcnxFace> ()
   ;
   return tid;
 }
 
 /** 
- * By default, Ccnx face are created in the "down" state
- *  with no IP addresses.  Before becoming useable, the user must 
- * invoke SetUp on them once an Ccnx address and mask have been set.
+ * By default, Ccnx face are created in the "down" state.  Before
+ * becoming useable, the user must invoke SetUp on the face
  */
-CcnxNetDeviceFace::CcnxNetDeviceFace () 
-  : m_netDevice (0)
+CcnxNetDeviceFace::CcnxNetDeviceFace (const Ptr<NetDevice> &netDevice) 
 {
   NS_LOG_FUNCTION (this);
+
+  m_netDevice = netDevice;
 }
 
 CcnxNetDeviceFace::~CcnxNetDeviceFace ()
@@ -77,12 +78,6 @@
   Object::DoDispose ();
 }
 
-void 
-CcnxNetDeviceFace::SetNetDevice (Ptr<NetDevice> netDevice)
-{
-  m_netDevice = netDevice;
-}
-
 Ptr<NetDevice>
 CcnxNetDeviceFace::GetNetDevice () const
 {
@@ -127,7 +122,7 @@
                                          const Address &to,
                                          NetDevice::PacketType packetType)
 {
-  // bla bla bla
+  m_protocolHandler (Ptr<CcnxFace>(this), p);
 }
 
 
diff --git a/model/ccnx-net-device-face.h b/model/ccnx-net-device-face.h
index 397d6c1..baf6a48 100644
--- a/model/ccnx-net-device-face.h
+++ b/model/ccnx-net-device-face.h
@@ -36,6 +36,10 @@
  * component responsible for actual delivery of data packet to and
  * from CCNx stack
  *
+ * CcnxNetDevice face is permanently associated with one NetDevice
+ * object and this object cannot be changed for the lifetime of the
+ * face
+ *
  * \see CcnxLocalFace, CcnxNetDeviceFace, CcnxIpv4Face, CcnxUdpFace
  */
 class CcnxNetDeviceFace  : public CcnxFace
@@ -49,9 +53,12 @@
   static TypeId GetTypeId (void);
 
   /**
-   * \brief Default constructor
+   * \brief Constructor
+   *
+   * \param netDevice a smart pointer to NetDevice object to which
+   * this face will be associate
    */
-  CcnxNetDeviceFace ();
+  CcnxNetDeviceFace (const Ptr<NetDevice> &netDevice);
   virtual ~CcnxNetDeviceFace();
 
   ////////////////////////////////////////////////////////////////////
@@ -64,13 +71,6 @@
   ////////////////////////////////////////////////////////////////////
 
   /**
-   * \brief Associate NetDevice object with face
-   *
-   * \param node smart pointer to a NetDevice object
-   */
-  void SetNetDevice (Ptr<NetDevice> node);
-
-  /**
    * \brief Get NetDevice associated with the face
    *
    * \returns smart pointer to NetDevice associated with the face
@@ -84,7 +84,7 @@
   CcnxNetDeviceFace (const CcnxNetDeviceFace &); ///< \brief Disabled copy constructor
   CcnxNetDeviceFace& operator= (const CcnxNetDeviceFace &); ///< \brief Disabled copy operator
 
-  // callback
+  /// \brief callback from lower layers
   void ReceiveFromNetDevice (Ptr<NetDevice> device,
                              Ptr<const Packet> p,
                              uint16_t protocol,
diff --git a/model/ccnx.cc b/model/ccnx.cc
index a940c36..0fe4b31 100644
--- a/model/ccnx.cc
+++ b/model/ccnx.cc
@@ -32,6 +32,7 @@
 Ccnx::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::Ccnx")
+    .SetGroupName ("Ccnx")
     .SetParent<Object> ()
   ;
   return tid;
diff --git a/model/ccnx.h b/model/ccnx.h
index 1cbe428..666158f 100644
--- a/model/ccnx.h
+++ b/model/ccnx.h
@@ -90,7 +90,7 @@
    * \param p the packet
    */
   virtual void
-  Receive (const Ptr<CcnxFace> &device, const Ptr<Packet> &p) = 0;
+  Receive (const Ptr<CcnxFace> &face, const Ptr<const Packet> &p) = 0;
 
   /**
    * \brief Register a new forwarding strategy to be used by this Ccnx
@@ -140,128 +140,6 @@
    */
   virtual Ptr<CcnxFace>
   GetFace (uint32_t face) const = 0;
-
-public:
-   /**
-   * \brief Type tag for a ccnb start marker.
-   *
-   * \see http://www.ccnx.org/releases/latest/doc/technical/DTAG.html
-   */
-  enum ccn_tt {
-    CCN_EXT,        /**< starts composite extension - numval is subtype */
-    CCN_TAG,        /**< starts composite - numval is tagnamelen-1 */ 
-    CCN_DTAG,       /**< starts composite - numval is tagdict index (enum ccn_dtag) */
-    CCN_ATTR,       /**< attribute - numval is attrnamelen-1, value follows */
-    CCN_DATTR,      /**< attribute numval is attrdict index */
-    CCN_BLOB,       /**< opaque binary data - numval is byte count */
-    CCN_UDATA,      /**< UTF-8 encoded character data - numval is byte count */
-    CCN_NO_TOKEN    /**< should not occur in encoding */
-  };
-
-  /** \brief CCN_CLOSE terminates composites */
-  enum {CCN_CLOSE = 0};
-
-  /**
-   * \brief DTAG identifies ccnb-encoded elements.
-   *
-   * \see http://www.ccnx.org/releases/latest/doc/technical/DTAG.html
-   */
-  enum ccn_dtag {
-    CCN_DTAG_Any = 13,
-    CCN_DTAG_Name = 14,
-    CCN_DTAG_Component = 15,
-    CCN_DTAG_Certificate = 16,
-    CCN_DTAG_Collection = 17,
-    CCN_DTAG_CompleteName = 18,
-    CCN_DTAG_Content = 19,
-    CCN_DTAG_SignedInfo = 20,
-    CCN_DTAG_ContentDigest = 21,
-    CCN_DTAG_ContentHash = 22,
-    CCN_DTAG_Count = 24,
-    CCN_DTAG_Header = 25,
-    CCN_DTAG_Interest = 26,	/* 20090915 */
-    CCN_DTAG_Key = 27,
-    CCN_DTAG_KeyLocator = 28,
-    CCN_DTAG_KeyName = 29,
-    CCN_DTAG_Length = 30,
-    CCN_DTAG_Link = 31,
-    CCN_DTAG_LinkAuthenticator = 32,
-    CCN_DTAG_NameComponentCount = 33,	/* DeprecatedInInterest */
-    CCN_DTAG_RootDigest = 36,
-    CCN_DTAG_Signature = 37,
-    CCN_DTAG_Start = 38,
-    CCN_DTAG_Timestamp = 39,
-    CCN_DTAG_Type = 40,
-    CCN_DTAG_Nonce = 41,
-    CCN_DTAG_Scope = 42,
-    CCN_DTAG_Exclude = 43,
-    CCN_DTAG_Bloom = 44,
-    CCN_DTAG_BloomSeed = 45,
-    CCN_DTAG_AnswerOriginKind = 47,
-    CCN_DTAG_InterestLifetime = 48,
-    CCN_DTAG_Witness = 53,
-    CCN_DTAG_SignatureBits = 54,
-    CCN_DTAG_DigestAlgorithm = 55,
-    CCN_DTAG_BlockSize = 56,
-    CCN_DTAG_FreshnessSeconds = 58,
-    CCN_DTAG_FinalBlockID = 59,
-    CCN_DTAG_PublisherPublicKeyDigest = 60,
-    CCN_DTAG_PublisherCertificateDigest = 61,
-    CCN_DTAG_PublisherIssuerKeyDigest = 62,
-    CCN_DTAG_PublisherIssuerCertificateDigest = 63,
-    CCN_DTAG_ContentObject = 64,	/* 20090915 */
-    CCN_DTAG_WrappedKey = 65,
-    CCN_DTAG_WrappingKeyIdentifier = 66,
-    CCN_DTAG_WrapAlgorithm = 67,
-    CCN_DTAG_KeyAlgorithm = 68,
-    CCN_DTAG_Label = 69,
-    CCN_DTAG_EncryptedKey = 70,
-    CCN_DTAG_EncryptedNonceKey = 71,
-    CCN_DTAG_WrappingKeyName = 72,
-    CCN_DTAG_Action = 73,
-    CCN_DTAG_FaceID = 74,
-    CCN_DTAG_IPProto = 75,
-    CCN_DTAG_Host = 76,
-    CCN_DTAG_Port = 77,
-    CCN_DTAG_MulticastInterface = 78,
-    CCN_DTAG_ForwardingFlags = 79,
-    CCN_DTAG_FaceInstance = 80,
-    CCN_DTAG_ForwardingEntry = 81,
-    CCN_DTAG_MulticastTTL = 82,
-    CCN_DTAG_MinSuffixComponents = 83,
-    CCN_DTAG_MaxSuffixComponents = 84,
-    CCN_DTAG_ChildSelector = 85,
-    CCN_DTAG_RepositoryInfo = 86,
-    CCN_DTAG_Version = 87,
-    CCN_DTAG_RepositoryVersion = 88,
-    CCN_DTAG_GlobalPrefix = 89,
-    CCN_DTAG_LocalName = 90,
-    CCN_DTAG_Policy = 91,
-    CCN_DTAG_Namespace = 92,
-    CCN_DTAG_GlobalPrefixName = 93,
-    CCN_DTAG_PolicyVersion = 94,
-    CCN_DTAG_KeyValueSet = 95,
-    CCN_DTAG_KeyValuePair = 96,
-    CCN_DTAG_IntegerValue = 97,
-    CCN_DTAG_DecimalValue = 98,
-    CCN_DTAG_StringValue = 99,
-    CCN_DTAG_BinaryValue = 100,
-    CCN_DTAG_NameValue = 101,
-    CCN_DTAG_Entry = 102,
-    CCN_DTAG_ACL = 103,
-    CCN_DTAG_ParameterizedName = 104,
-    CCN_DTAG_Prefix = 105,
-    CCN_DTAG_Suffix = 106,
-    CCN_DTAG_Root = 107,
-    CCN_DTAG_ProfileName = 108,
-    CCN_DTAG_Parameters = 109,
-    CCN_DTAG_InfoString = 110,
-    CCN_DTAG_StatusResponse = 112,
-    CCN_DTAG_StatusCode = 113,
-    CCN_DTAG_StatusText = 114,
-    CCN_DTAG_SequenceNumber = 256,
-    CCN_DTAG_CCNProtocolDataUnit = 17702112
-  };
 };
 
 } // namespace ns3 
diff --git a/model/hash-helper.h b/model/hash-helper.h
index 880a217..36a9ee8 100644
--- a/model/hash-helper.h
+++ b/model/hash-helper.h
@@ -18,48 +18,50 @@
  * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
  */
 
-#ifndef ccnx_hash_helper_h
-#define ccnx_hash_helper_h
+#ifndef CCNX_HASH_HELPER_H
+#define CCNX_HASH_HELPER_H
 
 #include <string>
-#include <boost/unordered_map.hpp>
-#include <boost/functional/hash.hpp>
 #include <boost/foreach.hpp>
+#include "name-components.h"
 
-//size of content store
-#define NDN_CONTENT_STORE_SIZE 100
-//maximum length of content name
-#define NDN_MAX_NAME_LENGTH 30
-
-//using namespace std;
-
-#define KEY(x)		x->first
-#define VALUE(x)	x->second
-
-
-/*template<typename T> 
-struct hash : public std::unary_function<T, std::size_t> {
-    std::size_t operator()(T const&) const;
-};*/
-
-struct string_hash : public std::unary_function<std::string, std::size_t>
+namespace ns3
 {
-	inline std::size_t operator( )( std::string str ) const
-	{
-        std::size_t hash = str.size() + 23;
-		for( std::string::const_iterator it = str.begin( ); it!=str.end(); it++ )
-		{
-			hash = ((hash << 6) ^ (hash >> 27)) + static_cast<std::size_t>( *it );
-		}
-		
-		return boost::hash_value(hash); //hash;
-	}
-};
 
-// A collision-chaining hash table mapping strings to ints.
-template<typename Value>
-class string_key_hash_t : public boost::unordered_map<std::string,Value, string_hash, std::equal_to<std::string>,std::allocator<std::string> >
+/**
+ * \ingroup ccnx-helpers
+ * \brief Helper providing hash value for the name prefix
+ *
+ * The whole prefix is considered as a long string with '/' delimiters
+ *
+ * \todo Testing is required to determine if this hash function
+ * actually provides good hash results
+ */
+struct CcnxPrefixHash : public std::unary_function<Name::Components, std::size_t>
 {
+  std::size_t
+  operator() (const Name::Components &prefix) const
+  {
+    std::size_t hash = 23;
+    BOOST_FOREACH (const std::string &str, prefix.GetComponents ())
+      {
+        hash += str.size ();
+        hash = ((hash << 6) ^ (hash >> 27)) + '/';
+        BOOST_FOREACH (char c, str)
+          {
+            hash = ((hash << 6) ^ (hash >> 27)) + c;
+          }
+      }
+    return hash;
+  }
 };
+  
+// // A collision-chaining hash table mapping strings to ints.
+// template<typename Value>
+// class string_key_hash_t : public boost::unordered_map<std::string,Value, string_hash, std::equal_to<std::string>,std::allocator<std::string> >
+// {
+// };
 
-#endif
\ No newline at end of file
+} // namespace ns3
+
+#endif // CCNX_HASH_HELPER_H
diff --git a/model/name-components.h b/model/name-components.h
index 0ea4821..95d2347 100644
--- a/model/name-components.h
+++ b/model/name-components.h
@@ -24,6 +24,7 @@
 #include "ns3/simple-ref-count.h"
 
 #include <string>
+#include <algorithm>
 #include <list>
 
 namespace ns3 {
@@ -58,6 +59,12 @@
 
   inline size_t
   size () const;
+
+  inline bool
+  operator== (const Components &prefix) const;
+
+  inline bool
+  operator< (const Components &prefix) const;
   
 private:
   std::list<std::string> m_prefix;
@@ -79,8 +86,20 @@
 {
   (*this) (s);
 }
-  
-  
+
+bool
+Components::operator== (const Components &prefix) const
+{
+  return std::equal (m_prefix.begin (), m_prefix.end (), prefix.m_prefix.begin ());
+}
+
+bool
+Components::operator< (const Components &prefix) const
+{
+  return std::lexicographical_compare (m_prefix.begin (), m_prefix.end (),
+                                       prefix.m_prefix.begin (), prefix.m_prefix.end ());
+}
+
 } // Namespace Name
 } // namespace ns3
 
diff --git a/wscript b/wscript
index 0142dc2..0eb185e 100644
--- a/wscript
+++ b/wscript
@@ -10,7 +10,7 @@
 
 def configure(conf):
     conf.check_tool('boost')
-    conf.env['BOOST'] = conf.check_boost(lib = '', # need only base
+    conf.env['BOOST'] = conf.check_boost(lib = 'iostreams',
                                          min_version='1.40.0' )
     if not conf.env['BOOST']:
         conf.report_optional_feature("ndn-abstract", "NDN abstraction", False,
@@ -22,42 +22,46 @@
 
 
 def build(bld):
-    module = bld.create_ns3_module ('NDNabstraction', ['applications', 'core', 'network', 'point-to-point','topology-read','visualizer'])
+    module = bld.create_ns3_module ('NDNabstraction', ['core', 'network', 'point-to-point',
+                                                       'topology-read'])
+    module.uselib = 'BOOST BOOST_IOSTREAMS'
 
     tests = bld.create_ns3_module_test_library('NDNabstraction')
     headers = bld.new_task_gen('ns3header')
     headers.module = 'NDNabstraction'
 
     if not bld.env['ENABLE_NDN_ABSTRACT']:
+        conf.env['MODULES_NOT_BUILT'].append('NDNabstraction')
         return
    
-    module.find_sources_in_dirs (['model', 'apps', 'helper'],[],['.cc']);
+    module.find_sources_in_dirs (['model', 'apps', 'helper',
+                                   'helper/ccnb-parser',
+                                   'helper/ccnb-parser/visitors',
+                                   'helper/ccnb-parser/syntax-tree'],[],['.cc']);
     tests.find_sources_in_dirs( ['test'], [], ['.cc'] );
-    headers.find_sources_in_dirs( ['model', 'apps', 'helper'], [], ['.h'] );
+    headers.find_sources_in_dirs( ['model', 'apps', 'helper',
+                                   'helper/ccnb-parser',
+                                   'helper/ccnb-parser/visitors',
+                                   'helper/ccnb-parser/syntax-tree'], [], ['.h'] );
 
-
-    for path in ["examples"]:
-        anode = bld.path.find_dir (path)
-        if not anode or not anode.is_child_of(bld.srcnode):
-            raise Utils.WscriptError("Unable to use '%s' - either because \
-            it's not a relative path"", or it's not child of \
-            '%s'."%(name,bld.srcnode))
-        bld.rescan(anode)
-        for filename in bld.cache_dir_contents[anode.id]:
-            if filename.startswith('.') or not filename.endswith(".cc"):
-                continue
-            name = filename[:-len(".cc")]
-            obj = bld.create_ns3_program(name, ['NDNabstraction'])
-            obj.path = obj.path.find_dir (path)
-            obj.source = filename
-            obj.target = name
-            obj.name = obj.target
-
-    if bld.env['ENABLE_OPENSSL']:
-        module.uselib = 'OPENSSL'
-
-    if bld.env['ENABLE_EXAMPLES']:
-        bld.add_subdirs('examples')
+    if True or bld.env['ENABLE_EXAMPLES']:
+        for path in ["examples"]:
+            anode = bld.path.find_dir (path)
+            if not anode or not anode.is_child_of(bld.srcnode):
+                raise Utils.WscriptError("Unable to use '%s' - either because \
+                it's not a relative path"", or it's not child of \
+               '%s'."%(name,bld.srcnode))
+            bld.rescan(anode)
+            for filename in bld.cache_dir_contents[anode.id]:
+                if filename.startswith('.') or not filename.endswith(".cc"):
+                    continue
+                name = filename[:-len(".cc")]
+                obj = bld.create_ns3_program(name, ['NDNabstraction'])
+                obj.path = obj.path.find_dir (path)
+                obj.source = filename
+                obj.target = name
+                obj.name = obj.target
+                obj.uselib = 'BOOST BOOST_IOSTREAMS'
 
     bld.ns3_python_bindings()