First step in reimplementing CcnxPit. Everything is broken as of right now
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index ff30071..cfd7b4c 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -88,7 +88,7 @@
   
   Ptr<CcnxFib> fib = GetNode ()->GetObject<CcnxFib> ();
   
-  CcnxFib::iterator fibEntry = fib->Add (m_prefix, m_face, 0);
+  Ptr<CcnxFibEntry> fibEntry = fib->Add (m_prefix, m_face, 0);
   
   // make face green, so it will be used primarily
   StaticCast<CcnxFibImpl> (fib)->modify (fibEntry,
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index 31ff9b2..8fbbcce 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -34,10 +34,12 @@
 #include "ns3/point-to-point-net-device.h"
 #include "ns3/point-to-point-helper.h"
 
-#include "../model/ccnx-forwarding-strategy.h"
 #include "../model/ccnx-net-device-face.h"
 #include "../model/ccnx-l3-protocol.h"
-#include "../model/ccnx-fib.h"
+
+#include "ns3/ccnx-forwarding-strategy.h"
+#include "ns3/ccnx-fib.h"
+#include "ns3/ccnx-name-components.h"
 
 #include "ns3/node-list.h"
 // #include "ns3/loopback-net-device.h"
@@ -63,7 +65,7 @@
   m_ccnxFactory.        SetTypeId ("ns3::CcnxL3Protocol");
   m_strategyFactory.    SetTypeId ("ns3::CcnxFloodingStrategy");
   m_contentStoreFactory.SetTypeId ("ns3::CcnxContentStoreLru");
-  m_fibFactory.         SetTypeId ("ns3::CcnxFibImpl");
+  m_fibFactory.         SetTypeId ("ns3::CcnxFib");
   m_pitFactory.         SetTypeId ("ns3::CcnxPit");
 }
     
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index 8fc6f1e..3295d31 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -28,6 +28,7 @@
 #include "ns3/assert.h"
 #include "ns3/log.h"
 
+#include <boost/foreach.hpp>
 #include <boost/lambda/lambda.hpp>
 #include <boost/lambda/bind.hpp>
 namespace ll = boost::lambda;
@@ -99,7 +100,7 @@
           continue;
         }
 
-      m_pit->modify (m_pit->iterator_to (pitEntry),
+      m_pit->modify (pitEntry,
                      ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
 
       Ptr<Packet> packetToSend = packet->Copy ();
diff --git a/model/ccnx-fib-impl.cc b/model/ccnx-fib-impl.cc
index 6453bc6..d7ffb26 100644
--- a/model/ccnx-fib-impl.cc
+++ b/model/ccnx-fib-impl.cc
@@ -43,7 +43,7 @@
 TypeId 
 CcnxFibImpl::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("ns3::CcnxFibImpl") // cheating ns3 object system
+  static TypeId tid = TypeId ("ns3::CcnxFib") // cheating ns3 object system
     .SetParent<CcnxFib> ()
     .SetGroupName ("Ccnx")
     .AddConstructor<CcnxFibImpl> ()
@@ -69,7 +69,7 @@
 }
 
 
-CcnxFib::iterator
+Ptr<CcnxFibEntry>
 CcnxFibImpl::LongestPrefixMatch (const CcnxInterestHeader &interest) const
 {
   super::iterator item = const_cast<CcnxFibImpl*> (this)->super::longest_prefix_match (interest.GetName ());
@@ -82,13 +82,13 @@
 }
 
 
-CcnxFib::iterator
+Ptr<CcnxFibEntry>
 CcnxFibImpl::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
 {
   return Add (Create<CcnxNameComponents> (prefix), face, metric);
 }
   
-CcnxFib::iterator
+Ptr<CcnxFibEntry>
 CcnxFibImpl::Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric)
 {
   NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix) << boost::cref(*face) << metric);
@@ -193,7 +193,7 @@
     }
 }
 
-CcnxFib::const_iterator
+Ptr<const CcnxFibEntry>
 CcnxFibImpl::Begin ()
 {
   super::parent_trie::const_recursive_iterator item (super::getTrie ());
@@ -210,14 +210,14 @@
     return item->payload ();
 }
 
-CcnxFib::const_iterator
+Ptr<const CcnxFibEntry>
 CcnxFibImpl::End ()
 {
   return 0;
 }
 
-CcnxFib::const_iterator
-CcnxFibImpl::Next (CcnxFib::const_iterator from)
+Ptr<const CcnxFibEntry>
+CcnxFibImpl::Next (Ptr<const CcnxFibEntry> from)
 {
   if (from == 0) return 0;
   
diff --git a/model/ccnx-fib-impl.h b/model/ccnx-fib-impl.h
index a9b9efc..09bd237 100644
--- a/model/ccnx-fib-impl.h
+++ b/model/ccnx-fib-impl.h
@@ -88,13 +88,13 @@
    */
   CcnxFibImpl ();
 
-  virtual CcnxFib::iterator
+  virtual Ptr<CcnxFibEntry>
   LongestPrefixMatch (const CcnxInterestHeader &interest) const;
   
-  virtual CcnxFib::iterator
+  virtual Ptr<CcnxFibEntry>
   Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
 
-  virtual CcnxFib::iterator
+  virtual Ptr<CcnxFibEntry>
   Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric);
 
   virtual void
