Enable limits options in CcnxStackHelper

Slightly modifying the way of how forwarding strategy is hooked up
diff --git a/examples/annotated-topology-read-example.cc b/examples/annotated-topology-read-example.cc
index 000b578..50c9d13 100644
--- a/examples/annotated-topology-read-example.cc
+++ b/examples/annotated-topology-read-example.cc
@@ -41,153 +41,156 @@
 
 int main (int argc, char *argv[])
 {
-    Packet::EnableChecking();
-    Packet::EnablePrinting();
-    string input ("/Users/iliamo/ns3-abstract-ndn/ns-3.11/src/NDNabstraction/examples/simpletopology.txt");
+  Packet::EnableChecking();
+  Packet::EnablePrinting();
+  string input ("/Users/iliamo/ns3-abstract-ndn/ns-3.11/src/NDNabstraction/examples/simpletopology.txt");
     
-    // Set up command line parameters used to control the experiment.
-    //CommandLine cmd;
-    //cmd.AddValue ("input", "Name of the input file.",
-    //              input);
-    //cmd.Parse (argc, argv);
+  // Set up command line parameters used to control the experiment.
+  //CommandLine cmd;
+  //cmd.AddValue ("input", "Name of the input file.",
+  //              input);
+  //cmd.Parse (argc, argv);
     
     
-    // ------------------------------------------------------------
-    // -- Read topology data.
-    // --------------------------------------------
+  // ------------------------------------------------------------
+  // -- Read topology data.
+  // --------------------------------------------
     
     
-    Ptr<AnnotatedTopologyReader> reader = CreateObject<AnnotatedTopologyReader> ();
-    reader->SetFileName (input);
+  Ptr<AnnotatedTopologyReader> reader = CreateObject<AnnotatedTopologyReader> ();
+  reader->SetFileName (input);
     
-    NodeContainer nodes;
-    if (reader != 0)
+  NodeContainer nodes;
+  if (reader != 0)
     {
-        nodes = reader->Read ();
+      nodes = reader->Read ();
     }
     
-    if (reader->LinksSize () == 0)
+  if (reader->LinksSize () == 0)
     {
-        NS_LOG_ERROR ("Problems reading the topology file. Failing.");
-        return -1;
+      NS_LOG_ERROR ("Problems reading the topology file. Failing.");
+      return -1;
     }
     
     
-    for(uint32_t j=0; j<nodes.GetN(); j++)
+  for(uint32_t j=0; j<nodes.GetN(); j++)
     {
-        uint32_t name = j+1;
-        std::stringstream ss;
-        ss<<name;
-        Names::Add (ss.str(), nodes.Get (j));
-        NS_LOG_INFO("Name = " << ss.str());
+      uint32_t name = j+1;
+      std::stringstream ss;
+      ss<<name;
+      Names::Add (ss.str(), nodes.Get (j));
+      NS_LOG_INFO("Name = " << ss.str());
     }
  
-    // ------------------------------------------------------------
-    // -- Create nodes and network stacks
-    // --------------------------------------------
-    NS_LOG_INFO ("creating internet stack");
-    InternetStackHelper stack;
+  // ------------------------------------------------------------
+  // -- Create nodes and network stacks
+  // --------------------------------------------
+  NS_LOG_INFO ("creating internet stack");
+  InternetStackHelper stack;
     
     
-    //routing
-    //Ipv4StaticRoutingHelper staticRouting;
-    //Ipv4ListRoutingHelper listRH;
-    //listRH.Add (staticRouting, 0);
-    //stack.SetRoutingHelper (listRH);  // has effect on the next Install ()
-    //stack.Install (nodes);
+  //routing
+  //Ipv4StaticRoutingHelper staticRouting;
+  //Ipv4ListRoutingHelper listRH;
+  //listRH.Add (staticRouting, 0);
+  //stack.SetRoutingHelper (listRH);  // has effect on the next Install ()
+  //stack.Install (nodes);
     
-    Ipv4GlobalRoutingHelper ipv4RoutingHelper;
-    // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
-    stack.SetRoutingHelper (ipv4RoutingHelper);
-    stack.Install(nodes);
+  Ipv4GlobalRoutingHelper ipv4RoutingHelper;
+  // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
+  stack.SetRoutingHelper (ipv4RoutingHelper);
+  stack.Install(nodes);
     
-    NS_LOG_INFO ("creating ip4 addresses");
-    Ipv4AddressHelper address;
-    address.SetBase ("10.0.0.0", "255.255.255.252");
+  NS_LOG_INFO ("creating ip4 addresses");
+  Ipv4AddressHelper address;
+  address.SetBase ("10.0.0.0", "255.255.255.252");
    
-    // // Create router nodes, initialize routing database and set up the routing
-    // // tables in the nodes.
-    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+  // // Create router nodes, initialize routing database and set up the routing
+  // // tables in the nodes.
+  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
     
-    /*grid.AssignIpv4Addresses (
-                              Ipv4AddressHelper("10.1.0.0", "255.255.255.0"),
-                              Ipv4AddressHelper("10.2.0.0", "255.255.255.0")
-                              );
-*/
+  /*grid.AssignIpv4Addresses (
+    Ipv4AddressHelper("10.1.0.0", "255.255.255.0"),
+    Ipv4AddressHelper("10.2.0.0", "255.255.255.0")
+    );
+  */
     
-    int totlinks = reader->LinksSize ();
+  int totlinks = reader->LinksSize ();
     
     
-    ///*** applying settings
-    NS_LOG_INFO ("creating node containers");
-    NodeContainer* nc = new NodeContainer[totlinks];
-    TopologyReader::ConstLinksIterator iter;
-    int i = 0;
-    for ( iter = reader->LinksBegin (); iter != reader->LinksEnd (); iter++, i++ )
+  ///*** applying settings
+  NS_LOG_INFO ("creating node containers");
+  NodeContainer* nc = new NodeContainer[totlinks];
+  TopologyReader::ConstLinksIterator iter;
+  int i = 0;
+  for ( iter = reader->LinksBegin (); iter != reader->LinksEnd (); iter++, i++ )
     {
-        nc[i] = NodeContainer (iter->GetFromNode (), iter->GetToNode ());
+      nc[i] = NodeContainer (iter->GetFromNode (), iter->GetToNode ());
     }
     
-    NetDeviceContainer* ndc = new NetDeviceContainer[totlinks];
-    reader->ApplySettings(ndc,nc);
-    ///*** settings applied
+  NetDeviceContainer* ndc = new NetDeviceContainer[totlinks];
+  reader->ApplySettings(ndc,nc);
+  ///*** settings applied
     
-    NS_LOG_INFO("installing ccnx stack");
-    CcnxStackHelper ccnx(Ccnx::NDN_FLOODING);
-    Ptr<CcnxFaceContainer> cf = ccnx.Install (nodes);
+  NS_LOG_INFO("installing ccnx stack");
+  CcnxStackHelper ccnx;
+  ccnx.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
+  ccnx.EnableLimits (false);
+    
+  Ptr<CcnxFaceContainer> cf = ccnx.Install (nodes);
      
-    NS_LOG_INFO ("Installing Applications");
-    CcnxConsumerHelper helper ("/3");
-    ApplicationContainer app = helper.Install (nodes.Get(1));
-    app.Start (Seconds (1.0));
-    app.Stop (Seconds (1000.05));
+  NS_LOG_INFO ("Installing Applications");
+  CcnxConsumerHelper helper ("/3");
+  ApplicationContainer app = helper.Install (nodes.Get(1));
+  app.Start (Seconds (1.0));
+  app.Stop (Seconds (1000.05));
     
-    /*CcnxConsumerHelper helper2 ("/4");
-     ApplicationContainer app2 = helper2.Install(c.Get(5));
-     app2.Start (Seconds (1.0));
-     app2.Stop (Seconds (1000.05));
-     */
-    CcnxProducerHelper helper3 ("/3",120);
-    ApplicationContainer app3 = helper3.Install(nodes.Get(6));
-    app3.Start(Seconds(0.0));
-    app3.Stop(Seconds(1500.0));
-    /*
-     CcnxProducerHelper helper4 ("/4",150);
-     ApplicationContainer app4 = helper4.Install(c.Get(0));
-     app4.Start(Seconds(0.0));
-     app4.Stop(Seconds(1500.0));
-     */
+  /*CcnxConsumerHelper helper2 ("/4");
+    ApplicationContainer app2 = helper2.Install(c.Get(5));
+    app2.Start (Seconds (1.0));
+    app2.Stop (Seconds (1000.05));
+  */
+  CcnxProducerHelper helper3 ("/3",120);
+  ApplicationContainer app3 = helper3.Install(nodes.Get(6));
+  app3.Start(Seconds(0.0));
+  app3.Stop(Seconds(1500.0));
+  /*
+    CcnxProducerHelper helper4 ("/4",150);
+    ApplicationContainer app4 = helper4.Install(c.Get(0));
+    app4.Start(Seconds(0.0));
+    app4.Stop(Seconds(1500.0));
+  */
 
-    NS_LOG_INFO("Routes");
-    ccnx.AddRoute("1","/3",0,1);
-    ccnx.AddRoute("3","/3",1,1);
-    ccnx.AddRoute("3","/3",2,2);
-    /*ccnx.AddRoute("4","/3",1,1);
+  NS_LOG_INFO("Routes");
+  ccnx.AddRoute("1","/3",0,1);
+  ccnx.AddRoute("3","/3",1,1);
+  ccnx.AddRoute("3","/3",2,2);
+  /*ccnx.AddRoute("4","/3",1,1);
     ccnx.AddRoute("5","/3",2,1);
-*/
+  */
     
-    // it creates little subnets, one for each couple of nodes.
-    NS_LOG_INFO ("creating ipv4 interfaces");
-    Ipv4InterfaceContainer* ipic = new Ipv4InterfaceContainer[totlinks];
-    for (int i = 0; i < totlinks; i++)
+  // it creates little subnets, one for each couple of nodes.
+  NS_LOG_INFO ("creating ipv4 interfaces");
+  Ipv4InterfaceContainer* ipic = new Ipv4InterfaceContainer[totlinks];
+  for (int i = 0; i < totlinks; i++)
     {
-        ipic[i] = address.Assign (ndc[i]);
-        address.NewNetwork ();
+      ipic[i] = address.Assign (ndc[i]);
+      address.NewNetwork ();
     }
     
-    // ------------------------------------------------------------
-    // -- Run the simulation
-    // --------------------------------------------
-    NS_LOG_INFO ("Run Simulation.");
-    Simulator::Stop (Seconds (20));
-    Simulator::Run ();
-    Simulator::Destroy ();
+  // ------------------------------------------------------------
+  // -- Run the simulation
+  // --------------------------------------------
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Stop (Seconds (20));
+  Simulator::Run ();
+  Simulator::Destroy ();
     
-    delete[] ipic;
-    delete[] ndc;
-    delete[] nc;
+  delete[] ipic;
+  delete[] ndc;
+  delete[] nc;
     
-    NS_LOG_INFO ("Done.");
+  NS_LOG_INFO ("Done.");
     
-    return 0;
+  return 0;
 }
