First steps in CCNx packet coding. ccnx_encode* routines rewritten in NS3 style (using NS3::Buffer)

diff --git a/helper/ccnx-coding-helper.cc b/helper/ccnx-coding-helper.cc
new file mode 100644
index 0000000..6899543
--- /dev/null
+++ b/helper/ccnx-coding-helper.cc
@@ -0,0 +1,223 @@
+/* -*- 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: 
+ */
+
+#include "ccnx-coding-helper.h"
+
+#include "ns3/name-components.h"
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+
+#include <sstream>
+
+namespace ns3 {
+
+#define CCN_TT_BITS 3
+#define CCN_TT_MASK ((1 << CCN_TT_BITS) - 1)
+#define CCN_MAX_TINY ((1 << (7-CCN_TT_BITS)) - 1)
+#define CCN_TT_HBIT ((unsigned char)(1 << 7))
+
+size_t
+CcnxCodingHelper::AppendBlockHeader (Buffer::Iterator start, size_t val, enum 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 & ~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) | CCN_CLOSE;
+    n++;
+    val >>= 7;
+  }
+  start.Write (p,n);
+  return n;
+}
+
+size_t
+CcnxCodingHelper::AppendNumber (Buffer::Iterator start, uint32_t number)
+{
+  std::ostringstream os;
+  os << number;
+
+  size_t written = 0;
+  written += AppendBlockHeader (start, os.str().size(), CCN_UDATA);
+  written += os.str().size();
+  start.Write (reinterpret_cast<const unsigned char*>(os.str().c_str()), os.str().size());
+
+  return written;
+}
+
+  
+size_t
+CcnxCodingHelper::CcnxCodingHelper::AppendCloser (Buffer::Iterator start)
+{
+  start.WriteU8 (CCN_CLOSE);
+  return 1;
+}
+
+size_t
+CcnxCodingHelper::AppendName (Buffer::Iterator start, const Name::Components &name)
+{
+  return 0;
+}
+
+size_t
+CcnxCodingHelper::AppendTimestampBlob (Buffer::Iterator start, Time time)
+{
+  // the original function implements Markers... thought not sure what are these markers for...
+
+  // Determine miminal number of bytes required to store the timestamp
+  int required_bytes = 2; // 12 bits for fractions of a second, 4 bits left for seconds. Sometimes it is enough
+  intmax_t ts = time.ToInteger (Time::S) >> 4;
+  for (;  required_bytes < 7 && ts != 0; ts >>= 8) // not more than 6 bytes?
+     required_bytes++;
+  
+  size_t len = AppendBlockHeader(start, required_bytes, CCN_BLOB);
+
+  // write part with seconds
+  ts = time.ToInteger (Time::S) >> 4;
+  for (int i = 0; i < required_bytes - 2; i++)
+    start.WriteU8 ( ts >> (8 * (required_bytes - 3 - i)) );
+
+  /* arithmetic contortions are to avoid overflowing 31 bits */
+  ts = ((time.ToInteger (Time::S) & 15) << 12) + ((time.ToInteger (Time::NS) / 5 * 8 + 195312) / 390625);
+  for (int i = required_bytes - 2; i < required_bytes; i++)
+    start.WriteU8 ( ts >> (8 * (required_bytes - 1 - i)) );
+  
+  return len + required_bytes;
+}
+
+size_t
+CcnxCodingHelper::AppendTaggedBlob (Buffer::Iterator start, ccn_dtag dtag,
+                  const uint8_t *data, size_t size)
+{
+  size_t written = AppendBlockHeader (start, dtag, CCN_DTAG);
+  if (size>0)
+    {
+      written += AppendBlockHeader (start, size, CCN_BLOB);
+      start.Write (data, size);
+      written += size;
+    }
+  written += AppendCloser (start);
+
+  return written;
+}
+
+
+size_t
+CcnxCodingHelper::Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest)
+{
+  size_t written = 0;
+  written += AppendBlockHeader (start, CCN_DTAG_Interest, CCN_DTAG); // <Interest>
+  
+  written += AppendBlockHeader (start, CCN_DTAG_Name, CCN_DTAG); // <Name>
+  written += AppendName (start, interest.GetName());                // <Component>...</Component>...
+  written += AppendCloser (start);                               // </Name>
+
+  if (interest.GetMinSuffixComponents() >= 0)
+    {
+      written += AppendBlockHeader (start, CCN_DTAG_MinSuffixComponents, CCN_DTAG);
+      written += AppendNumber (start, interest.GetMinSuffixComponents ());
+      written += AppendCloser (start);
+    }
+  if (interest.GetMaxSuffixComponents() >= 0)
+    {
+      written += AppendBlockHeader (start, CCN_DTAG_MaxSuffixComponents, CCN_DTAG);
+      written += AppendNumber (start, interest.GetMaxSuffixComponents ());
+      written += AppendCloser (start);
+    }
+  if (interest.GetExclude().size() > 0)
+    {
+      written += AppendBlockHeader (start, CCN_DTAG_Exclude, CCN_DTAG); // <Exclude>
+      written += AppendName (start, interest.GetExclude());                // <Component>...</Component>...
+      written += AppendCloser (start);                                  // </Exclude>
+    }
+  if (interest.IsEnabledChildSelector())
+    {
+      written += AppendBlockHeader (start, CCN_DTAG_ChildSelector, CCN_DTAG);
+      written += AppendNumber (start, 1);
+      written += AppendCloser (start);
+    }
+  if (interest.IsEnabledAnswerOriginKind())
+    {
+      written += AppendBlockHeader (start, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
+      written += AppendNumber (start, 1);
+      written += AppendCloser (start);
+    }
+  if (interest.GetScope() >= 0)
+    {
+      written += AppendBlockHeader (start, CCN_DTAG_Scope, CCN_DTAG);
+      written += AppendNumber (start, interest.GetScope ());
+      written += AppendCloser (start);
+    }
+  if (!interest.GetInterestLifetime().IsZero())
+    {
+      written += AppendBlockHeader (start, CCN_DTAG_InterestLifetime, CCN_DTAG);
+      written += AppendTimestampBlob (start, interest.GetInterestLifetime());
+      written += AppendCloser (start);
+    }
+  if (interest.GetNonce()>0)
+    {
+      uint32_t nonce = interest.GetNonce();
+      written += AppendTaggedBlob (start, CCN_DTAG_Nonce,
+                                   reinterpret_cast<const uint8_t*>(&nonce),
+                                   sizeof(nonce));
+    }
+  written += AppendCloser (start); // </Interest>
+
+  return written;
+}
+
+size_t
+CcnxCodingHelper::Serialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject)
+{
+  size_t written = 0;
+  written += AppendBlockHeader (start, CCN_DTAG_ContentObject, CCN_DTAG); // <ContentObject>
+
+  // fake signature
+  written += AppendBlockHeader (start, CCN_DTAG_Signature, CCN_DTAG); // <Signature>
+  // Signature ::= DigestAlgorithm? 
+  //               Witness?         
+  //               SignatureBits   
+  written += AppendTaggedBlob (start, CCN_DTAG_SignatureBits, 0, 0);      // <SignatureBits />
+  written += AppendCloser (start);                                    // </Signature>  
+
+  written += AppendName (start, contentObject.GetName()); // <Name><Component>...</Component>...</Name>
+
+  // fake signature
+  written += AppendBlockHeader (start, CCN_DTAG_SignedInfo, CCN_DTAG); // <SignedInfo>
+  // SignedInfo ::= PublisherPublicKeyDigest
+  //                Timestamp
+  //                Type?
+  //                FreshnessSeconds?
+  //                FinalBlockID?
+  //                KeyLocator?
+  written += AppendTaggedBlob (start, CCN_DTAG_PublisherPublicKeyDigest, 0, 0); // <PublisherPublicKeyDigest />
+  written += AppendCloser (start);                                     // </SignedInfo>
+
+  written += AppendBlockHeader (start, CCN_DTAG_Content, CCN_DTAG); // <Content>
+
+  // there is no closing tag !!!
+  return written;
+}
+
+} // namespace ns3
diff --git a/helper/ccnx-coding-helper.h b/helper/ccnx-coding-helper.h
new file mode 100644
index 0000000..3cafcbc
--- /dev/null
+++ b/helper/ccnx-coding-helper.h
@@ -0,0 +1,245 @@
+/* -*- 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 _CCNX_CODING_HELPER_H_
+#define _CCNX_CODING_HELPER_H_
+
+#include <sys/types.h>
+#include "ns3/ptr.h"
+#include "ns3/nstime.h"
+#include "ns3/buffer.h"
+
+namespace ns3 {
+
+namespace Name{ class Components; }
+
+class CcnxInterestHeader;
+class CcnxContentObjectHeader;
+  
+/**
+ * Helper to encode/decode ccnb formatted CCNx message
+ *
+ */
+class CcnxCodingHelper
+{
+public:
+  static size_t
+  Serialize (Buffer::Iterator start, const CcnxInterestHeader &interest);
+
+  static size_t
+  Serialize (Buffer::Iterator start, const CcnxContentObjectHeader &contentObject);
+
+private:
+  /**
+   * 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 */
+  };
+
+  /** CCN_CLOSE terminates composites */
+  enum {CCN_CLOSE = 0};
+
+  // enum ccn_ext_subtype {
+  //   /* skip smallest values for now */
+  //   CCN_PROCESSING_INSTRUCTIONS = 16 /* <?name:U value:U?> */
+  // };
+
+  /**
+   * 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
+  };
+
+  /**
+   * The decoder state is one of these, possibly with some
+   * additional bits set for internal use.  A complete parse
+   * ends up in state 0 or an error state.  Not all possible
+   * error states are listed here.
+   */
+  enum ccn_decoder_state {
+    CCN_DSTATE_INITIAL = 0,
+    CCN_DSTATE_NEWTOKEN,
+    CCN_DSTATE_NUMVAL,
+    CCN_DSTATE_UDATA,
+    CCN_DSTATE_TAGNAME,
+    CCN_DSTATE_ATTRNAME,
+    CCN_DSTATE_BLOB,
+    /* All error states are negative */
+    CCN_DSTATE_ERR_OVERFLOW = -1,
+    CCN_DSTATE_ERR_ATTR     = -2,       
+    CCN_DSTATE_ERR_CODING   = -3,
+    CCN_DSTATE_ERR_NEST     = -4, 
+    CCN_DSTATE_ERR_BUG      = -5
+  };
+
+
+private:
+  static size_t
+  AppendBlockHeader (Buffer::Iterator start, size_t value, ccn_tt block_type);
+
+  static size_t
+  AppendNumber (Buffer::Iterator start, uint32_t number);
+
+  static size_t
+  AppendCloser (Buffer::Iterator start);
+
+  static size_t
+  AppendName (Buffer::Iterator start, const Name::Components &name);
+
+  /**
+   * Append a binary timestamp as a BLOB using the ccn binary
+   * Timestamp representation (12-bit fraction).
+   *
+   * @param start start iterator of  the buffer to append to.
+   * @param time - Time object
+   *
+   * @returns written length
+   */
+  static size_t
+  AppendTimestampBlob (Buffer::Iterator start, Time time);
+
+  /**
+   * Append a tagged BLOB
+   *
+   * This is a ccnb-encoded element with containing the BLOB as content
+   *
+   * @param start start iterator of  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 written length
+   */
+  static size_t
+  AppendTaggedBlob (Buffer::Iterator start, ccn_dtag dtag,
+                    const uint8_t *data, size_t size);
+  
+};
+
+} // namespace ns3
+
+#endif // _CCNX_CODING_HELPER_H_
+
diff --git a/helper/ccnx-forwarding-helper.cc b/helper/ccnx-forwarding-helper.cc
index ed038cb..83f16d5 100644
--- a/helper/ccnx-forwarding-helper.cc
+++ b/helper/ccnx-forwarding-helper.cc
@@ -20,7 +20,7 @@
 #include "ns3/node.h"
 #include "ns3/node-list.h"
 #include "ns3/simulator.h"
