Checkpoint
diff --git a/examples/trie.cc b/examples/trie.cc
index 7ec0c40..9c9cc3c 100644
--- a/examples/trie.cc
+++ b/examples/trie.cc
@@ -35,22 +35,22 @@
 
 NS_LOG_COMPONENT_DEFINE ("Trie");
 
-class Integer : public ns3::SimpleRefCount<Integer>
-{
-public:
-  Integer (int value) : value_ (value) {}
+// class Integer : public ns3::SimpleRefCount<Integer>
+// {
+// public:
+//   ::Integer (int value) : value_ (value) {}
 
-  operator int () const { return value_; }
-private:
-  int value_;
-};
+//   operator int () const { return value_; }
+// private:
+//   int value_;
+// };
 
-std::ostream &
-operator << (std::ostream &os, const Integer &i)
-{
-  os << (int)i;
-  return os;
-}
+// std::ostream &
+// operator << (std::ostream &os, const ::Integer &i)
+// {
+//   os << (int)i;
+//   return os;
+// }
 
 int
 main (int argc, char *argv[])
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index f455d60..6548ae5 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -73,7 +73,7 @@
 
   int propagatedCount = 0;
 
-  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry->m_fibEntry->m_faces.get<i_metric> ())
+  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry->GetFibEntry ()->m_faces.get<i_metric> ())
     {
       if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED) // all non-read faces are in front
         break;
@@ -81,16 +81,16 @@
       if (metricFace.m_face == incomingFace) 
         continue; // same face as incoming, don't forward
 
-      if (pitEntry->m_incoming.find (metricFace.m_face) != pitEntry->m_incoming.end ()) 
+      if (pitEntry->GetIncoming ().find (metricFace.m_face) != pitEntry->GetIncoming ().end ()) 
         continue; // don't forward to face that we received interest from
 
       CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
-        pitEntry->m_outgoing.find (metricFace.m_face);
+        pitEntry->GetOutgoing ().find (metricFace.m_face);
       
-      if (outgoing != pitEntry->m_outgoing.end () &&
-          outgoing->m_retxCount >= pitEntry->m_maxRetxCount)
+      if (outgoing != pitEntry->GetOutgoing ().end () &&
+          outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
         {
-          NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry->m_maxRetxCount);
+          NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry->GetMaxRetxCount ());
           continue; // already forwarded before during this retransmission cycle
         }
 
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 76c12a2..3531249 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -15,7 +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
  *
- * Author: Ilya Moiseenko <iliamo@cs.ucla.edu>
+ * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *         Ilya Moiseenko <iliamo@cs.ucla.edu>
  */
 
 #include "ccnx-flooding-strategy.h"
@@ -83,7 +84,7 @@
 
   int propagatedCount = 0;
 
-  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry->m_fibEntry->m_faces.get<i_metric> ())
+  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry->GetFibEntry ()->m_faces.get<i_metric> ())
     {
       NS_LOG_DEBUG ("Trying " << boost::cref(metricFace));
       if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED) // all non-read faces are in the front of the list
@@ -96,15 +97,15 @@
         }
 
       CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
-        pitEntry->m_outgoing.find (metricFace.m_face);
+        pitEntry->GetOutgoing ().find (metricFace.m_face);
       
-      if (outgoing != pitEntry->m_outgoing.end () &&
-          outgoing->m_retxCount >= pitEntry->m_maxRetxCount)
+      if (outgoing != pitEntry->GetOutgoing ().end () &&
+          outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
         {
           NS_LOG_DEBUG ("continue (same as previous outgoing)");
           continue; // already forwarded before during this retransmission cycle
         }
-      NS_LOG_DEBUG ("max retx count: " << pitEntry->m_maxRetxCount);
+      NS_LOG_DEBUG ("max retx count: " << pitEntry->GetMaxRetxCount ());
 
       bool faceAvailable = metricFace.m_face->IsBelowLimit ();
       if (!faceAvailable) // huh...
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index f518f95..df398c8 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -92,22 +92,22 @@
 
   int propagatedCount = 0;
   
-  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry->m_fibEntry->m_faces.get<i_metric> ())
+  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry->GetFibEntry ()->m_faces.get<i_metric> ())
     {
       if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED ||
           metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_YELLOW)
         break; //propagate only to green faces
 