diff --git a/examples/ccnx-grid.cc b/examples/ccnx-grid.cc
index e60e962..c183413 100644
--- a/examples/ccnx-grid.cc
+++ b/examples/ccnx-grid.cc
@@ -87,7 +87,9 @@
 
   // Install CCNx stack
   NS_LOG_INFO ("Installing CCNx stack");
-  CcnxStackHelper ccnxHelper(Ccnx::NDN_FLOODING/*Ccnx::NDN_BESTROUTE*/);
+  CcnxStackHelper ccnxHelper;
+  ccnxHelper.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
+  ccnxHelper.EnableLimits (true);
   ccnxHelper.InstallAll ();
 
   // Install IP stack (necessary to populate FIB)
diff --git a/examples/syntactic-topology-ndnabstraction.cc b/examples/syntactic-topology-ndnabstraction.cc
index 5ca03e1..3fc04a1 100644
--- a/examples/syntactic-topology-ndnabstraction.cc
+++ b/examples/syntactic-topology-ndnabstraction.cc
@@ -43,8 +43,8 @@
   Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
   Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
   
-    Packet::EnableChecking();
-    Packet::EnablePrinting();
+  Packet::EnableChecking();
+  Packet::EnablePrinting();
 
   // Allow the user to override any of the defaults and the above
   // DefaultValue::Bind ()s at run-time, via command-line arguments
@@ -55,13 +55,13 @@
   NS_LOG_INFO ("Create nodes.");
   NodeContainer c;
   c.Create (7);
-    Names::Add ("1", c.Get (0));
-    Names::Add ("2", c.Get (1));
-    Names::Add ("3", c.Get (2));
-    Names::Add ("4", c.Get (3));
-    Names::Add ("5", c.Get (4));
-    Names::Add ("6", c.Get (5));
-    Names::Add ("7", c.Get (6));
+  Names::Add ("1", c.Get (0));
+  Names::Add ("2", c.Get (1));
+  Names::Add ("3", c.Get (2));
+  Names::Add ("4", c.Get (3));
+  Names::Add ("5", c.Get (4));
+  Names::Add ("6", c.Get (5));
+  Names::Add ("7", c.Get (6));
     
     
   NodeContainer n13 = NodeContainer (c.Get (0), c.Get (2));
@@ -104,14 +104,14 @@
   p2p.SetChannelAttribute ("Delay", StringValue ("50ms"));
   NetDeviceContainer nd35 = p2p.Install (n35);
   
-    InternetStackHelper stack;
-    Ipv4GlobalRoutingHelper ipv4RoutingHelper;
-    // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
-    stack.SetRoutingHelper (ipv4RoutingHelper);
-    stack.Install(c);
-    // // Create router nodes, initialize routing database and set up the routing
-    // // tables in the nodes.
-    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+  InternetStackHelper stack;
+  Ipv4GlobalRoutingHelper ipv4RoutingHelper;
+  // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
+  stack.SetRoutingHelper (ipv4RoutingHelper);
+  stack.Install(c);
+  // // Create router nodes, initialize routing database and set up the routing
+  // // tables in the nodes.
+  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
     
   // Later, we add IP addresses.
   NS_LOG_INFO ("Assign IP Addresses.");
@@ -128,38 +128,40 @@
     
     
     
-    CcnxStackHelper ccnx(Ccnx::NDN_FLOODING/*Ccnx::NDN_BESTROUTE*/);
-    Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
+  CcnxStackHelper ccnx;
+  ccnx.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
+  ccnx.EnableLimits (false);
+  Ptr<CcnxFaceContainer> cf = ccnx.Install (c);
     
-    NS_LOG_INFO ("Installing Applications");
-    CcnxConsumerHelper helper ("/3");
-    ApplicationContainer app = helper.Install (c.Get(1));
-    app.Start (Seconds (1.0));
-    app.Stop (Seconds (1000.05));
+  NS_LOG_INFO ("Installing Applications");
+  CcnxConsumerHelper helper ("/3");
+  ApplicationContainer app = helper.Install (c.Get(1));
+  app.Start (Seconds (1.0));
+  app.Stop (Seconds (1000.05));
     
