limits: Adding ability for GlobalRoutingController to set precise BDP prefix limits using knowledge of RTT for destination
diff --git a/bindings/callbacks_list.py b/bindings/callbacks_list.py
index 875d39f..51e879c 100644
--- a/bindings/callbacks_list.py
+++ b/bindings/callbacks_list.py
@@ -1,5 +1,6 @@
 callback_classes = [
     ['bool', 'ns3::Ptr<ns3::Packet const> const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::ndn::Face> const&', 'ns3::Ptr<ns3::Packet const> const&', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
+    ['void', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
     ['void', 'ns3::Ptr<ns3::NetDevice>', 'ns3::Ptr<ns3::Packet const>', 'unsigned short', 'ns3::Address const&', 'ns3::Address const&', 'ns3::NetDevice::PacketType', 'ns3::empty', 'ns3::empty', 'ns3::empty'],
 ]
diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
index 1b1c512..591c8f4 100644
--- a/bindings/modulegen__gcc_ILP32.py
+++ b/bindings/modulegen__gcc_ILP32.py
@@ -2520,12 +2520,12 @@
     return
 
 def register_Ns3Int64x64_t_methods(root_module, cls):
-    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('!=')
     cls.add_inplace_numeric_operator('*=', param('ns3::int64x64_t const &', 'right'))
     cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', 'right'))
     cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', 'right'))
     cls.add_output_stream_operator()
+    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('==')
     cls.add_binary_comparison_operator('>=')
     cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', 'right'))
@@ -3070,11 +3070,11 @@
     return
 
 def register_Ns3Time_methods(root_module, cls):
-    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('!=')
     cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', 'right'))
     cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', 'right'))
     cls.add_output_stream_operator()
+    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('==')
     cls.add_binary_comparison_operator('>=')
     cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
@@ -4032,6 +4032,10 @@
     cls.add_constructor([param('ns3::MobilityModel const &', 'arg0')])
     ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel() [constructor]
     cls.add_constructor([])
+    ## mobility-model.h (module 'mobility'): int64_t ns3::MobilityModel::AssignStreams(int64_t stream) [member function]
+    cls.add_method('AssignStreams', 
+                   'int64_t', 
+                   [param('int64_t', 'stream')])
     ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr<const ns3::MobilityModel> position) const [member function]
     cls.add_method('GetDistanceFrom', 
                    'double', 
@@ -4071,6 +4075,11 @@
                    'void', 
                    [], 
                    is_const=True, visibility='protected')
+    ## mobility-model.h (module 'mobility'): int64_t ns3::MobilityModel::DoAssignStreams(int64_t start) [member function]
+    cls.add_method('DoAssignStreams', 
+                   'int64_t', 
+                   [param('int64_t', 'start')], 
+                   visibility='private', is_virtual=True)
     ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function]
     cls.add_method('DoGetPosition', 
                    'ns3::Vector', 
@@ -4093,7 +4102,7 @@
     cls.add_constructor([])
     ## net-device.h (module 'network'): ns3::NetDevice::NetDevice(ns3::NetDevice const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::NetDevice const &', 'arg0')])
-    ## net-device.h (module 'network'): void ns3::NetDevice::AddLinkChangeCallback(ns3::Callback<void,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> callback) [member function]
+    ## net-device.h (module 'network'): void ns3::NetDevice::AddLinkChangeCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
     cls.add_method('AddLinkChangeCallback', 
                    'void', 
                    [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], 
@@ -5444,6 +5453,11 @@
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
                    is_virtual=True)
+    ## ndn-forwarding-strategy.h (module 'ndnSIM'): bool ns3::ndn::ForwardingStrategy::CanSendOutInterest(ns3::Ptr<ns3::ndn::Face> inFace, ns3::Ptr<ns3::ndn::Face> outFace, ns3::Ptr<ns3::ndn::InterestHeader const> header, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
+    cls.add_method('CanSendOutInterest', 
+                   'bool', 
+                   [param('ns3::Ptr< ns3::ndn::Face >', 'inFace'), param('ns3::Ptr< ns3::ndn::Face >', 'outFace'), param('ns3::Ptr< ns3::ndn::InterestHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'origPacket'), param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
+                   visibility='protected', is_virtual=True)
     ## ndn-forwarding-strategy.h (module 'ndnSIM'): bool ns3::ndn::ForwardingStrategy::DetectRetransmittedInterest(ns3::Ptr<ns3::ndn::Face> inFace, ns3::Ptr<ns3::ndn::InterestHeader const> header, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
     cls.add_method('DetectRetransmittedInterest', 
                    'bool', 
@@ -5474,10 +5488,10 @@
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::Face >', 'inFace'), param('ns3::Ptr< ns3::ndn::ContentObjectHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'payload'), param('ns3::Ptr< ns3::Packet const >', 'origPacket')], 
                    visibility='protected', is_virtual=True)
-    ## ndn-forwarding-strategy.h (module 'ndnSIM'): void ns3::ndn::ForwardingStrategy::DidSendOutData(ns3::Ptr<ns3::ndn::Face> inFace, ns3::Ptr<ns3::ndn::ContentObjectHeader const> header, ns3::Ptr<const ns3::Packet> payload, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
+    ## ndn-forwarding-strategy.h (module 'ndnSIM'): void ns3::ndn::ForwardingStrategy::DidSendOutData(ns3::Ptr<ns3::ndn::Face> outFace, ns3::Ptr<ns3::ndn::ContentObjectHeader const> header, ns3::Ptr<const ns3::Packet> payload, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
     cls.add_method('DidSendOutData', 
                    'void', 
-                   [param('ns3::Ptr< ns3::ndn::Face >', 'inFace'), param('ns3::Ptr< ns3::ndn::ContentObjectHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'payload'), param('ns3::Ptr< ns3::Packet const >', 'origPacket'), param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
+                   [param('ns3::Ptr< ns3::ndn::Face >', 'outFace'), param('ns3::Ptr< ns3::ndn::ContentObjectHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'payload'), param('ns3::Ptr< ns3::Packet const >', 'origPacket'), param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
                    visibility='protected', is_virtual=True)
     ## ndn-forwarding-strategy.h (module 'ndnSIM'): void ns3::ndn::ForwardingStrategy::DidSendOutInterest(ns3::Ptr<ns3::ndn::Face> outFace, ns3::Ptr<ns3::ndn::InterestHeader const> header, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
     cls.add_method('DidSendOutInterest', 
@@ -5809,11 +5823,26 @@
                    'double', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetCurrentLimitRate() const [member function]
+    cls.add_method('GetCurrentLimitRate', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetLinkDelay() const [member function]
+    cls.add_method('GetLinkDelay', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxDelay() const [member function]
     cls.add_method('GetMaxDelay', 
                    'double', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxLimit() const [member function]
+    cls.add_method('GetMaxLimit', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxRate() const [member function]
     cls.add_method('GetMaxRate', 
                    'double', 
@@ -5834,6 +5863,10 @@
                    'bool', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::RegisterAvailableSlotCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> handler) [member function]
+    cls.add_method('RegisterAvailableSlotCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'handler')])
     ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::ReturnLimit() [member function]
     cls.add_method('ReturnLimit', 
                    'void', 
@@ -5844,11 +5877,21 @@
                    'void', 
                    [param('double', 'rate'), param('double', 'delay')], 
                    is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::SetLinkDelay(double delay) [member function]
+    cls.add_method('SetLinkDelay', 
+                   'void', 
+                   [param('double', 'delay')], 
+                   is_virtual=True)
     ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::UpdateCurrentLimit(double limit) [member function]
     cls.add_method('UpdateCurrentLimit', 
                    'void', 
                    [param('double', 'limit')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::FireAvailableSlotCallback() [member function]
+    cls.add_method('FireAvailableSlotCallback', 
+                   'void', 
+                   [], 
+                   visibility='protected')
     return
 
 def register_Ns3NdnNameComponents_methods(root_module, cls):
diff --git a/bindings/modulegen__gcc_LP64.py b/bindings/modulegen__gcc_LP64.py
index 1b1c512..591c8f4 100644
--- a/bindings/modulegen__gcc_LP64.py
+++ b/bindings/modulegen__gcc_LP64.py
@@ -2520,12 +2520,12 @@
     return
 
 def register_Ns3Int64x64_t_methods(root_module, cls):
-    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('!=')
     cls.add_inplace_numeric_operator('*=', param('ns3::int64x64_t const &', 'right'))
     cls.add_inplace_numeric_operator('+=', param('ns3::int64x64_t const &', 'right'))
     cls.add_inplace_numeric_operator('-=', param('ns3::int64x64_t const &', 'right'))
     cls.add_output_stream_operator()
+    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('==')
     cls.add_binary_comparison_operator('>=')
     cls.add_inplace_numeric_operator('/=', param('ns3::int64x64_t const &', 'right'))
@@ -3070,11 +3070,11 @@
     return
 
 def register_Ns3Time_methods(root_module, cls):
-    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('!=')
     cls.add_inplace_numeric_operator('+=', param('ns3::Time const &', 'right'))
     cls.add_inplace_numeric_operator('-=', param('ns3::Time const &', 'right'))
     cls.add_output_stream_operator()
+    cls.add_binary_comparison_operator('<=')
     cls.add_binary_comparison_operator('==')
     cls.add_binary_comparison_operator('>=')
     cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
@@ -4032,6 +4032,10 @@
     cls.add_constructor([param('ns3::MobilityModel const &', 'arg0')])
     ## mobility-model.h (module 'mobility'): ns3::MobilityModel::MobilityModel() [constructor]
     cls.add_constructor([])
+    ## mobility-model.h (module 'mobility'): int64_t ns3::MobilityModel::AssignStreams(int64_t stream) [member function]
+    cls.add_method('AssignStreams', 
+                   'int64_t', 
+                   [param('int64_t', 'stream')])
     ## mobility-model.h (module 'mobility'): double ns3::MobilityModel::GetDistanceFrom(ns3::Ptr<const ns3::MobilityModel> position) const [member function]
     cls.add_method('GetDistanceFrom', 
                    'double', 
@@ -4071,6 +4075,11 @@
                    'void', 
                    [], 
                    is_const=True, visibility='protected')
+    ## mobility-model.h (module 'mobility'): int64_t ns3::MobilityModel::DoAssignStreams(int64_t start) [member function]
+    cls.add_method('DoAssignStreams', 
+                   'int64_t', 
+                   [param('int64_t', 'start')], 
+                   visibility='private', is_virtual=True)
     ## mobility-model.h (module 'mobility'): ns3::Vector ns3::MobilityModel::DoGetPosition() const [member function]
     cls.add_method('DoGetPosition', 
                    'ns3::Vector', 
@@ -4093,7 +4102,7 @@
     cls.add_constructor([])
     ## net-device.h (module 'network'): ns3::NetDevice::NetDevice(ns3::NetDevice const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::NetDevice const &', 'arg0')])
-    ## net-device.h (module 'network'): void ns3::NetDevice::AddLinkChangeCallback(ns3::Callback<void,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty,ns3::empty> callback) [member function]
+    ## net-device.h (module 'network'): void ns3::NetDevice::AddLinkChangeCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> callback) [member function]
     cls.add_method('AddLinkChangeCallback', 
                    'void', 
                    [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')], 
@@ -5444,6 +5453,11 @@
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
                    is_virtual=True)
+    ## ndn-forwarding-strategy.h (module 'ndnSIM'): bool ns3::ndn::ForwardingStrategy::CanSendOutInterest(ns3::Ptr<ns3::ndn::Face> inFace, ns3::Ptr<ns3::ndn::Face> outFace, ns3::Ptr<ns3::ndn::InterestHeader const> header, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
+    cls.add_method('CanSendOutInterest', 
+                   'bool', 
+                   [param('ns3::Ptr< ns3::ndn::Face >', 'inFace'), param('ns3::Ptr< ns3::ndn::Face >', 'outFace'), param('ns3::Ptr< ns3::ndn::InterestHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'origPacket'), param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
+                   visibility='protected', is_virtual=True)
     ## ndn-forwarding-strategy.h (module 'ndnSIM'): bool ns3::ndn::ForwardingStrategy::DetectRetransmittedInterest(ns3::Ptr<ns3::ndn::Face> inFace, ns3::Ptr<ns3::ndn::InterestHeader const> header, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
     cls.add_method('DetectRetransmittedInterest', 
                    'bool', 
@@ -5474,10 +5488,10 @@
                    'void', 
                    [param('ns3::Ptr< ns3::ndn::Face >', 'inFace'), param('ns3::Ptr< ns3::ndn::ContentObjectHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'payload'), param('ns3::Ptr< ns3::Packet const >', 'origPacket')], 
                    visibility='protected', is_virtual=True)
-    ## ndn-forwarding-strategy.h (module 'ndnSIM'): void ns3::ndn::ForwardingStrategy::DidSendOutData(ns3::Ptr<ns3::ndn::Face> inFace, ns3::Ptr<ns3::ndn::ContentObjectHeader const> header, ns3::Ptr<const ns3::Packet> payload, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
+    ## ndn-forwarding-strategy.h (module 'ndnSIM'): void ns3::ndn::ForwardingStrategy::DidSendOutData(ns3::Ptr<ns3::ndn::Face> outFace, ns3::Ptr<ns3::ndn::ContentObjectHeader const> header, ns3::Ptr<const ns3::Packet> payload, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
     cls.add_method('DidSendOutData', 
                    'void', 
-                   [param('ns3::Ptr< ns3::ndn::Face >', 'inFace'), param('ns3::Ptr< ns3::ndn::ContentObjectHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'payload'), param('ns3::Ptr< ns3::Packet const >', 'origPacket'), param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
+                   [param('ns3::Ptr< ns3::ndn::Face >', 'outFace'), param('ns3::Ptr< ns3::ndn::ContentObjectHeader const >', 'header'), param('ns3::Ptr< ns3::Packet const >', 'payload'), param('ns3::Ptr< ns3::Packet const >', 'origPacket'), param('ns3::Ptr< ns3::ndn::pit::Entry >', 'pitEntry')], 
                    visibility='protected', is_virtual=True)
     ## ndn-forwarding-strategy.h (module 'ndnSIM'): void ns3::ndn::ForwardingStrategy::DidSendOutInterest(ns3::Ptr<ns3::ndn::Face> outFace, ns3::Ptr<ns3::ndn::InterestHeader const> header, ns3::Ptr<const ns3::Packet> origPacket, ns3::Ptr<ns3::ndn::pit::Entry> pitEntry) [member function]
     cls.add_method('DidSendOutInterest', 
@@ -5809,11 +5823,26 @@
                    'double', 
                    [], 
                    is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetCurrentLimitRate() const [member function]
+    cls.add_method('GetCurrentLimitRate', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetLinkDelay() const [member function]
+    cls.add_method('GetLinkDelay', 
+                   'double', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxDelay() const [member function]
     cls.add_method('GetMaxDelay', 
                    'double', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxLimit() const [member function]
+    cls.add_method('GetMaxLimit', 
+                   'double', 
+                   [], 
+                   is_pure_virtual=True, is_const=True, is_virtual=True)
     ## ndn-limits.h (module 'ndnSIM'): double ns3::ndn::Limits::GetMaxRate() const [member function]
     cls.add_method('GetMaxRate', 
                    'double', 
@@ -5834,6 +5863,10 @@
                    'bool', 
                    [], 
                    is_const=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::RegisterAvailableSlotCallback(ns3::Callback<void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> handler) [member function]
+    cls.add_method('RegisterAvailableSlotCallback', 
+                   'void', 
+                   [param('ns3::Callback< void, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'handler')])
     ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::ReturnLimit() [member function]
     cls.add_method('ReturnLimit', 
                    'void', 
@@ -5844,11 +5877,21 @@
                    'void', 
                    [param('double', 'rate'), param('double', 'delay')], 
                    is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::SetLinkDelay(double delay) [member function]
+    cls.add_method('SetLinkDelay', 
+                   'void', 
+                   [param('double', 'delay')], 
+                   is_virtual=True)
     ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::UpdateCurrentLimit(double limit) [member function]
     cls.add_method('UpdateCurrentLimit', 
                    'void', 
                    [param('double', 'limit')], 
                    is_pure_virtual=True, is_virtual=True)
+    ## ndn-limits.h (module 'ndnSIM'): void ns3::ndn::Limits::FireAvailableSlotCallback() [member function]
+    cls.add_method('FireAvailableSlotCallback', 
+                   'void', 
+                   [], 
+                   visibility='protected')
     return
 
 def register_Ns3NdnNameComponents_methods(root_module, cls):
diff --git a/helper/boost-graph-ndn-global-routing-helper.h b/helper/boost-graph-ndn-global-routing-helper.h
index df08c73..f406a3e 100644
--- a/helper/boost-graph-ndn-global-routing-helper.h
+++ b/helper/boost-graph-ndn-global-routing-helper.h
@@ -29,6 +29,7 @@
 #include <boost/ref.hpp>
 
 #include "ns3/ndn-face.h"
+#include "ns3/ndn-limits.h"
 #include "ns3/node-list.h"
 #include "ns3/channel-list.h"
 #include "../model/ndn-global-router.h"
@@ -205,14 +206,14 @@
 struct property_traits< EdgeWeights >
 {
   // Metric property map
-  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint16_t > value_type;
-  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint16_t > reference;
+  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint16_t, double > value_type;
+  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint16_t, double > reference;
   typedef ns3::ndn::GlobalRouter::Incidency key_type;
   typedef readable_property_map_tag category;
 };
 
-const property_traits< EdgeWeights >::value_type WeightZero (0, 0);
-const property_traits< EdgeWeights >::value_type WeightInf (0, std::numeric_limits<uint16_t>::max ());
+const property_traits< EdgeWeights >::value_type WeightZero (0, 0, 0.0);
+const property_traits< EdgeWeights >::value_type WeightInf (0, std::numeric_limits<uint16_t>::max (), 0.0);
 
 struct WeightCompare :
     public std::binary_function<property_traits< EdgeWeights >::reference,
@@ -253,14 +254,14 @@
     return a + b.get<1> ();
   }
 
-  tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t >
-  operator () (tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t > a,
+  tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t, double >
+  operator () (tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t, double > a,
                property_traits< EdgeWeights >::reference b) const
   {
     if (a.get<0> () == 0)
-      return make_tuple (b.get<0> (), a.get<1> () + b.get<1> ());
+      return make_tuple (b.get<0> (), a.get<1> () + b.get<1> (), a.get<2> () + b.get<2> ());
     else
-      return make_tuple (a.get<0> (), a.get<1> () + b.get<1> ());
+      return make_tuple (a.get<0> (), a.get<1> () + b.get<1> (), a.get<2> () + b.get<2> ());
   }
 };
   
@@ -311,9 +312,17 @@
 get(const boost::EdgeWeights&, ns3::ndn::GlobalRouter::Incidency &edge)
 {
   if (edge.get<1> () == 0)
-    return property_traits< EdgeWeights >::reference (0, 0);
+    return property_traits< EdgeWeights >::reference (0, 0, 0.0);
   else
-    return property_traits< EdgeWeights >::reference (edge.get<1> (), edge.get<1> ()->GetMetric ());
+    {
+      ns3::Ptr<ns3::ndn::Limits> limits = edge.get<1> ()->GetObject<ns3::ndn::Limits> ();
+      double delay = 0.0;
+      if (limits != 0) // valid limits object
+        {
+          delay = limits->GetLinkDelay ();
+        }
+      return property_traits< EdgeWeights >::reference (edge.get<1> (), edge.get<1> ()->GetMetric (), delay);
+    }
 }
 
 struct PredecessorsMap :
@@ -333,7 +342,7 @@
 
 
 struct DistancesMap :
-    public std::map< ns3::Ptr< ns3::ndn::GlobalRouter >, tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t > >
+  public std::map< ns3::Ptr< ns3::ndn::GlobalRouter >, tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t, double > >
 {
 };
 
@@ -341,18 +350,18 @@
 struct property_traits< reference_wrapper<DistancesMap> >
 {
   // Metric property map
-  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t > value_type;
-  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t > reference;
+  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t, double > value_type;
+  typedef tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t, double > reference;
   typedef ns3::Ptr< ns3::ndn::GlobalRouter > key_type;
   typedef read_write_property_map_tag category;
 };
 
-inline tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t >
+inline tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t, double >
 get (DistancesMap &map, ns3::Ptr<ns3::ndn::GlobalRouter> key)
 {
   boost::DistancesMap::iterator i = map.find (key);
   if (i == map.end ())
-    return tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t > (0, std::numeric_limits<uint32_t>::max ());
+    return tuple< ns3::Ptr<ns3::ndn::Face>, uint32_t, double > (0, std::numeric_limits<uint32_t>::max (), 0.0);
   else
     return i->second;
 }
diff --git a/helper/ndn-global-routing-helper.cc b/helper/ndn-global-routing-helper.cc
index 3d18042..68f7228 100644
--- a/helper/ndn-global-routing-helper.cc
+++ b/helper/ndn-global-routing-helper.cc
@@ -258,7 +258,7 @@
       fib->InvalidateAll ();
       NS_ASSERT (fib != 0);
       
-      // cout << "Reachability from Node: " << source->GetObject<Node> ()->GetId () << endl;
+      cout << "Reachability from Node: " << source->GetObject<Node> ()->GetId () << endl;
       for (DistancesMap::iterator i = distances.begin ();
 	   i != distances.end ();
 	   i++)
@@ -274,25 +274,26 @@
 		}
 	      else
 		{
-		// cout << " reachable via face " << *i->second.get<0> ()
-		//      << " with distance " << i->second.get<1> () << endl;
-
-		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> ());
-                    Ptr<Limits> limits = i->second.get<0> ()->GetObject<Limits> ();
+                  BOOST_FOREACH (const Ptr<const NameComponents> &prefix, i->first->GetLocalPrefixes ())
+                    {
+                      cout << " prefix " << prefix << " reachable via face " << *i->second.get<0> ()
+                           << " with distance " << i->second.get<1> ()
+                           << " with delay " << i->second.get<2> () << endl;
                     
-                    if (limits != 0 && limits->IsEnabled ())
-                      {
-                        ObjectFactory limitsFactory;
-                        limitsFactory.SetTypeId (limits->GetInstanceTypeId ());
+                      Ptr<fib::Entry> entry = fib->Add (prefix, i->second.get<0> (), i->second.get<1> ());
+                      Ptr<Limits> limits = i->second.get<0> ()->GetObject<Limits> ();
+                    
+                      if (limits != 0 && limits->IsEnabled ())
+                        {
+                          ObjectFactory limitsFactory;
+                          limitsFactory.SetTypeId (limits->GetInstanceTypeId ());
 
-                        Ptr<Limits> entryLimits = limitsFactory.Create<Limits> ();
-                        entryLimits->SetLimits (limits->GetMaxRate (), limits->GetMaxDelay ());
+                          Ptr<Limits> entryLimits = limitsFactory.Create<Limits> ();
+                          entryLimits->SetLimits (limits->GetMaxRate (), 2*i->second.get<2> ());
 
-                        entry->AggregateObject (entryLimits);
-                      }
-		  }
+                          entry->AggregateObject (entryLimits);
+                        }
+                    }
 		}
 	    }
 	}
diff --git a/helper/ndn-stack-helper.cc b/helper/ndn-stack-helper.cc
index 5dade78..983c8cf 100644
--- a/helper/ndn-stack-helper.cc
+++ b/helper/ndn-stack-helper.cc
@@ -28,6 +28,7 @@
 #include "ns3/simulator.h"
 #include "ns3/string.h"
 #include "ns3/net-device.h"
+#include "ns3/channel.h"
 #include "ns3/callback.h"
 #include "ns3/node.h"
 #include "ns3/core-config.h"
@@ -270,6 +271,7 @@
               // Set maximum buckets (averaging over 1 second)
       
               DataRateValue dataRate; device->GetAttribute ("DataRate", dataRate);
+              TimeValue linkDelay;   device->GetChannel ()->GetAttribute ("Delay", linkDelay);
           
               NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
 
@@ -280,6 +282,7 @@
 
               // Set max to BDP
               limits->SetLimits (maxInterestPackets, m_avgRtt.ToDouble (Time::S));
+              limits->SetLinkDelay (linkDelay.Get ().ToDouble (Time::S));
             }
         }
         
diff --git a/utils/ndn-limits-rate.h b/utils/ndn-limits-rate.h
index 7da0f1a..7f0efef 100644
--- a/utils/ndn-limits-rate.h
+++ b/utils/ndn-limits-rate.h
@@ -56,6 +56,13 @@
   virtual void
   SetLimits (double rate, double delay);
 
+  virtual
+  double
+  GetMaxLimit () const
+  {
+    return GetMaxRate ();
+  }
+
   /**
    * @brief Check if Interest limit is reached (token bucket is not empty)
    */
@@ -89,6 +96,12 @@
     return m_bucketLeak;
   }
 
+  virtual double
+  GetCurrentLimitRate () const
+  {
+    return m_bucketLeak;
+  }
+  
 protected:
   // from Node
   void
diff --git a/utils/ndn-limits-window.h b/utils/ndn-limits-window.h
index 5b93b6e..655b8ef 100644
--- a/utils/ndn-limits-window.h
+++ b/utils/ndn-limits-window.h
@@ -62,6 +62,13 @@
     m_curMaxLimit = GetMaxRate () * GetMaxDelay ();
   }
 
+  virtual
+  double
+  GetMaxLimit () const
+  {
+    return GetMaxRate () * GetMaxDelay ();
+  }
+  
   virtual void
   UpdateCurrentLimit (double limit);
   
@@ -71,6 +78,12 @@
     return m_curMaxLimit;
   }
 
+  virtual double
+  GetCurrentLimitRate () const
+  {
+    return m_curMaxLimit / GetMaxDelay ();
+  }
+  
   /**
    * @brief Check if current interest window (number of pending interests) if less than maximum 
    */
diff --git a/utils/ndn-limits.cc b/utils/ndn-limits.cc
index ee4160e..1d7b283 100644
--- a/utils/ndn-limits.cc
+++ b/utils/ndn-limits.cc
@@ -44,6 +44,7 @@
   : m_maxRate (-1)
   , m_maxDelay (1.0)
   , m_handler (MakeNullCallback<void> ())
+  , m_linkDelay (0)
 {
 }
 
diff --git a/utils/ndn-limits.h b/utils/ndn-limits.h
index 5fdad53..d1daa10 100644
--- a/utils/ndn-limits.h
+++ b/utils/ndn-limits.h
@@ -83,6 +83,13 @@
   }
 
   /**
+   * @brief Get maximum limit (interpretation of the limit depends on realization)
+   */
+  virtual
+  double
+  GetMaxLimit () const = 0;
+
+  /**
    * @brief Check whether limits are enabled or not
    */
   virtual inline bool
@@ -110,6 +117,15 @@
    */
   virtual double
   GetCurrentLimit () const = 0;
+
+  /**
+   * @brief Get value of the current limit in terms of maximum rate that needs to be enforced
+   *
+   * Compared to GetCurrentLimit, this method guarantees that the returned value is maximum number of packets
+   * that can be send out within one second (max "rate")
+   */
+  virtual double
+  GetCurrentLimitRate () const = 0;
   
   ////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////
@@ -135,6 +151,26 @@
   virtual void
   ReturnLimit () = 0;
 
+  /**
+   * @brief Set link delay (in seconds)
+   *
+   * This is a supplementary information that may or may not be useful for limits
+   */
+  virtual void
+  SetLinkDelay (double delay)
+  {
+    m_linkDelay = delay;
+  }
+
+  /**
+   * @brief Get link delay (in seconds)
+   */
+  virtual double
+  GetLinkDelay () const
+  {
+    return m_linkDelay;
+  }
+  
   ////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////
   ////////////////////////////////////////////////////////////////////////////
@@ -154,6 +190,8 @@
   double m_maxDelay;
 
   CallbackHandler m_handler;
+
+  double m_linkDelay;
 };