-#include "ns3/ccnx-forwarding-protocol.h"
+#include "ns3/ccnx-forwarding-strategy.h"
 #include "ccnx-forwarding-helper.h"
 
 namespace ns3 {
@@ -65,7 +65,7 @@
 CcnxForwardingHelper::Print (Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const
 {
   Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
-  Ptr<CcnxForwardingProtocol> rp = ccnx->GetForwardingProtocol ();
+  Ptr<CcnxForwardingStrategy> rp = ccnx->GetForwardingStrategy ();
   NS_ASSERT (rp);
   rp->PrintForwardingTable (stream);
 }
@@ -74,7 +74,7 @@
 CcnxForwardingHelper::PrintEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const
 {
   Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
-  Ptr<CcnxForwardingProtocol> rp = ccnx->GetForwardingProtocol ();
+  Ptr<CcnxForwardingStrategy> rp = ccnx->GetForwardingStrategy ();
   NS_ASSERT (rp);
   rp->PrintForwardingTable (stream);
   Simulator::Schedule (printInterval, &CcnxForwardingHelper::PrintEvery, this, printInterval, node, stream);
diff --git a/helper/ccnx-forwarding-helper.h b/helper/ccnx-forwarding-helper.h
index d66584f..a7d0bf8 100644
--- a/helper/ccnx-forwarding-helper.h
+++ b/helper/ccnx-forwarding-helper.h
@@ -26,14 +26,14 @@
 
 namespace ns3 {
 
-class CcnxForwardingProtocol;
+class CcnxForwardingStrategy;
 class Node;
 
 /**
- * \brief a factory to create ns3::CcnxForwardingProtocol objects
+ * \brief a factory to create ns3::CcnxForwardingStrategy objects
  *
  * For each new forwarding protocol created as a subclass of 
- * ns3::CcnxForwardingProtocol, you need to create 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.
@@ -59,7 +59,7 @@
    * \param node the node within which the new forwarding protocol will run
    * \returns a newly-created forwarding protocol
    */
-  virtual Ptr<CcnxForwardingProtocol> Create (Ptr<Node> node) const = 0;
+  virtual Ptr<CcnxForwardingStrategy> Create (Ptr<Node> node) const = 0;
 
   /**
    * \brief prints the forwarding tables of all nodes at a particular time.
@@ -67,7 +67,7 @@
    * \param stream The output stream object to use 
    *
    * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingProtocol stored in the Ccnx object, for all nodes at the
+   * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
    * specified time; the output format is forwarding protocol-specific.
    */
   void PrintForwardingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const;
@@ -78,7 +78,7 @@
    * \param stream The output stream object to use
    *
    * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingProtocol stored in the Ccnx object, for all nodes at the
+   * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
    * specified time interval; the output format is forwarding protocol-specific.
    */
   void PrintForwardingTableAllEvery (Time printInterval, Ptr<OutputStreamWrapper> stream) const;
@@ -90,7 +90,7 @@
    * \param stream The output stream object to use
    *
    * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingProtocol stored in the Ccnx object, for the selected node 
+   * CcnxForwardingStrategy stored in the Ccnx object, for the selected node 
    * at the specified time; the output format is forwarding protocol-specific.
    */
   void PrintForwardingTableAt (Time printTime, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
@@ -102,7 +102,7 @@
    * \param stream The output stream object to use
    *
    * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingProtocol stored in the Ccnx object, for the selected node 
+   * CcnxForwardingStrategy stored in the Ccnx object, for the selected node 
    * at the specified interval; the output format is forwarding protocol-specific.
    */
   void PrintForwardingTableEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
diff --git a/helper/ccnx-header-helper.cc b/helper/ccnx-header-helper.cc
new file mode 100644
index 0000000..fdc986a
--- /dev/null
+++ b/helper/ccnx-header-helper.cc
@@ -0,0 +1,61 @@
+/* -*- 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 "ccnx-header-helper.h"
+
+#include "ns3/log.h"
+#include "ns3/packet.h"
+#include "ns3/header.h"
+#include "ns3/object.h"
+
+#include "ns3/ccnx-interest-header.h"
+#include "ns3/ccnx-content-object-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("CcnxHeaderHelper");
+
+#define INTEREST_BYTE0 0x01
+#define INTEREST_BYTE1 0xD2
+
+#define CONTENT_OBJECT_BYTE0 0x04
+#define CONTENT_OBJECT_BYTE1 0x82
+
+namespace ns3
+{
+
+Ptr<Header>
+CcnxHeaderHelper::CreateCorrectCcnxHeader (Ptr<const Packet> packet)
+{
+  uint8_t type[2];
+  uint32_t read=packet->CopyData (type,2);
+  if (read!=2) throw CcnxUnknownHeaderException();
+  
+  if (type[0] == INTEREST_BYTE0 && type[1] == INTEREST_BYTE1)
+    {
+      return Create<CcnxInterestHeader> ();
+    }
+  else if (type[0] == CONTENT_OBJECT_BYTE0 && type[1] == CONTENT_OBJECT_BYTE1)
+    {
+      return Create<CcnxContentObjectHeader> ();
+    }
+
+  throw CcnxUnknownHeaderException();
+}
+
+} // namespace ns3
diff --git a/helper/ccnx-header-helper.h b/helper/ccnx-header-helper.h
new file mode 100644
index 0000000..35aeab8
--- /dev/null
+++ b/helper/ccnx-header-helper.h
@@ -0,0 +1,75 @@
+/* -*- 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_HEADER_HELPER_H_
+#define _CCNX_HEADER_HELPER_H_
+
+#include "ns3/ptr.h"
+
+namespace ns3
+{
+
+class Header;
+class Packet;
+
+/**
+ * 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
+ * determine type of CCNx packet and return corresponent header class,
+ * CcnxInterestHeader or CcnxContentObjectHeader
+ *
+ * Throws CcnxUnknownHeaderException if header type couldn't be determined
+ */
+class CcnxHeaderHelper
+{
+public:
+
+  /**
+   * Static function to create an appropriate CCNx header
+   *
+   * It peeks first 2 bytes of a packet.
+   *
+   *  All interests start with 
+   *   +-----------------+  +---+---------+-------+
+   *   | 0 0 0 0 0 0 0 1 |  | 1 | 1 0 1 0 | 0 1 0 |   (0x01 0xD2)
+   *   +-----------------+  +---+---------+-------+
+   *
+   *  All content objects start with 
+   *   +-----------------+  +---+---------+-------+
+   *   | 0 0 0 0 0 1 0 0 |  | 1 | 0 0 0 0 | 0 1 0 |   (0x04 0x82)
+   *   +-----------------+  +---+---------+-------+
+   *                          ^             ^^^^^
+   *                          |               |
+   *                      terminator      DTAG (Dictionary TAG)
+   *
+   * \see http://www.ccnx.org/releases/latest/doc/technical/BinaryEncoding.html
+   */
+  
+  static Ptr<Header>
+  CreateCorrectCcnxHeader (Ptr<const Packet> packet);
+};
+
+class CcnxUnknownHeaderException {};
+
+} // namespace ns3
+
+#endif // _CCNX_HEADER_HELPER_H_
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 836c379..50839a3 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -66,7 +66,7 @@
 #include "ns3/callback.h"
 #include "ns3/node.h"
 #include "ns3/core-config.h"
-#include "ns3/ccnx-forwarding-protocol.h"
+#include "ns3/ccnx-forwarding-strategy.h"
 
 #include "ccnx-stack-helper.h"
 #include "ccnx-forwarding-helper.h"
@@ -216,8 +216,8 @@
       CreateAndAggregateObjectFromTypeId (node, "ns3::CcnxL3Protocol");
       // Set forwarding
       Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
-      Ptr<CcnxForwardingProtocol> ccnxForwarding = m_forwarding->Create (node);
-      ccnx->SetForwardingProtocol (ccnxForwarding);
+      Ptr<CcnxForwardingStrategy> ccnxForwarding = m_forwarding->Create (node);
+      ccnx->SetForwardingStrategy (ccnxForwarding);
     }
 }
 
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index d692b05..3d0b3a4 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -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
  *
diff --git a/helper/ccnx-trace-helper.h b/helper/ccnx-trace-helper.h
index 6c4fa7b..a0390e7 100644
--- a/helper/ccnx-trace-helper.h
+++ b/helper/ccnx-trace-helper.h
@@ -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) 2010 University of Washington
  *
diff --git a/helper/ndn_stupidinterestgenerator_helper.cc b/helper/ndn_stupidinterestgenerator_helper.cc
index 1699f40..8fde311 100644
--- a/helper/ndn_stupidinterestgenerator_helper.cc
+++ b/helper/ndn_stupidinterestgenerator_helper.cc
@@ -1,11 +1,11 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; c-set-offset 'innamespace 0; -*- */
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
 //
 //  ndn_stupidinterestgenerator_helper.cpp
 //  Abstraction
 //
 //  Created by Ilya Moiseenko on 05.08.11.
 //  Copyright 2011 UCLA. All rights reserved.
-//
+//w
 
 #include "ndn_stupidinterestgenerator_helper.h"
 #include "ns3/inet-socket-address.h"
diff --git a/model/ndn_contentstore.cc b/in-progress/ccnx-contentstore.cc
similarity index 100%
rename from model/ndn_contentstore.cc
rename to in-progress/ccnx-contentstore.cc
diff --git a/model/ndn_contentstore.h b/in-progress/ccnx-contentstore.h
similarity index 100%
rename from model/ndn_contentstore.h
rename to in-progress/ccnx-contentstore.h
diff --git a/in-progress/ccnx-cs.cpp b/in-progress/ccnx-cs.cpp
new file mode 100644
index 0000000..c102cd5
--- /dev/null
+++ b/in-progress/ccnx-cs.cpp
@@ -0,0 +1,90 @@
+/* 
+ * 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
new file mode 100644
index 0000000..096b0c0
--- /dev/null
+++ b/in-progress/ccnx-cs.h
@@ -0,0 +1,65 @@
+/* 
+ * 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
new file mode 100644
index 0000000..a8adbd0
--- /dev/null
+++ b/in-progress/ccnx-fib.cpp
@@ -0,0 +1,300 @@
+/* 
+ * 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
new file mode 100644
index 0000000..9a1c3d6
--- /dev/null
+++ b/in-progress/ccnx-fib.h
@@ -0,0 +1,193 @@
+/* 
+ * 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
new file mode 100644
index 0000000..5d10b90
--- /dev/null
+++ b/in-progress/ccnx-pit.cpp
@@ -0,0 +1,243 @@
+/* -*- 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
new file mode 100644
index 0000000..83fad09
--- /dev/null
+++ b/in-progress/ccnx-pit.h
@@ -0,0 +1,276 @@
+/* -*- 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
new file mode 100644
index 0000000..b84f9d0
--- /dev/null
+++ b/in-progress/ccnx-rit.cpp
@@ -0,0 +1,64 @@
+/* 
+ * 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
new file mode 100644
index 0000000..4a03bda
--- /dev/null
+++ b/in-progress/ccnx-rit.h
@@ -0,0 +1,52 @@
+/* 
+ * 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/ccn/ccn.h b/model/ccn/ccn.h
index 6b0443c..af9dcae 100644
--- a/model/ccn/ccn.h
+++ b/model/ccn/ccn.h
@@ -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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_buf_decoder.cc b/model/ccn/ccn_buf_decoder.cc
index 5e1d713..eeb51fa 100644
--- a/model/ccn/ccn_buf_decoder.cc
+++ b/model/ccn/ccn_buf_decoder.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 University of California, Los Angeles
  *
@@ -18,15 +18,6 @@
  * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
  */
 
-/*
- *  ccn_buf_decoder.cc
- *  Abstraction
- *
- *  Created by Ilya on 7/29/11.
- *  Copyright 2011 __MyCompanyName__. All rights reserved.
- *
- */
-
 #include <string.h>
 #include <stdlib.h>
 #include "ccn.h"
@@ -34,26 +25,6 @@
 #include "ccn_coding.h"
 #include "ccn_indexbuf.h"
 
-/**
- * @file ccn_buf_decoder.c
- * @brief Support for Interest and ContentObject decoding.
- * 
- * Part of the CCNx C Library.
- *
- * Copyright (C) 2008, 2009, 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.
- */
-
 
 struct ccn_buf_decoder *
 ccn_buf_decoder_start(struct ccn_buf_decoder *d,
diff --git a/model/ccn/ccn_buf_encoder.cc b/model/ccn/ccn_buf_encoder.cc
index cc34551..d0d157b 100644
--- a/model/ccn/ccn_buf_encoder.cc
+++ b/model/ccn/ccn_buf_encoder.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 University of California, Los Angeles
  *
@@ -18,15 +18,6 @@
  * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
  */
 
-/*
- *  ccn_buf_encoder.cc
- *  Abstraction
- *
- *  Created by Ilya on 7/29/11.
- *  Copyright 2011 __MyCompanyName__. All rights reserved.
- *
- */
-
 #include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -38,34 +29,6 @@
 #include "ccn_indexbuf.h"
 
 /**
- * Append a ccnb start marker
- *
- * This forms the basic building block of ccnb-encoded data.
- * @param c is the buffer to append to.
- * @param val is the numval, intepreted according to tt (see enum ccn_tt).
- * @param tt is the type field.
- * @returns 0 for success or -1 for error.
- */
-int
-ccn_charbuf_append_tt(struct ccn_charbuf *c, size_t val, enum ccn_tt tt)
-{
-  unsigned char buf[1+8*((sizeof(val)+6)/7)];
-  unsigned char *p = &(buf[sizeof(buf)-1]);
-  int n = 1;
-  p[0] = (CCN_TT_HBIT & ~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) | CCN_CLOSE;
-    n++;
-    val >>= 7;
-  }
-  return(ccn_charbuf_append(c, p, n));
-}
-
-
-/**
  * 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.
@@ -87,45 +50,7 @@
                          )
 {
     int res = 0;
-    //struct ccn_sigc *sig_ctx;
-    //struct ccn_signature *signature;
-    //size_t signature_size;
-    struct ccn_charbuf *content_header;
-    size_t closer_start;
     
-    content_header = ccn_charbuf_create();
-    res |= ccn_charbuf_append_tt(content_header, CCN_DTAG_Content, CCN_DTAG);
-    if (size != 0)
-        res |= ccn_charbuf_append_tt(content_header, size, CCN_BLOB);
-    closer_start = content_header->length;
-    res |= ccn_charbuf_append_closer(content_header);
-    if (res < 0)
-        return(-1);
-    //sig_ctx = ccn_sigc_create();
-    //if (sig_ctx == NULL)
-    //    return(-1);
-    //if (0 != ccn_sigc_init(sig_ctx, digest_algorithm))
-    //    return(-1);
-    //if (0 != ccn_sigc_update(sig_ctx, Name->buf, Name->length))
-    //    return(-1);
-    //if (0 != ccn_sigc_update(sig_ctx, SignedInfo->buf, SignedInfo->length))
-    //    return(-1);
-    //if (0 != ccn_sigc_update(sig_ctx, content_header->buf, closer_start))
-    //    return(-1);
-    //if (0 != ccn_sigc_update(sig_ctx, data, size))
-    //    return(-1);
-    //if (0 != ccn_sigc_update(sig_ctx, content_header->buf + closer_start,
-    //                         content_header->length - closer_start))
-    //    return(-1);
-    //signature = calloc(1, ccn_sigc_signature_max_size(sig_ctx, private_key));
-    //if (signature == NULL)
-    //    return(-1);
-    //res = ccn_sigc_final(sig_ctx, signature, &signature_size, private_key);
-    //if (0 != res) {
-    //    free(signature);
-    //    return(-1);
-    //}
-    //ccn_sigc_destroy(&sig_ctx);
     res |= ccn_charbuf_append_tt(buf, CCN_DTAG_ContentObject, CCN_DTAG);
     //res |= ccn_encode_Signature(buf, digest_algorithm,
     //                            NULL, 0, signature, signature_size);
diff --git a/model/ccn/ccn_charbuf.cc b/model/ccn/ccn_charbuf.cc
index f71b0a0..06c6544 100644
--- a/model/ccn/ccn_charbuf.cc
+++ b/model/ccn/ccn_charbuf.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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_charbuf.h b/model/ccn/ccn_charbuf.h
index 1b2c61b..066eda2 100644
--- a/model/ccn/ccn_charbuf.h
+++ b/model/ccn/ccn_charbuf.h
@@ -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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_coding.cc b/model/ccn/ccn_coding.cc
deleted file mode 100644
index e7a54e7..0000000
--- a/model/ccn/ccn_coding.cc
+++ /dev/null
@@ -1,284 +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_coding.h"
-
-/**
- * @file ccn_coding.c
- * @brief Support for scanning and parsing ccnb-encoded data.
- * 
- * 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 <ccn/coding.h>
-
-/**
- * This macro documents what's happening in the state machine by
- * hinting at the XML syntax would be emitted in a re-encoder.
- * But it actually does nothing.
- */
-#define XML(goop) ((void)0)
-
-/**
- * Decodes ccnb decoded data
- *
- * @param d holds the current state of the decoder.
- * @param p points to a new block of ccnb data to feed to the decoder.
- * @param n is the size of the input, in bytes.
- * @returns the number of bytes consumed.
- *
- * The client should ensure that the decoder is initialized to all zero
- * before the first call.  In the default mode, the decoder will return
- * only when it runs out of data, encounters an error, or reaches the end
- * of the element that it started at.  This is a good way to pull
- * ccnb-encoded objects from a byte stream.
- *
- * By setting the CCN_DSTATE_PAUSE bit is set in the decoder state, the
- * decoder will additionally return just after recognizing each token.
- * In this instance, use CCN_GET_TT_FROM_DSTATE() to extract
- * the token type from the decoder state;
- * CCN_CLOSE will be reported as CCN_NO_TOKEN.
- *
- * The pause bit persists, so the end test should take that into account
- * by using the CCN_FINAL_DSTATE() macro instead of testing for state 0.
- *
- * Once an error state is entered, no addition input is processed.
- *
- * @see ccn_buf_decoder_start(), ccn_buf_advance(), ccn_buf_check_close()
- */
-ssize_t
-ccn_skeleton_decode(struct ccn_skeleton_decoder *d,
-                    const unsigned char *p, size_t n)
-{
-  enum ccn_decoder_state state = (ccn_decoder_state)(d->state);
-  int tagstate = 0;
-  size_t numval = d->numval;
-  ssize_t i = 0;
-  unsigned char c;
-  size_t chunk;
-  int pause = 0;
-  if (d->state >= 0) {
-    pause = d->state & CCN_DSTATE_PAUSE;
-    tagstate = (d->state >> 8) & 3;
-    state = (ccn_decoder_state)(d->state & 0xFF);
-  }
-  while (i < (ssize_t)n) {
-    switch (state) {
-      case CCN_DSTATE_INITIAL:
-      case CCN_DSTATE_NEWTOKEN: /* start new thing */
-        d->token_index = i + d->index;
-        if (tagstate > 1 && tagstate-- == 2) {
-          XML("\""); /* close off the attribute value */
-        } 
-        if (p[i] == CCN_CLOSE) {
-          i++;
-          if (d->nest <= 0 || tagstate > 1) {
-            state = CCN_DSTATE_ERR_NEST;
-            break;
-          }
-          if (tagstate == 1) {
-            tagstate = 0;
-            XML("/>");
-          }
-          else {
-            XML("</%s>");
-          }
-          d->nest -= 1;
-          if (d->nest == 0) {
-            state = CCN_DSTATE_INITIAL;
-            n = i;
-          }
-          if (pause) {
-            int temp = (int)state;
-            //state |= (((int)CCN_NO_TOKEN) << 16);
-            temp |= (((int)CCN_NO_TOKEN) << 16);
-            state = (ccn_decoder_state)temp;
-            n = i;
-          }
-          break;
-        }
-        numval = 0;
-        state = CCN_DSTATE_NUMVAL;
-        /* FALLTHRU */
-      case CCN_DSTATE_NUMVAL: /* parsing numval */
-        c = p[i++];
-        if ((c & CCN_TT_HBIT) == CCN_CLOSE) {
-          if (numval > ((~(size_t)0U) >> (7 + CCN_TT_BITS)))
-            state = CCN_DSTATE_ERR_OVERFLOW;
-          numval = (numval << 7) + (c & 127);
-        }
-        else {
-          numval = (numval << (7-CCN_TT_BITS)) +
-          ((c >> CCN_TT_BITS) & CCN_MAX_TINY);
-          c &= CCN_TT_MASK;
-          switch (c) {
-            case CCN_EXT:
-              if (tagstate == 1) {
-                tagstate = 0;
-                XML(">");
-              }
-              d->nest += 1;
-              d->element_index = d->token_index;
-              state = CCN_DSTATE_NEWTOKEN;
-              break;
-            case CCN_DTAG:
-              if (tagstate == 1) {
-                tagstate = 0;
-                XML(">");
-              }
-              d->nest += 1;
-              d->element_index = d->token_index;
-              XML("<%s");
-              tagstate = 1;
-              state = CCN_DSTATE_NEWTOKEN;
-              break;
-            case CCN_BLOB:
-              if (tagstate == 1) {
-                tagstate = 0;
-                XML(" ccnbencoding=\"base64Binary\">");
-              }
-              state = CCN_DSTATE_BLOB;
-              if (numval == 0)
-                state = CCN_DSTATE_NEWTOKEN;
-              break;
-            case CCN_UDATA:
-              if (tagstate == 1) {
-                tagstate = 0;
-                XML(">");
-              }
-              state = CCN_DSTATE_UDATA;
-              if (numval == 0)
-                state = CCN_DSTATE_NEWTOKEN;
-              break;
-            case CCN_DATTR:
-              if (tagstate != 1) {
-                state = CCN_DSTATE_ERR_ATTR;
-                break;
-              }
-              tagstate = 3;
-              state = CCN_DSTATE_NEWTOKEN;
-              break;
-            case CCN_ATTR:
-              if (tagstate != 1) {
-                state = CCN_DSTATE_ERR_ATTR;
-                break;
-              }
-              numval += 1; /* encoded as length-1 */
-              state = CCN_DSTATE_ATTRNAME;
-              break;
-            case CCN_TAG:
-              if (tagstate == 1) {
-                tagstate = 0;
-                XML(">");
-              }
-              numval += 1; /* encoded as length-1 */
-              d->nest += 1;
-              d->element_index = d->token_index;
-              state = CCN_DSTATE_TAGNAME;
-              break;
-            default:
-              state = CCN_DSTATE_ERR_CODING;
-          }
-          if (pause) {
-            int temp = (int)state;
-            //state |= (c << 16);
-            temp |= (c << 16);
-            state = (ccn_decoder_state)temp;
-            n = i;
-          }
-        }
-        break;
-      case CCN_DSTATE_TAGNAME: /* parsing tag name */
-        chunk = n - i;
-        if (chunk > numval)
-          chunk = numval;
-        if (chunk == 0) {
-          state = CCN_DSTATE_ERR_BUG;
-          break;
-        }
-        numval -= chunk;
-        i += chunk;
-        if (numval == 0) {
-          if (d->nest == 0) {
-            state = CCN_DSTATE_ERR_NEST;
-            break;
-          }
-          XML("<%s");
-          tagstate = 1;
-          state = CCN_DSTATE_NEWTOKEN;
-        }
-        break;                
-      case CCN_DSTATE_ATTRNAME: /* parsing attribute name */
-        chunk = n - i;
-        if (chunk > numval)
-          chunk = numval;
-        if (chunk == 0) {
-          state = CCN_DSTATE_ERR_BUG;
-          break;
-        }
-        numval -= chunk;
-        i += chunk;
-        if (numval == 0) {
-          if (d->nest == 0) {
-            state = CCN_DSTATE_ERR_ATTR;
-            break;
-          }
-          XML(" %s=\"");
-          tagstate = 3;
-          state = CCN_DSTATE_NEWTOKEN;
-        }
-        break;
-      case CCN_DSTATE_UDATA: /* utf-8 data */
-      case CCN_DSTATE_BLOB: /* BLOB */
-        chunk = n - i;
-        if (chunk > numval)
-          chunk = numval;
-        if (chunk == 0) {
-          state = CCN_DSTATE_ERR_BUG;
-          break;
-        }
-        numval -= chunk;
-        i += chunk;
-        if (numval == 0)
-          state = CCN_DSTATE_NEWTOKEN;
-        break;
-      default:
-        n = i;
-    }
-  }
-  if (state < 0)
-    tagstate = pause = 0;
-  d->state = state | pause | (tagstate << 8); 
-  d->numval = numval;
-  d->index += i;
-  return(i);
-}
diff --git a/model/ccn/ccn_coding.h b/model/ccn/ccn_coding.h
deleted file mode 100644
index acf346c..0000000
--- a/model/ccn/ccn_coding.h
+++ /dev/null
@@ -1,241 +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/coding.h
- * 
- * Details of the ccn binary wire encoding.
- *
- * 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.
- */
-
-#ifndef CCN_CODING_DEFINED
-#define CCN_CODING_DEFINED
-
-#include <sys/types.h>
-#include <stddef.h>
-
-#define CCN_TT_BITS 3
-#define CCN_TT_MASK ((1 << CCN_TT_BITS) - 1)
-#define CCN_MAX_TINY ((1 << (7-CCN_TT_BITS)) - 1)
-#define CCN_TT_HBIT ((unsigned char)(1 << 7))
-
-/**
- * Type tag for a ccnb start marker.
- */
-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 */
-};
-
-/** CCN_CLOSE terminates composites */
-#define CCN_CLOSE ((unsigned char)(0))
-
-enum ccn_ext_subtype {
-  /* skip smallest values for now */
-  CCN_PROCESSING_INSTRUCTIONS = 16 /* <?name:U value:U?> */
-};
-
-/**
- * DTAG identifies ccnb-encoded elements.
- * c.f. tagname.csvdict
- * See the gen_enum_dtag script for help updating these.
- */
-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
-};
-
-struct ccn_dict_entry {
-  int index;              /**< matches enum ccn_dtag above */
-  const char *name;       /**< textual name of dtag */
-};
-
-struct ccn_dict {
-  int count;              /**< Count of elements in the table */
-  const struct ccn_dict_entry *dict; /**< the table entries */
-};
-
-/**
- * Table for translating from DTAGs to names and vice versa.
- */
-extern const struct ccn_dict ccn_dtag_dict; /* matches enum ccn_dtag above */
-
-struct ccn_skeleton_decoder { /* initialize to all 0 */
-  ssize_t index;          /**< Number of bytes processed */
-  int state;              /**< Decoder state */
-  int nest;               /**< Element nesting */
-  size_t numval;          /**< Current numval, meaning depends on state */
-  size_t token_index;     /**< Starting index of most-recent token */
-  size_t element_index;   /**< Starting index of most-recent element */
-};
-
-/**
- * The decoder state is one of these, possibly with some
- * additional bits set for internal use.  A complete parse
- * ends up in state 0 or an error state.  Not all possible
- * error states are listed here.
- */
-enum ccn_decoder_state {
-  CCN_DSTATE_INITIAL = 0,
-  CCN_DSTATE_NEWTOKEN,
-  CCN_DSTATE_NUMVAL,
-  CCN_DSTATE_UDATA,
-  CCN_DSTATE_TAGNAME,
-  CCN_DSTATE_ATTRNAME,
-  CCN_DSTATE_BLOB,
-  /* All error states are negative */
-  CCN_DSTATE_ERR_OVERFLOW = -1,
-  CCN_DSTATE_ERR_ATTR     = -2,       
-  CCN_DSTATE_ERR_CODING   = -3,
-  CCN_DSTATE_ERR_NEST     = -4, 
-  CCN_DSTATE_ERR_BUG      = -5
-};
-
-/**
- * If the CCN_DSTATE_PAUSE bit is set in the decoder state,
- * the decoder will return just after recognizing each token.
- * In this instance, use CCN_GET_TT_FROM_DSTATE() to extract
- * the token type from the decoder state;
- * CCN_CLOSE will be reported as CCN_NO_TOKEN.
- * The pause bit persists, so the end test should take that into account
- * by using the CCN_FINAL_DSTATE macro instead of testing for state 0.
- */
-#define CCN_DSTATE_PAUSE (1 << 15)
-#define CCN_GET_TT_FROM_DSTATE(state) (CCN_TT_MASK & ((state) >> 16))
-#define CCN_FINAL_DSTATE(state) (((state) & (CCN_DSTATE_PAUSE-1)) == 0)
-
-ssize_t ccn_skeleton_decode(struct ccn_skeleton_decoder *d,
-                            const unsigned char *p,
-                            size_t n);
-
-#endif
-
diff --git a/model/ccn/ccn_indexbuf.cc b/model/ccn/ccn_indexbuf.cc
index a1cd87d..034c5db 100644
--- a/model/ccn/ccn_indexbuf.cc
+++ b/model/ccn/ccn_indexbuf.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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_indexbuf.h b/model/ccn/ccn_indexbuf.h
index 9c9a8c9..3e133c3 100644
--- a/model/ccn/ccn_indexbuf.h
+++ b/model/ccn/ccn_indexbuf.h
@@ -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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_name_util.cc b/model/ccn/ccn_name_util.cc
index 94f3991..64405ce 100644
--- a/model/ccn/ccn_name_util.cc
+++ b/model/ccn/ccn_name_util.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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_name_util.h b/model/ccn/ccn_name_util.h
index 95df0e3..6e5fda7 100644
--- a/model/ccn/ccn_name_util.h
+++ b/model/ccn/ccn_name_util.h
@@ -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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_random.cc b/model/ccn/ccn_random.cc
index 6e2dd0c..6176c79 100644
--- a/model/ccn/ccn_random.cc
+++ b/model/ccn/ccn_random.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 University of California, Los Angeles
  *