-    /*CcnxConsumerHelper helper2 ("/4");
+  /*CcnxConsumerHelper helper2 ("/4");
     ApplicationContainer app2 = helper2.Install(c.Get(5));
     app2.Start (Seconds (1.0));
     app2.Stop (Seconds (1000.05));
-    */
-    CcnxProducerHelper helper3 ("/3",120);
-    ApplicationContainer app3 = helper3.Install(c.Get(6));
-    app3.Start(Seconds(0.0));
-    app3.Stop(Seconds(1500.0));
-    /*
+  */
+  CcnxProducerHelper helper3 ("/3",120);
+  ApplicationContainer app3 = helper3.Install(c.Get(6));
+  app3.Start(Seconds(0.0));
+  app3.Stop(Seconds(1500.0));
+  /*
     CcnxProducerHelper helper4 ("/4",150);
     ApplicationContainer app4 = helper4.Install(c.Get(0));
     app4.Start(Seconds(0.0));
     app4.Stop(Seconds(1500.0));
   */
     
-    ccnx.AddRoute("1","/3",0,1);
-    ccnx.AddRoute("3","/3",2,1);
-    ccnx.AddRoute("3","/3",3,1);
-    ccnx.AddRoute("4","/3",1,1);
-    ccnx.AddRoute("5","/3",2,1);
+  ccnx.AddRoute("1","/3",0,1);
+  ccnx.AddRoute("3","/3",2,1);
+  ccnx.AddRoute("3","/3",3,1);
+  ccnx.AddRoute("4","/3",1,1);
+  ccnx.AddRoute("5","/3",2,1);
     
-    /*ccnx.AddRoute ("1", "/3", 0, 1);
+  /*ccnx.AddRoute ("1", "/3", 0, 1);
     ccnx.AddRoute ("1", "/3", 1, 1);
     
     ccnx.AddRoute ("2", "/3", 1, 1);
@@ -178,40 +180,40 @@
   // Create the OnOff application to send UDP datagrams of size
   // 210 bytes at a rate of 448 Kb/s from n0 to n4
   /*NS_LOG_INFO ("Create Applications.");
-  uint16_t port = 9;   // Discard port (RFC 863)
+    uint16_t port = 9;   // Discard port (RFC 863)
   
-  std::string sendsizeattr = "SendSize";
-  //flow2 7-->2
-  BulkSendHelper bulksend0 ("ns3::UdpSocketFactory", InetSocketAddress (i23.GetAddress (0), port));
-  //bulksend0.SetAttribute(sendsizeattr, AttributeValue(ConstantVariable(2560)));
-  bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
-  ApplicationContainer apps = bulksend0.Install(c.Get(6));
-  apps.Start(Seconds (1.0));
-  apps.Stop(Seconds (10.0));
+    std::string sendsizeattr = "SendSize";
+    //flow2 7-->2
+    BulkSendHelper bulksend0 ("ns3::UdpSocketFactory", InetSocketAddress (i23.GetAddress (0), port));
+    //bulksend0.SetAttribute(sendsizeattr, AttributeValue(ConstantVariable(2560)));
+    bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
+    ApplicationContainer apps = bulksend0.Install(c.Get(6));
+    apps.Start(Seconds (1.0));
+    apps.Stop(Seconds (10.0));
   
-  // Create a packet sink to receive these packets
-  PacketSinkHelper sink0 ("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny (), port));
-  apps = sink0.Install(c.Get(1));
-  apps.Start(Seconds(0.0));
-  apps.Stop(Seconds(20.0));
+    // Create a packet sink to receive these packets
+    PacketSinkHelper sink0 ("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny (), port));
+    apps = sink0.Install(c.Get(1));
+    apps.Start(Seconds(0.0));
+    apps.Stop(Seconds(20.0));
   
-  //flow1 1-->6
-  BulkSendHelper bulksend ("ns3::UdpSocketFactory", InetSocketAddress (i56.GetAddress (1), port));
-  //bulksend.SetAttribute(sendsizeattr, AttributeValue( ConstantVariable(2560)));
-  bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
-  apps = bulksend.Install (c.Get (0));
-  apps.Start (Seconds (6.0));
-  apps.Stop (Seconds (20.0));
+    //flow1 1-->6
+    BulkSendHelper bulksend ("ns3::UdpSocketFactory", InetSocketAddress (i56.GetAddress (1), port));
+    //bulksend.SetAttribute(sendsizeattr, AttributeValue( ConstantVariable(2560)));
+    bulksend0.SetAttribute("MaxBytes", UintegerValue(2560));
+    apps = bulksend.Install (c.Get (0));
+    apps.Start (Seconds (6.0));
+    apps.Stop (Seconds (20.0));
   
-  // Create a packet sink to receive these packets
-  PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
-  apps = sink.Install (c.Get (5));
-  apps.Start(Seconds(0.0));
-  apps.Stop(Seconds(20.0));
+    // Create a packet sink to receive these packets
+    PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
+    apps = sink.Install (c.Get (5));
+    apps.Start(Seconds(0.0));
+    apps.Stop(Seconds(20.0));
   
-  AsciiTraceHelper ascii;
-  p2p.EnableAsciiAll (ascii.CreateFileStream ("sync-topology-ndnabstraction.tr"));
-  p2p.EnablePcapAll ("sync-topology-ndnabstraction");*/
+    AsciiTraceHelper ascii;
+    p2p.EnableAsciiAll (ascii.CreateFileStream ("sync-topology-ndnabstraction.tr"));
+    p2p.EnablePcapAll ("sync-topology-ndnabstraction");*/
   
   Simulator::Stop (Seconds (2000));
   
@@ -220,5 +222,5 @@
   Simulator::Destroy ();
   NS_LOG_INFO ("Done.");
   
-	return 0;
+  return 0;
 }
