diff --git a/examples/blackhole-sprint.cc b/examples/blackhole-sprint.cc
index f97be29..a6afb82 100644
--- a/examples/blackhole-sprint.cc
+++ b/examples/blackhole-sprint.cc
@@ -27,7 +27,6 @@
 #include "ns3/ipv4-global-routing-helper.h"
 #include "ns3/random-variable.h"
 
-#include <iostream>
 #include <sstream>
 #include <map>
 #include <list>
@@ -50,209 +49,74 @@
   Simulator::Schedule (Seconds (1.0), PrintTime);
 }
 
+#include "base-experiment.h"
 
-class Experiment
+class Experiment : public BaseExperiment
 {
 public:
-  Experiment ()
-  : m_reader ("/sprint") { }
-
-  void
-  ConfigureTopology ()
-  {
-    Names::Clear ();
-    
-    string weights   ("./src/NDNabstraction/examples/sprint-pops.weights");
-    string latencies ("./src/NDNabstraction/examples/sprint-pops.latencies");
-    string positions ("./src/NDNabstraction/examples/sprint-pops.positions");
-
-    m_reader.SetFileName (positions);
-    m_reader.SetFileType (RocketfuelWeightsReader::POSITIONS);
-    m_reader.Read ();
-  
-    m_reader.SetFileName (weights);
-    m_reader.SetFileType (RocketfuelWeightsReader::WEIGHTS);    
-    m_reader.Read ();
-
-    m_reader.SetFileName (latencies);
-    m_reader.SetFileType (RocketfuelWeightsReader::LATENCIES);    
-    m_reader.Read ();
-    
-    m_reader.Commit ();
-    NS_ASSERT_MSG (m_reader.LinksSize () != 0, "Problems reading the topology file. Failing.");
-    
-    NS_LOG_INFO("Nodes = " << m_reader.GetNodes ().GetN());
-    NS_LOG_INFO("Links = " << m_reader.LinksSize ());
-  
-    // ------------------------------------------------------------
-    // -- Read topology data.
-    // --------------------------------------------
-        
-    InternetStackHelper stack;
-    Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
-    stack.SetRoutingHelper (ipv4RoutingHelper);
-    stack.Install (m_reader.GetNodes ());
-
-    m_reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
-    
-    // Install CCNx stack
-    NS_LOG_INFO ("Installing CCNx stack");
-    CcnxStackHelper ccnxHelper;
-    ccnxHelper.SetForwardingStrategy ("ns3::CcnxBestRouteStrategy");
-    ccnxHelper.EnableLimits (true, Seconds(0.1));
-    ccnxHelper.SetDefaultRoutes (false);
-    ccnxHelper.InstallAll ();
-    
-    m_rand = UniformVariable (0, m_reader.GetNodes ().GetN());
-    m_linkRand = UniformVariable(0, m_reader.LinksSize());
-  }
-
-  void
-  ConfigureRouting ()
-  {
-    CcnxStackHelper ccnxHelper;
-    // // Populate FIB based on IPv4 global routing controller
-    ccnxHelper.InstallFakeGlobalRoutes ();
-    ccnxHelper.InstallRoutesToAll ();
-  }
-
-public:  
-  void
-  Run (const Time &finishTime)
-  {
-    cout << "Run Simulation.\n";
-    Simulator::Stop (finishTime);
-    //Simulator::Schedule (Seconds (1.0), PrintTime);
-    Simulator::Run ();
-    Simulator::Destroy ();
-    cout << "Done.\n";
-  }
-
   //We are creating 10 pairs of producer-hijacker and everybody else is a consumer
   ApplicationContainer
-  AddApplications(uint32_t numOfPairs)
+  AddApplications ()
   {
-    NS_LOG_INFO("Adding applications");
     ApplicationContainer apps;
-    
-    list<uint32_t > usedNodes;
-    list<uint32_t >::iterator listIterator;
-    list<uint32_t >::iterator listIterator2;
-    
-    uint32_t producerNodeId;
-    uint32_t hijackerNodeId;
 
-    for(uint32_t pairCount = 0; pairCount < numOfPairs; pairCount++)
+    list<string> prefixes;
+
+    // Create Producers/Hijackers
+    for (list<tuple<uint32_t,uint32_t> >::iterator i = m_pairs.begin (); i != m_pairs.end (); i++)
       {
-        NS_LOG_INFO("pairCount = "<<pairCount);
-        while(true)
-          {
-            producerNodeId = m_rand.GetValue ();
-            hijackerNodeId = m_rand.GetValue ();
-        
-            bool unique = true; 
-            for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator)
-              {
-                if((*listIterator == producerNodeId) || (*listIterator == hijackerNodeId))
-                  {
-                    NS_LOG_INFO("NonUnique");
-                    unique = false;
-                  }
-              }
-        
-            if(unique == true)
-              {
-                usedNodes.push_back(producerNodeId);
-                usedNodes.push_back(hijackerNodeId);
-                break;
-              }
-          }
-      
-        NS_LOG_INFO("Producer #" << producerNodeId);
-        Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (producerNodeId));
-        CcnxAppHelper producerHelper ("ns3::CcnxProducer");
-        producerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-        
-        apps.Add(producerHelper.Install (node1));
+        uint32_t node1_num = i->get<0> ();
+        uint32_t node2_num = i->get<1> ();
 
-        NS_LOG_INFO("Hijacker # "<<hijackerNodeId);
-        Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (hijackerNodeId));
-        CcnxAppHelper hijackerHelper ("ns3::CcnxHijacker");
-        hijackerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-        
-        apps.Add(hijackerHelper.Install (node1));
-        
-        /*NS_LOG_INFO("Consumers");
-        for(uint32_t j = 0; j<m_reader.GetNodes().GetN();j++)
-          {
-            //NS_LOG_INFO("j="<<j);
-            bool consumer = true;
-            for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator)
-              {
-                if(*listIterator == j)
-                {
-                  consumer = false;
-                  NS_LOG_INFO(j<<" CANNOT be CONSUMER");
-                  break;
-                }
-              }
-        
-            if(consumer == true)
-              {
-                Ptr<Node> node3 = Names::Find<Node> ("/sprint", lexical_cast<string> (j));
-        
-                CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
-                consumerHelper.SetPrefix ("/" + lexical_cast<string> (node1->GetId ()));
-                consumerHelper.SetAttribute ("MeanRate", StringValue ("1Kbps"));
-                consumerHelper.SetAttribute ("Size", StringValue ("2"));  
-        
-                apps.Add(consumerHelper.Install (node3));
-              }
-          }*/
-        }
-      
-      NS_LOG_INFO("Consumers");
-      for(listIterator=usedNodes.begin(); listIterator != usedNodes.end(); ++listIterator,++listIterator)
-        {
-          for(uint32_t j = 0; j<m_reader.GetNodes().GetN();j++)
-          {
-            //NS_LOG_INFO("j="<<j);
-            bool consumer = true;
-            for(listIterator2=usedNodes.begin(); listIterator2 != usedNodes.end(); ++listIterator2)
-              {
-                if(*listIterator2 == j)
-                {
-                  consumer = false;
-                  NS_LOG_INFO(j<<" CANNOT be a CONSUMER");
-                  break;
-                }
-              }
-        
-            if(consumer == true)
-              {
-                Ptr<Node> node3 = Names::Find<Node> ("/sprint", lexical_cast<string> (j));
-                Ptr<Node> node4 = Names::Find<Node> ("/sprint", lexical_cast<string> (*listIterator));
+        Ptr<Node> node1 = Names::Find<Node> ("/sprint", lexical_cast<string> (node1_num));
+        Ptr<Node> node2 = Names::Find<Node> ("/sprint", lexical_cast<string> (node2_num));
 
-                CcnxAppHelper consumerHelper ("ns3::CcnxConsumer");
-                NS_LOG_INFO("Node = " << *listIterator);
-                consumerHelper.SetPrefix ("/" + lexical_cast<string> (node4->GetId ()));
-                consumerHelper.SetAttribute ("MeanRate", StringValue ("1Kbps"));
-                consumerHelper.SetAttribute ("Size", StringValue ("2"));  
+        // node1 legitimate producer
+        // node2 "fake" producer
+
+        string prefix = "/" + lexical_cast<string> (node1->GetId ());
+
+        CcnxAppHelper legitimateProducerHelper ("ns3::CcnxProducer");
+        legitimateProducerHelper.SetPrefix (prefix);
+        apps.Add
+          (legitimateProducerHelper.Install (node1));
         
-                apps.Add(consumerHelper.Install (node3));
-              }
+        CcnxAppHelper fakeProducerHelper ("ns3::CcnxHijacker");
+        fakeProducerHelper.SetPrefix (prefix);
+        apps.Add
+          (fakeProducerHelper.Install (node2));
+        
+        // one more trick. Need to install route to hijacker (aka "hijacker announces itself as a legitimate producer")
+        CcnxStackHelper::InstallRouteTo (prefix, node2);
+
+        prefixes.push_back (prefix); // remember prefixes that consumers will be requesting
+      }
+
+    // All consumers request exactly 10 packets, to convert number interests packets to requested size:
+    // size = 1040 * (max_number_of_packets-1) / 1024 / 1024
+    double requestSize = 1040.0 * (10 - 1) / 1024.0 / 1024.0;
+    
+    // Create Consumers
+    NodeContainer nodes = reader->GetNodes ();
+    for (NodeContainer::Iterator node = nodes.Begin (); node != nodes.End (); node++)
+      {
+        uint32_t namedId = lexical_cast<uint32_t> (Names::FindName (*node));
+        if (m_usedNodes.count (namedId) > 0)
+          continue;
+
+        CcnxAppHelper consumerHelper ("ns3::CcnxConsumerCbr");
+        BOOST_FOREACH (const string &prefix, prefixes)
+          {
+            consumerHelper.SetPrefix (prefix);
+            consumerHelper.SetAttribute ("MeanRate", StringValue ("8Kbps")); // this is about 1 interest a second
+            consumerHelper.SetAttribute ("Size", DoubleValue(requestSize));
+            
+            apps.Add
+              (consumerHelper.Install (*node));
           }
-        }
-      
-      
+      }
     return apps;
   }