diff --git a/model/ccn/ccn_random.h b/model/ccn/ccn_random.h
index 0a8be4c..ddd0a38 100644
--- a/model/ccn/ccn_random.h
+++ b/model/ccn/ccn_random.h
@@ -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 University of California, Los Angeles
  *
diff --git a/model/ccnx-content-object-header.cc b/model/ccnx-content-object-header.cc
index 726415e..46a1554 100644
--- a/model/ccnx-content-object-header.cc
+++ b/model/ccnx-content-object-header.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 University of California, Los Angeles
  *
@@ -29,6 +29,7 @@
 {
 
 NS_OBJECT_ENSURE_REGISTERED (CcnxContentObjectHeader);
+NS_OBJECT_ENSURE_REGISTERED (CcnxContentObjectTail);
 
 TypeId
 CcnxContentObjectHeader::GetTypeId (void)
@@ -83,8 +84,63 @@
 void
 CcnxContentObjectHeader::Print (std::ostream &os) const
 {
-  os << "ContentObject: " << *m_name;
+  os << "<ContentObject><Name>" << *m_name << "</Name><Content>";
 }
 
-} // namespace ns3
 
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+CcnxContentObjectTail::CcnxContentObjectTail ()
+{
+}
+
+TypeId
+CcnxContentObjectTail::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::CcnxContentObjectHeader")
+    .SetParent<Header> ()
+    .AddConstructor<CcnxContentObjectHeader> ()
+    ;
+  return tid;
+}
+
+TypeId
+CcnxContentObjectTail::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+CcnxContentObjectTail::Print (std::ostream &os) const
+{
+  os << "</Content></ContentObject>";
+}
+
+uint32_t
+CcnxContentObjectTail::GetSerializedSize (void) const
+{
+  return 2;
+}
+
+void
+CcnxContentObjectTail::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteU8 (0x00); // </Content>
+  i.WriteU8 (0x00); // </ContentObject>
+}
+
+uint32_t
+CcnxContentObjectTail::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  uint8_t __attribute__ ((unused)) closing_tag_content = i.ReadU8 ();
+  NS_ASSERT_MSG (closing_tag_content==0, "Should be closing tag </Content> (0x00)");
+
+  uint8_t __attribute__ ((unused)) closing_tag_content_object = i.ReadU8 ();
+  NS_ASSERT_MSG (closing_tag_content_object==0, "Should be closing tag </ContentObject> (0x00)");
+
+  return 2;
+}
+  
+} // namespace ns3
diff --git a/model/ccnx-content-object-header.h b/model/ccnx-content-object-header.h
index 0800885..c26052b 100644
--- a/model/ccnx-content-object-header.h
+++ b/model/ccnx-content-object-header.h
@@ -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 University of California, Los Angeles
  *
