Some progress on CcnxPit. Partially working
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index 3295d31..f455d60 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -57,7 +57,7 @@
 }
     
 bool
-CcnxBestRouteStrategy::PropagateInterest (const CcnxPitEntry  &pitEntry, 
+CcnxBestRouteStrategy::PropagateInterest (Ptr<CcnxPitEntry> pitEntry, 
                                           const Ptr<CcnxFace> &incomingFace,
                                           Ptr<CcnxInterestHeader> &header,
                                           const Ptr<const Packet> &packet)
@@ -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->m_fibEntry->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->m_incoming.find (metricFace.m_face) != pitEntry->m_incoming.end ()) 
         continue; // don't forward to face that we received interest from
 
       CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
-        pitEntry.m_outgoing.find (metricFace.m_face);
+        pitEntry->m_outgoing.find (metricFace.m_face);
       
-      if (outgoing != pitEntry.m_outgoing.end () &&
-          outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
+      if (outgoing != pitEntry->m_outgoing.end () &&
+          outgoing->m_retxCount >= pitEntry->m_maxRetxCount)
         {
-          NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry.m_maxRetxCount);
+          NS_LOG_ERROR (outgoing->m_retxCount << " >= " << pitEntry->m_maxRetxCount);
           continue; // already forwarded before during this retransmission cycle
         }
 
@@ -100,8 +100,7 @@
           continue;
         }
 
-      m_pit->modify (pitEntry,
-                     ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
+      pitEntry->AddOutgoing (metricFace.m_face);
 
       Ptr<Packet> packetToSend = packet->Copy ();
 
diff --git a/model/ccnx-bestroute-strategy.h b/model/ccnx-bestroute-strategy.h
index f2d591b..6768da6 100644
--- a/model/ccnx-bestroute-strategy.h
+++ b/model/ccnx-bestroute-strategy.h
@@ -48,7 +48,7 @@
         
   // inherited from  CcnxForwardingStrategy
   virtual bool
-  PropagateInterest (const CcnxPitEntry  &pitEntry, 
+  PropagateInterest (Ptr<CcnxPitEntry> pitEntry, 
                      const Ptr<CcnxFace> &incomingFace,
                      Ptr<CcnxInterestHeader> &header,
                      const Ptr<const Packet> &packet);
diff --git a/model/ccnx-content-object-header.cc b/model/ccnx-content-object-header.cc
index 0dba3cb..f11296c 100644
--- a/model/ccnx-content-object-header.cc
+++ b/model/ccnx-content-object-header.cc
@@ -79,6 +79,12 @@
   return *m_name;
 }
 
+Ptr<const CcnxNameComponents>
+CcnxContentObjectHeader::GetNamePtr () const
+{
+  return m_name;
+}
+
 #define CCNB CcnxEncodingHelper // just to simplify writing
 
 void
diff --git a/model/ccnx-content-object-header.h b/model/ccnx-content-object-header.h
index 5040dba..c563f70 100644
--- a/model/ccnx-content-object-header.h
+++ b/model/ccnx-content-object-header.h
@@ -243,6 +243,12 @@
   GetName () const;
 
   /**
+   * @brief Get smart pointer to the interest name (to avoid extra memory usage)
+   */
+  Ptr<const CcnxNameComponents>
+  GetNamePtr () const;
+
+  /**
    * @brief Get editable reference to content object's Signature
    */
   inline Signature &
diff --git a/model/ccnx-content-store-impl.h b/model/ccnx-content-store-impl.h
index 9619341..9bdc58e 100644
--- a/model/ccnx-content-store-impl.h
+++ b/model/ccnx-content-store-impl.h
@@ -58,7 +58,7 @@
   // NS_LOG_FUNCTION (this << interest->GetName ());
 
   /// @todo Change to search with predicate
-  typename Container::iterator node = this->deepest_prefix_match (interest->GetName ());
+  typename Container::const_iterator node = this->deepest_prefix_match (interest->GetName ());
   
   if (node != this->end ())
     {
diff --git a/model/ccnx-fib-impl.cc b/model/ccnx-fib-impl.cc
index d7ffb26..e298875 100644
--- a/model/ccnx-fib-impl.cc
+++ b/model/ccnx-fib-impl.cc
@@ -70,9 +70,9 @@
 
 
 Ptr<CcnxFibEntry>
-CcnxFibImpl::LongestPrefixMatch (const CcnxInterestHeader &interest) const
+CcnxFibImpl::LongestPrefixMatch (const CcnxInterestHeader &interest)
 {
-  super::iterator item = const_cast<CcnxFibImpl*> (this)->super::longest_prefix_match (interest.GetName ());
+  super::iterator item = super::longest_prefix_match (interest.GetName ());
   // @todo use predicate to search with exclude filters
 
   if (item == super::end ())
@@ -94,16 +94,23 @@
   NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix) << boost::cref(*face) << metric);
 
   // will add entry if doesn't exists, or just return an iterator to the existing entry
-  Ptr<CcnxFibEntryImpl> newEntry = Create<CcnxFibEntryImpl> (prefix);
-  std::pair< super::iterator, bool > result = super::insert (*prefix, newEntry);
-  newEntry->SetTrie (result.first);
+  std::pair< super::iterator, bool > result = super::insert (*prefix, 0);
+  if (result.first != super::end ())
+    {
+      if (result.second)
+        {
+            Ptr<CcnxFibEntryImpl> newEntry = Create<CcnxFibEntryImpl> (prefix);
+            newEntry->SetTrie (result.first);
+            result.first->set_payload (newEntry);
+        }
   
-  NS_ASSERT_MSG (face != NULL, "Trying to modify NULL face");
-  
-  super::modify (result.first,
-                 ll::bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, ll::_1, face, metric));
+      super::modify (result.first,
+                     ll::bind (&CcnxFibEntry::AddOrUpdateRoutingMetric, ll::_1, face, metric));
     
-  return result.first->payload ();
+      return result.first->payload ();
+    }
+  else
+    return 0;
 }
 
 void