diff --git a/helper/ccnx-forwarding-helper.cc b/helper/ccnx-forwarding-helper.cc
index 31ffecb..0e74e97 100644
--- a/helper/ccnx-forwarding-helper.cc
+++ b/helper/ccnx-forwarding-helper.cc
@@ -26,32 +26,9 @@
 #include "ccnx-forwarding-helper.h"
 
 namespace ns3 {
-
-CcnxForwardingHelper::CcnxForwardingHelper()
-{
-    m_strategy = Ccnx::NDN_FLOODING;
-}
     
-CcnxForwardingHelper::CcnxForwardingHelper (Ccnx::ForwardingStrategy strategy)
+CcnxForwardingHelper::CcnxForwardingHelper ()
 {
-    m_strategy = strategy;
-}
-
-void 
-CcnxForwardingHelper::SetForwarding (Ptr<Ccnx> ccnx) const
-{
-    if(m_strategy == Ccnx::NDN_FLOODING)
-    {
-        Ptr<CcnxFloodingStrategy> ccnxForwarding = CreateObject<CcnxFloodingStrategy> ();
-        ccnx->SetForwardingStrategy (ccnxForwarding);
-    }
-    else if(m_strategy == Ccnx::NDN_BESTROUTE)
-    {
-        Ptr<CcnxBestRouteStrategy> ccnxForwarding = CreateObject<CcnxBestRouteStrategy> ();
-        ccnx->SetForwardingStrategy (ccnxForwarding);
-    }
-    else if (m_strategy == Ccnx::NDN_RANKING)
-    {}
 }
 
 // void
diff --git a/helper/ccnx-forwarding-helper.h b/helper/ccnx-forwarding-helper.h
index d75a35a..5a59381 100644
--- a/helper/ccnx-forwarding-helper.h
+++ b/helper/ccnx-forwarding-helper.h
@@ -43,70 +43,59 @@
 {
 public:
   /*
-   * \brief Default constructor, which sets NDN_FLOODING forwarding strategy
+   * \brief Default constructor
    */
   CcnxForwardingHelper();
-  
-  /*
-   * \brief This constructor sets a specified forwarding strategy 
-   */
-  CcnxForwardingHelper(Ccnx::ForwardingStrategy strategy);
-
-  /*
-   * \brief creates a specified ForwardingStrategy object
-   */
-  void SetForwarding(Ptr<Ccnx> ccnx) const;
     
-  /**
-   * \brief prints the forwarding tables of all nodes at a particular time.
-   * \param printTime the time at which the forwarding table is supposed to be printed.
-   * \param stream The output stream object to use 
-   *
-   * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
-   * specified time; the output format is forwarding protocol-specific.
-   */
-  void PrintForwardingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const;
+  // /**
+  //  * \brief prints the forwarding tables of all nodes at a particular time.
+  //  * \param printTime the time at which the forwarding table is supposed to be printed.
+  //  * \param stream The output stream object to use 
+  //  *
+  //  * This method calls the PrintForwardingTable() method of the 
+  //  * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
+  //  * specified time; the output format is forwarding protocol-specific.
+  //  */
+  // void PrintForwardingTableAllAt (Time printTime, Ptr<OutputStreamWrapper> stream) const;
 
-  /**
-   * \brief prints the forwarding tables of all nodes at regular intervals specified by user.
-   * \param printInterval the time interval for which the forwarding table is supposed to be printed.
-   * \param stream The output stream object to use
-   *
-   * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
-   * specified time interval; the output format is forwarding protocol-specific.
-   */
-  void PrintForwardingTableAllEvery (Time printInterval, Ptr<OutputStreamWrapper> stream) const;
+  // /**
+  //  * \brief prints the forwarding tables of all nodes at regular intervals specified by user.
+  //  * \param printInterval the time interval for which the forwarding table is supposed to be printed.
+  //  * \param stream The output stream object to use
+  //  *
+  //  * This method calls the PrintForwardingTable() method of the 
+  //  * CcnxForwardingStrategy stored in the Ccnx object, for all nodes at the
+  //  * specified time interval; the output format is forwarding protocol-specific.
+  //  */
+  // void PrintForwardingTableAllEvery (Time printInterval, Ptr<OutputStreamWrapper> stream) const;
 
-  /**
-   * \brief prints the forwarding tables of a node at a particular time.
-   * \param printTime the time at which the forwarding table is supposed to be printed.
-   * \param node The node ptr for which we need the forwarding table to be printed
-   * \param stream The output stream object to use
-   *
-   * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingStrategy stored in the Ccnx object, for the selected node 
-   * at the specified time; the output format is forwarding protocol-specific.
-   */
-  void PrintForwardingTableAt (Time printTime, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+  // /**
+  //  * \brief prints the forwarding tables of a node at a particular time.
+  //  * \param printTime the time at which the forwarding table is supposed to be printed.
+  //  * \param node The node ptr for which we need the forwarding table to be printed
+  //  * \param stream The output stream object to use
+  //  *
+  //  * This method calls the PrintForwardingTable() method of the 
+  //  * CcnxForwardingStrategy stored in the Ccnx object, for the selected node 
+  //  * at the specified time; the output format is forwarding protocol-specific.
+  //  */
+  // void PrintForwardingTableAt (Time printTime, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
 
-  /**
-   * \brief prints the forwarding tables of a node at regular intervals specified by user.
-   * \param printInterval the time interval for which the forwarding table is supposed to be printed.
-   * \param node The node ptr for which we need the forwarding table to be printed
-   * \param stream The output stream object to use
-   *
-   * This method calls the PrintForwardingTable() method of the 
-   * CcnxForwardingStrategy stored in the Ccnx object, for the selected node 
-   * at the specified interval; the output format is forwarding protocol-specific.
-   */
-  void PrintForwardingTableEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+  // /**
+  //  * \brief prints the forwarding tables of a node at regular intervals specified by user.
+  //  * \param printInterval the time interval for which the forwarding table is supposed to be printed.
+  //  * \param node The node ptr for which we need the forwarding table to be printed
+  //  * \param stream The output stream object to use
+  //  *
+  //  * This method calls the PrintForwardingTable() method of the 
+  //  * CcnxForwardingStrategy stored in the Ccnx object, for the selected node 
+  //  * at the specified interval; the output format is forwarding protocol-specific.
+  //  */
+  // void PrintForwardingTableEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
 
 private:
-  Ccnx::ForwardingStrategy m_strategy;
-  void Print (Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
-  void PrintEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+  // void Print (Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
+  // void PrintEvery (Time printInterval, Ptr<Node> node, Ptr<OutputStreamWrapper> stream) const;
 };
 
 } // namespace ns3
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index f965fc7..234a64c 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -71,11 +71,14 @@
 #include "ns3/ccnx-l3-protocol.h"
 #include "ns3/ccnx-fib.h"
 #include "ns3/node-list.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-routing-helper.h"
-#include "ns3/ipv4-global-routing-ordered-nexthops.h"
+#include "ns3/loopback-net-device.h"
 #include "ns3/global-router-interface.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-global-routing.h"
+#include "ns3/ipv4-global-routing-ordered-nexthops.h"
+#include "ns3/ipv4-routing-helper.h"
 #include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/data-rate.h"
 
 #include "ccnx-face-container.h"
 #include "ccnx-stack-helper.h"
@@ -86,8 +89,6 @@
 #include <boost/foreach.hpp>
 
 #define NDN_DEFAULT_DATA_SIZE      1024
-#define NDN_INTEREST_RESET_PERIOD  Seconds(0.01)
-
 
 NS_LOG_COMPONENT_DEFINE ("CcnxStackHelper");
 
@@ -116,47 +117,33 @@
 // leaks.  Global maps of protocol/face pairs to file objects seems to
 // fit the bill.
 //
-typedef std::pair<Ptr<Ccnx>, uint32_t> FacePairCcnx; 
-typedef std::map<FacePairCcnx, Ptr<PcapFileWrapper> > FaceFileMapCcnx;
-typedef std::map<FacePairCcnx, Ptr<OutputStreamWrapper> > FaceStreamMapCcnx;
+// typedef std::pair<Ptr<Ccnx>, uint32_t> FacePairCcnx; 
+// typedef std::map<FacePairCcnx, Ptr<PcapFileWrapper> > FaceFileMapCcnx;
+// typedef std::map<FacePairCcnx, Ptr<OutputStreamWrapper> > FaceStreamMapCcnx;
 
-static FaceFileMapCcnx g_faceFileMapCcnx; /**< A mapping of Ccnx/face pairs to pcap files */
-static FaceStreamMapCcnx g_faceStreamMapCcnx; /**< A mapping of Ccnx/face pairs to ascii streams */
+// static FaceFileMapCcnx g_faceFileMapCcnx; /**< A mapping of Ccnx/face pairs to pcap files */
+// static FaceStreamMapCcnx g_faceStreamMapCcnx; /**< A mapping of Ccnx/face pairs to ascii streams */
 
     
 CcnxStackHelper::CcnxStackHelper ()
-    : m_forwardingHelper (Ccnx::NDN_FLOODING)
 {
-}
-    
-CcnxStackHelper::CcnxStackHelper (Ccnx::ForwardingStrategy strategy)
-    : m_forwardingHelper (strategy)
-{
+  m_strategyFactory.SetTypeId ("ns3::CcnxFloodingStrategy");
 }
     
 CcnxStackHelper::~CcnxStackHelper ()
 {
 }
 
-CcnxStackHelper::CcnxStackHelper (const CcnxStackHelper &o)
-{
-}
-
-CcnxStackHelper &
-CcnxStackHelper::operator = (const CcnxStackHelper &o)
-{
-  if (this == &o)
-    {
-      return *this;
-    }
-  return *this;
-}
-
 void 
-CcnxStackHelper::SetForwardingStrategy (Ccnx::ForwardingStrategy strategy)
+CcnxStackHelper::SetForwardingStrategy (std::string strategy)
 {
-  CcnxForwardingHelper newForwardingHelper (strategy);
-  m_forwardingHelper = newForwardingHelper;
+  m_strategyFactory.SetTypeId (strategy);
+}
+
+void
+CcnxStackHelper::EnableLimits (bool enable/* = true*/)
+{
+  m_limitsEnabled = enable;
 }
 
 Ptr<CcnxFaceContainer>
@@ -176,15 +163,6 @@
   return Install (NodeContainer::GetGlobal ());
 }
 
-// void
-// CcnxStackHelper::CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId)
-// {
-//   ObjectFactory factory;
-//   factory.SetTypeId (typeId);
-//   Ptr<Object> protocol = factory.Create <Object> ();
-//   node->AggregateObject (protocol);
-// }
-
 Ptr<CcnxFaceContainer>
 CcnxStackHelper::Install (Ptr<Node> node) const
 {
@@ -204,39 +182,44 @@
   Ptr<CcnxL3Protocol> ccnx = CreateObject<CcnxL3Protocol> ();
   node->AggregateObject (ccnx);
 
-  NS_LOG_INFO("NODE->GetNDevices()=" << node->GetNDevices());
-    
+  ccnx->SetForwardingStrategy
+    (DynamicCast<CcnxForwardingStrategy> (m_strategyFactory.Create<Object> ()));
+  
   for (uint32_t index=0; index < node->GetNDevices (); index++)
     {
-      Ptr<PointToPointNetDevice> device = DynamicCast<PointToPointNetDevice>(node->GetDevice(index));
-      if(device == 0)
-        continue;
-        
-      Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node, node->GetDevice (index));
+      Ptr<NetDevice> device = node->GetDevice (index);
+      if (DynamicCast<LoopbackNetDevice> (device) != 0)
+        continue; // don't create face for a LoopbackNetDevice
+
+      Ptr<CcnxNetDeviceFace> face = Create<CcnxNetDeviceFace> (node, device);
 
       uint32_t __attribute__ ((unused)) face_id = ccnx->AddFace (face);
       NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << face_id);
-      // Setup bucket filtering
-      // Assume that we know average data packet size, and this size is equal default size
-      // Set maximum buckets (averaging over 1 second)
+
+      if (m_limitsEnabled)
+        {
+          Ptr<PointToPointNetDevice> p2p = DynamicCast<PointToPointNetDevice> (device);
+          if (p2p == 0)
+            continue; // only PointToPointNetDevice supports limits
+
+          // Setup bucket filtering
+          // Assume that we know average data packet size, and this size is equal default size
+          // Set maximum buckets (averaging over 1 second)
       
-      // DataRateValue dataRate;
-      // device->GetAttribute ("DataRate", dataRate);
-      // NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
-      // pit->maxBucketsPerFace[face->GetId()] = 0.1 * dataRate.Get().GetBitRate () /(NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
-      // NS_LOG_INFO("maxBucketsPerFace["<<face->GetId()<<"] = " << pit->maxBucketsPerFace[face->GetId()]); 
-      // pit->leakSize[face->GetId()] = 0.97 * NDN_INTEREST_RESET_PERIOD.ToDouble(Time::S) * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof(CcnxInterestHeader));
-      // NS_LOG_INFO("pit->leakSize["<<face->GetId()<<"] = " << pit->leakSize[face->GetId()]);
+          DataRateValue dataRate; device->GetAttribute ("DataRate", dataRate);
+          
+          NS_LOG_INFO("DataRate for this link is " << dataRate.Get());
+          face->SetBucketMax
+            (0.1 * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof (CcnxInterestHeader)));
+             
+          face->SetBucketLeak
+            (0.97 * dataRate.Get().GetBitRate () / (NDN_DEFAULT_DATA_SIZE + sizeof (CcnxInterestHeader)));
+        }
         