@@ -40,9 +40,13 @@
  * Only few important fields are actually implemented in the simulation
  *
  *
- * NDN ContentObjectHeader and routines to serialize/deserialize
+ * ContentObjectHeader serializes/deserializes header up-to and including <Content> tags
+ * Necessary closing tags should be added using ContentObjectTail
  *
- *  Simplifications:
+ * This hacks are necessary to optimize memory use (i.e., virtual payload)
+ *
+ * "<ContentObject><Signature>..</Signature><Name>...</Name><SignedInfo>...</SignedInfo><Content>"
+ * 
  */
   
 class CcnxContentObjectHeader : public Header
@@ -77,12 +81,6 @@
 
   // ?
   // GetSignedInfo () const;
-
-  // void
-  // SetContent ();
-
-  // ?
-  // GetContent ();
   
   //////////////////////////////////////////////////////////////////
   
@@ -97,9 +95,27 @@
   Ptr<Name::Components> m_name;
   // m_signature;
   // m_signedInfo;
-  // ? content
 };
 
+/**
+ * ContentObjectTail should always be 2 bytes, representing two closing tags:
+ * "</Content><ContentObject>"
+ */
+class CcnxContentObjectTail : public Header
+{
+public:
+  CcnxContentObjectTail ();
+  //////////////////////////////////////////////////////////////////
+  
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+};
+
+  
 } // namespace ns3
 
 #endif // _CCNX_CONTENT_OBJECT_HEADER_H_
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index 7635a3e..15ddb84 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.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) 2005,2006,2007 INRIA
  *
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index 2b5ba5f..35f7dc1 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -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) 2005,2006,2007 INRIA
  *
