Checkpoint. Enabling nacks back, "reverting" count statistics on nacks
diff --git a/model/fw/fw-stats.cc b/model/fw/fw-stats.cc
index 3ff136e..e7be6bb 100644
--- a/model/fw/fw-stats.cc
+++ b/model/fw/fw-stats.cc
@@ -227,7 +227,8 @@
                               uint32_t nackCode,
                               Ptr<pit::Entry> pitEntry)
 {
-  m_stats.Satisfy (pitEntry->GetPrefix ().cut (1));
+  // m_stats.Satisfy (pitEntry->GetPrefix ().cut (1));
+  m_stats.RemoveFromStats (pitEntry->GetPrefix ().cut (1));
   ScheduleRefreshingIfNecessary ();
   
   // m_stats.UndoNewPitEntry (header->GetName ().cut (1));
diff --git a/model/fw/per-fib-limits.cc b/model/fw/per-fib-limits.cc
index 5c2d3a2..ba9e81a 100644
--- a/model/fw/per-fib-limits.cc
+++ b/model/fw/per-fib-limits.cc
@@ -53,6 +53,11 @@
     .SetGroupName ("Ndn")
     .SetParent <super> ()
     .AddConstructor <PerFibLimits> ()
+
+    .AddAttribute ("AnnounceLimits", "Enable limit announcement using scope 0 interests",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&PerFibLimits::m_announceLimits),
+                   MakeBooleanChecker ())
     ;
   return tid;
 }
@@ -74,10 +79,13 @@
 {
   super::NotifyNewAggregate ();
 
-  if (m_pit != 0 && m_fib != 0)
+  if (m_announceLimits)
     {
-      m_announceEvent = Simulator::Schedule (Seconds (1.0),
-                                             &PerFibLimits::AnnounceLimits, this);
+      if (m_pit != 0 && m_fib != 0)
+        {
+          m_announceEvent = Simulator::Schedule (Seconds (1.0),
+                                                 &PerFibLimits::AnnounceLimits, this);
+        }
     }
 }
 
@@ -125,7 +133,7 @@
   
   if (header->GetInterestLifetime () < Seconds (0.1))
     {
-      NS_LOG_DEBUG( "What the fuck? Why interest lifetime is so short? [" << header->GetInterestLifetime ().ToDouble (Time::S) << "s]");
+      NS_LOG_DEBUG( "??? Why interest lifetime is so short? [" << header->GetInterestLifetime ().ToDouble (Time::S) << "s]");
     }
   
   pit::Entry::out_iterator outgoing =
@@ -180,32 +188,38 @@
 PerFibLimits::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
-  super::WillEraseTimedOutPendingInterest (pitEntry);
 
-  // if (pitEntry->GetOutgoing ().size () == 0)
-  //   {
-  //     Ptr<InterestHeader> nackHeader = Create<InterestHeader> (*pitEntry->GetInterest ());
+  if (pitEntry->GetOutgoing ().size () == 0)
+    {
+      super::DidReceiveValidNack (0, 0, pitEntry); // semi safe
       
-  //     NS_ASSERT (pitEntry->GetFwTag<PitQueueTag> () != boost::shared_ptr<PitQueueTag> ());
-  //     if (pitEntry->GetFwTag<PitQueueTag> ()->IsLastOneInQueues ())
-  //       {
-  //         nackHeader->SetNack (100);
-  //       }
-  //     else
-  //       {
-  //         nackHeader->SetNack (101);
-  //       }
+      Ptr<InterestHeader> nackHeader = Create<InterestHeader> (*pitEntry->GetInterest ());
+      
+      NS_ASSERT (pitEntry->GetFwTag<PitQueueTag> () != boost::shared_ptr<PitQueueTag> ());
+      if (pitEntry->GetFwTag<PitQueueTag> ()->IsLastOneInQueues ())
+        {
+          nackHeader->SetNack (100);
+        }
+      else
+        {
+          nackHeader->SetNack (101);
+        }
           
-  //     Ptr<Packet> pkt = Create<Packet> ();
-  //     pkt->AddHeader (*nackHeader);
+      Ptr<Packet> pkt = Create<Packet> ();
+      pkt->AddHeader (*nackHeader);
       
-  //     for (pit::Entry::in_container::iterator face = pitEntry->GetIncoming ().begin ();
-  //          face != pitEntry->GetIncoming ().end ();
-  //          face ++)
-  //       {
-  //         face->m_face->Send (pkt->Copy ());
-  //       }
-  //   }
+      for (pit::Entry::in_container::iterator face = pitEntry->GetIncoming ().begin ();
+           face != pitEntry->GetIncoming ().end ();
+           face ++)
+        {
+          face->m_face->Send (pkt->Copy ());
+        }
+    }
+  else
+    {
+      // make bad stats only for "legitimately" timed out interests
+      super::WillEraseTimedOutPendingInterest (pitEntry);
+    }    
 
   PitQueue::Remove (pitEntry);
   