-      NS_LOG_INFO("Face #" << face_id << " is turned on");
       face->SetUp ();
       faces->Add (face);
     }
     
-  m_forwardingHelper.SetForwarding (ccnx);
-
-  // ccnx->ScheduleLeakage ();
-    
   return faces;
 }
 
@@ -275,10 +258,10 @@
   AddRoute (node, prefix, face, metric);
 }
 /*
-void
-CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
-{
-    NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
+  void
+  CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
+  {
+  NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
     
   NS_ASSERT_MSG (node != 0, "Node does not exist");
         
@@ -290,259 +273,259 @@
   CcnxNameComponentsValue prefixValue;
   prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
   fib->Add (prefixValue.Get (), face, metric);
-}
+  }
 */
 
-static void
-CcnxL3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ccnx> ccnx, uint32_t face)
-{
-  NS_LOG_FUNCTION (p << ccnx << face);
+// static void
+// CcnxL3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ccnx> ccnx, uint32_t face)
+// {
+//   NS_LOG_FUNCTION (p << ccnx << face);
 
-  //
-  // Since trace sources are independent of face, if we hook a source
-  // on a particular protocol we will get traces for all of its faces.
-  // We need to filter this to only report faces for which the user 
-  // has expressed interest.
-  //
-  FacePairCcnx pair = std::make_pair (ccnx, face);
-  if (g_faceFileMapCcnx.find (pair) == g_faceFileMapCcnx.end ())
-    {
-      NS_LOG_INFO ("Ignoring packet to/from face " << face);
-      return;
-    }
+//   //
+//   // Since trace sources are independent of face, if we hook a source
+//   // on a particular protocol we will get traces for all of its faces.
+//   // We need to filter this to only report faces for which the user 
+//   // has expressed interest.
+//   //
+//   FacePairCcnx pair = std::make_pair (ccnx, face);
+//   if (g_faceFileMapCcnx.find (pair) == g_faceFileMapCcnx.end ())
+//     {
+//       NS_LOG_INFO ("Ignoring packet to/from face " << face);
+//       return;
+//     }
 
-  Ptr<PcapFileWrapper> file = g_faceFileMapCcnx[pair];
-  file->Write (Simulator::Now (), p);
-}
+//   Ptr<PcapFileWrapper> file = g_faceFileMapCcnx[pair];
+//   file->Write (Simulator::Now (), p);
+// }
 
-bool
-CcnxStackHelper::PcapHooked (Ptr<Ccnx> ccnx)
-{
-  for (FaceFileMapCcnx::const_iterator i = g_faceFileMapCcnx.begin (); 
-       i != g_faceFileMapCcnx.end (); 
-       ++i)
-    {
-      if ((*i).first.first == ccnx)
-        {
-          return true;
-        }
-    }
-  return false;
-}
+// bool
+// CcnxStackHelper::PcapHooked (Ptr<Ccnx> ccnx)
+// {
+//   for (FaceFileMapCcnx::const_iterator i = g_faceFileMapCcnx.begin (); 
+//        i != g_faceFileMapCcnx.end (); 
+//        ++i)
+//     {
+//       if ((*i).first.first == ccnx)
+//         {
+//           return true;
+//         }
+//     }
+//   return false;
+// }
 