diff --git a/model/ccnx-forwarding-protocol.cc b/model/ccnx-forwarding-strategy.cc
similarity index 73%
rename from model/ccnx-forwarding-protocol.cc
rename to model/ccnx-forwarding-strategy.cc
index afc7f33..6d4b045 100644
--- a/model/ccnx-forwarding-protocol.cc
+++ b/model/ccnx-forwarding-strategy.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) 2009 University of Washington
  *
@@ -19,22 +19,22 @@
 #include "ns3/assert.h"
 
 #include "ccnx-route.h"
-#include "ccnx-forwarding-protocol.h"
+#include "ccnx-forwarding-strategy.h"
 
 namespace ns3 {
 
-NS_OBJECT_ENSURE_REGISTERED (CcnxForwardingProtocol);
+NS_OBJECT_ENSURE_REGISTERED (CcnxForwardingStrategy);
 
-TypeId CcnxForwardingProtocol::GetTypeId (void)
+TypeId CcnxForwardingStrategy::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("ns3::CcnxForwardingProtocol")
+  static TypeId tid = TypeId ("ns3::CcnxForwardingStrategy")
     .SetParent<Object> ()
   ;
   return tid;
 }
 
 void
-CcnxForwardingProtocol::SetCcnx (Ptr<Ccnx> ccnx)
+CcnxForwardingStrategy::SetCcnx (Ptr<Ccnx> ccnx)
 {
   m_ccnx = ccnx;
 }
