Several important corrections. Adding option to delay data at every node (random from 0.1 to 2 ms)
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index e8b0fc1..c06e0cf 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -32,6 +32,7 @@
 #include "ns3/boolean.h"
 #include "ns3/string.h"
 #include "ns3/simulator.h"
+#include "ns3/random-variable.h"
 
 #include "ns3/ccnx-header-helper.h"
 
@@ -83,6 +84,10 @@
                    BooleanValue (false),
                    MakeBooleanAccessor (&CcnxL3Protocol::m_cacheUnsolicitedData),
                    MakeBooleanChecker ())
+    .AddAttribute ("RandomDataDelaying", "Delaying data processing",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&CcnxL3Protocol::m_delayingDataProcessing),
+                   MakeBooleanChecker ())
   ;
   return tid;
 }
@@ -392,8 +397,9 @@
                                  Ptr<CcnxInterestHeader> &header,
                                  const Ptr<const Packet> &packet)
 {
-  NS_LOG_FUNCTION (incomingFace << header << packet);
+  NS_LOG_FUNCTION (incomingFace << header << packet << header->GetName ());
   m_inInterests (header, incomingFace);
+  // NS_LOG_DEBUG (*m_pit);
 
   // Lookup of Pit (and associated Fib) entry for this Interest 
   tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
@@ -532,6 +538,55 @@
     }
 }
 
+void
+CcnxL3Protocol::OnDataDelayed (Ptr<CcnxContentObjectHeader> header,
+                               Ptr<Packet> payload,
+                               const Ptr<const Packet> &packet)
+{
+  if (m_delayingDataProcessing)
+    {
+      NS_LOG_DEBUG ("Delayed processing " << header->GetName ());
+      // NS_LOG_DEBUG (*m_pit);
+    }
+  
+  // 1. Lookup PIT entry
+  try
+    {
+      CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header);
+      
+      //satisfy all pending incoming Interests
+      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->m_incoming)
+        {
+          incoming.m_face->Send (packet->Copy ());
+          m_outData (header, payload, false, incoming.m_face);
+          NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
+          
+          // successfull forwarded data trace
+        }
+
+      if (pitEntry->m_incoming.size () > 0)
+        {
+          // All incoming interests are satisfied. Remove them
+          m_pit->modify (pitEntry,
+                         ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
+
+          // Remove all outgoing faces
+          m_pit->modify (pitEntry,
+                         ll::bind (&CcnxPitEntry::ClearOutgoing, ll::_1));
+          
+          // Set pruning timout on PIT entry (instead of deleting the record)
+          m_pit->modify (pitEntry,
+                         ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+                                   Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+        }
+    }
+  catch (CcnxPitEntryNotFound)
+    {
+      NS_LOG_DEBUG ("Pit entry not found (was satisfied and removed before)");
+      return; // do not process unsoliced data packets
+    }
+}
+
 // Processing ContentObjects
 void
 CcnxL3Protocol::OnData (const Ptr<CcnxFace> &incomingFace,
@@ -542,20 +597,21 @@
     
   NS_LOG_FUNCTION (incomingFace << header->GetName () << payload << packet);
   m_inData (header, payload, incomingFace);
-
+  // NS_LOG_DEBUG (*m_pit);
+  
   // 1. Lookup PIT entry
   try
     {
-      const CcnxPitEntry &pitEntry = m_pit->Lookup (*header);
+      CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header);
 
       // Note that with MultiIndex we need to modify entries indirectly
 
-      CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry.m_outgoing.find (incomingFace);
+      CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry->m_outgoing.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->m_outgoing.end ())
         {
-          m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry.m_fibEntry),
+          m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry->m_fibEntry),
                                ll::bind (&CcnxFibEntry::UpdateFaceRtt,
                                          ll::_1,
                                          incomingFace,
@@ -582,37 +638,37 @@
         }
 
       // Update metric status for the incoming interface in the corresponding FIB entry
-      m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry.m_fibEntry),
+      m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry->m_fibEntry),
                            ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
                                      incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
   
       // Add or update entry in the content store
       m_contentStore->Add (header, payload);
 