-void 
-CcnxStackHelper::EnablePcapCcnxInternal (std::string prefix, Ptr<Ccnx> ccnx, uint32_t face, bool explicitFilename)
-{
-  NS_LOG_FUNCTION (prefix << ccnx << face);
+// void 
+// CcnxStackHelper::EnablePcapCcnxInternal (std::string prefix, Ptr<Ccnx> ccnx, uint32_t face, bool explicitFilename)
+// {
+//   NS_LOG_FUNCTION (prefix << ccnx << face);
 
-  //
-  // We have to create a file and a mapping from protocol/face to file 
-  // irrespective of how many times we want to trace a particular protocol.
-  //
-  PcapHelper pcapHelper;
+//   //
+//   // We have to create a file and a mapping from protocol/face to file 
+//   // irrespective of how many times we want to trace a particular protocol.
+//   //
+//   PcapHelper pcapHelper;
 
-  std::string filename;
-  if (explicitFilename)
-    {
-      filename = prefix;
-    }
-  else
-    {
-      filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
-    }
+//   std::string filename;
+//   if (explicitFilename)
+//     {
+//       filename = prefix;
+//     }
+//   else
+//     {
+//       filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
+//     }
 
-  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
+//   Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);
 
-  //
-  // However, we only hook the trace source once to avoid multiple trace sink
-  // calls per event (connect is independent of face).
-  //
-  if (!PcapHooked (ccnx))
-    {
-      //
-      // Ptr<Ccnx> is aggregated to node and CcnxL3Protocol is aggregated to 
-      // node so we can get to CcnxL3Protocol through Ccnx.
-      //
-      Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
-      NS_ASSERT_MSG (ccnxL3Protocol, "CcnxStackHelper::EnablePcapCcnxInternal(): "
-                     "m_ccnxEnabled and ccnxL3Protocol inconsistent");
+//   //
+//   // However, we only hook the trace source once to avoid multiple trace sink
+//   // calls per event (connect is independent of face).
+//   //
+//   if (!PcapHooked (ccnx))
+//     {
+//       //
+//       // Ptr<Ccnx> is aggregated to node and CcnxL3Protocol is aggregated to 
+//       // node so we can get to CcnxL3Protocol through Ccnx.
+//       //
+//       Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
+//       NS_ASSERT_MSG (ccnxL3Protocol, "CcnxStackHelper::EnablePcapCcnxInternal(): "
+//                      "m_ccnxEnabled and ccnxL3Protocol inconsistent");
 
-      bool result = ccnxL3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&CcnxL3ProtocolRxTxSink));
-      NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal():  "
-                     "Unable to connect ccnxL3Protocol \"Tx\"");
+//       bool result = ccnxL3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&CcnxL3ProtocolRxTxSink));
+//       NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal():  "
+//                      "Unable to connect ccnxL3Protocol \"Tx\"");
 
-      result = ccnxL3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&CcnxL3ProtocolRxTxSink));
-      NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal():  "
-                     "Unable to connect ccnxL3Protocol \"Rx\"");
-      // cast result to void, to suppress ‘result’ set but not used compiler-warning
-      // for optimized builds
-      (void) result;
-    }
+//       result = ccnxL3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&CcnxL3ProtocolRxTxSink));
+//       NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal():  "
+//                      "Unable to connect ccnxL3Protocol \"Rx\"");
+//       // cast result to void, to suppress ‘result’ set but not used compiler-warning
+//       // for optimized builds
+//       (void) result;
+//     }
 
-  g_faceFileMapCcnx[std::make_pair (ccnx, face)] = file;
-}
+//   g_faceFileMapCcnx[std::make_pair (ccnx, face)] = file;
+// }
 
-static void
-CcnxL3ProtocolDropSinkWithoutContext (
-  Ptr<OutputStreamWrapper> stream,
-  Ptr<const Packet> packet,
-  CcnxL3Protocol::DropReason reason, 
-  Ptr<Ccnx> ccnx, 
-  uint32_t face)
-{
-  //
-  // Since trace sources are independent of face, if we hook a source
-  // on a particular protocol we will get traces for all of its faces.
-  // We need to filter this to only report faces for which the user 
-  // has expressed interest.
-  //
-  FacePairCcnx pair = std::make_pair (ccnx, face);
-  if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
-    {
-      NS_LOG_INFO ("Ignoring packet to/from face " << face);
-      return;
-    }
+// static void
+// CcnxL3ProtocolDropSinkWithoutContext (
+//   Ptr<OutputStreamWrapper> stream,
+//   Ptr<const Packet> packet,
+//   CcnxL3Protocol::DropReason reason, 
+//   Ptr<Ccnx> ccnx, 
+//   uint32_t face)
+// {
+//   //
+//   // Since trace sources are independent of face, if we hook a source
+//   // on a particular protocol we will get traces for all of its faces.
+//   // We need to filter this to only report faces for which the user 
+//   // has expressed interest.
+//   //
+//   FacePairCcnx pair = std::make_pair (ccnx, face);
+//   if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
+//     {
+//       NS_LOG_INFO ("Ignoring packet to/from face " << face);
+//       return;
+//     }
 
-  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
-}
+//   *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
+// }
 
-static void
-CcnxL3ProtocolDropSinkWithContext (
-  Ptr<OutputStreamWrapper> stream,
-  std::string context,
-  Ptr<const Packet> packet,
-  CcnxL3Protocol::DropReason reason, 
-  Ptr<Ccnx> ccnx, 
-  uint32_t face)
-{
-  //
-  // Since trace sources are independent of face, if we hook a source
-  // on a particular protocol we will get traces for all of its faces.
-  // We need to filter this to only report faces for which the user 
-  // has expressed interest.
-  //
-  FacePairCcnx pair = std::make_pair (ccnx, face);
-  if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
-    {
-      NS_LOG_INFO ("Ignoring packet to/from face " << face);
-      return;
-    }
+// static void
+// CcnxL3ProtocolDropSinkWithContext (
+//   Ptr<OutputStreamWrapper> stream,
+//   std::string context,
+//   Ptr<const Packet> packet,
+//   CcnxL3Protocol::DropReason reason, 
+//   Ptr<Ccnx> ccnx, 
+//   uint32_t face)
+// {
+//   //
+//   // Since trace sources are independent of face, if we hook a source
+//   // on a particular protocol we will get traces for all of its faces.
+//   // We need to filter this to only report faces for which the user 
+//   // has expressed interest.
+//   //
+//   FacePairCcnx pair = std::make_pair (ccnx, face);
+//   if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
+//     {
+//       NS_LOG_INFO ("Ignoring packet to/from face " << face);
+//       return;
+//     }
 
-  *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << face << ") " 
-                        << *packet << std::endl;
-}
+//   *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << face << ") " 
+//                         << *packet << std::endl;
+// }
 