diff --git a/model/ccnx-forwarding-protocol.h b/model/ccnx-forwarding-strategy.h
similarity index 92%
rename from model/ccnx-forwarding-protocol.h
rename to model/ccnx-forwarding-strategy.h
index 072c7f9..6a76531 100644
--- a/model/ccnx-forwarding-protocol.h
+++ b/model/ccnx-forwarding-strategy.h
@@ -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) 2009 University of Washington
  *
@@ -15,8 +15,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#ifndef CCNX_FORWARDING_PROTOCOL_H
-#define CCNX_FORWARDING_PROTOCOL_H
+#ifndef CCNX_FORWARDING_STRATEGY_H
+#define CCNX_FORWARDING_STRATEGY_H
 
 #include "ns3/packet.h"
 #include "ns3/callback.h"
@@ -33,7 +33,7 @@
 
 /**
  * \ingroup internet 
- * \defgroup ccnxForwarding CcnxForwardingProtocol 
+ * \defgroup ccnxForwarding CcnxForwardingStrategy 
  */
 /**
  * \ingroup ccnxForwarding
@@ -45,7 +45,7 @@
  * Also defines the signatures of four callbacks used in RouteInput().
  *
  */
-class CcnxForwardingProtocol : public Object
+class CcnxForwardingStrategy : public Object
 {
 public:
   static TypeId GetTypeId (void);
@@ -75,7 +75,7 @@
    * \brief Route an input packet (to be forwarded or locally delivered)
    *
    * This lookup is used in the forwarding process.  The packet is
-   * handed over to the CcnxForwardingProtocol, and will get forwarded onward
+   * handed over to the CcnxForwardingStrategy, and will get forwarded onward
    * by one of the callbacks.  The Linux equivalent is ip_route_input().
    * There are four valid outcomes, and a matching callbacks to handle each.
    *
@@ -84,7 +84,7 @@
    * \param iface Pointer to ingress face
    * \param ucb Callback for the case in which the packet is to be forwarded
    * \param ecb Callback to call if there is an error in forwarding
-   * \returns true if the CcnxForwardingProtocol takes responsibility for 
+   * \returns true if the CcnxForwardingStrategy takes responsibility for 
    *          forwarding or delivering the packet, false otherwise
    */ 
   virtual bool RouteInput  (Ptr<Packet> p, Ptr<CcnxFace> iface, 
@@ -131,7 +131,7 @@
   /**
    * \param ccnx the ccnx object this forwarding protocol is being associated with
    * 
-   * Typically, invoked directly or indirectly from ns3::Ccnx::SetForwardingProtocol
+   * Typically, invoked directly or indirectly from ns3::Ccnx::SetForwardingStrategy
    */
   virtual void SetCcnx (Ptr<Ccnx> ccnx);
 
@@ -143,4 +143,4 @@
 
 } //namespace ns3
 
-#endif /* CCNX_FORWARDING_PROTOCOL_H */
+#endif /* CCNX_FORWARDING_STRATEGY_H */
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index 6b322e2..627946c 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.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 University of California, Los Angeles
  *
@@ -105,9 +105,9 @@
 }
 
 void
