limits: Introducing modularity for Interest limits

Now ndn::Limits object can be aggregated on a face/FIB entry. A
forwarding strategy module is responsible in creating an appropriate
implementation of the Interest limits module.
diff --git a/helper/ndn-global-routing-helper.cc b/helper/ndn-global-routing-helper.cc
index d235185..7acf7d6 100644
--- a/helper/ndn-global-routing-helper.cc
+++ b/helper/ndn-global-routing-helper.cc
@@ -35,6 +35,7 @@
 #include "ns3/names.h"
 #include "ns3/node-list.h"
 #include "ns3/channel-list.h"
+#include "ns3/object-factory.h"
 
 #include <boost/lexical_cast.hpp>
 #include <boost/foreach.hpp>
@@ -279,9 +280,17 @@
 		BOOST_FOREACH (const Ptr<const NameComponents> &prefix, i->first->GetLocalPrefixes ())
 		  {
 		    Ptr<fib::Entry> entry = fib->Add (prefix, i->second.get<0> (), i->second.get<1> ());
-                    if (i->second.get<0> ()->GetLimits ().IsEnabled ())
+                    Ptr<Limits> limits = i->second.get<0> ()->GetObject<Limits> ();
+                    
+                    if (limits != 0 && limits->IsEnabled ())
                       {
-                        entry->GetLimits ().SetMaxLimit (i->second.get<0> ()->GetLimits ().GetMaxLimit ());
+                        ObjectFactory limitsFactory;
+                        limitsFactory.SetTypeId (limits->GetInstanceTypeId ());
+
+                        Ptr<Limits> entryLimits = limitsFactory.Create<Limits> ();
+                        entryLimits->SetMaxLimit (limits->GetMaxLimit ());
+
+                        entry->AggregateObject (entryLimits);
                       }
 		  }
 		}
diff --git a/helper/ndn-stack-helper.cc b/helper/ndn-stack-helper.cc
index 72bec65..9c29bf9 100644
--- a/helper/ndn-stack-helper.cc
+++ b/helper/ndn-stack-helper.cc
@@ -254,6 +254,13 @@
       
       if (m_limitsEnabled)
         {
+          Ptr<Limits> limits = face->GetObject<Limits> ();
+          if (limits == 0)
+            {
+              NS_FATAL_ERROR ("Limits are enabled, but the selected forwarding strategy does not support limits. Please revise your scenario");
+              exit (1);
+            }
+          
           NS_LOG_INFO ("Limits are enabled");
           Ptr<PointToPointNetDevice> p2p = DynamicCast<PointToPointNetDevice> (device);
           if (p2p != 0)
@@ -272,7 +279,7 @@
               NS_LOG_INFO ("MaxLimit: " << (int)(m_avgRtt.ToDouble (Time::S) * maxInterestPackets));
 
               // Set max to BDP
-              face->GetLimits ().SetMaxLimit (m_avgRtt.ToDouble (Time::S) * maxInterestPackets);
+              limits->SetMaxLimit (m_avgRtt.ToDouble (Time::S) * maxInterestPackets);
             }
         }