-      if (pitEntry->m_incoming.find (metricFace.m_face) != pitEntry->m_incoming.end ()) 
+      if (pitEntry->GetIncoming ().find (metricFace.m_face) != pitEntry->GetIncoming ().end ()) 
         continue; // don't forward to face that we received interest from
 
       CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
-        pitEntry->m_outgoing.find (metricFace.m_face);
+        pitEntry->GetOutgoing ().find (metricFace.m_face);
       
-      if (outgoing != pitEntry->m_outgoing.end () &&
-          outgoing->m_retxCount >= pitEntry->m_maxRetxCount)
+      if (outgoing != pitEntry->GetOutgoing ().end () &&
+          outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
         {
-          NS_LOG_DEBUG ("retxCount: " << outgoing->m_retxCount << ", maxRetxCount: " << pitEntry->m_maxRetxCount);
+          NS_LOG_DEBUG ("retxCount: " << outgoing->m_retxCount << ", maxRetxCount: " << pitEntry->GetMaxRetxCount ());
           continue;
         }
       
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 27012e3..8cebc00 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -182,8 +182,8 @@
       
       // 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)
+      if (pitEntry->GetFibEntry ()->m_faces.size () == 1 &&
+          pitEntry->GetFibEntry ()->m_faces.begin ()->m_face == face)
         {
           entriesToRemoves.push_back (pitEntry);
         }
@@ -301,14 +301,14 @@
       return;
     }
   
-  // CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry->m_incoming.find (incomingFace);
-  CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry->m_outgoing.find (incomingFace);
+  // CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry->GetIncoming ().find (incomingFace);
+  CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry->GetOutgoing ().find (incomingFace);
 
-  if (outFace == pitEntry->m_outgoing.end ())
+  if (outFace == pitEntry->GetOutgoing ().end ())
     {
 //      NS_ASSERT_MSG (false,
 //                     "Node " << GetObject<Node> ()->GetId () << ", outgoing entry should exist for face " << boost::cref(*incomingFace) << "\n" <<
-//                     "size: " << pitEntry.m_outgoing.size ());
+//                     "size: " << pitEntry.GetOutgoing ().size ());
       
       // m_dropNacks (header, NON_DUPLICATE, incomingFace);
       return;
@@ -331,12 +331,12 @@
       pitEntry->RemoveIncoming (incomingFace);
     }
 
-  pitEntry->m_fibEntry->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW);
-  // StaticCast<CcnxFibImpl> (m_fib)->modify (pitEntry->m_fibEntry,
+  pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW);
+  // StaticCast<CcnxFibImpl> (m_fib)->modify (pitEntry->GetFibEntry (),
   //                                           ll::bind (&CcnxFibEntry::UpdateStatus,
   //                                                     ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
 
-  if (pitEntry->m_incoming.size () == 0) // interest was actually satisfied
+  if (pitEntry->GetIncoming ().size () == 0) // interest was actually satisfied
     {
       // no need to do anything
       m_dropNacks (header, AFTER_SATISFIED, incomingFace);
@@ -392,7 +392,7 @@
       return;
     }
   
-  bool isNew = pitEntry->m_incoming.size () == 0 && pitEntry->m_outgoing.size () == 0;
+  bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
   bool isDuplicated = true;
   if (!pitEntry->IsNonceSeen (header->GetNonce ()))
     {
@@ -413,12 +413,12 @@
   /////////////////////////////////////////////////////////////////////////////////////////
   
   // Data is not in cache
-  CcnxPitEntry::in_iterator inFace   = pitEntry->m_incoming.find (incomingFace);
-  CcnxPitEntry::out_iterator outFace = pitEntry->m_outgoing.find (incomingFace);
+  CcnxPitEntry::in_iterator inFace   = pitEntry->GetIncoming ().find (incomingFace);
+  CcnxPitEntry::out_iterator outFace = pitEntry->GetOutgoing ().find (incomingFace);
 
   bool isRetransmitted = false;
   
-  if (inFace != pitEntry->m_incoming.end ())
+  if (inFace != pitEntry->GetIncoming ().end ())
     {
       // CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
 
@@ -474,7 +474,7 @@
   // update PIT entry lifetime
   pitEntry->UpdateLifetime (header->GetInterestLifetime ());
   
-  if (outFace != pitEntry->m_outgoing.end ())
+  if (outFace != pitEntry->GetOutgoing ().end ())
     {
       NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
       // got a non-duplicate interest from the face we have sent interest to
@@ -485,8 +485,8 @@
 
       // ?? not sure if we need to do that ?? ...
       
-      pitEntry->m_fibEntry->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW);
-      // StaticCast<CcnxFibImpl> (m_fib)->modify(pitEntry->m_fibEntry,
+      pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW);
+      // StaticCast<CcnxFibImpl> (m_fib)->modify(pitEntry->GetFibEntry (),
       //                                          ll::bind (&CcnxFibEntry::UpdateStatus,
       //                                                    ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
     }