-      //satisfy all pending incoming Interests
-      BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
+      m_pit->modify (pitEntry,
+                     ll::bind (&CcnxPitEntry::RemoveIncoming, ll::_1, incomingFace));
+
+      if (pitEntry->m_incoming.size () == 0)
         {
-          if (incoming.m_face != incomingFace)
+          // Set pruning timout on PIT entry (instead of deleting the record)
+          m_pit->modify (pitEntry,
+                         ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+                                   Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+        }
+      else
+        {
+          if (!m_delayingDataProcessing)
             {
-              incoming.m_face->Send (packet->Copy ());
-              m_outData (header, payload, false, incoming.m_face);
-              NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
+              OnDataDelayed (header, payload, packet);
             }
           else
             {
-              NS_LOG_DEBUG ("Ignore incoming interests from ourselves (" << *incoming.m_face << ")");
+              NS_LOG_DEBUG ("Delaying Data forwarding " << header->GetName ());
+              UniformVariable delay (0.0001, 0.002);
+              Simulator::Schedule (Seconds (delay.GetValue ()),
+                                   &CcnxL3Protocol::OnDataDelayed, this, header, payload, packet);
             }
-          
-          // successfull forwarded data trace
         }
-      // All incoming interests are satisfied. Remove them
-      m_pit->modify (m_pit->iterator_to (pitEntry),
-                     ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
-      
-      // Set pruning timout on PIT entry (instead of deleting the record)
-      m_pit->modify (m_pit->iterator_to (pitEntry),
-                     ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
-                                  Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
     }
   catch (CcnxPitEntryNotFound)
     {
@@ -639,6 +695,7 @@
                                 Ptr<CcnxInterestHeader> header)
 {
   NS_LOG_FUNCTION (this << &pitEntry);
+  // NS_LOG_DEBUG (*m_pit);
   if (m_nacksEnabled)
     {
       Ptr<Packet> packet = Create<Packet> ();
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index ba4fcaa..a9c4f8a 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -195,6 +195,11 @@
   GiveUpInterest (const CcnxPitEntry &pitEntry,
                   Ptr<CcnxInterestHeader> header);
 
+  void
+  OnDataDelayed (Ptr<CcnxContentObjectHeader> header,
+                 Ptr<Packet> payload,
+                 const Ptr<const Packet> &packet);
+  
 private:
   uint32_t m_faceCounter; ///< \brief counter of faces. Increased every time a new face is added to the stack
   typedef std::vector<Ptr<CcnxFace> > CcnxFaceList;
@@ -210,6 +215,7 @@
 
   bool m_nacksEnabled;
   bool m_cacheUnsolicitedData;
+  bool m_delayingDataProcessing;
   
   // Time    m_bucketLeakInterval;
   // EventId m_bucketLeakEvent;
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index b9cd3f5..d0615b0 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -49,7 +49,7 @@
 void
 CcnxPitEntry::SetExpireTime (const Time &expireTime)
 {
-  NS_LOG_FUNCTION (expireTime);
+  NS_LOG_FUNCTION (expireTime.ToDouble (Time::S));
   m_expireTime = expireTime;
 }
 
@@ -57,11 +57,13 @@
 void
 CcnxPitEntry::UpdateLifetime (const Time &offsetTime)
 {
+  NS_LOG_FUNCTION (offsetTime.ToDouble (Time::S));
+  
   Time newExpireTime = Simulator::Now () + offsetTime;
   if (newExpireTime > m_expireTime)
     m_expireTime = newExpireTime;
   
-  NS_LOG_DEBUG ("Updated lifetime to " << m_expireTime.ToDouble (Time::S));
+  NS_LOG_INFO ("Updated lifetime to " << m_expireTime.ToDouble (Time::S));
 }
 
 CcnxPitEntryIncomingFaceContainer::type::iterator
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index ead991c..a68c4a7 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -140,7 +140,7 @@
   m_fib = fib;
 }
 
-const CcnxPitEntry&
+CcnxPitEntryContainer::type::iterator
 CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
 {
   // NS_LOG_FUNCTION_NOARGS ();
@@ -157,19 +157,16 @@
 
       entry = get<i_prefix> ().find (subPrefix);
       if (entry != end())
-        return *entry;
+        return entry;
     }
   
-  if (entry == end ())
-    throw CcnxPitEntryNotFound();
-
-  return *entry;
+  throw CcnxPitEntryNotFound();
 }
 
 boost::tuple<const CcnxPitEntry&, bool, bool>
 CcnxPit::Lookup (const CcnxInterestHeader &header)
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (header.GetName ());
   NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
 
   bool isDuplicate = false;
@@ -195,7 +192,17 @@
     }
   else
     {
-      isNew = false;
+      NS_LOG_INFO ("ExpireTime: " << entry->m_expireTime.ToDouble (Time::S));
+      if (entry->m_expireTime - Simulator::Now () < MilliSeconds (10))
+        {
+          modify (entry,
+                  boost::bind(&CcnxPitEntry::ClearIncoming, boost::lambda::_1));
+          
+          modify (entry,
+                  boost::bind(&CcnxPitEntry::ClearOutgoing, boost::lambda::_1));
+        }
+      
+      isNew = entry->m_incoming.size () == 0 && entry->m_outgoing.size () == 0; // entry was preserved to detect loops, but technically removed
       isDuplicate = entry->IsNonceSeen (header.GetNonce ());
     }
 
@@ -212,7 +219,7 @@
 {
   BOOST_FOREACH (const CcnxPitEntry &entry, pit)
     {
-      os << entry;
+      os << entry << std::endl;
     }
 
   return os;
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index 70347e4..0638fa9 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -123,7 +123,7 @@
    * \returns const reference to Pit entry. If record not found,
    *          CcnxPitEntryNotFound exception will be thrown
    */
-  const CcnxPitEntry&
+  CcnxPitEntryContainer::type::iterator
   Lookup (const CcnxContentObjectHeader &header) const;
 
   /**