@@ -295,36 +309,33 @@
                                    uint32_t nackCode,
                                    Ptr<pit::Entry> pitEntry)
 {
-//   super::DidReceiveValidNack (inFace, nackCode, pitEntry);
+  super::DidReceiveValidNack (inFace, nackCode, pitEntry); // will reset count stats
   
-//   // NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
-//   PitQueue::Remove (pitEntry);
+  // NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());
+  PitQueue::Remove (pitEntry);
  
+  Ptr<InterestHeader> nackHeader = Create<InterestHeader> (*pitEntry->GetInterest ());
+  nackHeader->SetNack (100);
+  Ptr<Packet> pkt = Create<Packet> ();
+  pkt->AddHeader (*nackHeader);
 
-//   Ptr<InterestHeader> nackHeader = Create<InterestHeader> (*pitEntry->GetInterest ());
-//   // nackHeader->SetNack (100);
-//   Ptr<Packet> pkt = Create<Packet> ();
-//   pkt->AddHeader (*nackHeader);
-
-//   for (pit::Entry::in_container::iterator face = pitEntry->GetIncoming ().begin ();
-//        face != pitEntry->GetIncoming ().end ();
-//        face ++)
-//     {
-//       face->m_face->Send (pkt->Copy ());
-//     }
-
-
+  for (pit::Entry::in_container::iterator face = pitEntry->GetIncoming ().begin ();
+       face != pitEntry->GetIncoming ().end ();
+       face ++)
+    {
+      face->m_face->Send (pkt->Copy ());
+    }
   
-//   for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
-//        face != pitEntry->GetOutgoing ().end ();
-//        face ++)
-//     {
-//       face->m_face->GetLimits ().RemoveOutstanding ();
-//     }
+  for (pit::Entry::out_container::iterator face = pitEntry->GetOutgoing ().begin ();
+       face != pitEntry->GetOutgoing ().end ();
+       face ++)
+    {
+      face->m_face->GetLimits ().RemoveOutstanding ();
+    }
 
-//   m_pit->MarkErased (pitEntry);
+  m_pit->MarkErased (pitEntry);
   
-//   ProcessFromQueue ();
+  ProcessFromQueue ();
 }
 
 void
diff --git a/model/fw/per-fib-limits.h b/model/fw/per-fib-limits.h
index 4088ae2..b00173a 100644
--- a/model/fw/per-fib-limits.h
+++ b/model/fw/per-fib-limits.h
@@ -100,6 +100,8 @@
   typedef std::map< Ptr<Face>, PitQueue > PitQueueMap;
   PitQueueMap m_pitQueues; // per-outgoing face pit queue
 
+  bool    m_announceLimits;
+
   EventId m_announceEvent;
 };
 
diff --git a/utils/stats/load-stats-node.cc b/utils/stats/load-stats-node.cc
index 39e9d60..743f764 100644
--- a/utils/stats/load-stats-node.cc
+++ b/utils/stats/load-stats-node.cc
@@ -93,6 +93,26 @@
 }
 
 void
+LoadStatsNode::RemoveFromStats ()
+{
+  m_pit.count ()--;
+  
+  for (stats_container::iterator item = m_incoming.begin ();
+       item != m_incoming.end ();
+       item ++)
+    {
+      item->second.count ()--;
+    }
+
+  for (stats_container::iterator item = m_outgoing.begin ();
+       item != m_outgoing.end ();
+       item ++)
+    {
+      item->second.count ()--;
+    }
+}
+
+void
 LoadStatsNode::Timeout ()
 {
   m_pit.unsatisfied ()++;
diff --git a/utils/stats/load-stats-node.h b/utils/stats/load-stats-node.h
index 365db55..135c5f0 100644
--- a/utils/stats/load-stats-node.h
+++ b/utils/stats/load-stats-node.h
@@ -71,6 +71,12 @@
   Satisfy ();
 
   /**
+   * Remove a packet from all stats
+   */
+  void
+  RemoveFromStats ();
+
+  /**
    * Increment counter to both incoming and outgoing lists, for all faces
    */
   void
diff --git a/utils/stats/load-stats.cc b/utils/stats/load-stats.cc
index d785845..4bc1e5b 100644
--- a/utils/stats/load-stats.cc
+++ b/utils/stats/load-stats.cc
@@ -66,6 +66,13 @@
 }
 
 LoadStats &
+LoadStats::operator -- (int)
+{
+  counter_ --;
+  return *this;
+}
+
+LoadStats &
 LoadStats::operator += (uint32_t amount)
 {
   counter_ += amount;
diff --git a/utils/stats/load-stats.h b/utils/stats/load-stats.h
index 3e71753..d07c548 100644
--- a/utils/stats/load-stats.h
+++ b/utils/stats/load-stats.h
@@ -45,6 +45,9 @@
 
   LoadStats &
   operator ++ (int);
+
+  LoadStats &
+  operator -- (int);
   
   // uint32_t
   // GetCounter () const;
diff --git a/utils/stats/stats-tree.cc b/utils/stats/stats-tree.cc
index f84d902..f27281a 100644
--- a/utils/stats/stats-tree.cc
+++ b/utils/stats/stats-tree.cc
@@ -79,6 +79,14 @@
 }
 
 void
+StatsTree::RemoveFromStats (const NameComponents &key)
+{
+  std::pair<tree_type::iterator, bool> item = m_tree.insert (key, LoadStatsNode ());
+
+  item.first->payload ().RemoveFromStats ();
+}
+
+void
 StatsTree::Timeout (const NameComponents &key)
 {
   std::pair<tree_type::iterator, bool> item = m_tree.insert (key, LoadStatsNode ());
diff --git a/utils/stats/stats-tree.h b/utils/stats/stats-tree.h
index 955f798..bcab66d 100644
--- a/utils/stats/stats-tree.h
+++ b/utils/stats/stats-tree.h
@@ -54,6 +54,9 @@
   Satisfy (const NameComponents &key);
 
   void
+  RemoveFromStats (const NameComponents &key);
+
+  void
   Timeout (const NameComponents &key);
 
   void