@@ -537,7 +537,7 @@
   if (pitEntry != 0)
     {
       //satisfy all pending incoming Interests
-      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->m_incoming)
+      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->GetIncoming ())
         {
           incoming.m_face->Send (packet->Copy ());
           m_outData (header, payload, false, incoming.m_face);
@@ -546,7 +546,7 @@
           // successfull forwarded data trace
         }
 
-      if (pitEntry->m_incoming.size () > 0)
+      if (pitEntry->GetIncoming ().size () > 0)
         {
           // All incoming interests are satisfied. Remove them
           pitEntry->ClearIncoming ();
@@ -582,13 +582,13 @@
     {
       // Note that with MultiIndex we need to modify entries indirectly
 
-      CcnxPitEntry::out_iterator out = pitEntry->m_outgoing.find (incomingFace);
+      CcnxPitEntry::out_iterator out = pitEntry->GetOutgoing ().find (incomingFace);
   
       // If we have sent interest for this data via this face, then update stats.
-      if (out != pitEntry->m_outgoing.end ())
+      if (out != pitEntry->GetOutgoing ().end ())
         {
-          pitEntry->m_fibEntry->UpdateFaceRtt (incomingFace, Simulator::Now () - out->m_sendTime);
-          // StaticCast<CcnxFibImpl> (m_fib)->modify (pitEntry->m_fibEntry,
+          pitEntry->GetFibEntry ()->UpdateFaceRtt (incomingFace, Simulator::Now () - out->m_sendTime);
+          // StaticCast<CcnxFibImpl> (m_fib)->modify (pitEntry->GetFibEntry (),
           //                                          ll::bind (&CcnxFibEntry::UpdateFaceRtt,
           //                                                    ll::_1,
           //                                                    incomingFace,
@@ -615,8 +615,8 @@
         }
 
       // Update metric status for the incoming interface in the corresponding FIB entry
-      pitEntry->m_fibEntry->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN);
-      // StaticCast<CcnxFibImpl>(m_fib)->modify (pitEntry->m_fibEntry,
+      pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN);
+      // StaticCast<CcnxFibImpl>(m_fib)->modify (pitEntry->GetFibEntry (),
       //                                          ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
       //                                                    incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
   
@@ -625,7 +625,7 @@
 
       pitEntry->RemoveIncoming (incomingFace);
 