-CcnxInterestHeader::EnableChildSelector ()
+CcnxInterestHeader::SetChildSelector (bool value)
 {
-  m_childSelector = true;
+  m_childSelector = value;
 }
 
 bool
@@ -117,9 +117,9 @@
 }
 
 void
-CcnxInterestHeader::EnableAnswerOriginKind ()
+CcnxInterestHeader::SetAnswerOriginKind (bool value)
 {
-  m_answerOriginKind = true;
+  m_answerOriginKind = value;
 }
 
 bool
@@ -141,12 +141,12 @@
 }
 
 void
-CcnxInterestHeader::SetInterestLifetime (intmax_t lifetime)
+CcnxInterestHeader::SetInterestLifetime (Time lifetime)
 {
   m_interestLifetime = lifetime;
 }
 
-intmax_t
+Time
 CcnxInterestHeader::GetInterestLifetime () const
 {
   return m_interestLifetime;
diff --git a/model/ccnx-interest-header.h b/model/ccnx-interest-header.h
index 259e156..44ffa6b 100644
--- a/model/ccnx-interest-header.h
+++ b/model/ccnx-interest-header.h
@@ -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 University of California, Los Angeles
  *
@@ -24,6 +24,7 @@
 
 #include "ns3/integer.h"
 #include "ns3/header.h"
+#include "ns3/nstime.h"
 
 #include <string>
 #include <vector>
@@ -121,10 +122,10 @@
    - ChildSelector, AnswerOriginKind: 0 - false, 1 - true, -1 not set
    - Publisher* elements are not supported
    - Exclude: only simple name matching is supported (Bloom support has been deprecated in CCNx)
-   - InterestLifetime: not used if negative
+   - InterestLifetime: ?
    - Nonce: 32 bit random integer.  If value is 0, will not be serialized
  */
-class CcnxInterestHeader : public Header
+  class CcnxInterestHeader : public Header
 {
 public:
   /**
@@ -169,13 +170,13 @@
   GetExclude () const;
 
   void
-  EnableChildSelector ();
+  SetChildSelector (bool value);
 
   bool
   IsEnabledChildSelector () const;
 
   void
-  EnableAnswerOriginKind ();
+  SetAnswerOriginKind (bool value);
 
   bool
   IsEnabledAnswerOriginKind () const;
@@ -187,9 +188,9 @@
   GetScope () const;
 
   void
-  SetInterestLifetime (intmax_t lifetime);
+  SetInterestLifetime (Time time);
 
-  intmax_t
+  Time
   GetInterestLifetime () const;
 
   void
@@ -215,7 +216,7 @@
   bool m_childSelector;    
   bool m_answerOriginKind; 
   int8_t m_scope;            ///< -1 not set, 0 local scope, 1 this host, 2 immediate neighborhood
-  intmax_t m_interestLifetime; ///< InterestLifetime in 2^{-12} (0.000244140625 sec). not used if negative
+  Time  m_interestLifetime;
   uint32_t m_nonce; ///< Nonce. not used if zero
 };
 
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index b906a4c..2ea1414 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.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) 2006 Georgia Tech Research Corporation
 //
@@ -30,9 +30,14 @@
 #include "ns3/object-vector.h"
 #include "ns3/boolean.h"
 
+#include "ns3/ccnx-header-helper.h"
+
 #include "ccnx-face.h"
 #include "ccnx-route.h"
-#include "ccnx-forwarding-protocol.h"
+#include "ccnx-forwarding-strategy.h"
+#include "ccnx-interest-header.h"
+#include "ccnx-content-object-header.h"
+
 
 NS_LOG_COMPONENT_DEFINE ("CcnxL3Protocol");
 
@@ -103,17 +108,17 @@
 }
 
 void
-CcnxL3Protocol::SetForwardingProtocol (Ptr<CcnxForwardingProtocol> forwardingProtocol)
+CcnxL3Protocol::SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy)
 {
   NS_LOG_FUNCTION (this);
-  m_forwardingProtocol = forwardingProtocol;
-  m_forwardingProtocol->SetCcnx (this);
+  m_forwardingStrategy = forwardingStrategy;
+  m_forwardingStrategy->SetCcnx (this);
 }
 
-Ptr<CcnxForwardingProtocol>
-CcnxL3Protocol::GetForwardingProtocol (void) const
+Ptr<CcnxForwardingStrategy>
+CcnxL3Protocol::GetForwardingStrategy (void) const
 {
-  return m_forwardingProtocol;
+  return m_forwardingStrategy;
 }
 
 void 
@@ -127,7 +132,7 @@
     }
   m_faces.clear ();
   m_node = 0;
-  // m_forwardingProtocol = 0;
+  // m_forwardingStrategy = 0;
   Object::DoDispose ();
 }
 
@@ -196,30 +201,59 @@
   Ptr<CcnxFace> ccnxFace = GetFaceForDevice (device);
 
   Ptr<Packet> packet = p->Copy (); // give upper layers a rw copy of the packet
-  ReceiveAndProcess (ccnxFace, packet);
+  try
+    {
+      Ptr<Header> header = CcnxHeaderHelper::CreateCorrectCcnxHeader (p);
+      ReceiveAndProcess (ccnxFace, header, packet);  // header should serve as overloaded method selector... not sure whether it works with this "smart" pointers...
+    }
+  catch (CcnxUnknownHeaderException)
+    {
+      NS_ASSERT_MSG (false, "Unknown CCNx header. Should not happen");
+    }
 }
 
-// Callback from higher level
-void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<Packet> packet)
+// Processing Interests
+void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<CcnxInterestHeader> header, Ptr<Packet> packet)
 {
-  if ( incomingFace->IsUp ())
+  if (incomingFace->IsUp ())
     {
       NS_LOG_LOGIC ("Dropping received packet -- interface is down");
       m_dropTrace (packet, DROP_INTERFACE_DOWN, m_node->GetObject<Ccnx> (), incomingFace);
       return;
     }
-  
-  m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
 
-  NS_ASSERT_MSG (m_forwardingProtocol != 0, "Need a forwarding protocol object to process packets");
-  if (!m_forwardingProtocol->RouteInput (packet, incomingFace,
-                                      MakeCallback (&CcnxL3Protocol::Send, this),
-                                      MakeCallback (&CcnxL3Protocol::RouteInputError, this)
-                                      ))
+  NS_LOG_LOGIC ("Receiving interest from " << incomingFace);
+  // m_rxTrace (packet, m_node->GetObject<Ccnx> (), incomingFace);
+
+  // NS_ASSERT_MSG (m_forwardingStrategy != 0, "Need a forwarding protocol object to process packets");
+  // if (!m_forwardingStrategy->RouteInput (packet, incomingFace,
+  //                                     MakeCallback (&CcnxL3Protocol::Send, this),
+  //                                     MakeCallback (&CcnxL3Protocol::RouteInputError, this)
+  //                                     ))
+  //   {
+  //     NS_LOG_WARN ("No route found for forwarding packet.  Drop.");
+  //     m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
+  //   }
+}
+
+// Processing ContentObjects
+void CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> incomingFace, Ptr<CcnxContentObjectHeader> header, Ptr<Packet> packet)
+{
+  if (incomingFace->IsUp ())
     {
-      NS_LOG_WARN ("No route found for forwarding packet.  Drop.");
-      m_dropTrace (packet, DROP_NO_ROUTE, m_node->GetObject<Ccnx> (), incomingFace);
+      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);
+}
+
+// fake method
+void
+CcnxL3Protocol::ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p)
+{
+  NS_ASSERT_MSG (false, "This function should never be called");
 }
 
 
@@ -286,9 +320,9 @@
   Ptr<CcnxFace> interface = GetFace (i);
   interface->SetUp ();
 
-  if (m_forwardingProtocol != 0)
+  if (m_forwardingStrategy != 0)
     {
-      m_forwardingProtocol->NotifyInterfaceUp (i);
+      m_forwardingStrategy->NotifyInterfaceUp (i);
     }
 }
 
@@ -299,9 +333,9 @@
   Ptr<CcnxFace> interface = GetFace (ifaceIndex);
   interface->SetDown ();
 
-  if (m_forwardingProtocol != 0)
+  if (m_forwardingStrategy != 0)
     {
-      m_forwardingProtocol->NotifyInterfaceDown (ifaceIndex);
+      m_forwardingStrategy->NotifyInterfaceDown (ifaceIndex);
     }
 }
 
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 3af0c9a..32425c4 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -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) 2006 Georgia Tech Research Corporation
 //
@@ -37,8 +37,11 @@
 class Node;
 class CcnxFace;
 class CcnxRoute;
-class CcnxForwardingProtocol;
-
+class CcnxForwardingStrategy;
+class Header;
+class CcnxInterestHeader;
+class CcnxContentObjectHeader;
+  
 /**
  * \brief Implement the Ccnx layer.
  * 
@@ -82,8 +85,8 @@
 
   // functions defined in base class Ccnx
   
-  void SetForwardingProtocol (Ptr<CcnxForwardingProtocol> forwardingProtocol);
-  Ptr<CcnxForwardingProtocol> GetForwardingProtocol (void) const;
+  void SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy);
+  Ptr<CcnxForwardingStrategy> GetForwardingStrategy (void) const;
 
   /**
    * Lower layer calls this method after calling L3Demux::Lookup
@@ -102,8 +105,20 @@
 
   /**
    * Actual processing of incoming CCNx packets. Also processing packets coming from local apps
+   * 
+   * Processing Interest packets
    */
-  void ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Packet> p);
+  virtual void
+  ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<CcnxInterestHeader> header, Ptr<Packet> p);
+
+  
+  /**
+   * Actual processing of incoming CCNx packets. Also processing packets coming from local apps
+   * 
+   * Processing ContentObject packets
+   */
+  virtual void
+  ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<CcnxContentObjectHeader> header, Ptr<Packet> p);
   
   /**
    * \param packet packet to send
@@ -146,12 +161,18 @@
   void RouteInputError (Ptr<Packet> p);
                         //, Socket::SocketErrno sockErrno);
 
+  /**
+   * false function. should never be called. Just to trick C++ to compile
+   */
+  virtual void
+  ReceiveAndProcess (Ptr<CcnxFace> face, Ptr<Header> header, Ptr<Packet> p);
+
 private:
   typedef std::vector<Ptr<CcnxFace> > CcnxFaceList;
   CcnxFaceList m_faces;
 
   Ptr<Node> m_node;
