One more big change: prototypes of most of the forwarding strategy functions has been changed

InterestHeader now constant everywhere and only smart pointer is used, instead of passing some parameters by
reference to the smart pointer (doesn't really make sense).

Another big change that is not fully visible for now: PIT entry now
stores the whole pointer to InterestHeader, which can be used with
delayed Interest processing procedures (previously, only Name was
stored, which is really a big simplification of PIT).
diff --git a/model/fw/best-route.cc b/model/fw/best-route.cc
index 84e74fe..a034e1e 100644
--- a/model/fw/best-route.cc
+++ b/model/fw/best-route.cc
@@ -46,7 +46,7 @@
 {
   static TypeId tid = TypeId ("ns3::ndn::fw::BestRoute")
     .SetGroupName ("Ndn")
-    .SetParent <GreenYellowRed> ()
+    .SetParent <super> ()
     .AddConstructor <BestRoute> ()
     ;
   return tid;
@@ -57,16 +57,16 @@
 }
     
 bool
-BestRoute::DoPropagateInterest (const Ptr<Face> &incomingFace,
-                                Ptr<InterestHeader> header,
-                                const Ptr<const Packet> &packet,
+BestRoute::DoPropagateInterest (Ptr<Face> incomingFace,
+                                Ptr<const InterestHeader> header,
+                                Ptr<const Packet> origPacket,
                                 Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this);
 
 
   // Try to work out with just green faces
-  bool greenOk = super::DoPropagateInterest (incomingFace, header, packet, pitEntry);
+  bool greenOk = super::DoPropagateInterest (incomingFace, header, origPacket, pitEntry);
   if (greenOk)
     return true;
 
@@ -88,10 +88,10 @@
         }
 
       //transmission
-      Ptr<Packet> packetToSend = packet->Copy ();
+      Ptr<Packet> packetToSend = origPacket->Copy ();
       metricFace.m_face->Send (packetToSend);
 
-      DidSendOutInterest (metricFace.m_face, header, packet, pitEntry);
+      DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
 
       propagatedCount++;
       break; // do only once
diff --git a/model/fw/best-route.h b/model/fw/best-route.h
index 7326b5b..3f4fef7 100644
--- a/model/fw/best-route.h
+++ b/model/fw/best-route.h
@@ -36,6 +36,9 @@
 class BestRoute :
     public GreenYellowRed
 {
+private:
+  typedef GreenYellowRed super;
+
 public:
   static TypeId
   GetTypeId ();
@@ -45,15 +48,12 @@
    */
   BestRoute ();
         
-  // inherited from  NdnForwardingStrategy
+  // from super
   virtual bool
-  DoPropagateInterest (const Ptr<Face> &incomingFace,
-                       Ptr<InterestHeader> header,
-                       const Ptr<const Packet> &packet,
+  DoPropagateInterest (Ptr<Face> incomingFace,
+                       Ptr<const InterestHeader> header,
+                       Ptr<const Packet> origPacket,
                        Ptr<pit::Entry> pitEntry);
-
-private:
-  typedef GreenYellowRed super;
 };
 
 } // namespace fw
diff --git a/model/fw/flooding.cc b/model/fw/flooding.cc
index be969be..8c43c52 100644
--- a/model/fw/flooding.cc
+++ b/model/fw/flooding.cc
@@ -59,9 +59,9 @@
 }
 
 bool
-Flooding::DoPropagateInterest (const Ptr<Face> &incomingFace,
-                               Ptr<InterestHeader> header,
-                               const Ptr<const Packet> &packet,
+Flooding::DoPropagateInterest (Ptr<Face> inFace,
+                               Ptr<const InterestHeader> header,
+                               Ptr<const Packet> origPacket,
                                Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this);
@@ -74,7 +74,7 @@
       if (metricFace.m_status == fib::FaceMetric::NDN_FIB_RED) // all non-read faces are in the front of the list
         break;
       
-      if (metricFace.m_face == incomingFace) 
+      if (metricFace.m_face == inFace) 
         {
           NS_LOG_DEBUG ("continue (same as incoming)");
           continue; // same face as incoming, don't forward
@@ -86,10 +86,10 @@
         }
 
       //transmission
-      Ptr<Packet> packetToSend = packet->Copy ();
+      Ptr<Packet> packetToSend = origPacket->Copy ();
       metricFace.m_face->Send (packetToSend);
 
-      DidSendOutInterest (metricFace.m_face, header, packet, pitEntry);
+      DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
       
       propagatedCount++;
     }
diff --git a/model/fw/flooding.h b/model/fw/flooding.h
index d6a83e0..d730113 100644
--- a/model/fw/flooding.h
+++ b/model/fw/flooding.h
@@ -48,9 +48,9 @@
 protected:
   // inherited from  Nacks/ForwardingStrategy
   virtual bool
