ForwardingStrategy removes PIT if interest wasn't propagated.  Updated
Limits interface (adding config options). Small randomization for decay
frequency in PerFibLimits strategy.
diff --git a/helper/ndn-global-routing-helper.cc b/helper/ndn-global-routing-helper.cc
index 4ee8f58..d235185 100644
--- a/helper/ndn-global-routing-helper.cc
+++ b/helper/ndn-global-routing-helper.cc
@@ -278,7 +278,11 @@
 
 		BOOST_FOREACH (const Ptr<const NameComponents> &prefix, i->first->GetLocalPrefixes ())
 		  {
-		    fib->Add (prefix, i->second.get<0> (), i->second.get<1> ());
+		    Ptr<fib::Entry> entry = fib->Add (prefix, i->second.get<0> (), i->second.get<1> ());
+                    if (i->second.get<0> ()->GetLimits ().IsEnabled ())
+                      {
+                        entry->GetLimits ().SetMaxLimit (i->second.get<0> ()->GetLimits ().GetMaxLimit ());
+                      }
 		  }
 		}
 	    }
diff --git a/helper/ndn-stack-helper.cc b/helper/ndn-stack-helper.cc
index d84b86b..cfa6f3e 100644
--- a/helper/ndn-stack-helper.cc
+++ b/helper/ndn-stack-helper.cc
@@ -271,7 +271,7 @@
               NS_LOG_INFO ("Max burst: " << m_avgRtt.ToDouble (Time::S) * maxInterestPackets);
 
               // Set max to BDP
-              face->GetLimits ()->SetMaxLimit (m_avgRtt.ToDouble (Time::S) * maxInterestPackets);
+              face->GetLimits ().SetMaxLimit (m_avgRtt.ToDouble (Time::S) * maxInterestPackets);
             }
         }
         
diff --git a/model/fw/nacks.cc b/model/fw/nacks.cc
index a148794..2c8c92f 100644
--- a/model/fw/nacks.cc
+++ b/model/fw/nacks.cc
@@ -156,8 +156,6 @@
                                     const Ptr<const Packet> &packet,
                                     Ptr<pit::Entry> pitEntry)
 {
-  super::DidExhaustForwardingOptions (incomingFace, header, packet, pitEntry);
-
   if (m_nacksEnabled)
     {
       Ptr<Packet> packet = Create<Packet> ();
@@ -171,16 +169,9 @@
 
           m_outNacks (header, incoming.m_face);
         }
+    }
   
-      // All incoming interests cannot be satisfied. Remove them
-      pitEntry->ClearIncoming ();
-
-      // Remove also outgoing
-      pitEntry->ClearOutgoing ();
-  
-      // Set pruning timout on PIT entry (instead of deleting the record)
-      m_pit->MarkErased (pitEntry);
-    }  
+  super::DidExhaustForwardingOptions (incomingFace, header, packet, pitEntry);
 }
 
 void
diff --git a/model/fw/ndn-forwarding-strategy.cc b/model/fw/ndn-forwarding-strategy.cc
index cf09878..913448f 100644
--- a/model/fw/ndn-forwarding-strategy.cc
+++ b/model/fw/ndn-forwarding-strategy.cc
@@ -244,12 +244,24 @@
 
 void
 ForwardingStrategy::DidExhaustForwardingOptions (const Ptr<Face> &incomingFace,
-                                                     Ptr<InterestHeader> header,
-                                                     const Ptr<const Packet> &packet,
-                                                     Ptr<pit::Entry> pitEntry)
+                                                 Ptr<InterestHeader> header,
+                                                 const Ptr<const Packet> &packet,
+                                                 Ptr<pit::Entry> pitEntry)
 {
   NS_LOG_FUNCTION (this << boost::cref (*incomingFace));
-  m_dropInterests (header, incomingFace);
+  if (pitEntry->GetOutgoing ().size () == 0)
+    {
+      m_dropInterests (header, incomingFace);
+
+      // All incoming interests cannot be satisfied. Remove them
+      pitEntry->ClearIncoming ();
+
+      // Remove also outgoing
+      pitEntry->ClearOutgoing ();
+  
+      // Set pruning timout on PIT entry (instead of deleting the record)
+      m_pit->MarkErased (pitEntry);
+    }
 }
 
 void
diff --git a/model/fw/per-fib-limits.cc b/model/fw/per-fib-limits.cc
index 77851bc..ba11f7f 100644
--- a/model/fw/per-fib-limits.cc
+++ b/model/fw/per-fib-limits.cc
@@ -29,6 +29,7 @@
 #include "ns3/assert.h"
 #include "ns3/log.h"
 #include "ns3/simulator.h"