diff --git a/model/ccnx-fib-impl.h b/model/ccnx-fib-impl.h
index cd42ae0..2768a7d 100644
--- a/model/ccnx-fib-impl.h
+++ b/model/ccnx-fib-impl.h
@@ -89,7 +89,7 @@
   CcnxFibImpl ();
 
   virtual Ptr<CcnxFibEntry>
-  LongestPrefixMatch (const CcnxInterestHeader &interest) const;
+  LongestPrefixMatch (const CcnxInterestHeader &interest);
   
   virtual Ptr<CcnxFibEntry>
   Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 09caab7..e5bda1e 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -62,7 +62,7 @@
    * \returns If entry found a valid iterator will be returned, otherwise end ()
    */
   virtual Ptr<CcnxFibEntry>
-  LongestPrefixMatch (const CcnxInterestHeader &interest) const = 0;
+  LongestPrefixMatch (const CcnxInterestHeader &interest) = 0;
   
   /**
    * \brief Add or update FIB entry
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index f16aa78..76c12a2 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -64,7 +64,7 @@
 }
 
 bool
-CcnxFloodingStrategy::PropagateInterest (const CcnxPitEntry  &pitEntry, 
+CcnxFloodingStrategy::PropagateInterest (Ptr<CcnxPitEntry> pitEntry, 
                                          const Ptr<CcnxFace> &incomingFace,
                                          Ptr<CcnxInterestHeader> &header,
                                          const Ptr<const Packet> &packet)
@@ -83,7 +83,7 @@
 
   int propagatedCount = 0;
 
-  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry->m_faces.get<i_metric> ())
+  BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry->m_fibEntry->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
@@ -95,22 +95,16 @@
           continue; // same face as incoming, don't forward
         }
 
-      // if (pitEntry.m_incoming.find (metricFace.m_face) != pitEntry.m_incoming.end ()) 
-      //   {
-      //     NS_LOG_DEBUG ("continue (same as previous incoming)");
-      //     continue; // don't forward to face that we received interest from
-      //   }
-
       CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
-        pitEntry.m_outgoing.find (metricFace.m_face);
+        pitEntry->m_outgoing.find (metricFace.m_face);
       
-      if (outgoing != pitEntry.m_outgoing.end () &&
-          outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
+      if (outgoing != pitEntry->m_outgoing.end () &&
+          outgoing->m_retxCount >= pitEntry->m_maxRetxCount)
         {
           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->m_maxRetxCount);
 
       bool faceAvailable = metricFace.m_face->IsBelowLimit ();
       if (!faceAvailable) // huh...
@@ -118,14 +112,7 @@
           continue;
         }
 
-      m_pit->modify (pitEntry,
-                     ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
-
-      // if (Simulator::GetContext ()==2)
-      //   {
-      //     NS_LOG_ERROR ("new outgoing entry for " << boost::cref (*metricFace.m_face));
-      //     NS_LOG_ERROR ("size: " << pitEntry.m_outgoing.size ());
-      //   }
+      pitEntry->AddOutgoing (metricFace.m_face);
 
       Ptr<Packet> packetToSend = packet->Copy ();
 
diff --git a/model/ccnx-flooding-strategy.h b/model/ccnx-flooding-strategy.h
index 750f21c..fa77988 100644
--- a/model/ccnx-flooding-strategy.h
+++ b/model/ccnx-flooding-strategy.h
@@ -47,7 +47,7 @@
 
   // inherited from  CcnxForwardingStrategy
   virtual bool
-  PropagateInterest (const CcnxPitEntry  &pitEntry, 
+  PropagateInterest (Ptr<CcnxPitEntry> pitEntry, 
                      const Ptr<CcnxFace> &incomingFace,
                      Ptr<CcnxInterestHeader> &header,
                      const Ptr<const Packet> &packet);
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 414e200..f518f95 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -82,7 +82,7 @@
 }
 
 bool
-CcnxForwardingStrategy::PropagateInterestViaGreen (const CcnxPitEntry  &pitEntry, 
+CcnxForwardingStrategy::PropagateInterestViaGreen (Ptr<CcnxPitEntry> pitEntry, 
                                                    const Ptr<CcnxFace> &incomingFace,
                                                    Ptr<CcnxInterestHeader> &header,
                                                    const Ptr<const Packet> &packet)
@@ -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->m_fibEntry->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->m_incoming.find (metricFace.m_face) != pitEntry->m_incoming.end ()) 
         continue; // don't forward to face that we received interest from
 
       CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
-        pitEntry.m_outgoing.find (metricFace.m_face);
+        pitEntry->m_outgoing.find (metricFace.m_face);
       
-      if (outgoing != pitEntry.m_outgoing.end () &&
-          outgoing->m_retxCount >= pitEntry.m_maxRetxCount)
+      if (outgoing != pitEntry->m_outgoing.end () &&
+          outgoing->m_retxCount >= pitEntry->m_maxRetxCount)
         {
-          NS_LOG_DEBUG ("retxCount: " << outgoing->m_retxCount << ", maxRetxCount: " << pitEntry.m_maxRetxCount);
+          NS_LOG_DEBUG ("retxCount: " << outgoing->m_retxCount << ", maxRetxCount: " << pitEntry->m_maxRetxCount);
           continue;
         }
       
@@ -118,8 +118,7 @@
           continue;
         }
 
-      m_pit->modify (pitEntry,
-                     ll::bind (&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
+      pitEntry->AddOutgoing (metricFace.m_face);
 
       Ptr<Packet> packetToSend = packet->Copy ();
 
diff --git a/model/ccnx-forwarding-strategy.h b/model/ccnx-forwarding-strategy.h
index 99ed02c..ed28fd4 100644
--- a/model/ccnx-forwarding-strategy.h
+++ b/model/ccnx-forwarding-strategy.h
@@ -61,7 +61,7 @@
    * @return true if interest was successfully propagated, false if all options have failed
    */
   virtual bool