-  Ptr<CcnxForwardingProtocol> m_forwardingProtocol;
+  Ptr<CcnxForwardingStrategy> m_forwardingStrategy;
 
   TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_sendOutgoingTrace;
   TracedCallback<Ptr<const Packet>, Ptr<const CcnxFace> > m_unicastForwardTrace;
diff --git a/model/ccnx-local-face.cc b/model/ccnx-local-face.cc
index d5de90f..4a6fa55 100644
--- a/model/ccnx-local-face.cc
+++ b/model/ccnx-local-face.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) 2005,2006,2007 INRIA
  *
diff --git a/model/ccnx-local-face.h b/model/ccnx-local-face.h
index 63ea570..118333a 100644
--- a/model/ccnx-local-face.h
+++ b/model/ccnx-local-face.h
@@ -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) 2005,2006,2007 INRIA
  *
diff --git a/model/ccnx-route.cc b/model/ccnx-route.cc
index 987c001..c2033f6 100644
--- a/model/ccnx-route.cc
+++ b/model/ccnx-route.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) 2009 University of Washington
  *
diff --git a/model/ccnx-route.h b/model/ccnx-route.h
index 4d45023..fcff012 100644
--- a/model/ccnx-route.h
+++ b/model/ccnx-route.h
@@ -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) 2009 University of Washington
  *
diff --git a/model/ccnx.cc b/model/ccnx.cc
index f54d1b0..7716366 100644
--- a/model/ccnx.cc
+++ b/model/ccnx.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) 2007 INRIA
  *
diff --git a/model/ccnx.h b/model/ccnx.h
index b2cde94..12c45d2 100644
--- a/model/ccnx.h
+++ b/model/ccnx.h
@@ -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) 2007 INRIA
  *
@@ -32,7 +32,7 @@
 class Node;
 class NetDevice;
 class Packet;
-class CcnxForwardingProtocol;
+class CcnxForwardingStrategy;
 
 /**
  * \ingroup internet
@@ -68,18 +68,18 @@
    *
    * This call will replace any forwarding protocol that has been previously 
    * registered.  If you want to add multiple forwarding protocols, you must
-   * add them to a CcnxListForwardingProtocol directly.
+   * add them to a CcnxListForwardingStrategy directly.
    * 
-   * \param forwardingProtocol smart pointer to CcnxForwardingProtocol object
+   * \param forwardingStrategy smart pointer to CcnxForwardingStrategy object
    */
-  virtual void SetForwardingProtocol (Ptr<CcnxForwardingProtocol> forwardingProtocol) = 0;
+  virtual void SetForwardingStrategy (Ptr<CcnxForwardingStrategy> forwardingStrategy) = 0;
 
   /**
    * \brief Get the forwarding protocol to be used by this Ccnx stack
    * 
-   * \returns smart pointer to CcnxForwardingProtocol object, or null pointer if none
+   * \returns smart pointer to CcnxForwardingStrategy object, or null pointer if none
    */
-  virtual Ptr<CcnxForwardingProtocol> GetForwardingProtocol (void) const = 0;
+  virtual Ptr<CcnxForwardingStrategy> GetForwardingStrategy (void) const = 0;
 
   /**
    * \param device device to add to the list of Ccnx interfaces
diff --git a/model/name-components.cc b/model/name-components.cc
index c0e9ea0..55e57c4 100644
--- a/model/name-components.cc
+++ b/model/name-components.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 University of California, Los Angeles
  *
diff --git a/model/name-components.h b/model/name-components.h
index 6faa38c..8c124f8 100644
--- a/model/name-components.h
+++ b/model/name-components.h
@@ -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 University of California, Los Angeles
  *
@@ -48,6 +48,9 @@
   // Deserialize (Buffer::Iterator start);
 
   void Print (std::ostream &os) const;
+
+  inline size_t
+  size () const;
   
 private:
   std::list<std::string> m_prefix;
@@ -58,6 +61,13 @@
 
 std::ostream & operator << (std::ostream &os, const Components &components);
 
+size_t
+Components::size () const
+{
+  return m_prefix.size ();
+}
+  
+  
 } // Namespace Name
 } // namespace ns3
 
diff --git a/model/ndnabstraction-header.cc b/model/ndnabstraction-header.cc
index ccb3cf3..4cbd9f0 100644
--- a/model/ndnabstraction-header.cc
+++ b/model/ndnabstraction-header.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 University of California, Los Angeles
  *
diff --git a/model/ndnabstraction-header.h b/model/ndnabstraction-header.h
index cd172c7..2bc30ec 100644
--- a/model/ndnabstraction-header.h
+++ b/model/ndnabstraction-header.h
@@ -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 University of California, Los Angeles
  *
diff --git a/waf b/waf
deleted file mode 100644
index 4283ec1..0000000
--- a/waf
+++ /dev/null
@@ -1 +0,0 @@
-exec "`dirname "$0"`"/../../../waf "$@"
diff --git a/wscript b/wscript
index d5ea04d..e169e72 100644
--- a/wscript
+++ b/wscript
@@ -6,14 +6,14 @@
 
 def build(bld):
     module = bld.create_ns3_module ('NDNabstraction', ['applications', 'core', 'network', 'point-to-point'])
-    module.find_sources_in_dirs (['model', 'model/ccn', 'apps', 'helper'],[],['.cc']);
+    module.find_sources_in_dirs (['model', 'apps', 'helper'],[],['.cc']);
 
     tests = bld.create_ns3_module_test_library('NDNabstraction')
     tests.find_sources_in_dirs( ['test'], [], ['.cc'] );
 
     headers = bld.new_task_gen('ns3header')
     headers.module = 'NDNabstraction'
-    headers.find_sources_in_dirs( ['model', 'model/ccn', 'apps', 'helper'], [], ['.h'] );
+    headers.find_sources_in_dirs( ['model', 'apps', 'helper'], [], ['.h'] );
 
     for path in ["examples"]:
         anode = bld.path.find_dir (path)