-  DoPropagateInterest (const Ptr<Face> &incomingFace,
-                       Ptr<InterestHeader> header,
-                       const Ptr<const Packet> &packet,
+  DoPropagateInterest (Ptr<Face> inFace,
+                       Ptr<const InterestHeader> header,
+                       Ptr<const Packet> origPacket,
                        Ptr<pit::Entry> pitEntry);
 
 private:
diff --git a/model/fw/fw-stats.cc b/model/fw/fw-stats.cc
index 46cd775..367ba14 100644
--- a/model/fw/fw-stats.cc
+++ b/model/fw/fw-stats.cc
@@ -52,7 +52,7 @@
 {
   static TypeId tid = TypeId ("ns3::ndn::fw::Stats")
     .SetGroupName ("Ndn")
-    .SetParent <BestRoute> ()
+    .SetParent <super> ()
     .AddConstructor <FwStats> ()
 
     .AddTraceSource ("Stats", "Fired every time stats tree is updated",
@@ -73,65 +73,65 @@
 }
 
 void
-FwStats::OnInterest (const Ptr<Face> &face,
-                     Ptr<InterestHeader> &header,
-                     const Ptr<const Packet> &packet)
+FwStats::OnInterest (Ptr<Face> face,
+                     Ptr<const InterestHeader> header,
+                     Ptr<const Packet> origPacket)
 {
-  super::OnInterest (face, header, packet);
+  super::OnInterest (face, header, origPacket);
   
-  m_stats.Rx (header->GetName ().cut (1), face, packet->GetSize ());
+  m_stats.Rx (header->GetName ().cut (1), face, origPacket->GetSize ());
 
   ScheduleRefreshingIfNecessary ();
 }
 
 void
-FwStats::OnData (const Ptr<Face> &face,
-                 Ptr<ContentObjectHeader> &header,
-                 Ptr<Packet> &payload,
-                 const Ptr<const Packet> &packet)
+FwStats::OnData (Ptr<Face> face,
+                 Ptr<const ContentObjectHeader> header,
+                 Ptr<Packet> payload,
+                 Ptr<const Packet> origPacket)
 {
-  super::OnData (face, header, payload, packet);
+  super::OnData (face, header, payload, origPacket);
   
-  m_stats.Rx (header->GetName ().cut (1), face, packet->GetSize ());
+  m_stats.Rx (header->GetName ().cut (1), face, origPacket->GetSize ());
 
   ScheduleRefreshingIfNecessary ();
 }
 
 
 void
-FwStats::FailedToCreatePitEntry (const Ptr<Face> &incomingFace,
-                                 Ptr<InterestHeader> header,
-                                 const Ptr<const Packet> &packet)
+FwStats::FailedToCreatePitEntry (Ptr<Face> inFace,
+                                 Ptr<const InterestHeader> header,
+                                 Ptr<const Packet> origPacket)
 {
-  super::FailedToCreatePitEntry (incomingFace, header, packet);
+  super::FailedToCreatePitEntry (inFace, header, origPacket);
 
   // Kind of cheating... But at least this way we will have some statistics
   m_stats.NewPitEntry (header->GetName ().cut (1));
-  m_stats.Incoming (header->GetName ().cut (1), incomingFace);
+  m_stats.Incoming (header->GetName ().cut (1), inFace);
   m_stats.Timeout (header->GetName ().cut (1));
 
   ScheduleRefreshingIfNecessary ();
 }
 
 void
-FwStats::DidCreatePitEntry (const Ptr<Face> &incomingFace,
-                            Ptr<InterestHeader> header,
-                            const Ptr<const Packet> &packet,
+FwStats::DidCreatePitEntry (Ptr<Face> inFace,
+                            Ptr<const InterestHeader> header,
+                            Ptr<const Packet> origPacket,
                             Ptr<pit::Entry> pitEntry)
 {
-  super::DidCreatePitEntry (incomingFace, header, packet, pitEntry);
+  super::DidCreatePitEntry (inFace, header, origPacket, pitEntry);
   
   m_stats.NewPitEntry (header->GetName ().cut (1));
-  m_stats.Incoming (header->GetName ().cut (1), incomingFace);
+  m_stats.Incoming (header->GetName ().cut (1), inFace);
   
   ScheduleRefreshingIfNecessary ();
 }
 
 void
-FwStats::WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
+FwStats::WillSatisfyPendingInterest (Ptr<Face> inFace,
                                      Ptr<pit::Entry> pitEntry)
 {
-  super::WillSatisfyPendingInterest (incomingFace, pitEntry);
+  super::WillSatisfyPendingInterest (inFace, pitEntry);
   
   m_stats.Satisfy (pitEntry->GetPrefix ().cut (1));
   
@@ -139,28 +139,29 @@
 }
 
 void
-FwStats::DidSendOutInterest (const Ptr<Face> &outgoingFace,
-                             Ptr<InterestHeader> header,
-                             const Ptr<const Packet> &packet,
+FwStats::DidSendOutInterest (Ptr<Face> outFace,
+                             Ptr<const InterestHeader> header,
+                             Ptr<const Packet> origPacket,
                              Ptr<pit::Entry> pitEntry)
 {
-  super::DidSendOutInterest (outgoingFace, header, packet, pitEntry);
+  super::DidSendOutInterest (outFace, header, origPacket, pitEntry);
 
-  m_stats.Outgoing (header->GetName ().cut (1), outgoingFace);
-  m_stats.Tx (header->GetName ().cut (1), outgoingFace, packet->GetSize ());
+  m_stats.Outgoing (header->GetName ().cut (1), outFace);
+  m_stats.Tx (header->GetName ().cut (1), outFace, origPacket->GetSize ());
   
   ScheduleRefreshingIfNecessary ();
 }
 
 void
-FwStats::DidSendOutData (const Ptr<Face> &face,
+FwStats::DidSendOutData (Ptr<Face> outFace,
                          Ptr<const ContentObjectHeader> header,
                          Ptr<const Packet> payload,
-                         const Ptr<const Packet> &packet)
+                         Ptr<const Packet> origPacket,
+                         Ptr<pit::Entry> pitEntry)
 {
-  super::DidSendOutData (face, header, payload, packet);
+  super::DidSendOutData (outFace, header, payload, origPacket, pitEntry);
 
-  m_stats.Tx (header->GetName ().cut (1), face, packet->GetSize ());
+  m_stats.Tx (header->GetName ().cut (1), outFace, origPacket->GetSize ());
   
   ScheduleRefreshingIfNecessary ();
 }
@@ -177,12 +178,12 @@
 }
 
 void
-FwStats::DidExhaustForwardingOptions (const Ptr<Face> &incomingFace,
-                                      Ptr<InterestHeader> header,
-                                      const Ptr<const Packet> &packet,
+FwStats::DidExhaustForwardingOptions (Ptr<Face> inFace,
+                                      Ptr<const InterestHeader> header,
+                                      Ptr<const Packet> origPacket,
                                       Ptr<pit::Entry> pitEntry)
 {
-  super::DidExhaustForwardingOptions (incomingFace, header, packet, pitEntry);
+  super::DidExhaustForwardingOptions (inFace, header, origPacket, pitEntry);
   
   if (pitEntry->GetOutgoing ().size () == 0)
     {
diff --git a/model/fw/fw-stats.h b/model/fw/fw-stats.h
index 404f487..cb50ea7 100644
--- a/model/fw/fw-stats.h
+++ b/model/fw/fw-stats.h
@@ -52,54 +52,55 @@
   GetStatsTree () const;  
 
   virtual void
-  OnInterest (const Ptr<Face> &face,
-              Ptr<InterestHeader> &header,
-              const Ptr<const Packet> &p);
+  OnInterest (Ptr<Face> face,
+              Ptr<const InterestHeader> header,
+              Ptr<const Packet> origPacket);
 
   virtual void
-  OnData (const Ptr<Face> &face,
-          Ptr<ContentObjectHeader> &header,
-          Ptr<Packet> &payload,
-          const Ptr<const Packet> &packet);
+  OnData (Ptr<Face> face,
+          Ptr<const ContentObjectHeader> header,
+          Ptr<Packet> payload,
+          Ptr<const Packet> origPacket);
 
   virtual void
   RemoveFace (Ptr<Face> face);
 
 protected:
   virtual void
-  DidCreatePitEntry (const Ptr<Face> &incomingFace,
-                     Ptr<InterestHeader> header,
-                     const Ptr<const Packet> &packet,
+  DidCreatePitEntry (Ptr<Face> inFace,
+                     Ptr<const InterestHeader> header,
+                     Ptr<const Packet> packet,
                      Ptr<pit::Entry> pitEntry);
 
   virtual void
-  FailedToCreatePitEntry (const Ptr<Face> &incomingFace,
-                          Ptr<InterestHeader> header,
-                          const Ptr<const Packet> &packet);
+  FailedToCreatePitEntry (Ptr<Face> inFace,
+                          Ptr<const InterestHeader> header,
+                          Ptr<const Packet> packet);
 
   virtual void
-  WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
+  WillSatisfyPendingInterest (Ptr<Face> inFace,
                               Ptr<pit::Entry> pitEntry);
 
   virtual void
-  DidSendOutInterest (const Ptr<Face> &outgoingFace,
-                      Ptr<InterestHeader> header,
-                      const Ptr<const Packet> &packet,
+  DidSendOutInterest (Ptr<Face> outFace,
+                      Ptr<const InterestHeader> header,
+                      Ptr<const Packet> origPacket,
                       Ptr<pit::Entry> pitEntry);
 
   virtual void
-  DidSendOutData (const Ptr<Face> &face,
+  DidSendOutData (Ptr<Face> outFace,
                   Ptr<const ContentObjectHeader> header,
                   Ptr<const Packet> payload,
-                  const Ptr<const Packet> &packet);
+                  Ptr<const Packet> origPacket,
+                  Ptr<pit::Entry> pitEntry);
 
   virtual void
   WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry);
 
   virtual void
-  DidExhaustForwardingOptions (const Ptr<Face> &incomingFace,
-                               Ptr<InterestHeader> header,
-                               const Ptr<const Packet> &packet,
+  DidExhaustForwardingOptions (Ptr<Face> inFace,
+                               Ptr<const InterestHeader> header,
+                               Ptr<const Packet> origPacket,
                                Ptr<pit::Entry> pitEntry);
   
   // from Object
diff --git a/model/fw/green-yellow-red.cc b/model/fw/green-yellow-red.cc
index 3f0653f..f13b29b 100644
--- a/model/fw/green-yellow-red.cc
+++ b/model/fw/green-yellow-red.cc
@@ -63,9 +63,9 @@
 }
 
 bool
-GreenYellowRed::DoPropagateInterest (const Ptr<Face> &incomingFace,
-                                     Ptr<InterestHeader> header,
-                                     const Ptr<const Packet> &packet,
+GreenYellowRed::DoPropagateInterest (Ptr<Face> inFace,
+                                     Ptr<const InterestHeader> header,
+                                     Ptr<const Packet> origPacket,
                                      Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this);
@@ -88,10 +88,10 @@
         }
 
       //transmission
-      Ptr<Packet> packetToSend = packet->Copy ();
+      Ptr<Packet> packetToSend = origPacket->Copy ();
       metricFace.m_face->Send (packetToSend);
 
-      DidSendOutInterest (metricFace.m_face, header, packet, pitEntry);
+      DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
       
       propagatedCount++;
       break; // propagate only one interest
@@ -101,29 +101,29 @@
 }
 
 void
-GreenYellowRed::WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
+GreenYellowRed::WillSatisfyPendingInterest (Ptr<Face> inFace,
                                             Ptr<pit::Entry> pitEntry)
 {
-  if (incomingFace != 0)
+  if (inFace != 0)
     {
       // Update metric status for the incoming interface in the corresponding FIB entry
-      pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, fib::FaceMetric::NDN_FIB_GREEN);
+      pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_GREEN);
     }
 
-  super::WillSatisfyPendingInterest (incomingFace, pitEntry);
+  super::WillSatisfyPendingInterest (inFace, pitEntry);
 }
 
 void
-GreenYellowRed::DidReceiveValidNack (const Ptr<Face> &incomingFace,
+GreenYellowRed::DidReceiveValidNack (Ptr<Face> inFace,
                                      uint32_t nackCode,
                                      Ptr<pit::Entry> pitEntry)
 {
-  super::DidReceiveValidNack (incomingFace, nackCode, pitEntry);
+  super::DidReceiveValidNack (inFace, nackCode, pitEntry);
 
-  if (incomingFace != 0 &&
+  if (inFace != 0 &&
       nackCode != InterestHeader::NACK_LOOP)
     {
-      pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, fib::FaceMetric::NDN_FIB_YELLOW);
+      pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
     }
 }
 
diff --git a/model/fw/green-yellow-red.h b/model/fw/green-yellow-red.h
index f324376..4099a12 100644
--- a/model/fw/green-yellow-red.h
+++ b/model/fw/green-yellow-red.h
@@ -38,16 +38,16 @@
 
 protected:
   virtual void
-  WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
+  WillSatisfyPendingInterest (Ptr<Face> inFace,
                               Ptr<pit::Entry> pitEntry);
 
   virtual bool
-  DoPropagateInterest (const Ptr<Face> &incomingFace,
-                       Ptr<InterestHeader> header,
-                       const Ptr<const Packet> &packet,
+  DoPropagateInterest (Ptr<Face> inFace,
+                       Ptr<const InterestHeader> header,
+                       Ptr<const Packet> origPacket,
                        Ptr<pit::Entry> pitEntry);
   virtual void
-  DidReceiveValidNack (const Ptr<Face> &incomingFace,
+  DidReceiveValidNack (Ptr<Face> incomingFace,
                        uint32_t nackCode,
                        Ptr<pit::Entry> pitEntry);
 
diff --git a/model/fw/nacks.cc b/model/fw/nacks.cc
index 2c8c92f..6ad5066 100644
--- a/model/fw/nacks.cc
+++ b/model/fw/nacks.cc
@@ -73,109 +73,112 @@
 }
 
 void
-Nacks::OnInterest (const Ptr<Face> &incomingFace,
-                   Ptr<InterestHeader> &header,
-                   const Ptr<const Packet> &packet)
+Nacks::OnInterest (Ptr<Face> inFace,
+                   Ptr<const InterestHeader> header,
+                   Ptr<const Packet> origPacket)
 {
   if (header->GetNack () > 0)
-    OnNack (incomingFace, header, packet/*original packet*/);
+    OnNack (inFace, header, origPacket/*original packet*/);
   else
-    super::OnInterest (incomingFace, header, packet/*original packet*/);  
+    super::OnInterest (inFace, header, origPacket/*original packet*/);  
 }
 
 void
-Nacks::OnNack (const Ptr<Face> &incomingFace,
-               Ptr<InterestHeader> &header,
-               const Ptr<const Packet> &packet)
+Nacks::OnNack (Ptr<Face> inFace,
+               Ptr<const InterestHeader> header,
+               Ptr<const Packet> origPacket)
 {
   NS_ASSERT (m_nacksEnabled);
 
-  // NS_LOG_FUNCTION (incomingFace << header << packet);
-  m_inNacks (header, incomingFace);
+  // NS_LOG_FUNCTION (inFace << header << origPacket);
+  m_inNacks (header, inFace);
 
   Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
   if (pitEntry == 0)
     {
       // somebody is doing something bad
-      m_dropNacks (header, incomingFace);
+      m_dropNacks (header, inFace);
       return;
     }
   
   // This was done in error. Never, never do anything, except normal leakage. This way we ensure that we will not have losses,
   // at least when there is only one client
   //
-  // incomingFace->LeakBucketByOnePacket ();
+  // inFace->LeakBucketByOnePacket ();
 
-  pitEntry->SetWaitingInVain (incomingFace);
+  pitEntry->SetWaitingInVain (inFace);
 
-  DidReceiveValidNack (incomingFace, header->GetNack (), pitEntry);
+  DidReceiveValidNack (inFace, header->GetNack (), pitEntry);
   
   if (!pitEntry->AreAllOutgoingInVain ()) // not all ougtoing are in vain
     {
       NS_LOG_DEBUG ("Not all outgoing are in vain");
       // suppress
       // Don't do anything, we are still expecting data from some other face
-      m_dropNacks (header, incomingFace);
+      m_dropNacks (header, inFace);
       return;
     }
   
   Ptr<Packet> nonNackInterest = Create<Packet> ();
-  header->SetNack (InterestHeader::NORMAL_INTEREST);
-  nonNackInterest->AddHeader (*header);
+  Ptr<InterestHeader> nonNackHeader = Create<InterestHeader> (*header);
+  nonNackHeader->SetNack (InterestHeader::NORMAL_INTEREST);
+  nonNackInterest->AddHeader (*nonNackHeader);
   
-  bool propagated = DoPropagateInterest (incomingFace, header, nonNackInterest, pitEntry);
+  bool propagated = DoPropagateInterest (inFace, nonNackHeader, nonNackInterest, pitEntry);
   if (!propagated)
     {
-      DidExhaustForwardingOptions (incomingFace, header, nonNackInterest, pitEntry);
+      DidExhaustForwardingOptions (inFace, nonNackHeader, nonNackInterest, pitEntry);
     }  
 }
 
 void
-Nacks::DidReceiveDuplicateInterest (const Ptr<Face> &incomingFace,
-                                    Ptr<InterestHeader> &header,
-                                    const Ptr<const Packet> &packet,
+Nacks::DidReceiveDuplicateInterest (Ptr<Face> inFace,
+                                    Ptr<const InterestHeader> header,
+                                    Ptr<const Packet> origPacket,
                                     Ptr<pit::Entry> pitEntry)
 {
-  super::DidReceiveDuplicateInterest (incomingFace, header, packet, pitEntry);
+  super::DidReceiveDuplicateInterest (inFace, header, origPacket, pitEntry);
 
   if (m_nacksEnabled)
     {
       NS_LOG_DEBUG ("Sending NACK_LOOP");
-      header->SetNack (InterestHeader::NACK_LOOP);
+      Ptr<InterestHeader> nackHeader = Create<InterestHeader> (*header);
+      nackHeader->SetNack (InterestHeader::NACK_LOOP);
       Ptr<Packet> nack = Create<Packet> ();
-      nack->AddHeader (*header);
+      nack->AddHeader (*nackHeader);
 
-      incomingFace->Send (nack);
-      m_outNacks (header, incomingFace);
+      inFace->Send (nack);
+      m_outNacks (nackHeader, inFace);
     }
 }
 
 void
-Nacks::DidExhaustForwardingOptions (const Ptr<Face> &incomingFace,
-                                    Ptr<InterestHeader> header,
-                                    const Ptr<const Packet> &packet,
+Nacks::DidExhaustForwardingOptions (Ptr<Face> inFace,
+                                    Ptr<const InterestHeader> header,
+                                    Ptr<const Packet> origPacket,
                                     Ptr<pit::Entry> pitEntry)
 {
   if (m_nacksEnabled)
     {
       Ptr<Packet> packet = Create<Packet> ();
-      header->SetNack (InterestHeader::NACK_GIVEUP_PIT);
-      packet->AddHeader (*header);
+      Ptr<InterestHeader> nackHeader = Create<InterestHeader> (*header);
+      nackHeader->SetNack (InterestHeader::NACK_GIVEUP_PIT);
+      packet->AddHeader (*nackHeader);
 
       BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
         {
-          NS_LOG_DEBUG ("Send NACK for " << boost::cref (header->GetName ()) << " to " << boost::cref (*incoming.m_face));
+          NS_LOG_DEBUG ("Send NACK for " << boost::cref (nackHeader->GetName ()) << " to " << boost::cref (*incoming.m_face));
           incoming.m_face->Send (packet->Copy ());
 
-          m_outNacks (header, incoming.m_face);
+          m_outNacks (nackHeader, incoming.m_face);
         }
     }
   
-  super::DidExhaustForwardingOptions (incomingFace, header, packet, pitEntry);
+  super::DidExhaustForwardingOptions (inFace, header, origPacket, pitEntry);
 }
 
 void
-Nacks::DidReceiveValidNack (const Ptr<Face> &incomingFace,
+Nacks::DidReceiveValidNack (Ptr<Face> inFace,
                             uint32_t nackCode,
                             Ptr<pit::Entry> pitEntry)
 {
@@ -183,10 +186,10 @@
   // So, if we had an incoming entry to this neighbor, then we can remove it now
   if (nackCode == InterestHeader::NACK_GIVEUP_PIT)
     {
-      pitEntry->RemoveIncoming (incomingFace);
+      pitEntry->RemoveIncoming (inFace);
     }
 
-  pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, fib::FaceMetric::NDN_FIB_YELLOW);
+  pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
 }
 
 } // namespace fw
diff --git a/model/fw/nacks.h b/model/fw/nacks.h
index 4e7da4e..f247f25 100644
--- a/model/fw/nacks.h
+++ b/model/fw/nacks.h
@@ -28,48 +28,46 @@
 
 /**
  * \ingroup ndn
- * \brief Abstract base class for Ndn forwarding strategies
+ * \brief Implementation of experimental NACK messages (enables with EnableNACKs option)
  */
 class Nacks :
     public ForwardingStrategy
 {
+private:
+  typedef ForwardingStrategy super;
+
 public:
   static TypeId
   GetTypeId ();
 
-  /**
-   * \brief Actual processing of incoming Ndn interests. Note, interests do not have payload
-   * 
-   * Processing Interest packets
-   * @param face    incoming face
-   * @param header  deserialized Interest header
-   * @param packet  original packet
-   */
+  // from super
   virtual void
-  OnInterest (const Ptr<Face> &face,
-              Ptr<InterestHeader> &header,
-              const Ptr<const Packet> &p);
+  OnInterest (Ptr<Face> face,
+              Ptr<const InterestHeader> header,
+              Ptr<const Packet> origPacket);
 
 protected:
+  // from super
   virtual void
-  DidReceiveDuplicateInterest (const Ptr<Face> &face,
-                               Ptr<InterestHeader> &header,
-                               const Ptr<const Packet> &packet,
+  DidReceiveDuplicateInterest (Ptr<Face> inFace,
+                               Ptr<const InterestHeader> header,
+                               Ptr<const Packet> packet,
                                Ptr<pit::Entry> pitEntry);
-  
+
+  // from super
   virtual void
-  DidExhaustForwardingOptions (const Ptr<Face> &incomingFace,
-                               Ptr<InterestHeader> header,
-                               const Ptr<const Packet> &packet,
+  DidExhaustForwardingOptions (Ptr<Face> inFace,
+                               Ptr<const InterestHeader> header,
+                               Ptr<const Packet> packet,
                                Ptr<pit::Entry> pitEntry);
 
   virtual void
-  OnNack (const Ptr<Face> &face,
-          Ptr<InterestHeader> &header,
-          const Ptr<const Packet> &p);
+  OnNack (Ptr<Face> inFace,
+          Ptr<const InterestHeader> header,
+          Ptr<const Packet> origPacket);
 
   virtual void
-  DidReceiveValidNack (const Ptr<Face> &incomingFace,
+  DidReceiveValidNack (Ptr<Face> inFace,
                        uint32_t nackCode,
                        Ptr<pit::Entry> pitEntry);
   
@@ -84,9 +82,6 @@
 
   TracedCallback<Ptr<const InterestHeader>,
                  Ptr<const Face> > m_dropNacks; ///< @brief trace of dropped NACKs
-
-private:
-  typedef ForwardingStrategy super;
 };
 
 } // namespace fw
diff --git a/model/fw/ndn-forwarding-strategy.cc b/model/fw/ndn-forwarding-strategy.cc
index 913448f..6348424 100644
--- a/model/fw/ndn-forwarding-strategy.cc
+++ b/model/fw/ndn-forwarding-strategy.cc
@@ -123,11 +123,11 @@
 }
 
 void
-ForwardingStrategy::OnInterest (const Ptr<Face> &incomingFace,
-                                    Ptr<InterestHeader> &header,
-                                    const Ptr<const Packet> &packet)
+ForwardingStrategy::OnInterest (Ptr<Face> inFace,
+                                Ptr<const InterestHeader> header,
+                                Ptr<const Packet> origPacket)
 {
-  m_inInterests (header, incomingFace);
+  m_inInterests (header, inFace);
 
   Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
   if (pitEntry == 0)
@@ -135,11 +135,11 @@
       pitEntry = m_pit->Create (header);
       if (pitEntry != 0)
         {
-          DidCreatePitEntry (incomingFace, header, packet, pitEntry);
+          DidCreatePitEntry (inFace, header, origPacket, pitEntry);
         }
       else
         {
-          FailedToCreatePitEntry (incomingFace, header, packet);
+          FailedToCreatePitEntry (inFace, header, origPacket);
           return;
         }
     }
@@ -153,7 +153,7 @@
 
   if (isDuplicated) 
     {
-      DidReceiveDuplicateInterest (incomingFace, header, packet, pitEntry);
+      DidReceiveDuplicateInterest (inFace, header, origPacket, pitEntry);
       return;
     }
 
@@ -165,7 +165,7 @@
     {
       NS_ASSERT (contentObjectHeader != 0);      
 
-      pitEntry->AddIncoming (incomingFace/*, Seconds (1.0)*/);
+      pitEntry->AddIncoming (inFace/*, Seconds (1.0)*/);
 
       // Do data plane performance measurements
       WillSatisfyPendingInterest (0, pitEntry);
@@ -175,35 +175,35 @@
       return;
     }
 
-  if (ShouldSuppressIncomingInterest (incomingFace, pitEntry))
+  if (ShouldSuppressIncomingInterest (inFace, header, origPacket, pitEntry))
     {
-      pitEntry->AddIncoming (incomingFace/*, header->GetInterestLifetime ()*/);
+      pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
       // update PIT entry lifetime
       pitEntry->UpdateLifetime (header->GetInterestLifetime ());
 
       // Suppress this interest if we're still expecting data from some other face
       NS_LOG_DEBUG ("Suppress interests");
-      m_dropInterests (header, incomingFace);
+      m_dropInterests (header, inFace);
       return;
     }
 
-  PropagateInterest (incomingFace, header, packet, pitEntry);
+  PropagateInterest (inFace, header, origPacket, pitEntry);
 }
 
 void
-ForwardingStrategy::OnData (const Ptr<Face> &incomingFace,
-                                Ptr<ContentObjectHeader> &header,
-                                Ptr<Packet> &payload,
-                                const Ptr<const Packet> &packet)
+ForwardingStrategy::OnData (Ptr<Face> inFace,
+                            Ptr<const ContentObjectHeader> header,
+                            Ptr<Packet> payload,
+                            Ptr<const Packet> origPacket)
 {
-  NS_LOG_FUNCTION (incomingFace << header->GetName () << payload << packet);
-  m_inData (header, payload, incomingFace);
+  NS_LOG_FUNCTION (inFace << header->GetName () << payload << origPacket);
+  m_inData (header, payload, inFace);
   
   // Lookup PIT entry
   Ptr<pit::Entry> pitEntry = m_pit->Lookup (*header);
   if (pitEntry == 0)
     {
-      DidReceiveUnsolicitedData (incomingFace, header, payload);
+      DidReceiveUnsolicitedData (inFace, header, payload, origPacket);
       return;
     }
   else
@@ -215,10 +215,10 @@
   while (pitEntry != 0)
     {
       // Do data plane performance measurements
-      WillSatisfyPendingInterest (incomingFace, pitEntry);
+      WillSatisfyPendingInterest (inFace, pitEntry);
 
       // Actually satisfy pending interest
-      SatisfyPendingInterest (incomingFace, header, payload, packet, pitEntry);
+      SatisfyPendingInterest (inFace, header, payload, origPacket, pitEntry);
 
       // Lookup another PIT entry
       pitEntry = m_pit->Lookup (*header);
@@ -227,31 +227,31 @@
 
 
 void
-ForwardingStrategy::DidReceiveDuplicateInterest (const Ptr<Face> &incomingFace,
-                                                     Ptr<InterestHeader> &header,
-                                                     const Ptr<const Packet> &packet,
-                                                     Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::DidReceiveDuplicateInterest (Ptr<Face> inFace,
+                                                 Ptr<const InterestHeader> header,
+                                                 Ptr<const Packet> origPacket,
+                                                 Ptr<pit::Entry> pitEntry)
 {
-  NS_LOG_FUNCTION (this << boost::cref (*incomingFace));
+  NS_LOG_FUNCTION (this << boost::cref (*inFace));
   /////////////////////////////////////////////////////////////////////////////////////////
   //                                                                                     //
   // !!!! IMPORTANT CHANGE !!!! Duplicate interests will create incoming face entry !!!! //
   //                                                                                     //
   /////////////////////////////////////////////////////////////////////////////////////////
-  pitEntry->AddIncoming (incomingFace);
-  m_dropInterests (header, incomingFace);
+  pitEntry->AddIncoming (inFace);
+  m_dropInterests (header, inFace);
 }
 
 void
-ForwardingStrategy::DidExhaustForwardingOptions (const Ptr<Face> &incomingFace,
-                                                 Ptr<InterestHeader> header,
-                                                 const Ptr<const Packet> &packet,
+ForwardingStrategy::DidExhaustForwardingOptions (Ptr<Face> inFace,
+                                                 Ptr<const InterestHeader> header,
+                                                 Ptr<const Packet> origPacket,
                                                  Ptr<pit::Entry> pitEntry)
 {
-  NS_LOG_FUNCTION (this << boost::cref (*incomingFace));
+  NS_LOG_FUNCTION (this << boost::cref (*inFace));
   if (pitEntry->GetOutgoing ().size () == 0)
     {
-      m_dropInterests (header, incomingFace);
+      m_dropInterests (header, inFace);
 
       // All incoming interests cannot be satisfied. Remove them
       pitEntry->ClearIncoming ();
@@ -265,31 +265,33 @@
 }
 
 void
-ForwardingStrategy::FailedToCreatePitEntry (const Ptr<Face> &incomingFace,
-                                                Ptr<InterestHeader> header,
-                                                const Ptr<const Packet> &packet)
+ForwardingStrategy::FailedToCreatePitEntry (Ptr<Face> inFace,
+                                            Ptr<const InterestHeader> header,
+                                            Ptr<const Packet> origPacket)
 {
   NS_LOG_FUNCTION (this);
-  m_dropInterests (header, incomingFace);
+  m_dropInterests (header, inFace);
 }
   
 void
-ForwardingStrategy::DidCreatePitEntry (const Ptr<Face> &incomingFace,
-                                           Ptr<InterestHeader> header,
-                                           const Ptr<const Packet> &packet,
-                                           Ptr<pit::Entry> pitEntrypitEntry)
+ForwardingStrategy::DidCreatePitEntry (Ptr<Face> inFace,
+                                       Ptr<const InterestHeader> header,
+                                       Ptr<const Packet> origPacket,
+                                       Ptr<pit::Entry> pitEntrypitEntry)
 {
 }
 
 bool
-ForwardingStrategy::DetectRetransmittedInterest (const Ptr<Face> &incomingFace,
-                                                     Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::DetectRetransmittedInterest (Ptr<Face> inFace,
+                                                 Ptr<const InterestHeader> header,
+                                                 Ptr<const Packet> packet,
+                                                 Ptr<pit::Entry> pitEntry)
 {
-  pit::Entry::in_iterator inFace = pitEntry->GetIncoming ().find (incomingFace);
+  pit::Entry::in_iterator existingInFace = pitEntry->GetIncoming ().find (inFace);
 
   bool isRetransmitted = false;
   
-  if (inFace != pitEntry->GetIncoming ().end ())
+  if (existingInFace != pitEntry->GetIncoming ().end ())
     {
       // this is almost definitely a retransmission. But should we trust the user on that?
       isRetransmitted = true;
@@ -299,23 +301,23 @@
 }
 
 void
-ForwardingStrategy::SatisfyPendingInterest (const Ptr<Face> &incomingFace,
-                                                Ptr<const ContentObjectHeader> header,
-                                                Ptr<const Packet> payload,
-                                                const Ptr<const Packet> &packet,
-                                                Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::SatisfyPendingInterest (Ptr<Face> inFace,
+                                            Ptr<const ContentObjectHeader> header,
+                                            Ptr<const Packet> payload,
+                                            Ptr<const Packet> origPacket,
+                                            Ptr<pit::Entry> pitEntry)
 {
-  if (incomingFace != 0)
-    pitEntry->RemoveIncoming (incomingFace);
+  if (inFace != 0)
+    pitEntry->RemoveIncoming (inFace);
 
   //satisfy all pending incoming Interests
   BOOST_FOREACH (const pit::IncomingFace &incoming, pitEntry->GetIncoming ())
     {
-      bool ok = incoming.m_face->Send (packet->Copy ());
+      bool ok = incoming.m_face->Send (origPacket->Copy ());
       if (ok)
         {
-          m_outData (header, payload, incomingFace == 0, incoming.m_face);
-          DidSendOutData (incoming.m_face, header, payload, packet);
+          m_outData (header, payload, inFace == 0, incoming.m_face);
+          DidSendOutData (incoming.m_face, header, payload, origPacket, pitEntry);
           
           NS_LOG_DEBUG ("Satisfy " << *incoming.m_face);
         }
@@ -339,9 +341,10 @@
 }
 
 void
-ForwardingStrategy::DidReceiveUnsolicitedData (const Ptr<Face> &incomingFace,
-                                                   Ptr<const ContentObjectHeader> header,
-                                                   Ptr<const Packet> payload)
+ForwardingStrategy::DidReceiveUnsolicitedData (Ptr<Face> inFace,
+                                               Ptr<const ContentObjectHeader> header,
+                                               Ptr<const Packet> payload,
+                                               Ptr<const Packet> origPacket)
 {
   if (m_cacheUnsolicitedData)
     {
@@ -354,35 +357,37 @@
       // (unsolicited data packets should not "poison" content store)
       
       //drop dulicated or not requested data packet
-      m_dropData (header, payload, incomingFace);
+      m_dropData (header, payload, inFace);
     }
 }
 
 void
-ForwardingStrategy::WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
-                                                    Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::WillSatisfyPendingInterest (Ptr<Face> inFace,
+                                                Ptr<pit::Entry> pitEntry)
 {
-  pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (incomingFace);
+  pit::Entry::out_iterator out = pitEntry->GetOutgoing ().find (inFace);
   
   // If we have sent interest for this data via this face, then update stats.
   if (out != pitEntry->GetOutgoing ().end ())
     {
-      pitEntry->GetFibEntry ()->UpdateFaceRtt (incomingFace, Simulator::Now () - out->m_sendTime);
+      pitEntry->GetFibEntry ()->UpdateFaceRtt (inFace, Simulator::Now () - out->m_sendTime);
     } 
 }
 
 bool
-ForwardingStrategy::ShouldSuppressIncomingInterest (const Ptr<Face> &incomingFace,
-                                                        Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::ShouldSuppressIncomingInterest (Ptr<Face> inFace,
+                                                    Ptr<const InterestHeader> header,
+                                                    Ptr<const Packet> origPacket,
+                                                    Ptr<pit::Entry> pitEntry)
 {
   bool isNew = pitEntry->GetIncoming ().size () == 0 && pitEntry->GetOutgoing ().size () == 0;
 
   if (isNew) return false; // never suppress new interests
   
   bool isRetransmitted = m_detectRetransmissions && // a small guard
-                         DetectRetransmittedInterest (incomingFace, pitEntry);  
+                         DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);  
 
-  if (pitEntry->GetOutgoing ().find (incomingFace) != pitEntry->GetOutgoing ().end ())
+  if (pitEntry->GetOutgoing ().find (inFace) != 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
@@ -393,7 +398,7 @@
 
       // ?? not sure if we need to do that ?? ...
       
-      // pitEntry->GetFibEntry ()->UpdateStatus (incomingFace, fib::FaceMetric::NDN_FIB_YELLOW);
+      // pitEntry->GetFibEntry ()->UpdateStatus (inFace, fib::FaceMetric::NDN_FIB_YELLOW);
     }
   else
     if (!isNew && !isRetransmitted)
@@ -405,19 +410,19 @@
 }
 
 void
-ForwardingStrategy::PropagateInterest (const Ptr<Face> &incomingFace,
-                                           Ptr<InterestHeader> header,
-                                           const Ptr<const Packet> &packet,
-                                           Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::PropagateInterest (Ptr<Face> inFace,
+                                       Ptr<const InterestHeader> header,
+                                       Ptr<const Packet> origPacket,
+                                       Ptr<pit::Entry> pitEntry)
 {
   bool isRetransmitted = m_detectRetransmissions && // a small guard
-                         DetectRetransmittedInterest (incomingFace, pitEntry);  
+                         DetectRetransmittedInterest (inFace, header, origPacket, pitEntry);  
   
-  pitEntry->AddIncoming (incomingFace/*, header->GetInterestLifetime ()*/);
+  pitEntry->AddIncoming (inFace/*, header->GetInterestLifetime ()*/);
   /// @todo Make lifetime per incoming interface
   pitEntry->UpdateLifetime (header->GetInterestLifetime ());
   
-  bool propagated = DoPropagateInterest (incomingFace, header, packet, pitEntry);
+  bool propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
 
   if (!propagated && isRetransmitted) //give another chance if retransmitted
     {
@@ -425,7 +430,7 @@
       pitEntry->IncreaseAllowedRetxCount ();
 
       // try again
-      propagated = DoPropagateInterest (incomingFace, header, packet, pitEntry);
+      propagated = DoPropagateInterest (inFace, header, origPacket, pitEntry);
     }
 
   // ForwardingStrategy will try its best to forward packet to at least one interface.
@@ -433,17 +438,17 @@
   // ForwardingStrategy failed to find it. 
   if (!propagated && pitEntry->GetOutgoing ().size () == 0)
     {
-      DidExhaustForwardingOptions (incomingFace, header, packet, pitEntry);
+      DidExhaustForwardingOptions (inFace, header, origPacket, pitEntry);
     }
 }
 
 bool
-ForwardingStrategy::WillSendOutInterest (const Ptr<Face> &outgoingFace,
-                                         Ptr<InterestHeader> header,
+ForwardingStrategy::WillSendOutInterest (Ptr<Face> outFace,
+                                         Ptr<const InterestHeader> header,
                                          Ptr<pit::Entry> pitEntry)
 {
   pit::Entry::out_iterator outgoing =
-    pitEntry->GetOutgoing ().find (outgoingFace);
+    pitEntry->GetOutgoing ().find (outFace);
       
   if (outgoing != pitEntry->GetOutgoing ().end () &&
       outgoing->m_retxCount >= pitEntry->GetMaxRetxCount ())
@@ -452,24 +457,25 @@
       return false; // already forwarded before during this retransmission cycle
     }
 
-  pitEntry->AddOutgoing (outgoingFace);
+  pitEntry->AddOutgoing (outFace);
   return true;
 }
 
 void
-ForwardingStrategy::DidSendOutInterest (const Ptr<Face> &outgoingFace,
-                                            Ptr<InterestHeader> header,
-                                            const Ptr<const Packet> &packet,
-                                            Ptr<pit::Entry> pitEntry)
+ForwardingStrategy::DidSendOutInterest (Ptr<Face> outFace,
+                                        Ptr<const InterestHeader> header,
+                                        Ptr<const Packet> origPacket,
+                                        Ptr<pit::Entry> pitEntry)
 {
-  m_outInterests (header, outgoingFace);
+  m_outInterests (header, outFace);
 }
 
 void
-ForwardingStrategy::DidSendOutData (const Ptr<Face> &face,
-                                        Ptr<const ContentObjectHeader> header,
-                                        Ptr<const Packet> payload,
-                                        const Ptr<const Packet> &packet)
+ForwardingStrategy::DidSendOutData (Ptr<Face> inFace,
+                                    Ptr<const ContentObjectHeader> header,
+                                    Ptr<const Packet> payload,
+                                    Ptr<const Packet> origPacket,
+                                    Ptr<pit::Entry> pitEntry)
 {
 }
 
diff --git a/model/fw/ndn-forwarding-strategy.h b/model/fw/ndn-forwarding-strategy.h
index 75f6647..65de9b8 100644
--- a/model/fw/ndn-forwarding-strategy.h
+++ b/model/fw/ndn-forwarding-strategy.h
@@ -16,8 +16,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author:  Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- *          Ilya Moiseenko <iliamo@cs.ucla.edu>
  */
+
 #ifndef NDN_FORWARDING_STRATEGY_H
 #define NDN_FORWARDING_STRATEGY_H
 
@@ -60,12 +60,12 @@
    * Processing Interest packets
    * @param face    incoming face
    * @param header  deserialized Interest header
-   * @param packet  original packet
+   * @param origPacket  original packet
    */
   virtual void
-  OnInterest (const Ptr<Face> &face,
-              Ptr<InterestHeader> &header,
-              const Ptr<const Packet> &p);
+  OnInterest (Ptr<Face> face,
+              Ptr<const InterestHeader> header,
+              Ptr<const Packet> origPacket);
 
   /**
    * \brief Actual processing of incoming Ndn content objects
@@ -74,13 +74,13 @@
    * @param face    incoming face
    * @param header  deserialized ContentObject header
    * @param payload data packet payload
-   * @param packet  original packet
+   * @param origPacket  original packet
    */
   virtual void
-  OnData (const Ptr<Face> &face,
-          Ptr<ContentObjectHeader> &header,
-          Ptr<Packet> &payload,
-          const Ptr<const Packet> &packet);
+  OnData (Ptr<Face> face,
+          Ptr<const ContentObjectHeader> header,
+          Ptr<Packet> payload,
+          Ptr<const Packet> origPacket);
 
   /**
    * @brief Event fired just before PIT entry is removed by timeout
@@ -101,59 +101,64 @@
 protected:
   // events
   virtual void
-  DidReceiveDuplicateInterest (const Ptr<Face> &face,
-                               Ptr<InterestHeader> &header,
-                               const Ptr<const Packet> &packet,
+  DidReceiveDuplicateInterest (Ptr<Face> inFace,
+                               Ptr<const InterestHeader> header,
+                               Ptr<const Packet> origPacket,
                                Ptr<pit::Entry> pitEntry);
 
   virtual void
-  DidExhaustForwardingOptions (const Ptr<Face> &incomingFace,
-                               Ptr<InterestHeader> header,
-                               const Ptr<const Packet> &packet,
+  DidExhaustForwardingOptions (Ptr<Face> inFace,
+                               Ptr<const InterestHeader> header,
+                               Ptr<const Packet> origPacket,
                                Ptr<pit::Entry> pitEntry);
 
   virtual void
-  FailedToCreatePitEntry (const Ptr<Face> &incomingFace,
-                          Ptr<InterestHeader> header,
-                          const Ptr<const Packet> &packet);
+  FailedToCreatePitEntry (Ptr<Face> inFace,
+                          Ptr<const InterestHeader> header,
+                          Ptr<const Packet> origPacket);
   
   virtual void
-  DidCreatePitEntry (const Ptr<Face> &incomingFace,
-                     Ptr<InterestHeader> header,
-                     const Ptr<const Packet> &packet,
+  DidCreatePitEntry (Ptr<Face> inFace,
+                     Ptr<const InterestHeader> header,
+                     Ptr<const Packet> origPacket,
                      Ptr<pit::Entry> pitEntry);
 
   virtual bool
-  DetectRetransmittedInterest (const Ptr<Face> &incomingFace,
+  DetectRetransmittedInterest (Ptr<Face> inFace,
+                               Ptr<const InterestHeader> header,
+                               Ptr<const Packet> origPacket,
                                Ptr<pit::Entry> pitEntry);
 
-  // makes sense only for data received from network
   // When Interest is satisfied from the cache, incoming face is 0
   virtual void
-  WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
+  WillSatisfyPendingInterest (Ptr<Face> inFace,
                               Ptr<pit::Entry> pitEntry);
 
   // for data received both from network and cache
   virtual void
-  SatisfyPendingInterest (const Ptr<Face> &incomingFace, // 0 allowed (from cache)
+  SatisfyPendingInterest (Ptr<Face> inFace, // 0 allowed (from cache)
                           Ptr<const ContentObjectHeader> header,
                           Ptr<const Packet> payload,
-                          const Ptr<const Packet> &packet,
+                          Ptr<const Packet> origPacket,
                           Ptr<pit::Entry> pitEntry);
 
   virtual void
-  DidSendOutData (const Ptr<Face> &face,
+  DidSendOutData (Ptr<Face> inFace,
                   Ptr<const ContentObjectHeader> header,
                   Ptr<const Packet> payload,
-                  const Ptr<const Packet> &packet);
+                  Ptr<const Packet> origPacket,
+                  Ptr<pit::Entry> pitEntry);
   
   virtual void
-  DidReceiveUnsolicitedData (const Ptr<Face> &incomingFace,
+  DidReceiveUnsolicitedData (Ptr<Face> inFace,
                              Ptr<const ContentObjectHeader> header,
-                             Ptr<const Packet> payload);
+                             Ptr<const Packet> payload,
+                             Ptr<const Packet> origPacket);
   
   virtual bool
-  ShouldSuppressIncomingInterest (const Ptr<Face> &incomingFace,
+  ShouldSuppressIncomingInterest (Ptr<Face> inFace,
+                                  Ptr<const InterestHeader> header,
+                                  Ptr<const Packet> origPacket,
                                   Ptr<pit::Entry> pitEntry);
 
   /**
@@ -162,23 +167,23 @@
    * If event returns false, then there is some kind of a problem (e.g., per-face limit reached)
    */
   virtual bool
-  WillSendOutInterest (const Ptr<Face> &outgoingFace,
-                       Ptr<InterestHeader> header,
+  WillSendOutInterest (Ptr<Face> outFace,
+                       Ptr<const InterestHeader> header,
                        Ptr<pit::Entry> pitEntry);
 
   /**
    * @brief Event fired just after sending out an interest
    */
   virtual void
-  DidSendOutInterest (const Ptr<Face> &outgoingFace,
-                      Ptr<InterestHeader> header,
-                      const Ptr<const Packet> &packet,
+  DidSendOutInterest (Ptr<Face> outFace,
+                      Ptr<const InterestHeader> header,
+                      Ptr<const Packet> origPacket,
                       Ptr<pit::Entry> pitEntry);
 
   virtual void
-  PropagateInterest (const Ptr<Face> &incomingFace,
-                     Ptr<InterestHeader> header,
-                     const Ptr<const Packet> &packet,
+  PropagateInterest (Ptr<Face> inFace,
+                     Ptr<const InterestHeader> header,
+                     Ptr<const Packet> origPacket,
                      Ptr<pit::Entry> pitEntry);
   
   /**
@@ -186,16 +191,16 @@
    *
    * @param pitEntry      Reference to PIT entry (reference to corresponding FIB entry inside)
    * @param incomingFace  Incoming face
-   * @param header        InterestHeader
+   * @param header        Interest header
    * @param packet        Original Interest packet
    * @param sendCallback  Send callback
    *
    * @return true if interest was successfully propagated, false if all options have failed
    */
   virtual bool
-  DoPropagateInterest (const Ptr<Face> &incomingFace,
-                       Ptr<InterestHeader> header,
-                       const Ptr<const Packet> &packet,
+  DoPropagateInterest (Ptr<Face> inFace,
+                       Ptr<const InterestHeader> header,
+                       Ptr<const Packet> origPacket,
                        Ptr<pit::Entry> pitEntry) = 0;
   
 protected:
diff --git a/model/fw/per-fib-limits.cc b/model/fw/per-fib-limits.cc
index aa21ff2..a50124a 100644
--- a/model/fw/per-fib-limits.cc
+++ b/model/fw/per-fib-limits.cc
@@ -50,7 +50,7 @@
 {
   static TypeId tid = TypeId ("ns3::ndn::fw::PerFibLimits")
     .SetGroupName ("Ndn")
-    .SetParent <FwStats> ()
+    .SetParent <super> ()
     .AddConstructor <PerFibLimits> ()
 
     .AddAttribute ("Threshold", "Minimum number of incoming interests to enable dropping decision",
@@ -73,20 +73,20 @@
 void
 PerFibLimits::DoDispose ()
 {
-  BestRoute::DoDispose ();
+  super::DoDispose ();
   m_decayLimitsEvent.Cancel ();
 }
 
 bool
-PerFibLimits::WillSendOutInterest (const Ptr<Face> &outgoingFace,
-                                   Ptr<InterestHeader> header,
+PerFibLimits::WillSendOutInterest (Ptr<Face> outFace,
+                                   Ptr<const InterestHeader> header,
                                    Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
   // override all (if any) parent processing
   
   pit::Entry::out_iterator outgoing =
-    pitEntry->GetOutgoing ().find (outgoingFace);
+    pitEntry->GetOutgoing ().find (outFace);
 
   if (outgoing != pitEntry->GetOutgoing ().end ())
     {
@@ -117,9 +117,9 @@
   
   if (pitEntry->GetFibEntry ()->GetLimits ().IsBelowLimit ())
     {
-      if (outgoingFace->GetLimits ().IsBelowLimit ())
+      if (outFace->GetLimits ().IsBelowLimit ())
         {
-          pitEntry->AddOutgoing (outgoingFace);
+          pitEntry->AddOutgoing (outFace);
           return true;
         }
       else
@@ -157,12 +157,12 @@
 
 
 void
-PerFibLimits::WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
+PerFibLimits::WillSatisfyPendingInterest (Ptr<Face> inFace,
                                           Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
 
-  super::WillSatisfyPendingInterest (incomingFace, pitEntry);
+  super::WillSatisfyPendingInterest (inFace, pitEntry);
 
   for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
        face != pitEntry->GetOutgoing ().end ();
@@ -178,11 +178,11 @@
 
 
 // void
-// PerFibLimits::DidReceiveValidNack (const Ptr<Face> &incomingFace,
+// PerFibLimits::DidReceiveValidNack (Ptr<Face> inFace,
 //                                    uint32_t nackCode,
 //                                    Ptr<pit::Entry> pitEntry)
 // {
-//   // super::DidReceiveValidNack (incomingFace, nackCode, pitEntry);
+//   // super::DidReceiveValidNack (inFace, nackCode, pitEntry);
 
 //   // ??
 // }
diff --git a/model/fw/per-fib-limits.h b/model/fw/per-fib-limits.h
index 75d9f6e..ddd23f3 100644
--- a/model/fw/per-fib-limits.h
+++ b/model/fw/per-fib-limits.h
@@ -37,6 +37,9 @@
 class PerFibLimits :
     public FwStats
 {
+private:
+  typedef FwStats super;
+
 public:
   static TypeId
   GetTypeId ();
@@ -51,12 +54,12 @@
 
 protected:
   virtual bool
-  WillSendOutInterest (const Ptr<Face> &outgoingFace,
-                       Ptr<InterestHeader> header,
+  WillSendOutInterest (Ptr<Face> outFace,
+                       Ptr<const InterestHeader> header,
                        Ptr<pit::Entry> pitEntry);
   
   virtual void
-  WillSatisfyPendingInterest (const Ptr<Face> &incomingFace,
+  WillSatisfyPendingInterest (Ptr<Face> inFace,
                               Ptr<pit::Entry> pitEntry);
 
   // from Object
@@ -72,8 +75,6 @@
 
   double m_threshold;
   double m_graceAcceptProbability;
-
-  typedef FwStats super;
 };
 
 
diff --git a/model/fw/smart-flooding.cc b/model/fw/smart-flooding.cc
index 53272e9..4ca0fd1 100644
--- a/model/fw/smart-flooding.cc
+++ b/model/fw/smart-flooding.cc
@@ -59,15 +59,15 @@
 }
 
 bool
-SmartFlooding::DoPropagateInterest (const Ptr<Face> &incomingFace,
-                                    Ptr<InterestHeader> header,
-                                    const Ptr<const Packet> &packet,
+SmartFlooding::DoPropagateInterest (Ptr<Face> inFace,
+                                    Ptr<const InterestHeader> header,
+                                    Ptr<const Packet> origPacket,
                                     Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this);
 
   // Try to work out with just green faces
-  bool greenOk = super::DoPropagateInterest (incomingFace, header, packet, pitEntry);
+  bool greenOk = super::DoPropagateInterest (inFace, header, origPacket, pitEntry);
   if (greenOk)
     return true;
 
@@ -79,7 +79,7 @@
       if (metricFace.m_status == fib::FaceMetric::NDN_FIB_RED) // all non-read faces are in the front of the list
         break;
       
-      if (metricFace.m_face == incomingFace) 
+      if (metricFace.m_face == inFace) 
         {
           NS_LOG_DEBUG ("continue (same as incoming)");
           continue; // same face as incoming, don't forward
@@ -91,10 +91,10 @@
         }
 
       //transmission
-      Ptr<Packet> packetToSend = packet->Copy ();
+      Ptr<Packet> packetToSend = origPacket->Copy ();
       metricFace.m_face->Send (packetToSend);
 
-      DidSendOutInterest (metricFace.m_face, header, packet, pitEntry);
+      DidSendOutInterest (metricFace.m_face, header, origPacket, pitEntry);
       
       propagatedCount++;
     }
diff --git a/model/fw/smart-flooding.h b/model/fw/smart-flooding.h
index a228d3e..d30031b 100644
--- a/model/fw/smart-flooding.h
+++ b/model/fw/smart-flooding.h
@@ -43,9 +43,9 @@
 
   // inherited
   virtual bool
-  DoPropagateInterest (const Ptr<Face> &incomingFace,
-                       Ptr<InterestHeader> header,
-                       const Ptr<const Packet> &packet,
+  DoPropagateInterest (Ptr<Face> inFace,
+                       Ptr<const InterestHeader> header,
+                       Ptr<const Packet> origPacket,
                        Ptr<pit::Entry> pitEntry);
 
 private:
diff --git a/model/fw/stats-based-randomized-interest-accept.cc b/model/fw/stats-based-randomized-interest-accept.cc
new file mode 100644
index 0000000..f83604d
--- /dev/null
+++ b/model/fw/stats-based-randomized-interest-accept.cc
@@ -0,0 +1,170 @@
+/* -*-  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 "stats-based-randomized-interest-accept.h"
+
+#include "ns3/ndn-interest-header.h"
+#include "ns3/ndn-content-object-header.h"
+#include "ns3/ndn-pit.h"
+#include "ns3/ndn-pit-entry.h"
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/random-variable.h"
+#include "ns3/double.h"
+
+#include <boost/foreach.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+namespace ll = boost::lambda;
+
+NS_LOG_COMPONENT_DEFINE ("ndn.fw.StatsBasedRandomizedInterestAccept");
+
+namespace ns3 {
+namespace ndn {
+namespace fw {
+
+NS_OBJECT_ENSURE_REGISTERED (StatsBasedRandomizedInterestAccept);
+  
+TypeId
+StatsBasedRandomizedInterestAccept::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::ndn::fw::StatsBasedRandomizedInterestAccept")
+    .SetGroupName ("Ndn")
+    .SetParent <super> ()
+    .AddConstructor <StatsBasedRandomizedInterestAccept> ()
+
+    .AddAttribute ("Threshold", "Minimum number of incoming interests to enable dropping decision",
+                   DoubleValue (0.25),
+                   MakeDoubleAccessor (&StatsBasedRandomizedInterestAccept::m_threshold),
+                   MakeDoubleChecker<double> ())
+    
+    .AddAttribute ("GraceAcceptProbability", "Probability to accept Interest even though stats telling that satisfaction ratio is 0",
+                   DoubleValue (0.01),
+                   MakeDoubleAccessor (&StatsBasedRandomizedInterestAccept::m_graceAcceptProbability),
+                   MakeDoubleChecker<double> ())
+    ;
+  return tid;
+}
+    
+StatsBasedRandomizedInterestAccept::StatsBasedRandomizedInterestAccept ()
+{
+}
+
+void
+StatsBasedRandomizedInterestAccept::DoDispose ()
+{
+  super::DoDispose ();
+}
+
+bool
+StatsBasedRandomizedInterestAccept::WillSendOutInterest (Ptr<Face> outFace,
+                                                         Ptr<const InterestHeader> header,
+                                                         Ptr<pit::Entry> pitEntry)
+{
+  NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
+  // override all (if any) parent processing
+  
+  pit::Entry::out_iterator outgoing =
+    pitEntry->GetOutgoing ().find (outFace);
+
+  if (outgoing != pitEntry->GetOutgoing ().end ())
+    {
+      return false;
+    }
+
+  // check stats
+  Ptr<Face> inFace = pitEntry->GetIncoming ().begin ()->m_face;
+  // const ndnSIM::LoadStatsFace &stats = GetStatsTree ()[header->GetName ()].incoming ().find (inFace)->second;
+  const ndnSIM::LoadStatsFace &stats = GetStatsTree ()["/"].incoming ().find (inFace)->second;
+
+  if (stats.count ().GetStats ().get<0> () >= m_threshold * pitEntry->GetFibEntry ()->GetLimits ().GetMaxLimit ())
+  {
+    double ratio = std::min (1.0, stats.GetSatisfiedRatio ().get<0> ());
+    // NS_ASSERT_MSG (ratio > 0, "If count is a reasonable value, ratio cannot be negative");
+    UniformVariable randAccept (0, 1);
+    double dice = randAccept.GetValue ();
+    if (ratio < 0 || dice < ratio + m_graceAcceptProbability)
+      {
+        // ok, accepting the interests
+      }
+    else
+      {
+        // boo. bad luck
+        return false;
+      }
+  }
+  
+  if (pitEntry->GetFibEntry ()->GetLimits ().IsBelowLimit ())
+    {
+      if (outFace->GetLimits ().IsBelowLimit ())
+        {
+          pitEntry->AddOutgoing (outFace);
+          return true;
+        }
+      else
+        {
+          NS_LOG_DEBUG ("Face limit. Reverting back per-prefix allowance");
+          pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
+        }
+    }
+  
+  return false;
+}
+
+void
+StatsBasedRandomizedInterestAccept::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
+{
+  NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
+
+  for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
+       face != pitEntry->GetOutgoing ().end ();
+       face ++)
+    {
+      face->m_face->GetLimits ().RemoveOutstanding ();
+    }
+  
+  pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
+}
+
+
+void
+StatsBasedRandomizedInterestAccept::WillSatisfyPendingInterest (Ptr<Face> inFace,
+                                                                Ptr<pit::Entry> pitEntry)
+{
+  NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
+
+  super::WillSatisfyPendingInterest (inFace, pitEntry);
+
+  for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
+       face != pitEntry->GetOutgoing ().end ();
+       face ++)
+    {
+      face->m_face->GetLimits ().RemoveOutstanding ();
+    }
+  
+  pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
+}
+
+
+} // namespace fw
+} // namespace ndn
+} // namespace ns3
diff --git a/model/fw/stats-based-randomized-interest-accept.h b/model/fw/stats-based-randomized-interest-accept.h
new file mode 100644
index 0000000..7ce0e9c
--- /dev/null
+++ b/model/fw/stats-based-randomized-interest-accept.h
@@ -0,0 +1,86 @@
+/* -*-  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 NDNSIM_STATS_BASED_RANDOMIZED_INTEREST_ACCEPT_H
+#define NDNSIM_STATS_BASED_RANDOMIZED_INTEREST_ACCEPT_H
+
+#include "ns3/event-id.h"
+
+#include "fw-stats.h"
+
+namespace ns3 {
+namespace ndn {
+namespace fw {
+
+/**
+ * \ingroup ndn
+ * \brief Strategy implementing stats-based randomized accept for interests
+ *
+ * (prerequisite) Window-based limits should be enabled
+ *
+ * This strategy has several limitation to accept interest for further processing:
+ * - if per-fib-entry limit or per-face limit is exhausted, Interest will not be accepted
+ * - if the number of interests received from the incoming face is less than threshold, then no special handling
+ * - if this number is greater than threshold, an Interest will be accepted with probability equal to satisfaction ratio for this incoming face (overall per-face).
+ * (probability is shifted to allow small rate of acceptance (1% by default) of Interests from faces with 0 satisfaction ratio.
+ */
+class StatsBasedRandomizedInterestAccept :
+    public FwStats
+{
+public:
+  static TypeId
+  GetTypeId ();
+
+  /**
+   * @brief Default constructor
+   */
+  StatsBasedRandomizedInterestAccept ();
+
+  virtual void
+  WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry);
+
+protected:
+  virtual bool
+  WillSendOutInterest (Ptr<Face> outFace,
+                       Ptr<const InterestHeader> header,
+                       Ptr<pit::Entry> pitEntry);
+  
+  virtual void
+  WillSatisfyPendingInterest (Ptr<Face> inFace,
+                              Ptr<pit::Entry> pitEntry);
+
+  // from Object
+  void
+  DoDispose ();
+  
+private:
+  double m_threshold;
+  double m_graceAcceptProbability;
+
+  typedef FwStats super;
+};
+
+
+} // namespace fw
+} // namespace ndn
+} // namespace ns3
+
+#endif // NDNSIM_STATS_BASED_RANDOMIZED_INTEREST_ACCEPT_H
diff --git a/model/ndn-interest-header.cc b/model/ndn-interest-header.cc
index bb6c329..240bc48 100644
--- a/model/ndn-interest-header.cc
+++ b/model/ndn-interest-header.cc
@@ -50,8 +50,10 @@
   
 
 InterestHeader::InterestHeader ()
-  : m_minSuffixComponents (-1)
+  : m_name ()
+  , m_minSuffixComponents (-1)
   , m_maxSuffixComponents (-1)
+  , m_exclude ()
   , m_childSelector (false)
   , m_answerOriginKind (false)
   , m_scope (-1)
@@ -61,6 +63,20 @@
 {
 }
 
+InterestHeader::InterestHeader (const InterestHeader &interest)
+  : m_name                (Create<NameComponents> (interest.GetName ()))
+  , m_minSuffixComponents (interest.m_minSuffixComponents)
+  , m_maxSuffixComponents (interest.m_maxSuffixComponents)
+  , m_exclude             (Create<NameComponents> (interest.GetExclude ()))
+  , m_childSelector       (interest.m_childSelector)
+  , m_answerOriginKind    (interest.m_answerOriginKind)
+  , m_scope               (interest.m_scope)
+  , m_interestLifetime    (interest.m_interestLifetime)
+  , m_nonce               (interest.m_nonce)
+  , m_nackType            (interest.m_nackType)
+{
+}
+
 void
 InterestHeader::SetName (const Ptr<NameComponents> &name)
 {
diff --git a/model/ndn-interest-header.h b/model/ndn-interest-header.h
index c87ff32..95d9c39 100644
--- a/model/ndn-interest-header.h
+++ b/model/ndn-interest-header.h
@@ -137,6 +137,11 @@
   InterestHeader ();
 
   /**
+   * @brief Copy constructor
+   */
+  InterestHeader (const InterestHeader &interest);
+
+  /**
    * \brief Set interest name
    *
    * Sets name of the interest. For example, SetName( ndnNameComponents("prefix")("postfix") );
diff --git a/model/pit/ndn-pit-entry.cc b/model/pit/ndn-pit-entry.cc
index 765693f..95b81dd 100644
--- a/model/pit/ndn-pit-entry.cc
+++ b/model/pit/ndn-pit-entry.cc
@@ -42,16 +42,22 @@
               Ptr<const InterestHeader> header,
               Ptr<fib::Entry> fibEntry)
   : m_container (container)
-  , m_prefix (header->GetNamePtr ())
+  , m_interest (header)
   , m_fibEntry (fibEntry)
   , m_expireTime (Simulator::Now () + (!header->GetInterestLifetime ().IsZero ()?
                                        header->GetInterestLifetime ():
                                        Seconds (1.0)))
   , m_maxRetxCount (0)
 {
+  NS_LOG_FUNCTION (GetPrefix () << m_expireTime);
   // note that if interest lifetime is not set, the behavior is undefined
 }
 
+Entry::~Entry ()
+{
+  NS_LOG_FUNCTION (GetPrefix ());
+}
+
 void
 Entry::UpdateLifetime (const Time &offsetTime)
 {
@@ -64,6 +70,31 @@
   NS_LOG_INFO ("Updated lifetime to " << m_expireTime.ToDouble (Time::S));
 }
 
+const NameComponents &
+Entry::GetPrefix () const
+{
+  return m_interest->GetName ();
+}
+
+const Time &
+Entry::GetExpireTime () const
+{
+  return m_expireTime;
+}
+
+bool
+Entry::IsNonceSeen (uint32_t nonce) const
+{
+  return m_seenNonces.find (nonce) != m_seenNonces.end ();
+}
+
+void
+Entry::AddSeenNonce (uint32_t nonce)
+{
+  m_seenNonces.insert (nonce);
+}
+
+
 Entry::in_iterator
 Entry::AddIncoming (Ptr<Face> face)
 {
@@ -81,6 +112,11 @@
   m_incoming.erase (face);
 }
 
+void
+Entry::ClearIncoming ()
+{
+  m_incoming.clear ();
+}
 
 Entry::out_iterator
 Entry::AddOutgoing (Ptr<Face> face)
@@ -99,6 +135,12 @@
 }
 
 void
+Entry::ClearOutgoing ()
+{
+  m_outgoing.clear ();
+}
+
+void
 Entry::RemoveAllReferencesToFace (Ptr<Face> face)
 {
   in_iterator incoming = m_incoming.find (face);
@@ -175,9 +217,34 @@
     }
 }
 
+Ptr<fib::Entry>
+Entry::GetFibEntry ()
+{
+  return m_fibEntry;
+};
+
+const Entry::in_container &
+Entry::GetIncoming () const
+{
+  return m_incoming;
+}
+
+const Entry::out_container &
+Entry::GetOutgoing () const
+{
+  return m_outgoing;
+}
+
+uint32_t
+Entry::GetMaxRetxCount () const
+{
+  return m_maxRetxCount;
+}
+
+
 std::ostream& operator<< (std::ostream& os, const Entry &entry)
 {
-  os << "Prefix: " << *entry.m_prefix << "\n";
+  os << "Prefix: " << entry.GetPrefix () << "\n";
   os << "In: ";
   bool first = true;
   BOOST_FOREACH (const IncomingFace &face, entry.m_incoming)
diff --git a/model/pit/ndn-pit-entry.h b/model/pit/ndn-pit-entry.h
index 55aa7de..d08c09e 100644
--- a/model/pit/ndn-pit-entry.h
+++ b/model/pit/ndn-pit-entry.h
@@ -108,7 +108,7 @@
   /**
    * @brief Virtual destructor
    */
-  virtual ~Entry () {}
+  virtual ~Entry ();
   
   /**
    * @brief Update lifetime of PIT entry
@@ -125,27 +125,24 @@
    * @brief Get prefix of the PIT entry
    */
   const NameComponents &
-  GetPrefix () const
-  { return *m_prefix; }
-
+  GetPrefix () const;
+  
   /**
    * @brief Get current expiration time of the record
    *
    * @returns current expiration time of the record
    */
   const Time &
-  GetExpireTime () const
-  { return m_expireTime; }
-
+  GetExpireTime () const;
+  
   /**
    * @brief Check if nonce `nonce` for the same prefix has already been seen
    *
    * @param nonce Nonce to check
    */
   bool
-  IsNonceSeen (uint32_t nonce) const
-  { return m_seenNonces.find (nonce) != m_seenNonces.end (); }
-
+  IsNonceSeen (uint32_t nonce) const;
+  
   /**
    * @brief Add `nonce` to the list of seen nonces
    *
@@ -154,9 +151,8 @@
    * All nonces are stored for the lifetime of the PIT entry
    */
   virtual void
-  AddSeenNonce (uint32_t nonce)
-  { m_seenNonces.insert (nonce); }
-
+  AddSeenNonce (uint32_t nonce);
+  
   /**
    * @brief Add `face` to the list of incoming faces
    *
@@ -176,8 +172,7 @@
    * @brief Clear all incoming faces either after all of them were satisfied or NACKed
    */
   virtual void
-  ClearIncoming ()
-  { m_incoming.clear (); }
+  ClearIncoming ();
 
   /**
    * @brief Add `face` to the list of outgoing faces
@@ -192,8 +187,7 @@
    * @brief Clear all incoming faces either after all of them were satisfied or NACKed
    */
   virtual void
-  ClearOutgoing ()
-  { m_outgoing.clear (); }  
+  ClearOutgoing ();
   
   /**
    * @brief Remove all references to face.
@@ -231,25 +225,37 @@
   virtual void
   IncreaseAllowedRetxCount ();
 
-  Ptr<fib::Entry>
-  GetFibEntry () { return m_fibEntry; };
-
-  const in_container &
-  GetIncoming () const { return m_incoming; }
-
-  const out_container &
-  GetOutgoing () const { return m_outgoing; }
-
+  /**
+   * @brief Get maximum allowed number of retransmissions via outgoing faces
+   */
   uint32_t
-  GetMaxRetxCount () const { return m_maxRetxCount; }
+  GetMaxRetxCount () const;
+
+  /**
+   * @brief Get associated FIB entry
+   */
+  Ptr<fib::Entry>
+  GetFibEntry ();
+
+  /**
+   * @brief Get associated list (const reference) of incoming faces
+   */
+  const in_container &
+  GetIncoming () const;
+
+  /**
+   * @brief Get associated list (const reference) of outgoing faces
+   */
+  const out_container &
+  GetOutgoing () const;
 
 private:
   friend std::ostream& operator<< (std::ostream& os, const Entry &entry);
   
 protected:
   Pit &m_container; ///< @brief Reference to the container (to rearrange indexes, if necessary)
-  
-  Ptr<const NameComponents> m_prefix; ///< \brief Prefix of the PIT entry
+
+  Ptr<const InterestHeader> m_interest; ///< \brief Interest of the PIT entry (if several interests are received, then nonce is from the first Interest)
   Ptr<fib::Entry> m_fibEntry;     ///< \brief FIB entry related to this prefix
   
   nonce_container m_seenNonces;  ///< \brief map of nonces that were seen for this prefix  
diff --git a/test/ndnSIM-pit.cc b/test/ndnSIM-pit.cc
index c439adc..18c2751 100644
--- a/test/ndnSIM-pit.cc
+++ b/test/ndnSIM-pit.cc
@@ -21,6 +21,7 @@
 #include "ndnSIM-pit.h"
 #include "ns3/core-module.h"
 #include "ns3/ndnSIM-module.h"
+#include "ns3/point-to-point-module.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -109,8 +110,15 @@
 PitTest::DoRun ()
 {
   Ptr<Node> node = CreateObject<Node> ();
+  Ptr<Node> nodeSink = CreateObject<Node> ();
+  PointToPointHelper p2p;
+  p2p.Install (node, nodeSink);
+  
   ndn::StackHelper ndn;
   ndn.Install (node);
+  ndn.Install (nodeSink);
+
+  ndn::StackHelper::AddRoute (node, "/", 0, 0);
 
   Ptr<Client> app1 = CreateObject<Client> ();
   node->AddApplication (app1);
diff --git a/test/ndnSIM-tests.cc b/test/ndnSIM-tests.cc
index ee02a7a..0c4ad7e 100644
--- a/test/ndnSIM-tests.cc
+++ b/test/ndnSIM-tests.cc
@@ -37,10 +37,10 @@
   {
     SetDataDir (NS_TEST_SOURCEDIR);
     
-    // AddTestCase (new InterestSerializationTest ());
-    // AddTestCase (new ContentObjectSerializationTest ());
-    // AddTestCase (new PitTest ());
-    // AddTestCase (new StatsTreeTest ());
+    AddTestCase (new InterestSerializationTest ());
+    AddTestCase (new ContentObjectSerializationTest ());
+    AddTestCase (new PitTest ());
+    AddTestCase (new StatsTreeTest ());
     AddTestCase (new ndn::FwPerFibLimits ());
   }
 };