-
-  UniformVariable m_rand;
-  UniformVariable m_linkRand;
-  
-private:
-  RocketfuelWeightsReader m_reader;
 };
 
 int 
@@ -260,48 +124,45 @@
 {
   cout << "Begin blackhole scenario\n";
   
-  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("2Mbps"));
-  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("100"));
+  Config::SetDefault ("ns3::PointToPointNetDevice::DataRate", StringValue ("100Mbps"));
+  Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("2000"));
 
-  Time finishTime = Seconds (20.0);
-  
-   
+  Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("attributes.xml"));
+  Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
+  Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("Xml"));
+
+  uint32_t maxRuns = 1;
+  uint32_t startRun = 0;
   CommandLine cmd;
-  cmd.AddValue ("finish", "Finish time", finishTime);
+  cmd.AddValue ("start", "Initial run number", startRun);
+  cmd.AddValue ("runs", "Number of runs", maxRuns);
   cmd.Parse (argc, argv);
 
-  Experiment experiment;
+  // ConfigStore config;
+  // config.ConfigureDefaults ();
 
+  Experiment experiment;
   for (uint32_t i = 0; i < 80; i++)
     {
       Config::SetGlobal ("RngRun", IntegerValue (i));
       cout << "seed = " << SeedManager::GetSeed () << ", run = " << SeedManager::GetRun () << endl;
 
       Experiment experiment;
+      experiment.GenerateRandomPairs (10);
       cout << "Run " << i << endl;
       
       string prefix = "run-" + lexical_cast<string> (i) + "-";
   
       experiment.ConfigureTopology ();
-      ApplicationContainer apps = experiment.AddApplications (10);
-      experiment.ConfigureRouting ();
-      
-      /*ApplicationContainer apps = experiment.AddApplications ();
-
-      for (uint32_t i = 0; i < apps.GetN () / 2; i++) 
-        {
-          cout << "From " << apps.Get (i*2)->GetNode ()->GetId ()
-               << " to "  << apps.Get (i*2 + 1)->GetNode ()->GetId ();
-          cout << "\n";
-        }
-      */
-      
+      experiment.InstallCcnxStack ();
+      ApplicationContainer apps = experiment.AddApplications ();
+            
       //tracing
       CcnxTraceHelper traceHelper;
-      traceHelper.EnableRateL3All (prefix + "rate-trace.log");
+      // traceHelper.EnableRateL3All (prefix + "rate-trace.log");
       traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumer", prefix + "consumers-seqs.log");
       
-      experiment.Run (finishTime);
+      experiment.Run (Seconds(20.0));
     }
 
   cout << "Finish blackhole scenario\n";