-  PropagateInterest (const CcnxPitEntry  &pitEntry, 
+  PropagateInterest (Ptr<CcnxPitEntry> pitEntry, 
                      const Ptr<CcnxFace> &incomingFace,
                      Ptr<CcnxInterestHeader> &header,
                      const Ptr<const Packet> &packet) = 0;
@@ -80,7 +80,7 @@
    * \see PropagateInterest
    */
   bool
-  PropagateInterestViaGreen (const CcnxPitEntry  &pitEntry, 
+  PropagateInterestViaGreen (Ptr<CcnxPitEntry> pitEntry, 
                              const Ptr<CcnxFace> &incomingFace,
                              Ptr<CcnxInterestHeader> &header,
                              const Ptr<const Packet> &packet);
diff --git a/model/ccnx-interest-header.cc b/model/ccnx-interest-header.cc
index 554cded..2c7e798 100644
--- a/model/ccnx-interest-header.cc
+++ b/model/ccnx-interest-header.cc
@@ -74,6 +74,12 @@
   return *m_name;
 }
 
+Ptr<const CcnxNameComponents>
+CcnxInterestHeader::GetNamePtr () const
+{
+  return m_name;
+}
+
 void
 CcnxInterestHeader::SetMinSuffixComponents (int32_t value)
 {
diff --git a/model/ccnx-interest-header.h b/model/ccnx-interest-header.h
index 8b1d5c4..77b8426 100644
--- a/model/ccnx-interest-header.h
+++ b/model/ccnx-interest-header.h
@@ -155,6 +155,12 @@
   GetName () const;
 
   /**
+   * @brief Get smart pointer to the interest name (to avoid extra memory usage)
+   */
+  Ptr<const CcnxNameComponents>
+  GetNamePtr () const;
+
+  /**
    * \brief Set interest MinSuffixComponents
    *
    * MinSuffixComponents refer to the number of name components beyond those in the prefix, 
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 928d015..27012e3 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -175,24 +175,22 @@
   face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
 
   // just to be on a safe side. Do the process in two steps
-  std::list<boost::reference_wrapper<const CcnxPitEntry> > entriesToRemoves;
-  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));
-  //       }
-  //   }
-  BOOST_FOREACH (const CcnxPitEntry &removedEntry, entriesToRemoves)
+  std::list< Ptr<CcnxPitEntry> > entriesToRemoves;
+  for (Ptr<CcnxPitEntry> pitEntry = m_pit->Begin (); pitEntry != 0; pitEntry = m_pit->Next (pitEntry))
     {
-      m_pit->erase (removedEntry);
+      pitEntry->RemoveAllReferencesToFace (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 (pitEntry);
+        }
+    }
+  BOOST_FOREACH (Ptr<CcnxPitEntry> removedEntry, entriesToRemoves)
+    {
+      m_pit->MarkErased (removedEntry);
     }
 
   CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
@@ -322,17 +320,15 @@
   // incomingFace->LeakBucketByOnePacket ();
 
   NS_LOG_ERROR ("Nack on " << boost::cref(*incomingFace));
-
-  m_pit->modify (pitEntry,
-                 ll::bind (&CcnxPitEntry::SetWaitingInVain, ll::_1, outFace));
+  
+  pitEntry->SetWaitingInVain (outFace);
 
   // If NACK is NACK_GIVEUP_PIT, then neighbor gave up trying to and removed it's PIT entry.
   // So, if we had an incoming entry to this neighbor, then we can remove it now
 
   if (header->GetNack () == CcnxInterestHeader::NACK_GIVEUP_PIT)
     {
-      m_pit->modify (pitEntry,
-                     ll::bind (&CcnxPitEntry::RemoveIncoming, ll::_1, incomingFace));
+      pitEntry->RemoveIncoming (incomingFace);
     }
 
   pitEntry->m_fibEntry->UpdateStatus (incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW);
@@ -361,7 +357,7 @@
   nonNackInterest->AddHeader (*header);
   
   bool propagated = m_forwardingStrategy->
-    PropagateInterest (*pitEntry, incomingFace, header, nonNackInterest);
+    PropagateInterest (pitEntry, incomingFace, header, nonNackInterest);
 
   // // ForwardingStrategy will try its best to forward packet to at least one interface.
   // // If no interests was propagated, then there is not other option for forwarding or
@@ -386,7 +382,7 @@
   Ptr<CcnxPitEntry> pitEntry = m_pit->Lookup (*header);
   if (pitEntry == 0)
     {
-      pitEntry = m_pit->Create (*header);
+      pitEntry = m_pit->Create (header);
     }
 
   if (pitEntry == 0)
@@ -397,8 +393,13 @@
     }
   
   bool isNew = pitEntry->m_incoming.size () == 0 && pitEntry->m_outgoing.size () == 0;
-  bool isDuplicated = m_pit->CheckIfDuplicate (pitEntry, *header);
-  
+  bool isDuplicated = true;
+  if (!pitEntry->IsNonceSeen (header->GetNonce ()))
+    {
+      pitEntry->AddSeenNonce (header->GetNonce ());
+      isDuplicated = false;
+    }
+
   NS_LOG_FUNCTION (header->GetName () << header->GetNonce () << boost::cref (*incomingFace) << isDuplicated);
 
   /////////////////////////////////////////////////////////////////////////////////////////
@@ -426,8 +427,7 @@
     }
   else
     {
-      m_pit->modify (pitEntry,
-                     ll::var(inFace) = ll::bind (&CcnxPitEntry::AddIncoming, ll::_1, incomingFace));
+      inFace = pitEntry->AddIncoming (incomingFace);
     }
   //////////////////////////////////////////////////////////////////////////////////
   //////////////////////////////////////////////////////////////////////////////////
@@ -472,9 +472,7 @@
     }
 
   // update PIT entry lifetime
-  m_pit->modify (pitEntry,
-                 ll::bind (&CcnxPitEntry::UpdateLifetime, ll::_1,
-                           header->GetInterestLifetime ()));
+  pitEntry->UpdateLifetime (header->GetInterestLifetime ());
   
   if (outFace != pitEntry->m_outgoing.end ())
     {
@@ -506,17 +504,16 @@
   /////////////////////////////////////////////////////////////////////
   
   bool propagated = m_forwardingStrategy->
-    PropagateInterest (*pitEntry, incomingFace, header, packet);
+    PropagateInterest (pitEntry, incomingFace, header, packet);
 
   if (!propagated && isRetransmitted) //give another chance if retransmitted
     {
       // increase max number of allowed retransmissions
-      m_pit->modify (pitEntry,
-                     ll::bind (&CcnxPitEntry::IncreaseAllowedRetxCount, ll::_1));
+      pitEntry->IncreaseAllowedRetxCount ();
 
       // try again
       propagated = m_forwardingStrategy->
-        PropagateInterest (*pitEntry, incomingFace, header, packet);
+        PropagateInterest (pitEntry, incomingFace, header, packet);
     }
   
   // ForwardingStrategy will try its best to forward packet to at least one interface.
@@ -552,12 +549,10 @@
       if (pitEntry->m_incoming.size () > 0)
         {
           // All incoming interests are satisfied. Remove them
-          m_pit->modify (pitEntry,
-                         ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
+          pitEntry->ClearIncoming ();
 
           // Remove all outgoing faces
-          m_pit->modify (pitEntry,
-                         ll::bind (&CcnxPitEntry::ClearOutgoing, ll::_1));
+          pitEntry->ClearOutgoing ();
           
           // Set pruning timout on PIT entry (instead of deleting the record)
           m_pit->MarkErased (pitEntry);
@@ -628,8 +623,7 @@
       // Add or update entry in the content store
       m_contentStore->Add (header, payload);
 
-      m_pit->modify (pitEntry,
-                     ll::bind (&CcnxPitEntry::RemoveIncoming, ll::_1, incomingFace));
+      pitEntry->RemoveIncoming (incomingFace);
 
       if (pitEntry->m_incoming.size () == 0)
         {
@@ -682,12 +676,10 @@
         }
   
       // All incoming interests cannot be satisfied. Remove them
-      m_pit->modify (pitEntry,
-                     ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
+      pitEntry->ClearIncoming ();
 
       // Remove also outgoing
-      m_pit->modify (pitEntry,
-                     ll::bind (&CcnxPitEntry::ClearOutgoing, ll::_1));
+      pitEntry->ClearOutgoing ();
   
       // Set pruning timout on PIT entry (instead of deleting the record)
       m_pit->MarkErased (pitEntry);
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index ad81781..491896e 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -21,6 +21,7 @@
 #include "ccnx-pit-entry.h"
 #include "ccnx-name-components.h"
 #include "ccnx-fib.h"
+#include "ccnx-interest-header.h"
 
 #include "ns3/simulator.h"
 #include "ns3/log.h"
@@ -35,14 +36,14 @@
 namespace ns3
 {
 
-CcnxPitEntry::CcnxPitEntry (Ptr<const CcnxNameComponents> prefix,
-                            const Time &expireTime,
+CcnxPitEntry::CcnxPitEntry (Ptr<const CcnxInterestHeader> header,
                             Ptr<CcnxFibEntry> fibEntry)
-  : m_prefix (prefix)
+  : m_prefix (header->GetNamePtr ())
+  , m_expireTime (Simulator::Now () + header->GetInterestLifetime ())
   , m_fibEntry (fibEntry)
-  , m_expireTime (Simulator::Now () + expireTime)
   , m_maxRetxCount (0)
 {
+  // note that if interest lifetime is not set, the behavior is undefined
 }
 
 void
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index 62f7e3f..2e38657 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -98,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<const CcnxNameComponents> prefix, const Time &offsetTime, Ptr<CcnxFibEntry> fibEntry);
+  CcnxPitEntry (Ptr<const CcnxInterestHeader> header, Ptr<CcnxFibEntry> fibEntry);
   
   /**
    * @brief Update lifetime of PIT entry
@@ -227,8 +227,6 @@
   void
   IncreaseAllowedRetxCount ();
   
-protected:
-  
 private:
   friend std::ostream& operator<< (std::ostream& os, const CcnxPitEntry &entry);
   /**
diff --git a/model/ccnx-pit-impl.cc b/model/ccnx-pit-impl.cc
index 11c91e9..5e353a9 100644
--- a/model/ccnx-pit-impl.cc
+++ b/model/ccnx-pit-impl.cc
@@ -67,12 +67,13 @@
 uint32_t
 CcnxPitImpl::GetMaxSize () const
 {
-  return 0;
+  return getPolicy ().get_max_size ();
 }
 
 void
 CcnxPitImpl::SetMaxSize (uint32_t maxSize)
 {
+  getPolicy ().set_max_size (maxSize);
 }
 
 void 
@@ -87,7 +88,7 @@
 void 
 CcnxPitImpl::DoDispose ()
 {
-  // clear ();
+  clear ();
 }
 
 void
@@ -96,6 +97,7 @@
   // NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
   Time now = Simulator::Now ();
 
+  NS_LOG_ERROR ("Need to be repaired");
   // // uint32_t count = 0;
   // while (!empty ())
   //   {
@@ -111,101 +113,126 @@
 }
 
 Ptr<CcnxPitEntry>
-CcnxPitImpl::Lookup (const CcnxContentObjectHeader &header) const
+CcnxPitImpl::Lookup (const CcnxContentObjectHeader &header)
 {
-  return 0;
-  // iterator entry = end ();
+  /// @todo use predicate to search with exclude filters  
+  super::iterator item = super::longest_prefix_match (header.GetName ());
 
-  // // 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 ();
+  if (item == super::end ())
+    return 0;
+  else
+    return item->payload (); // which could also be 0
 }
 
 Ptr<CcnxPitEntry>
 CcnxPitImpl::Lookup (const CcnxInterestHeader &header)
 {
-  return 0;
-  // NS_LOG_FUNCTION (header.GetName ());
-  // NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
+  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;
-}
+  super::iterator foundItem, lastItem;
+  bool reachLast;
+  boost::tie (foundItem, reachLast, lastItem) = super::getTrie ().find (header.GetName ());
 
-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;
+  if (!reachLast || lastItem == super::end ())
+    return 0;
+  else
+    return lastItem->payload (); // which could also be 0
 }
 
 Ptr<CcnxPitEntry>
-CcnxPitImpl::Create (const CcnxInterestHeader &header)
+CcnxPitImpl::Create (Ptr<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);
+  Ptr<CcnxFibEntry> fibEntry = m_fib->LongestPrefixMatch (*header);
+  NS_ASSERT_MSG (fibEntry != 0,
+                 "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;
+
+  Ptr<CcnxPitEntryImpl> newEntry = ns3::Create<CcnxPitEntryImpl> (header, fibEntry);
+  std::pair< super::iterator, bool > result = super::insert (header->GetName (), newEntry);
+  if (result.first != super::end ())
+    {
+      if (result.second)
+        {
+          newEntry->SetTrie (result.first);
+          return newEntry;
+        }
+      else
+        {
+          // should we do anything?
+          // update payload? add new payload?
+          return result.first->payload ();
+        }
+    }
+  else
+    return 0;
 }
 
 
 void
 CcnxPitImpl::MarkErased (Ptr<CcnxPitEntry> entry)
 {
-  // modify (entry,
-  //         ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
-  //                   Simulator::Now () + m_PitEntryPruningTimout));
+  // entry->SetExpireTime (Simulator::Now () + m_PitEntryPruningTimout);
+  super::erase (StaticCast<CcnxPitEntryImpl> (entry)->to_iterator ());
 }
 
 
 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;
-  //   }
+  // !!! unordered_set imposes "random" order of item in the same level !!!
+  super::parent_trie::const_recursive_iterator item (super::getTrie ()), end (0);
+  for (; item != end; item++)
+    {
+      if (item->payload () == 0) continue;
+
+      os << item->payload ()->GetPrefix () << "\t" << *item->payload () << "\n";
+    }
 }
 
+Ptr<CcnxPitEntry>
+CcnxPitImpl::Begin ()
+{
+  super::parent_trie::recursive_iterator item (super::getTrie ()), end (0);
+  for (; item != end; item++)
+    {
+      if (item->payload () == 0) continue;
+      break;
+    }
+
+  if (item == end)
+    return End ();
+  else
+    return item->payload ();
+}
+
+Ptr<CcnxPitEntry>
+CcnxPitImpl::End ()
+{
+  return 0;
+}
+
+Ptr<CcnxPitEntry>
+CcnxPitImpl::Next (Ptr<CcnxPitEntry> from)
+{
+  if (from == 0) return 0;
+  
+  super::parent_trie::recursive_iterator
+    item (*StaticCast<CcnxPitEntryImpl> (from)->to_iterator ()),
+    end (0);
+  
+  for (item++; item != end; item++)
+    {
+      if (item->payload () == 0) continue;
+      break;
+    }
+
+  if (item == end)
+    return End ();
+  else
+    return item->payload ();
+}
+
+
 } // namespace ns3
diff --git a/model/ccnx-pit-impl.h b/model/ccnx-pit-impl.h
index 3f5fdfc..499957f 100644
--- a/model/ccnx-pit-impl.h
+++ b/model/ccnx-pit-impl.h
@@ -24,6 +24,7 @@
 #include "ccnx-pit.h"
 #include "../utils/trie-with-policy.h"
 #include "../utils/empty-policy.h"
+#include "../utils/persistent-policy.h"
 #include "ns3/ccnx-name-components.h"
 
 namespace ns3 {
@@ -34,11 +35,12 @@
   typedef ndnSIM::trie_with_policy<
     CcnxNameComponents,
     ndnSIM::smart_pointer_payload_traits<CcnxPitEntryImpl>,
-    ndnSIM::empty_policy_traits
+    ndnSIM::persistent_policy_traits
     > trie;
 
-  CcnxPitEntryImpl (const Ptr<const CcnxNameComponents> &prefix, const Time &offsetTime, Ptr<CcnxFibEntry> fibEntry)
-    : CcnxPitEntry (prefix, offsetTime, fibEntry)
+  CcnxPitEntryImpl (Ptr<const CcnxInterestHeader> header,
+                    Ptr<CcnxFibEntry> fibEntry)
+    : CcnxPitEntry (header, fibEntry)
     , item_ (0)
   {
   }
@@ -88,16 +90,13 @@
 
   // inherited from CcnxPit  
   virtual Ptr<CcnxPitEntry>
-  Lookup (const CcnxContentObjectHeader &header) const;
+  Lookup (const CcnxContentObjectHeader &header);
 
   virtual Ptr<CcnxPitEntry>
   Lookup (const CcnxInterestHeader &header);
 
-  virtual bool
-  CheckIfDuplicate (Ptr<CcnxPitEntry> entry, const CcnxInterestHeader &header);
-  
   virtual Ptr<CcnxPitEntry>
-  Create (const CcnxInterestHeader &header);
+  Create (Ptr<const CcnxInterestHeader> header);
   
   virtual void
   MarkErased (Ptr<CcnxPitEntry> entry);
@@ -105,15 +104,14 @@
   virtual void
   Print (std::ostream &os) const;
 
-  // /**
-  //  * @brief Modify element in container
-  //  */
-  // template<typename Modifier>
-  // bool
-  // modify (Ptr<CcnxPitEntry> item, Modifier mod)
-  // {
-  //   return super::modify (StaticCast<CcnxPitEntryImpl> (item)->to_iterator (), mod);
-  // }
+  virtual Ptr<CcnxPitEntry>
+  Begin ();
+
+  virtual Ptr<CcnxPitEntry>
+  End ();
+
+  virtual Ptr<CcnxPitEntry>
+  Next (Ptr<CcnxPitEntry>);
   
 protected:
   // inherited from CcnxPit
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index 3733880..a6328fd 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -54,12 +54,6 @@
                    StringValue ("100ms"),
                    MakeTimeAccessor (&CcnxPit::m_PitEntryPruningTimout),
                    MakeTimeChecker ())
-    
-    .AddAttribute ("PitEntryDefaultLifetime",
-                   "Default lifetime of PIT entry (aka default Interest lifetime)",
-                   StringValue("4s"),
-                   MakeTimeAccessor (&CcnxPit::m_PitEntryDefaultLifetime),
-                   MakeTimeChecker ())
     ;
 
   return tid;
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index b6e4388..0597863 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -63,12 +63,17 @@
 
   /**
    * \brief Find corresponding PIT entry for the given content name
+   *
+   * Not that this call should be repeated enough times until it return 0.
+   * This way all records with shorter or equal prefix as in content object will be found
+   * and satisfied.
+   *
    * \param prefix Prefix for which to lookup the entry
-   * \returns iterator to Pit entry. If record not found,
-   *          return end() iterator
+   * \returns smart pointer to PIT entry. If record not found,
+   *          returns 0
    */
   virtual Ptr<CcnxPitEntry>
-  Lookup (const CcnxContentObjectHeader &header) const = 0;
+  Lookup (const CcnxContentObjectHeader &header) = 0;
 
   /**
    * \brief Find a PIT entry for the given content interest
@@ -80,14 +85,6 @@
   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
-   */
-  virtual bool
-  CheckIfDuplicate (Ptr<CcnxPitEntry> entry, const CcnxInterestHeader &header) = 0;
-  
-  /**
    * @brief Creates a PIT entry for the given interest
    * @param header parsed interest header
    * @returns iterator to Pit entry. If record could not be created (e.g., limit reached),
@@ -96,7 +93,7 @@
    * Note. This call assumes that the entry does not exist (i.e., there was a Lookup call before)
    */
   virtual Ptr<CcnxPitEntry>
-  Create (const CcnxInterestHeader &header) = 0;
+  Create (Ptr<const CcnxInterestHeader> header) = 0;
   
   /**
    * @brief Mark PIT entry deleted
@@ -116,19 +113,37 @@
   virtual void
   Print (std::ostream &os) const = 0;
 
-  template<class A,class M>
-  void
-  modify (A, M)
-  {
-    ;
-  }
+  // template<class A,class M>
+  // void
+  // modify (A, M)
+  // {
+  //   ;
+  // }
 
-  template<class A>
-  void
-  erase (A)
-  {
-    ;
-  }
+  // template<class A>
+  // void
+  // erase (A)
+  // {
+  //   ;
+  // }
+
+  /**
+   * @brief Return first element of FIB (no order guaranteed)
+   */
+  virtual Ptr<CcnxPitEntry>
+  Begin () = 0;
+
+  /**
+   * @brief Return item next after last (no order guaranteed)
+   */
+  virtual Ptr<CcnxPitEntry>
+  End () = 0;
+
+  /**
+   * @brief Advance the iterator
+   */
+  virtual Ptr<CcnxPitEntry>
+  Next (Ptr<CcnxPitEntry>) = 0;
 
   ////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////
@@ -137,7 +152,7 @@
   /**
    * @brief Static call to cheat python bindings
    */
-  static inline Ptr<CcnxFib>
+  static inline Ptr<CcnxPit>
   GetCcnxPit (Ptr<Object> node);
 
   ////////////////////////////////////////////////////////////////////////////
@@ -179,7 +194,6 @@
 
   // configuration variables. Check implementation of GetTypeId for more details
   Time    m_PitEntryPruningTimout;
-  Time    m_PitEntryDefaultLifetime;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -192,6 +206,13 @@
   return os;
 }
 
+inline Ptr<CcnxPit>
+CcnxPit::GetCcnxPit (Ptr<Object> node)
+{
+  return node->GetObject<CcnxPit> ();
+}
+
+
 } // namespace ns3
 
 #endif	/* CCNX_PIT_H */