@@ -109,21 +109,21 @@
   virtual void
   Print (std::ostream &os) const;
 
-  virtual CcnxFib::const_iterator
+  virtual Ptr<const CcnxFibEntry>
   Begin ();
 
-  virtual CcnxFib::const_iterator
+  virtual Ptr<const CcnxFibEntry>
   End ();
 
-  virtual CcnxFib::const_iterator
-  Next (CcnxFib::const_iterator item);
+  virtual Ptr<const CcnxFibEntry>
+  Next (Ptr<const CcnxFibEntry> item);
   
   /**
    * @brief Modify element in container
    */
   template<typename Modifier>
   bool
-  modify (CcnxFib::iterator item, Modifier mod)
+  modify (Ptr<CcnxFibEntry> item, Modifier mod)
   {
     return super::modify (StaticCast<CcnxFibEntryImpl> (item)->to_iterator (), mod);
   }
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index f98839d..e25f161 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -42,7 +42,7 @@
 TypeId 
 CcnxFib::GetTypeId (void)
 {
-  static TypeId tid = TypeId ("ns3::CcnxFib") // cheating ns3 object system
+  static TypeId tid = TypeId ("ns3::private::CcnxFib") // cheating ns3 object system
     .SetParent<Object> ()
     .SetGroupName ("Ccnx")
   ;
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 0a24db9..09caab7 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -37,9 +37,6 @@
 class CcnxFib : public Object
 {
 public:
-  typedef ns3::Ptr<CcnxFibEntry> iterator; // not sure, but let's see what will happen
-  typedef ns3::Ptr<const CcnxFibEntry> const_iterator;
-
   /**
    * \brief Interface ID
    *
@@ -64,7 +61,7 @@
    * \param interest Interest packet header
    * \returns If entry found a valid iterator will be returned, otherwise end ()
    */
-  virtual iterator
+  virtual Ptr<CcnxFibEntry>
   LongestPrefixMatch (const CcnxInterestHeader &interest) const = 0;
   
   /**
@@ -78,7 +75,7 @@
    * @param face	Forwarding face
    * @param metric	Routing metric
    */
-  virtual iterator
+  virtual Ptr<CcnxFibEntry>
   Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric) = 0;
 
   /**
@@ -92,7 +89,7 @@
    * @param face	Forwarding face
    * @param metric	Routing metric
    */
-  virtual iterator
+  virtual Ptr<CcnxFibEntry>
   Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric) = 0;
 
   /**
@@ -137,26 +134,36 @@
   /**
    * @brief Return first element of FIB (no order guaranteed)
    */
-  virtual const_iterator
+  virtual Ptr<const CcnxFibEntry>
   Begin () = 0;
 
   /**
    * @brief Return item next after last (no order guaranteed)
    */
-  virtual const_iterator
+  virtual Ptr<const CcnxFibEntry>
   End () = 0;
 
   /**
    * @brief Advance the iterator
    */
-  virtual const_iterator
-  Next (const_iterator item) = 0;
+  virtual Ptr<const CcnxFibEntry>
+  Next (Ptr<const CcnxFibEntry>) = 0;
 
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
+  
+  /**
+   * @brief Static call to cheat python bindings
+   */
   static inline Ptr<CcnxFib>
   GetCcnxFib (Ptr<Object> node);
+
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
   
 private:
-  friend std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
   CcnxFib(const CcnxFib&) {} ; ///< \brief copy constructor is disabled
 };
 
@@ -173,4 +180,4 @@
 
 } // namespace ns3
 
-#endif	/* NDN_FIB_H */
+#endif // _CCNX_FIB_H_
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 3135afd..f16aa78 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -118,7 +118,7 @@
           continue;
         }
 