-      if (pitEntry->m_incoming.size () == 0)
+      if (pitEntry->GetIncoming ().size () == 0)
         {
           // Set pruning timout on PIT entry (instead of deleting the record)
           m_pit->MarkErased (pitEntry);
@@ -667,7 +667,7 @@
       header->SetNack (CcnxInterestHeader::NACK_GIVEUP_PIT);
       packet->AddHeader (*header);
 
-      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->m_incoming)
+      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->GetIncoming ())
         {
           NS_LOG_DEBUG ("Send NACK for " << boost::cref (header->GetName ()) << " to " << boost::cref (*incoming.m_face));
           incoming.m_face->Send (packet->Copy ());
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index 491896e..3d3e5d7 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -36,9 +36,11 @@
 namespace ns3
 {
 
-CcnxPitEntry::CcnxPitEntry (Ptr<const CcnxInterestHeader> header,
+CcnxPitEntry::CcnxPitEntry (CcnxPit &container,
+                            Ptr<const CcnxInterestHeader> header,
                             Ptr<CcnxFibEntry> fibEntry)
-  : m_prefix (header->GetNamePtr ())
+  : m_container (container)
+  , m_prefix (header->GetNamePtr ())
   , m_expireTime (Simulator::Now () + header->GetInterestLifetime ())
   , m_fibEntry (fibEntry)
   , m_maxRetxCount (0)
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index 2e38657..5d85c94 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -41,6 +41,7 @@
 
 class CcnxFace;
 class CcnxNameComponents;
+class CcnxPit;
 
 /// @cond include_hidden
 namespace __ccnx_private
@@ -80,6 +81,8 @@
 /**
  * \ingroup ccnx
  * \brief structure for PIT entry
+ *
+ * All set-methods are virtual, in case index rearrangement is necessary in the derived classes
  */
 struct CcnxPitEntry : SimpleRefCount<CcnxPitEntry>
 {
@@ -98,7 +101,12 @@
    * \param offsetTime Relative time to the current moment, representing PIT entry lifetime
    * \param fibEntry A FIB entry associated with the PIT entry
    */
-  CcnxPitEntry (Ptr<const CcnxInterestHeader> header, Ptr<CcnxFibEntry> fibEntry);
+  CcnxPitEntry (CcnxPit &container, Ptr<const CcnxInterestHeader> header, Ptr<CcnxFibEntry> fibEntry);
+
+  /**
+   * @brief Virtual destructor
+   */
+  virtual ~CcnxPitEntry () {}
   
   /**
    * @brief Update lifetime of PIT entry
@@ -108,7 +116,7 @@
    *
    * @param offsetTime Relative time to the current moment, representing PIT entry lifetime
    */
-  void
+  virtual void
   UpdateLifetime (const Time &offsetTime);
 
   /**
@@ -132,7 +140,7 @@
    *
    * @param expireTime absolute simulation time of when the record should expire
    */
-  void
+  virtual void
   SetExpireTime (const Time &expireTime);
   
   /**
@@ -151,7 +159,7 @@
    *
    * All nonces are stored for the lifetime of the PIT entry
    */
-  void
+  virtual void
   AddSeenNonce (uint32_t nonce)
   { m_seenNonces.insert (nonce); }
 
@@ -161,19 +169,19 @@
    * @param face Face to add to the list of incoming faces
    * @returns iterator to the added entry
    */
-  in_iterator
+  virtual in_iterator
   AddIncoming (Ptr<CcnxFace> face);
 
   /**
    * @brief Remove incoming entry for face `face`
    */
-  void
+  virtual void
   RemoveIncoming (Ptr<CcnxFace> face);
 
   /**
    * @brief Clear all incoming faces either after all of them were satisfied or NACKed
    */
-  void
+  virtual void
   ClearIncoming ()
   { m_incoming.clear (); }
 
@@ -183,13 +191,13 @@
    * @param face Face to add to the list of outgoing faces
    * @returns iterator to the added entry
    */
-  out_iterator
+  virtual out_iterator
   AddOutgoing (Ptr<CcnxFace> face);
 
   /**
    * @brief Clear all incoming faces either after all of them were satisfied or NACKed
    */
-  void
+  virtual void
   ClearOutgoing ()
   { m_outgoing.clear (); }  
   
@@ -199,13 +207,13 @@
    * This method should be called before face is completely removed from the stack.
    * Face is removed from the lists of incoming and outgoing faces
    */
-  void
+  virtual void
   RemoveAllReferencesToFace (Ptr<CcnxFace> face);
 
   /**
    * @brief Flag outgoing face as hopeless
    */
-  void
+  virtual void
   SetWaitingInVain (out_iterator face);
   
   /**
@@ -224,17 +232,27 @@
   /**
    * @brief Increase maximum limit of allowed retransmission per outgoing face
    */
-  void
+  virtual void
   IncreaseAllowedRetxCount ();
-  
+
+  Ptr<CcnxFibEntry>
+  GetFibEntry () { return m_fibEntry; };
+
+  const in_container &
+  GetIncoming () const { return m_incoming; }
+
+  const out_container &
+  GetOutgoing () const { return m_outgoing; }
+
+  uint32_t
+  GetMaxRetxCount () const { return m_maxRetxCount; }
+
 private:
   friend std::ostream& operator<< (std::ostream& os, const CcnxPitEntry &entry);
-  /**
-   * \brief Default constructor
-   */
-  CcnxPitEntry () {};
   
-public:
+protected:
+  CcnxPit &m_container; ///< @brief Reference to the container (to rearrange indexes, if necessary)
+  
   Ptr<const CcnxNameComponents> m_prefix; ///< \brief Prefix of the PIT entry
   Ptr<CcnxFibEntry> m_fibEntry;     ///< \brief FIB entry related to this prefix
   
diff --git a/model/ccnx-pit-impl.cc b/model/ccnx-pit-impl.cc
index 5e353a9..e5179d3 100644
--- a/model/ccnx-pit-impl.cc
+++ b/model/ccnx-pit-impl.cc
@@ -39,6 +39,21 @@
 
 NS_OBJECT_ENSURE_REGISTERED (CcnxPitImpl);
 
+
+// CcnxPitEntryImpl::CcnxPitEntryImpl (CcnxPit &pit,
+//                                     Ptr<const CcnxInterestHeader> header,
+//                                     Ptr<CcnxFibEntry> fibEntry)
+//   : CcnxPitEntry (pit, header, fibEntry)
+//   , item_ (0)
+// {
+//   static_cast<CcnxPitImpl&> (m_container).i_time.insert (*this);
+// }
+
+// CcnxPitEntryImpl::~CcnxPitEntryImpl ()
+// {
+//   static_cast<CcnxPitImpl&> (m_container).i_time.erase (*this);
+// }
+
 TypeId
 CcnxPitImpl::GetTypeId ()
 {
@@ -149,7 +164,7 @@
                  " Prefix = "<< header->GetName() << "NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
 
 
-  Ptr<CcnxPitEntryImpl> newEntry = ns3::Create<CcnxPitEntryImpl> (header, fibEntry);
+  Ptr< entry > newEntry = ns3::Create< entry > (boost::ref (*this), header, fibEntry);
   std::pair< super::iterator, bool > result = super::insert (header->GetName (), newEntry);
   if (result.first != super::end ())
     {
@@ -171,10 +186,10 @@
 
 
 void
-CcnxPitImpl::MarkErased (Ptr<CcnxPitEntry> entry)
+CcnxPitImpl::MarkErased (Ptr<CcnxPitEntry> item)
 {
   // entry->SetExpireTime (Simulator::Now () + m_PitEntryPruningTimout);
-  super::erase (StaticCast<CcnxPitEntryImpl> (entry)->to_iterator ());
+  super::erase (StaticCast< entry > (item)->to_iterator ());
 }
 
 
@@ -219,7 +234,7 @@
   if (from == 0) return 0;
   
   super::parent_trie::recursive_iterator
-    item (*StaticCast<CcnxPitEntryImpl> (from)->to_iterator ()),
+    item (*StaticCast< entry > (from)->to_iterator ()),
     end (0);
   
   for (item++; item != end; item++)
diff --git a/model/ccnx-pit-impl.h b/model/ccnx-pit-impl.h
index 499957f..9dfd62b 100644
--- a/model/ccnx-pit-impl.h
+++ b/model/ccnx-pit-impl.h
@@ -29,33 +29,46 @@
 
 namespace ns3 {
 
+template<class Pit>
 class CcnxPitEntryImpl : public CcnxPitEntry
 {
 public:
-  typedef ndnSIM::trie_with_policy<
-    CcnxNameComponents,
-    ndnSIM::smart_pointer_payload_traits<CcnxPitEntryImpl>,
-    ndnSIM::persistent_policy_traits
-    > trie;
-
-  CcnxPitEntryImpl (Ptr<const CcnxInterestHeader> header,
+  CcnxPitEntryImpl (CcnxPit &pit,
+                    Ptr<const CcnxInterestHeader> header,
                     Ptr<CcnxFibEntry> fibEntry)
-    : CcnxPitEntry (header, fibEntry)
-    , item_ (0)
+  : CcnxPitEntry (pit, header, fibEntry)
+  , item_ (0)
   {
+    static_cast<Pit&> (m_container).i_time.insert (*this);    
+  }
+  
+  virtual ~CcnxPitEntryImpl ()
+  {
+    static_cast<Pit&> (m_container).i_time.erase (*this);
   }
 
+  // to make sure policies work
   void
-  SetTrie (trie::iterator item)
-  {
-    item_ = item;
-  }
+  SetTrie (typename Pit::super::iterator item) { item_ = item; }
 
-  trie::iterator to_iterator () { return item_; }
-  trie::const_iterator to_iterator () const { return item_; }
+  typename Pit::super::iterator to_iterator () { return item_; }
+  typename Pit::super::const_iterator to_iterator () const { return item_; }
+
+public:
+  boost::intrusive::set_member_hook<> time_hook_;
   
 private:
-  trie::iterator item_;
+  typename Pit::super::iterator item_;
+};
+
+template<class T>
+struct TimestampIndex
+{
+  bool
+  operator () (const T &a, const T &b) const
+  {
+    return a.GetExpireTime () < b.GetExpireTime ();
+  }
 };
 
 ////////////////////////////////////////////////////////////////////////
@@ -66,10 +79,19 @@
  * \brief Class implementing Pending Interests Table
  */
 class CcnxPitImpl : public CcnxPit
-                  , protected CcnxPitEntryImpl::trie
+                  , protected ndnSIM::trie_with_policy<CcnxNameComponents,
+                                                       ndnSIM::smart_pointer_payload_traits<CcnxPitEntryImpl< CcnxPitImpl > >,
+                                                       ndnSIM::persistent_policy_traits
+                                                       >
 {
 public:
-  typedef CcnxPitEntryImpl::trie super;
+  typedef ndnSIM::trie_with_policy<CcnxNameComponents,
+                                   ndnSIM::smart_pointer_payload_traits<CcnxPitEntryImpl< CcnxPitImpl > >,
+                                   ndnSIM::persistent_policy_traits
+                                   > super;
+  typedef CcnxPitEntryImpl< CcnxPitImpl > entry;
+
+  // typedef CcnxPitEntryImpl::trie super;
 
   /**
    * \brief Interface ID
@@ -130,6 +152,18 @@
   
 private:
   Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
+
+  // indexes
+  typedef
+  boost::intrusive::set<entry,
+                        boost::intrusive::compare < TimestampIndex< entry > >,
+                        boost::intrusive::member_hook< entry,
+                                                       boost::intrusive::set_member_hook<>,
+                                                       &entry::time_hook_>
+                        > expireTimeIndexType;
+  expireTimeIndexType i_time; 
+                        
+  friend class CcnxPitEntryImpl< CcnxPitImpl >;
 };
 
 } // namespace ns3
diff --git a/utils/payload-with-policy.h b/utils/payload-with-policy.h
new file mode 100644
index 0000000..9fd6709
--- /dev/null
+++ b/utils/payload-with-policy.h
@@ -0,0 +1,104 @@
+/* -*-  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 PAYLOAD_WITH_INDEX_H_
+#define PAYLOAD_WITH_INDEX_H_
+
+namespace ndnSIM
+{
+
+template<typename PayloadTraits,
+         typename IndexTraits>
+class payload_with_index
+{
+public:
+  typedef PayloadTraits::pointer_type iterator;
+  
+  typedef typename IndexTraits::template index<
+    PayloadTraits,
+    typename IndexTraits::template container_hook<parent_trie>::type >::type index_container;
+
+  inline
+  payload_with_index ()
+    : index_ (*this)
+  {
+  }
+
+  inline std::pair< iterator, bool >
+  insert (typename iterator payload)
+  {
+    bool ok = policy_.insert (s_iterator_to (item.first));
+    if (!ok)
+      {
+        item.first->erase (); // cannot insert
+        return std::make_pair (end (), false);
+      }
+
+    return item;
+  }
+
+  // inline void
+  // erase (const FullKey &key)
+  // {
+  //   iterator foundItem, lastItem;
+  //   bool reachLast;
+  //   boost::tie (foundItem, reachLast, lastItem) = trie_.find (key);
+    
+  //   if (!reachLast || lastItem->payload () == PayloadTraits::empty_payload)
+  //     return; // nothing to invalidate
+
+  //   erase (lastItem);
+  // }
+
+  // inline void
+  // erase (iterator node)
+  // {
+  //   if (node == end ()) return;
+
+  //   policy_.erase (s_iterator_to (node));
+  //   node->erase (); // will do cleanup here
+  // }
+
+  // inline void
+  // clear ()
+  // {
+  //   policy_.clear ();
+  //   trie_.clear ();
+  // }
+
+  // template<typename Modifier>
+  // bool
+  // modify (iterator position, Modifier mod)
+  // {
+  //   if (position == end ()) return false;
+  //   if (position->payload () == PayloadTraits::empty_payload) return false;
+
+  //   mod (*position->payload ());
+  //   policy_.update (position);
+  //   return true;
+  // }
+
+private:
+  mutable index_container policy_;
+};
+
+} // ndnSIM
+
+#endif // PAYLOAD_WITH_POLICY_H_