-bool
-CcnxStackHelper::AsciiHooked (Ptr<Ccnx> ccnx)
-{
-  for (  FaceStreamMapCcnx::const_iterator i = g_faceStreamMapCcnx.begin (); 
-         i != g_faceStreamMapCcnx.end (); 
-         ++i)
-    {
-      if ((*i).first.first == ccnx)
-        {
-          return true;
-        }
-    }
-  return false;
-}
+// bool
+// CcnxStackHelper::AsciiHooked (Ptr<Ccnx> ccnx)
+// {
+//   for (  FaceStreamMapCcnx::const_iterator i = g_faceStreamMapCcnx.begin (); 
+//          i != g_faceStreamMapCcnx.end (); 
+//          ++i)
+//     {
+//       if ((*i).first.first == ccnx)
+//         {
+//           return true;
+//         }
+//     }
+//   return false;
+// }
 
-void 
-CcnxStackHelper::EnableAsciiCcnxInternal (
-  Ptr<OutputStreamWrapper> stream, 
-  std::string prefix, 
-  Ptr<Ccnx> ccnx, 
-  uint32_t face,
-  bool explicitFilename)
-{
-  //
-  // Our trace sinks are going to use packet printing, so we have to 
-  // make sure that is turned on.
-  //
-  Packet::EnablePrinting ();
+// void 
+// CcnxStackHelper::EnableAsciiCcnxInternal (
+//   Ptr<OutputStreamWrapper> stream, 
+//   std::string prefix, 
+//   Ptr<Ccnx> ccnx, 
+//   uint32_t face,
+//   bool explicitFilename)
+// {
+//   //
+//   // Our trace sinks are going to use packet printing, so we have to 
+//   // make sure that is turned on.
+//   //
+//   Packet::EnablePrinting ();
 
-  //
-  // If we are not provided an OutputStreamWrapper, we are expected to create 
-  // one using the usual trace filename conventions and hook WithoutContext
-  // since there will be one file per context and therefore the context would
-  // be redundant.
-  //
-  if (stream == 0)
-    {
-      //
-      // Set up an output stream object to deal with private ofstream copy 
-      // constructor and lifetime issues.  Let the helper decide the actual
-      // name of the file given the prefix.
-      //
-      // We have to create a stream and a mapping from protocol/face to 
-      // stream irrespective of how many times we want to trace a particular 
-      // protocol.
-      //
-      AsciiTraceHelper asciiTraceHelper;
+//   //
+//   // If we are not provided an OutputStreamWrapper, we are expected to create 
+//   // one using the usual trace filename conventions and hook WithoutContext
+//   // since there will be one file per context and therefore the context would
+//   // be redundant.
+//   //
+//   if (stream == 0)
+//     {
+//       //
+//       // Set up an output stream object to deal with private ofstream copy 
+//       // constructor and lifetime issues.  Let the helper decide the actual
+//       // name of the file given the prefix.
+//       //
+//       // We have to create a stream and a mapping from protocol/face to 
+//       // stream irrespective of how many times we want to trace a particular 
+//       // protocol.
+//       //
+//       AsciiTraceHelper asciiTraceHelper;
 
-      std::string filename;
-      if (explicitFilename)
-        {
-          filename = prefix;
-        }
-      else
-        {
-          filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
-        }
+//       std::string filename;
+//       if (explicitFilename)
+//         {
+//           filename = prefix;
+//         }
+//       else
+//         {
+//           filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
+//         }
 
-      Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
+//       Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);
 
-      //
-      // However, we only hook the trace sources once to avoid multiple trace sink
-      // calls per event (connect is independent of face).
-      //
-      if (!AsciiHooked (ccnx))
-        {
-          //
-          // The drop sink for the CcnxL3Protocol uses a different signature than
-          // the default sink, so we have to cook one up for ourselves.  We can get
-          // to the Ptr<CcnxL3Protocol> through our Ptr<Ccnx> since they must both 
-          // be aggregated to the same node.
-          //
-          Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
-          bool __attribute__ ((unused)) result = ccnxL3Protocol->TraceConnectWithoutContext ("Drop", 
-                                                                                             MakeBoundCallback (&CcnxL3ProtocolDropSinkWithoutContext, theStream));
-          NS_ASSERT_MSG (result == true, "CcnxStackHelper::EanableAsciiCcnxInternal():  "
-                         "Unable to connect ccnxL3Protocol \"Drop\"");
-        }
+//       //
+//       // However, we only hook the trace sources once to avoid multiple trace sink
+//       // calls per event (connect is independent of face).
+//       //
+//       if (!AsciiHooked (ccnx))
+//         {
+//           //
+//           // The drop sink for the CcnxL3Protocol uses a different signature than
+//           // the default sink, so we have to cook one up for ourselves.  We can get
+//           // to the Ptr<CcnxL3Protocol> through our Ptr<Ccnx> since they must both 
+//           // be aggregated to the same node.
+//           //
+//           Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
+//           bool __attribute__ ((unused)) result = ccnxL3Protocol->TraceConnectWithoutContext ("Drop", 
+//                                                                                              MakeBoundCallback (&CcnxL3ProtocolDropSinkWithoutContext, theStream));
+//           NS_ASSERT_MSG (result == true, "CcnxStackHelper::EanableAsciiCcnxInternal():  "
+//                          "Unable to connect ccnxL3Protocol \"Drop\"");
+//         }
 
-      g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = theStream;
-      return;
-    }
+//       g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = theStream;
+//       return;
+//     }
 
-  //
-  // If we are provided an OutputStreamWrapper, we are expected to use it, and
-  // to provide a context.  We are free to come up with our own context if we
-  // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
-  // compatibility and simplicity, we just use Config::Connect and let it deal
-  // with the context.
-  //
-  // We need to associate the ccnx/face with a stream to express interest
-  // in tracing events on that pair, however, we only hook the trace sources 
-  // once to avoid multiple trace sink calls per event (connect is independent
-  // of face).
-  //
-  if (!AsciiHooked (ccnx))
-    {
-      Ptr<Node> node = ccnx->GetObject<Node> ();
-      std::ostringstream oss;
+//   //
+//   // If we are provided an OutputStreamWrapper, we are expected to use it, and
+//   // to provide a context.  We are free to come up with our own context if we
+//   // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
+//   // compatibility and simplicity, we just use Config::Connect and let it deal
+//   // with the context.
+//   //
+//   // We need to associate the ccnx/face with a stream to express interest
+//   // in tracing events on that pair, however, we only hook the trace sources 
+//   // once to avoid multiple trace sink calls per event (connect is independent
+//   // of face).
+//   //
+//   if (!AsciiHooked (ccnx))
+//     {
+//       Ptr<Node> node = ccnx->GetObject<Node> ();
+//       std::ostringstream oss;
 
-      //
-      // This has all kinds of parameters coming with, so we have to cook up our
-      // own sink.
-      //
-      oss.str ("");
-      oss << "/NodeList/" << node->GetId () << "/$ns3::CcnxL3Protocol/Drop";
-      Config::Connect (oss.str (), MakeBoundCallback (&CcnxL3ProtocolDropSinkWithContext, stream));
-    }
+//       //
+//       // This has all kinds of parameters coming with, so we have to cook up our
+//       // own sink.
+//       //
+//       oss.str ("");
+//       oss << "/NodeList/" << node->GetId () << "/$ns3::CcnxL3Protocol/Drop";
+//       Config::Connect (oss.str (), MakeBoundCallback (&CcnxL3ProtocolDropSinkWithContext, stream));
+//     }
 
-  g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = stream;
-}
+//   g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = stream;
+// }
 
 void
 CcnxStackHelper::InstallFakeGlobalRoutes ()