+#include "ns3/random-variable.h"
 
 #include <boost/foreach.hpp>
 #include <boost/lambda/lambda.hpp>
@@ -83,13 +84,14 @@
 
   if (pitEntry->GetFibEntry ()->GetLimits ().IsBelowLimit ())
     {
-      if (outgoingFace->GetLimits ()->IsBelowLimit ())
+      if (outgoingFace->GetLimits ().IsBelowLimit ())
         {
           pitEntry->AddOutgoing (outgoingFace);
           return true;
         }
       else
         {
+          NS_LOG_DEBUG ("Face limit. Reverting back per-prefix allowance");
           pitEntry->GetFibEntry ()->GetLimits ().RemoveOutstanding ();
         }
     }
@@ -106,7 +108,7 @@
        face != pitEntry->GetOutgoing ().end ();
        face ++)
     {
-      face->m_face->GetLimits ()->RemoveOutstanding ();
+      face->m_face->GetLimits ().RemoveOutstanding ();
       // face->m_face->GetLimits ()->DecreaseLimit (); !!! do not decrease per-face limit. it doesn't make sense !!!
     }
   
@@ -114,7 +116,10 @@
   pitEntry->GetFibEntry ()->GetLimits ().DecreaseLimit (); // multiplicative decrease
 
   if (!m_decayLimitsEvent.IsRunning ())
-    m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0), &PerFibLimits::DecayLimits, this);
+    {
+      UniformVariable rand (0,5);
+      m_decayLimitsEvent = Simulator::Schedule (Seconds (1.0) + Seconds (0.001 * rand.GetValue ()), &PerFibLimits::DecayLimits, this);
+    }
 }
 
 
@@ -130,7 +135,7 @@
        face != pitEntry->GetOutgoing ().end ();
        face ++)
     {
-      face->m_face->GetLimits ()->RemoveOutstanding ();
+      face->m_face->GetLimits ().RemoveOutstanding ();
       // face->m_face->GetLimits ()->IncreaseLimit (); !!! do not increase (as do not decrease) per-face limit. again, it doesn't make sense
     }
   
diff --git a/model/ndn-face.h b/model/ndn-face.h
index d22e073..7741c1e 100644
--- a/model/ndn-face.h
+++ b/model/ndn-face.h
@@ -92,7 +92,7 @@
   /**
    * @brief Get reference to Limits object
    */
-  inline Ptr<Limits>
+  inline Limits&
   GetLimits ();    
   
   /**
@@ -255,10 +255,10 @@
   return !(*this == face);
 }
 
-inline Ptr<Limits>
+inline Limits&
 Face::GetLimits ()
 {
-  return m_limits;
+  return *m_limits;
 }
 
 
diff --git a/test/fw-per-fib-limits.cc b/test/fw-per-fib-limits.cc
index 859160a..555aca6 100644
--- a/test/fw-per-fib-limits.cc
+++ b/test/fw-per-fib-limits.cc
@@ -103,18 +103,18 @@
   ok = entry->GetLimits ().TraceConnect ("Outstanding", "fibEntry.out", MakeCallback (PrintTracedValue<uint32_t>));
   NS_TEST_ASSERT_MSG_EQ (ok, true, "");
 
-  ok = nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ()->TraceConnect ("CurMaxLimit", "face.curMax", MakeCallback (PrintTracedValue<double>));
+  ok = nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ().TraceConnect ("CurMaxLimit", "face.curMax", MakeCallback (PrintTracedValue<double>));
   NS_TEST_ASSERT_MSG_EQ (ok, true, "");
-  nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ()->TraceDisconnect ("CurMaxLimit", "face.curMax", MakeCallback (PrintTracedValue<double>));
+  nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ().TraceDisconnect ("CurMaxLimit", "face.curMax", MakeCallback (PrintTracedValue<double>));
 
-  ok = nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ()->TraceConnect ("Outstanding", "face.out",    MakeCallback (PrintTracedValue<uint32_t>));
+  ok = nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ().TraceConnect ("Outstanding", "face.out",    MakeCallback (PrintTracedValue<uint32_t>));
   NS_TEST_ASSERT_MSG_EQ (ok, true, "");
-  nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ()->TraceDisconnect ("Outstanding", "face.out",    MakeCallback (PrintTracedValue<uint32_t>));
+  nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ().TraceDisconnect ("Outstanding", "face.out",    MakeCallback (PrintTracedValue<uint32_t>));
 
   Config::Connect ("/NodeList/0/$ns3::ndn::L3Protocol/FaceList/*/Limits/CurMaxLimit", MakeCallback (PrintTracedValue<double>));
   Config::Connect ("/NodeList/0/$ns3::ndn::L3Protocol/FaceList/*/Limits/Outstanding", MakeCallback (PrintTracedValue<uint32_t>));
 