-      m_pit->modify (m_pit->iterator_to (pitEntry),
+      m_pit->modify (pitEntry,
                      ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
 
       // if (Simulator::GetContext ()==2)
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 4983860..414e200 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -118,7 +118,7 @@
           continue;
         }
 
-      m_pit->modify (m_pit->iterator_to (pitEntry),
+      m_pit->modify (pitEntry,
                      ll::bind (&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
 
       Ptr<Packet> packetToSend = packet->Copy ();
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 72273d5..d5f4438 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -176,22 +176,23 @@
 
   // just to be on a safe side. Do the process in two steps
   std::list<boost::reference_wrapper<const CcnxPitEntry> > entriesToRemoves;
-  BOOST_FOREACH (const CcnxPitEntry &pitEntry, *m_pit)
-    {
-      m_pit->modify (m_pit->iterator_to (pitEntry),
-                     ll::bind (&CcnxPitEntry::RemoveAllReferencesToFace, ll::_1, face));
+  NS_ASSERT_MSG (false, "Need to be repaired");
+  // BOOST_FOREACH (const CcnxPitEntry &pitEntry, *m_pit)
+  //   {
+  //     m_pit->modify (pitEntry,
+  //                    ll::bind (&CcnxPitEntry::RemoveAllReferencesToFace, ll::_1, face));
 
-      // If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
-      // Thus, we have to remove the whole PIT entry
-      if (pitEntry.m_fibEntry->m_faces.size () == 1 &&
-          pitEntry.m_fibEntry->m_faces.begin ()->m_face == face)
-        {
-          entriesToRemoves.push_back (boost::cref (pitEntry));
-        }
-    }
+  //     // If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
+  //     // Thus, we have to remove the whole PIT entry
+  //     if (pitEntry.m_fibEntry->m_faces.size () == 1 &&
+  //         pitEntry.m_fibEntry->m_faces.begin ()->m_face == face)
+  //       {
+  //         entriesToRemoves.push_back (boost::cref (pitEntry));
+  //       }
+  //   }
   BOOST_FOREACH (const CcnxPitEntry &removedEntry, entriesToRemoves)
     {
-      m_pit->erase (m_pit->iterator_to (removedEntry));
+      m_pit->erase (removedEntry);
     }
 
   CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
@@ -294,8 +295,8 @@
   NS_LOG_FUNCTION (incomingFace << header << packet);
   m_inNacks (header, incomingFace);
 
-  CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
-  if (pitEntry == m_pit->end ())
+  Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
+  if (pitEntry == 0)
     {
       // somebody is doing something bad
       m_dropNacks (header, NON_DUPLICATED, incomingFace);
@@ -381,13 +382,13 @@
 {
   m_inInterests (header, incomingFace);
 
-  CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
-  if (pitEntry == m_pit->end ())
+  Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
+  if (pitEntry == 0)
     {
       pitEntry = m_pit->Create (*header);
     }
 
-  if (pitEntry == m_pit->end ())
+  if (pitEntry == 0)
     {
       // if it is still not created, then give up processing
       m_dropInterests (header, PIT_LIMIT, incomingFace);
@@ -533,8 +534,8 @@
                                const Ptr<const Packet> &packet)
 {
   // 1. Lookup PIT entry
-  CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
-  if (pitEntry != m_pit->end ())
+  Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
+  if (pitEntry != 0)
     {
       //satisfy all pending incoming Interests
       BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->m_incoming)
@@ -579,8 +580,8 @@
   m_inData (header, payload, incomingFace);
   
   // 1. Lookup PIT entry
-  CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
-  if (pitEntry != m_pit->end ())
+  Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
+  if (pitEntry != 0)
     {
       // Note that with MultiIndex we need to modify entries indirectly
 
@@ -657,7 +658,7 @@
 }
 
 void
-CcnxL3Protocol::GiveUpInterest (CcnxPit::iterator pitEntry,
+CcnxL3Protocol::GiveUpInterest (Ptr<CcnxPitEntry> pitEntry,
                                 Ptr<CcnxInterestHeader> header)
 {
   NS_LOG_FUNCTION (this);
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 4d01da2..9731c8e 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -161,7 +161,7 @@
   CcnxL3Protocol &operator = (const CcnxL3Protocol &); ///< copy operator is disabled
 
   void
-  GiveUpInterest (CcnxPit::iterator pitEntry,
+  GiveUpInterest (Ptr<CcnxPitEntry> pitEntry,
                   Ptr<CcnxInterestHeader> header);
 
   void
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index 2fe1840..23b5e97 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -30,6 +30,7 @@
 
 #include "ns3/point-to-point-net-device.h"
 #include "ns3/channel.h"
+#include "ns3/ccnx-name-components.h"
 
 NS_LOG_COMPONENT_DEFINE ("CcnxNetDeviceFace");
 
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index 8375cf9..ad81781 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -35,9 +35,9 @@
 namespace ns3
 {
 
-CcnxPitEntry::CcnxPitEntry (Ptr<CcnxNameComponents> prefix,
+CcnxPitEntry::CcnxPitEntry (Ptr<const CcnxNameComponents> prefix,
                             const Time &expireTime,
-                            CcnxFib::iterator fibEntry)
+                            Ptr<CcnxFibEntry> fibEntry)
   : m_prefix (prefix)
   , m_fibEntry (fibEntry)
   , m_expireTime (Simulator::Now () + expireTime)
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index 1ab4f65..62f7e3f 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -22,6 +22,7 @@
 #define _CCNX_PIT_ENTRY_H_
 
 #include "ns3/ptr.h"
+#include "ns3/simple-ref-count.h"
 
 #include "ccnx-pit-entry-incoming-face.h"
 #include "ccnx-pit-entry-outgoing-face.h"
@@ -80,7 +81,7 @@
  * \ingroup ccnx
  * \brief structure for PIT entry
  */
-struct CcnxPitEntry
+struct CcnxPitEntry : SimpleRefCount<CcnxPitEntry>
 {
 public:
   typedef std::set< CcnxPitEntryIncomingFace > in_container; ///< @brief incoming faces container type
@@ -97,7 +98,7 @@
    * \param offsetTime Relative time to the current moment, representing PIT entry lifetime
    * \param fibEntry A FIB entry associated with the PIT entry
    */
-  CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const Time &offsetTime, CcnxFib::iterator fibEntry);
+  CcnxPitEntry (Ptr<const CcnxNameComponents> prefix, const Time &offsetTime, Ptr<CcnxFibEntry> fibEntry);
   
   /**
    * @brief Update lifetime of PIT entry
@@ -236,8 +237,8 @@
   CcnxPitEntry () {};
   
 public:
-  Ptr<CcnxNameComponents> m_prefix; ///< \brief Prefix of the PIT entry
-  CcnxFib::iterator m_fibEntry;     ///< \brief FIB entry related to this prefix
+  Ptr<const CcnxNameComponents> m_prefix; ///< \brief Prefix of the PIT entry
+  Ptr<CcnxFibEntry> m_fibEntry;     ///< \brief FIB entry related to this prefix
   
   nonce_container m_seenNonces;  ///< \brief map of nonces that were seen for this prefix  
   in_container  m_incoming;      ///< \brief container for incoming interests
diff --git a/model/ccnx-pit-impl.cc b/model/ccnx-pit-impl.cc
new file mode 100644
index 0000000..11c91e9
--- /dev/null
+++ b/model/ccnx-pit-impl.cc
@@ -0,0 +1,211 @@
+/* -*- 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-pit-impl.h"
+#include "ns3/log.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/simulator.h"
+#include "ccnx-interest-header.h"
+#include "ccnx-content-object-header.h"
+
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
+NS_LOG_COMPONENT_DEFINE ("CcnxPitImpl");
+
+using namespace boost::tuples;
+using namespace boost;
+namespace ll = boost::lambda;
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (CcnxPitImpl);
+
+TypeId
+CcnxPitImpl::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::CcnxPit")
+    .SetGroupName ("Ccnx")
+    .SetParent<CcnxPit> ()
+    .AddConstructor<CcnxPitImpl> ()
+    .AddAttribute ("MaxSize",
+                   "Set maximum number of entries in PIT. If 0, limit is not enforced",
+                   StringValue ("0"),
+                   MakeUintegerAccessor (&CcnxPitImpl::GetMaxSize, &CcnxPitImpl::SetMaxSize),
+                   MakeUintegerChecker<uint32_t> ())
+    ;
+
+  return tid;
+}
+
+CcnxPitImpl::CcnxPitImpl ()
+{
+}
+
+CcnxPitImpl::~CcnxPitImpl ()
+{
+}
+
+uint32_t
+CcnxPitImpl::GetMaxSize () const
+{
+  return 0;
+}
+
+void
+CcnxPitImpl::SetMaxSize (uint32_t maxSize)
+{
+}
+
+void 
+CcnxPitImpl::NotifyNewAggregate ()
+{
+  if (m_fib == 0)
+    {
+      m_fib = GetObject<CcnxFib> ();
+    }
+}
+
+void 
+CcnxPitImpl::DoDispose ()
+{
+  // clear ();
+}
+
+void
+CcnxPitImpl::DoCleanExpired ()
+{
+  // NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
+  Time now = Simulator::Now ();
+
+  // // uint32_t count = 0;
+  // while (!empty ())
+  //   {
+  //     CcnxPit::index<i_timestamp>::type::iterator entry = get<i_timestamp> ().begin ();
+  //     if (entry->GetExpireTime () <= now) // is the record stale?
+  //       {
+  //         get<i_timestamp> ().erase (entry);
+  //         // count ++;
+  //       }
+  //     else
+  //       break; // nothing else to do. All later records will not be stale
+  //   }
+}
+
+Ptr<CcnxPitEntry>
+CcnxPitImpl::Lookup (const CcnxContentObjectHeader &header) const
+{
+  return 0;
+  // iterator entry = end ();
+
+  // // do the longest prefix match
+  // const CcnxNameComponents &name = header.GetName ();
+  // for (size_t componentsCount = name.GetComponents ().size ()+1;
+  //      componentsCount > 0;
+  //      componentsCount--)
+  //   {
+  //     CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount-1));
+
+  //     entry = get<i_prefix> ().find (subPrefix);
+  //     if (entry != end())
+  //       return entry;
+  //   }
+
+  // return end ();
+}
+
+Ptr<CcnxPitEntry>
+CcnxPitImpl::Lookup (const CcnxInterestHeader &header)
+{
+  return 0;
+  // NS_LOG_FUNCTION (header.GetName ());
+  // NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
+
+  // iterator entry = get<i_prefix> ().find (header.GetName ());
+  // if (entry == end ())
+  //   return end ();
+   
+  // return entry;
+}
+
+bool
+CcnxPitImpl::CheckIfDuplicate (Ptr<CcnxPitEntry> entry, const CcnxInterestHeader &header)
+{
+  // if (!entry->IsNonceSeen (header.GetNonce ()))
+  //   {
+  //     modify (entry,
+  //             boost::bind(&CcnxPitEntry::AddSeenNonce, ll::_1, header.GetNonce ()));
+  //     return false;
+  //   }
+  // else
+    // return true;
+  return false;
+}
+
+Ptr<CcnxPitEntry>
+CcnxPitImpl::Create (const CcnxInterestHeader &header)
+{
+  // NS_ASSERT_MSG (get<i_prefix> ().find (header.GetName ()) == end (),
+  //                "Entry already exists, Create must not be called!!!");
+  
+  // if (m_maxSize > 0 &&
+  //     size () >= m_maxSize)
+  //   {
+  //     // remove old record
+  //     get<i_timestamp> ().erase (get<i_timestamp> ().begin ());
+  //   }
+      
+  // Ptr<CcnxFibEntry> fibEntry = m_fib->LongestPrefixMatch (header);
+  // // NS_ASSERT_MSG (fibEntry != m_fib->m_fib.end (),
+  // //                "There should be at least default route set" << " Prefix = "<<header.GetName() << "NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
+
+  // return insert (end (),
+  //                CcnxPitEntry (ns3::Create<CcnxNameComponents> (header.GetName ()),
+  //                              header.GetInterestLifetime ().IsZero ()?m_PitEntryDefaultLifetime
+  //                              :                                       header.GetInterestLifetime (),
+  //                              fibEntry));
+  return 0;
+}
+
+
+void
+CcnxPitImpl::MarkErased (Ptr<CcnxPitEntry> entry)
+{
+  // modify (entry,
+  //         ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+  //                   Simulator::Now () + m_PitEntryPruningTimout));
+}
+
+
+void
+CcnxPitImpl::Print (std::ostream& os) const
+{
+  os << "Should be implemented soon\n";
+  // BOOST_FOREACH (const CcnxPitEntry &entry, pit)
+  //   {
+  //     if (entry.m_incoming.size () == 0 && entry.m_outgoing.size () == 0)
+  //       continue; // these are stale to-be-removed records, so there is no need to print them out
+      
+  //     os << entry << std::endl;
+  //   }
+}
+
+} // namespace ns3
diff --git a/model/ccnx-pit-impl.h b/model/ccnx-pit-impl.h
new file mode 100644
index 0000000..e5a7f33
--- /dev/null
+++ b/model/ccnx-pit-impl.h
@@ -0,0 +1,127 @@
+/* -*- 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_PIT_IMPL_H_
+#define	_CCNX_PIT_IMPL_H_
+
+#include "ccnx-pit.h"
+#include "../utils/trie-with-policy.h"
+#include "../utils/empty-policy.h"
+#include "ns3/ccnx-name-components.h"
+
+namespace ns3 {
+
+class CcnxPitEntryImpl : public CcnxPitEntry
+{
+public:
+  typedef ndnSIM::trie_with_policy<
+    CcnxNameComponents,
+    ndnSIM::smart_pointer_payload_traits<CcnxPitEntryImpl>,
+    ndnSIM::empty_policy_traits
+    > trie;
+
+  CcnxPitEntryImpl (const Ptr<const CcnxNameComponents> &prefix, const Time &offsetTime, Ptr<CcnxFibEntry> fibEntry)
+    : CcnxPitEntry (prefix, offsetTime, fibEntry)
+    , item_ (0)
+  {
+  }
+
+  void
+  SetTrie (trie::iterator item)
+  {
+    item_ = item;
+  }
+
+  trie::iterator to_iterator () { return item_; }
+  trie::const_iterator to_iterator () const { return item_; }
+  
+private:
+  trie::iterator item_;
+};
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+/**
+ * \ingroup ccnx
+ * \brief Class implementing Pending Interests Table
+ */
+class CcnxPitImpl : public CcnxPit
+                  , protected CcnxPitEntryImpl::trie
+{
+public:
+  /**
+   * \brief Interface ID
+   *
+   * \return interface ID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief PIT constructor
+   */
+  CcnxPitImpl ();
+
+  /**
+   * \brief Destructor
+   */
+  virtual ~CcnxPitImpl ();
+
+  // inherited from CcnxPit  
+  virtual Ptr<CcnxPitEntry>
+  Lookup (const CcnxContentObjectHeader &header) const;
+
+  virtual Ptr<CcnxPitEntry>
+  Lookup (const CcnxInterestHeader &header);
+
+  virtual bool
+  CheckIfDuplicate (Ptr<CcnxPitEntry> entry, const CcnxInterestHeader &header);
+  
+  virtual Ptr<CcnxPitEntry>
+  Create (const CcnxInterestHeader &header);
+  
+  virtual void
+  MarkErased (Ptr<CcnxPitEntry> entry);
+
+  virtual void
+  Print (std::ostream &os) const;
+  
+protected:
+  // inherited from CcnxPit
+  virtual void DoCleanExpired ();
+  
+  // inherited from Object class                                                                                                                                                        
+  virtual void NotifyNewAggregate (); ///< @brief Even when object is aggregated to another Object
+  virtual void DoDispose (); ///< @brief Do cleanup
+
+private:
+  uint32_t
+  GetMaxSize () const;
+
+  void
+  SetMaxSize (uint32_t maxSize);
+  
+private:
+  Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
+};
+
+} // namespace ns3
+
+#endif	/* CCNX_PIT_IMPL_H */
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index 4824bb1..3733880 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -31,10 +31,6 @@
 
 NS_LOG_COMPONENT_DEFINE ("CcnxPit");
 
-using namespace boost::tuples;
-using namespace boost;
-namespace ll = boost::lambda;
-
 namespace ns3 {
 
 NS_OBJECT_ENSURE_REGISTERED (CcnxPit);
@@ -44,10 +40,9 @@
 TypeId
 CcnxPit::GetTypeId ()
 {
-  static TypeId tid = TypeId ("ns3::CcnxPit")
+  static TypeId tid = TypeId ("ns3::private::CcnxPit")
     .SetGroupName ("Ccnx")
     .SetParent<Object> ()
-    .AddConstructor<CcnxPit> ()
     .AddAttribute ("CleanupTimeout",
                    "Timeout defining how frequent RIT should be cleaned up",
                    StringValue ("1s"),
@@ -65,12 +60,6 @@
                    StringValue("4s"),
                    MakeTimeAccessor (&CcnxPit::m_PitEntryDefaultLifetime),
                    MakeTimeChecker ())
-
-    .AddAttribute ("MaxSize",
-                   "Set maximum number of entries in PIT. If 0, limit is not enforced",
-                   StringValue ("0"),
-                   MakeUintegerAccessor (&CcnxPit::m_maxSize),
-                   MakeUintegerChecker<uint32_t> ())
     ;
 
   return tid;
@@ -84,22 +73,13 @@
 {
 }
 
-void 
-CcnxPit::NotifyNewAggregate ()
+void CcnxPit::CleanExpired ()
 {
-  if (m_fib == 0)
-    {
-      m_fib = GetObject<CcnxFib> ();
-    }
-}
-
-void 
-CcnxPit::DoDispose ()
-{
-  if (m_cleanupEvent.IsRunning ())
-    m_cleanupEvent.Cancel ();
-
-  clear ();
+  DoCleanExpired ();
+  
+  // schedule next event  
+  m_cleanupEvent = Simulator::Schedule (m_cleanupTimeout,
+                                        &CcnxPit::CleanExpired, this); 
 }
 
 void
@@ -120,121 +100,5 @@
   return m_cleanupTimeout;
 }
 
-void CcnxPit::CleanExpired ()
-{
-  // NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
-  Time now = Simulator::Now ();
-
-  // uint32_t count = 0;
-  while (!empty ())
-    {
-      CcnxPit::index<i_timestamp>::type::iterator entry = get<i_timestamp> ().begin ();
-      if (entry->GetExpireTime () <= now) // is the record stale?
-        {
-          get<i_timestamp> ().erase (entry);
-          // count ++;
-        }
-      else
-        break; // nothing else to do. All later records will not be stale
-    }
-
-  // schedule next event  
-  m_cleanupEvent = Simulator::Schedule (m_cleanupTimeout,
-                                        &CcnxPit::CleanExpired, this); 
-}
-
-CcnxPit::iterator
-CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
-{
-  iterator entry = end ();
-
-  // do the longest prefix match
-  const CcnxNameComponents &name = header.GetName ();
-  for (size_t componentsCount = name.GetComponents ().size ()+1;
-       componentsCount > 0;
-       componentsCount--)
-    {
-      CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount-1));
-
-      entry = get<i_prefix> ().find (subPrefix);
-      if (entry != end())
-        return entry;
-    }
-
-  return end ();
-}
-
-CcnxPit::iterator
-CcnxPit::Lookup (const CcnxInterestHeader &header)
-{
-  NS_LOG_FUNCTION (header.GetName ());
-  NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
-
-  iterator entry = get<i_prefix> ().find (header.GetName ());
-  if (entry == end ())
-    return end ();
-   
-  return entry;
-}
-
-bool
-CcnxPit::CheckIfDuplicate (CcnxPit::iterator entry, const CcnxInterestHeader &header)
-{
-  if (!entry->IsNonceSeen (header.GetNonce ()))
-    {
-      modify (entry,
-              boost::bind(&CcnxPitEntry::AddSeenNonce, ll::_1, header.GetNonce ()));
-      return false;
-    }
-  else
-    return true;
-}
-
-CcnxPit::iterator
-CcnxPit::Create (const CcnxInterestHeader &header)
-{
-  NS_ASSERT_MSG (get<i_prefix> ().find (header.GetName ()) == end (),
-                 "Entry already exists, Create must not be called!!!");
-  
-  if (m_maxSize > 0 &&
-      size () >= m_maxSize)
-    {
-      // remove old record
-      get<i_timestamp> ().erase (get<i_timestamp> ().begin ());
-    }
-      
-  CcnxFib::iterator fibEntry = m_fib->LongestPrefixMatch (header);
-  // NS_ASSERT_MSG (fibEntry != m_fib->m_fib.end (),
-  //                "There should be at least default route set" << " Prefix = "<<header.GetName() << "NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
-
-  return insert (end (),
-                 CcnxPitEntry (ns3::Create<CcnxNameComponents> (header.GetName ()),
-                               header.GetInterestLifetime ().IsZero ()?m_PitEntryDefaultLifetime
-                               :                                       header.GetInterestLifetime (),
-                               fibEntry));
-}
-
-
-void
-CcnxPit::MarkErased (CcnxPit::iterator entry)
-{
-  modify (entry,
-          ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
-                    Simulator::Now () + m_PitEntryPruningTimout));
-}
-
-
-std::ostream& operator<< (std::ostream& os, const CcnxPit &pit)
-{
-  BOOST_FOREACH (const CcnxPitEntry &entry, pit)
-    {
-      if (entry.m_incoming.size () == 0 && entry.m_outgoing.size () == 0)
-        continue; // these are stale to-be-removed records, so there is no need to print them out
-      
-      os << entry << std::endl;
-    }
-
-  return os;
-}
 
 } // namespace ns3
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index 8bb746e..b6e4388 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -25,21 +25,8 @@
 #include "ns3/nstime.h"
 #include "ns3/event-id.h"
 
-#include "ccnx-name-components-hash-helper.h"
 #include "ccnx-pit-entry.h"
 
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/tag.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index/composite_key.hpp>
-#include <boost/multi_index/hashed_index.hpp>
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index/mem_fun.hpp>
-#include <map>
-#include <iostream>
-#include <algorithm>
-#include <boost/tuple/tuple.hpp>
-
 namespace ns3 {
 
 class Ccnx;
@@ -47,53 +34,6 @@
 class CcnxContentObjectHeader;
 class CcnxInterestHeader;
 
-/// @cond include_hidden
-/**
- * \ingroup ccnx
- * \private
- * \brief Private namespace for CCNx PIT implementation
- */
-namespace __ccnx_private
-{
-// class i_prefix{}; ///< tag for prefix hash
-class i_timestamp {}; ///< tag for timestamp-ordered records (for cleanup optimization)  
-};
-/// @endcond
-
-/**
- * \ingroup ccnx
- * \brief Typedef for RIT container implemented as a Boost.MultiIndex container
- *
- * - First index (tag<i_prefix>) is a unique hash index based on
- *   prefixes
- * - Second index (tag<i_timestamp>) is a sequenced index based on
- *   arrival order (for clean-up optimizations)
- *
- * \see http://www.boost.org/doc/libs/1_46_1/libs/multi_index/doc/ for more information on Boost.MultiIndex library
- */
-struct CcnxPitEntryContainer
-{
-  /// @cond include_hidden
-  typedef
-  boost::multi_index::multi_index_container<
-    CcnxPitEntry,
-    boost::multi_index::indexed_by<
-      // indexed by hash
-      boost::multi_index::hashed_unique<
-        boost::multi_index::tag<__ccnx_private::i_prefix>,
-        boost::multi_index::const_mem_fun<CcnxPitEntry, const CcnxNameComponents&, &CcnxPitEntry::GetPrefix>,
-        CcnxPrefixHash
-        >,
-      // sequenced to implement MRU
-      boost::multi_index::ordered_non_unique<
-        boost::multi_index::tag<__ccnx_private::i_timestamp>,
-        boost::multi_index::member<CcnxPitEntry, Time, &CcnxPitEntry::m_expireTime>
-        >
-      >
-    > type;
-  /// @endcond
-};
-
 ////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////
 
@@ -101,7 +41,7 @@
  * \ingroup ccnx
  * \brief Class implementing Pending Interests Table
  */
-class CcnxPit : public CcnxPitEntryContainer::type, public Object
+class CcnxPit : public Object
 {
 public:
   /**
@@ -127,8 +67,8 @@
    * \returns iterator to Pit entry. If record not found,
    *          return end() iterator
    */
-  iterator
-  Lookup (const CcnxContentObjectHeader &header) const;
+  virtual Ptr<CcnxPitEntry>
+  Lookup (const CcnxContentObjectHeader &header) const = 0;
 
   /**
    * \brief Find a PIT entry for the given content interest
@@ -136,16 +76,16 @@
    * \returns iterator to Pit entry. If record not found,
    *          return end() iterator
    */
-  iterator
-  Lookup (const CcnxInterestHeader &header);
+  virtual Ptr<CcnxPitEntry>
+  Lookup (const CcnxInterestHeader &header) = 0;
 
   /**
    * @brief Check if the Interest carries an existent nonce.
    * If not, nonce will be added to the list of known nonces
    * @returns true if interest is duplicate (carries an existent nonce), false otherwise
    */
-  bool
-  CheckIfDuplicate (iterator entry, const CcnxInterestHeader &header);
+  virtual bool
+  CheckIfDuplicate (Ptr<CcnxPitEntry> entry, const CcnxInterestHeader &header) = 0;
   
   /**
    * @brief Creates a PIT entry for the given interest
@@ -155,8 +95,8 @@
    *
    * Note. This call assumes that the entry does not exist (i.e., there was a Lookup call before)
    */
-  iterator
-  Create (const CcnxInterestHeader &header);
+  virtual Ptr<CcnxPitEntry>
+  Create (const CcnxInterestHeader &header) = 0;
   
   /**
    * @brief Mark PIT entry deleted
@@ -165,19 +105,56 @@
    * Effectively, this method removes all incoming/outgoing faces and set
    * lifetime +m_PitEntryDefaultLifetime from Now ()
    */
+  virtual void
+  MarkErased (Ptr<CcnxPitEntry> entry) = 0;
+
+  /**
+   * @brief Print out PIT contents for debugging purposes
+   *
+   * Note that there is no definite order in which entries are printed out
+   */
+  virtual void
+  Print (std::ostream &os) const = 0;
+
+  template<class A,class M>
   void
-  MarkErased (iterator entry);
+  modify (A, M)
+  {
+    ;
+  }
+
+  template<class A>
+  void
+  erase (A)
+  {
+    ;
+  }
+
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
+  
+  /**
+   * @brief Static call to cheat python bindings
+   */
+  static inline Ptr<CcnxFib>
+  GetCcnxPit (Ptr<Object> node);
+
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
+  ////////////////////////////////////////////////////////////////////////////
 
 protected:
-  // inherited from Object class                                                                                                                                                        
-  virtual void NotifyNewAggregate (); ///< @brief Even when object is aggregated to another Object
-  virtual void DoDispose (); ///< @brief Do cleanup
-
+  virtual void
+  DoCleanExpired () = 0;
+  
 private:
-  /** \brief Remove expired records from PIT */
+  /**
+   * @brief Remove expired records from PIT
+   */
   void
   CleanExpired ();
-
+  
   /**
    * \brief Set cleanup timeout
    *
@@ -195,27 +172,25 @@
    */
   Time
   GetCleanupTimeout () const;
-
-  friend std::ostream&
-  operator<< (std::ostream& os, const CcnxPit &fib);
   
-private:
+protected:
   Time    m_cleanupTimeout; ///< \brief Configurable timeout of how often cleanup events are working
   EventId m_cleanupEvent;   ///< \brief Cleanup event
 
   // configuration variables. Check implementation of GetTypeId for more details
   Time    m_PitEntryPruningTimout;
   Time    m_PitEntryDefaultLifetime;
-
-  uint32_t m_maxSize;
-
-  Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
 };
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
-std::ostream& operator<< (std::ostream& os, const CcnxPit &pit);
+inline std::ostream&
+operator<< (std::ostream& os, const CcnxPit &pit)
+{
+  pit.Print (os);
+  return os;
+}
 
 } // namespace ns3
 
diff --git a/wscript b/wscript
index 2fb7153..564d4fd 100644
--- a/wscript
+++ b/wscript
@@ -89,6 +89,7 @@
         "model/ccnx-content-store.h",
         "model/ccnx-fib.h",
         "model/ccnx-fib-entry.h",
+        "model/ccnx-forwarding-strategy.h",
         "model/ccnx-face.h",
         "model/ccnx-app-face.h",
         "model/ccnx-net-device-face.h",