@@ -557,7 +540,7 @@
       NS_ASSERT_MSG (Ipv4RoutingHelper::GetRouting<Ipv4GlobalRoutingOrderedNexthops>
                      (
                       (*node)->GetObject<Ipv4> ()->GetRoutingProtocol ()
-                     ),
+                      ),
                      "InternetStack should have Ipv4GlobalRoutingOrderedNexthops as routing protocol");
       // Example:
       //
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index 1a76201..af45c2b 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -29,7 +29,6 @@
 #include "ccnx-trace-helper.h"
 #include "ns3/ccnx-forwarding-helper.h"
 #include "ns3/ccnx.h"
-#include "ns3/data-rate.h"
 #include "ns3/ccnx-interest-header.h"
 
 namespace ns3 {
@@ -58,7 +57,7 @@
  * attribute or a set of functionality that may be of interest to many other
  * classes.
  */
-class CcnxStackHelper : public PcapHelperForCcnx, public AsciiTraceHelperForCcnx
+class CcnxStackHelper //: public PcapHelperForCcnx, public AsciiTraceHelperForCcnx
 {
 public:
   /**
@@ -67,19 +66,12 @@
   CcnxStackHelper();
   
   /**
-   * \brief Create a new CcnxStackHelper with a specified forwarding strategy
-   */
-  CcnxStackHelper (Ccnx::ForwardingStrategy);
-
-  /**
    * \brief Destroy the CcnxStackHelper
    */
   virtual ~CcnxStackHelper ();
-  CcnxStackHelper (const CcnxStackHelper &);
-  CcnxStackHelper &operator = (const CcnxStackHelper &o);
 
   /**
-   * Set forwarding strategy helper
+   * @brief Set forwarding strategy helper
    *
    * \param forwarding a new forwarding helper
    *
@@ -89,9 +81,15 @@
    * a single ns3::Ccnx object through its ns3::Ccnx::SetforwardingProtocol.
    */
   void
-  SetForwardingStrategy (Ccnx::ForwardingStrategy strategy);
+  SetForwardingStrategy (std::string forwardingStrategy);
 
   /**
+   * @brief Enable Interest limits (disabled by default)
+   */
+  void
+  EnableLimits (bool enable = true);
+  
+  /**
    * \brief Install CCNx stack on the node
    *
    * This method will assert if called on a node that already has Ccnx object
@@ -192,58 +190,63 @@
    */
   void
   InstallRoutesToAll ();
+
+private:
+  CcnxStackHelper (const CcnxStackHelper &);
+  CcnxStackHelper &operator = (const CcnxStackHelper &o);
   
 private:
-   CcnxForwardingHelper m_forwardingHelper;
-    
-  /**
-   * @brief Enable pcap output the indicated Ccnx and interface pair.
-   * @internal
-   *
-   * @param prefix Filename prefix to use for pcap files.
-   * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
-   * @param interface Interface ID on the Ccnx on which you want to enable tracing.
-   */
-  virtual void EnablePcapCcnxInternal (std::string prefix, 
-                                       Ptr<Ccnx> ccnx, 
-                                       uint32_t interface,
-                                       bool explicitFilename);
+  ObjectFactory m_strategyFactory;
+  bool m_limitsEnabled;
+  
+  // /**
+  //  * @brief Enable pcap output the indicated Ccnx and interface pair.
+  //  * @internal
+  //  *
+  //  * @param prefix Filename prefix to use for pcap files.
+  //  * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
+  //  * @param interface Interface ID on the Ccnx on which you want to enable tracing.
+  //  */
+  // virtual void EnablePcapCcnxInternal (std::string prefix, 
+  //                                      Ptr<Ccnx> ccnx, 
+  //                                      uint32_t interface,
+  //                                      bool explicitFilename);
 
-  /**
-   * @brief Enable ascii trace output on the indicated Ccnx and interface pair.
-   * @internal
-   *
-   * @param stream An OutputStreamWrapper representing an existing file to use
-   *               when writing trace data.
-   * @param prefix Filename prefix to use for ascii trace files.
-   * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
-   * @param interface Interface ID on the Ccnx on which you want to enable tracing.
-   */
-  virtual void EnableAsciiCcnxInternal (Ptr<OutputStreamWrapper> stream, 
-                                        std::string prefix, 
-                                        Ptr<Ccnx> ccnx, 
-                                        uint32_t interface,
-                                        bool explicitFilename);
+  // /**
+  //  * @brief Enable ascii trace output on the indicated Ccnx and interface pair.
+  //  * @internal
+  //  *
+  //  * @param stream An OutputStreamWrapper representing an existing file to use
+  //  *               when writing trace data.
+  //  * @param prefix Filename prefix to use for ascii trace files.
+  //  * @param ccnx Ptr to the Ccnx interface on which you want to enable tracing.
+  //  * @param interface Interface ID on the Ccnx on which you want to enable tracing.
+  //  */
+  // virtual void EnableAsciiCcnxInternal (Ptr<OutputStreamWrapper> stream, 
+  //                                       std::string prefix, 
+  //                                       Ptr<Ccnx> ccnx, 
+  //                                       uint32_t interface,
+  //                                       bool explicitFilename);
+
+  // // /**
+  // //  * \internal
+  // //  */
+  // // static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
 
   // /**
   //  * \internal
   //  */
-  // static void CreateAndAggregateObjectFromTypeId (Ptr<Node> node, const std::string typeId);
+  // static void Cleanup (void);
 
-  /**
-   * \internal
-   */
-  static void Cleanup (void);
+  // /**
+  //  * \internal
+  //  */
+  // bool PcapHooked (Ptr<Ccnx> ccnx);
 
-  /**
-   * \internal
-   */
-  bool PcapHooked (Ptr<Ccnx> ccnx);
-
-  /**
-   * \internal
-   */
-  bool AsciiHooked (Ptr<Ccnx> ccnx);
+  // /**
+  //  * \internal
+  //  */
+  // bool AsciiHooked (Ptr<Ccnx> ccnx);
 };
 
 } // namespace ns3
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index 20d1a81..ab525b5 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -38,9 +38,10 @@
 TypeId CcnxBestRouteStrategy::GetTypeId (void)
 {
   static TypeId tid = TypeId ("ns3::CcnxBestRouteStrategy")
-  .SetGroupName ("Ccnx")
-  .SetParent<CcnxForwardingStrategy> ()
-  ;
+    .SetGroupName ("Ccnx")
+    .SetParent <CcnxForwardingStrategy> ()
+    .AddConstructor <CcnxBestRouteStrategy> ()
+    ;
   return tid;
 }
     
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index 397a5b0..94b48ab 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -169,6 +169,12 @@
   SetBucketMax (double bucket);
 
   /**
+   * @brief Set a normalized value (one second) for Interest allowance bucket leak
+   */
+  inline void
+  SetBucketLeak (double leak);
+  
+  /**
    * @brief Leak the Interest allowance bucket by (1/interval) * m_bucketMax amount
    *
    * @param interval Time interval with which the bucket is leaked
@@ -249,6 +255,12 @@
 }
 
 void
+CcnxFace::SetBucketLeak (double leak)
+{
+  m_bucketLeak = leak;
+}
+
+void
 CcnxFace::LeakBucket (const Time &interval)
 {
   const double leak = m_bucketLeak * 1.0 / interval.ToDouble (Time::S);
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 147edba..ee7df67 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -40,7 +40,8 @@
 {
   static TypeId tid = TypeId ("ns3::CcnxFloodingStrategy")
     .SetGroupName ("Ccnx")
-    .SetParent<CcnxForwardingStrategy> ()
+    .SetParent <CcnxForwardingStrategy> ()
+    .AddConstructor <CcnxFloodingStrategy> ()
     ;
   return tid;
 }