-  nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ()->SetMaxLimit (100);
+  nodes.Get (0)->GetObject<L3Protocol> ()->GetFace (0)->GetLimits ().SetMaxLimit (100);
   
   entry->GetLimits ().SetMaxLimit (100);
   NS_TEST_ASSERT_MSG_EQ_TOL ((double)entry->GetLimits ().m_curMaxLimit, 100, 0.1, "");
diff --git a/utils/ndn-limits.cc b/utils/ndn-limits.cc
index 967c773..a14abb2 100644
--- a/utils/ndn-limits.cc
+++ b/utils/ndn-limits.cc
@@ -22,6 +22,7 @@
 
 #include "ns3/log.h"
 #include "ns3/simulator.h"
+#include "ns3/random-variable.h"
 
 NS_LOG_COMPONENT_DEFINE ("ndn.Limits");
 
@@ -38,6 +39,30 @@
     .SetParent <Object> ()
     .AddConstructor <Limits> ()
 
+    .AddAttribute ("ExpDecayTau", "Parameter 'tau' for the exponential delay of the current maximum limit variable",
+                   TimeValue (Seconds (100.0)),
+                   MakeTimeAccessor (&Limits::m_exponentialDecayTau),
+                   MakeTimeChecker ()
+                   )
+
+    .AddAttribute ("NonDecreasePeriod", "Only one decrease is allowed per one NonDecreasePeriod",
+                   TimeValue (Seconds (0.1)),
+                   MakeTimeAccessor (&Limits::m_nonDecreasePeriod),
+                   MakeTimeChecker ()
+                   )
+
+    .AddAttribute ("AdditiveIncrease", "Parameter for additive increase",
+                   DoubleValue (1.0),
+                   MakeDoubleAccessor (&Limits::m_additiveIncrease),
+                   MakeDoubleChecker<double> ()
+                   )
+
+    .AddAttribute ("MultiplicativeDecrease", "Parameter for multiplicative decrease",
+                   DoubleValue (0.5),
+                   MakeDoubleAccessor (&Limits::m_multiplicativeDecrease),
+                   MakeDoubleChecker<double> ()
+                   )
+    
     .AddTraceSource ("CurMaxLimit",
                      "Current maximum limit",
                      MakeTraceSourceAccessor (&Limits::m_curMaxLimit))
@@ -56,21 +81,25 @@
   m_curMaxLimit = max;
 }
 
+uint32_t
+Limits::GetMaxLimit () const
+{
+  return m_maxLimit;
+}
 
 void
 Limits::DecayCurrentLimit ()
 {
-  if (m_maxLimit == 0) return;
+  if (!IsEnabled ()) return;
   
   if (!m_lastDecay.IsZero ())
     {
-      const double tau = 100.0; // seconds
       double timeDiff = (Simulator::Now () - m_lastDecay).ToDouble (Time::S);
 
       NS_LOG_DEBUG ("m_maxLimit - (m_maxLimit - m_curMaxLimit) * exp (-timeDiff / tau)");
-      NS_LOG_DEBUG (m_maxLimit << " - " << " ( " << m_maxLimit << " - " << (double)m_curMaxLimit << " ) " << " * " << " exp (- " << timeDiff << " / " << tau << " ) ");
+      NS_LOG_DEBUG (m_maxLimit << " - " << " ( " << m_maxLimit << " - " << (double)m_curMaxLimit << " ) " << " * " << " exp (- " << timeDiff << " / " << m_exponentialDecayTau.ToDouble (Time::S) << " ) ");
       
-      m_curMaxLimit = m_maxLimit - (m_maxLimit - m_curMaxLimit) * exp (-timeDiff / tau);
+      m_curMaxLimit = m_maxLimit - (m_maxLimit - m_curMaxLimit) * exp (-timeDiff / m_exponentialDecayTau.ToDouble (Time::S));
     }
 
   m_lastDecay = Simulator::Now ();
@@ -79,39 +108,54 @@
 void
 Limits::IncreaseLimit ()
 {
-  if (m_maxLimit == 0) return;
+  if (!IsEnabled ()) return;
   
   // Additive increase
   m_curMaxLimit = std::min (1.0 * m_maxLimit,
-                            (double)m_curMaxLimit + 1.0 / (double)m_curMaxLimit);
+                            (double)m_curMaxLimit + m_additiveIncrease / (double)m_curMaxLimit);
 }
 
 void
 Limits::DecreaseLimit ()
 {
-  if (m_maxLimit == 0) return;
+  if (!IsEnabled ()) return;
+
+//   m_curMaxLimit = std::max (0.0,
+//                             (double)m_curMaxLimit - m_multiplicativeDecrease / (double)m_curMaxLimit);
+// }
   
-  const double maxDecreaseFrequency = 10.0;
-
-  if (!m_lastDecrease.IsZero () && Simulator::Now () - m_lastDecrease < Seconds (1 / maxDecreaseFrequency))
-    return;
-
-  // Multiplicative decrease... almost
-  m_curMaxLimit = 0.5 * m_curMaxLimit;
+  if (m_lastDecrease.IsZero () ||
+      (!m_lastDecrease.IsZero () && Simulator::Now () - m_lastDecrease > m_nonDecreasePeriod)) // allow
+    {
+      // Multiplicative decrease... almost
+      m_curMaxLimit = m_multiplicativeDecrease * m_curMaxLimit;
     
-  m_lastDecrease = Simulator::Now ();
+      m_lastDecrease = Simulator::Now ();
+    }
 }
 
 
 bool
 Limits::IsBelowLimit ()
 {
-  if (m_maxLimit == 0) return true;
+  if (!IsEnabled ()) return true;
 
   if (m_curMaxLimit - m_outstanding > 1.0)
     {
-      m_outstanding += 1;
-      return true;
+      // static UniformVariable acceptanceProbability (0, m_curMaxLimit);
+      // double value = acceptanceProbability.GetValue ();
+      double value = m_outstanding+ 1;
+      
+      if (m_outstanding < value)
+        {
+          m_outstanding += 1.0;
+          return true;
+        }
+      else
+        return false;
+      
+      // m_outstanding += 1;
+      // return true;
     }
   else
     return false;
@@ -120,7 +164,7 @@
 void
 Limits::RemoveOutstanding ()
 {
-  if (m_maxLimit == 0) return; //limits are disabled
+  if (!IsEnabled ()) return; //limits are disabled
   
   NS_LOG_DEBUG (m_outstanding);
   NS_ASSERT_MSG (m_outstanding >= 1, "Should not be possible, unless we decreasing this number twice somewhere");
diff --git a/utils/ndn-limits.h b/utils/ndn-limits.h
index b8ca50d..034c979 100644
--- a/utils/ndn-limits.h
+++ b/utils/ndn-limits.h
@@ -51,25 +51,40 @@
   { }
  
   /**
-   * Set per-prefix limit
+   * @brief Set limit for the number of outstanding interests
    */
   void
   SetMaxLimit (uint32_t max);
 
   /**
-   * Decay current limit (exponential decaying)
+   * @brief Get limit for the number of outstanding interests
+   */
+  uint32_t
+  GetMaxLimit () const;
+
+  /**
+   * @brief Check whether limits are enabled or not
+   */
+  inline bool
+  IsEnabled () const;
+
+  /**
+   * @brief Decay current limit (exponential decaying)
+   *
+   * If needed, this method should be called externally periodically (doesn't matter how often, decaying amount will remain the same).
+   * Decaying is most likely needed for per-prefix limits, but definitely not needed for per-face limits.
    */
   void
   DecayCurrentLimit ();
 
   /**
-   * Increase current limit (additive increase)
+   * @brief Increase current limit (additive increase)
    */
   void
   IncreaseLimit ();
 
   /**
-   * Decrease current limit (multiplicative decrease)
+   * @brief Decrease current limit (multiplicative decrease)
    */
   void
   DecreaseLimit ();
@@ -79,13 +94,13 @@
   ////////////////////////////////////////////////////////////////////////////
   
   /**
-   * Check if new interest can be send out, if yes, number of outstanding will be increased
+   * @brief Check if new interest can be send out, if yes, number of outstanding will be increased
    */
   bool
   IsBelowLimit ();
 
   /**
-   * Remove outstanding interests
+   * @brief Remove outstanding interests
    */
   void
   RemoveOutstanding ();
@@ -96,10 +111,22 @@
   TracedValue< double >   m_curMaxLimit;
   TracedValue< uint32_t > m_outstanding;
 
+  Time     m_exponentialDecayTau;
+  Time     m_nonDecreasePeriod;
+  double   m_additiveIncrease;
+  double   m_multiplicativeDecrease;
+
   Time     m_lastDecrease;
   Time     m_lastDecay;
 };
 
+inline bool
+Limits::IsEnabled () const
+{
+  return m_maxLimit != 0;
+}
+  
+
 } // namespace ndn
 } // namespace ns3