Merge remote-tracking branch 'git.irl/Ilya'
diff --git a/apps/ccnx-app.cc b/apps/ccnx-app.cc
index 7b9c2b9..afdf9de 100644
--- a/apps/ccnx-app.cc
+++ b/apps/ccnx-app.cc
@@ -55,7 +55,6 @@
     
 CcnxApp::~CcnxApp ()
 {
-  StopApplication ();
 }
 
 void
@@ -63,7 +62,9 @@
 {
   NS_LOG_FUNCTION_NOARGS ();
 
-  StopApplication ();
+  // Unfortunately, this causes SEGFAULT
+  // The best reason I see is that apps are freed after ccnx stack is removed
+  // StopApplication ();  
   Application::DoDispose ();
 }
 
diff --git a/examples/abilene-topology.cc b/examples/abilene-topology.cc
index a8ba422..747b588 100644
--- a/examples/abilene-topology.cc
+++ b/examples/abilene-topology.cc
@@ -25,6 +25,7 @@
 #include "ns3/NDNabstraction-module.h"
 #include "ns3/point-to-point-grid.h"
 #include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/animation-interface.h"
 
 #include <iostream>
 #include <sstream>
@@ -35,6 +36,29 @@
 
 NS_LOG_COMPONENT_DEFINE ("CcnxAbileneTopology");
 
+void PrintTime ()
+{
+  NS_LOG_INFO (Simulator::Now ());
+
+  Simulator::Schedule (Seconds (10.0), PrintTime);
+}
+
+void PrintFIBs ()
+{
+  NS_LOG_INFO ("Outputing FIBs into [fibs.log]");
+  Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("fibs.log", std::ios::out);
+  for (NodeList::Iterator node = NodeList::Begin ();
+       node != NodeList::End ();
+       node++)
+    {
+      // *routingStream->GetStream () << "Node " << (*node)->GetId () << "\n";
+
+      Ptr<CcnxFib> fib = (*node)->GetObject<CcnxFib> ();
+      NS_ASSERT_MSG (fib != 0, "Fire alarm");
+      *routingStream->GetStream () << *fib << "\n\n";
+    }
+}
+
 int 
 main (int argc, char *argv[])
 {
@@ -42,61 +66,63 @@
   // Packet::EnablePrinting();
   string input ("./src/NDNabstraction/examples/abilene-topology.txt");
     
+  Time finishTime = Seconds (20.0);
+  string animationFile;
+  string strategy = "ns3::CcnxFloodingStrategy";
   CommandLine cmd;
+  cmd.AddValue ("finish", "Finish time", finishTime);
+  cmd.AddValue ("netanim", "NetAnim filename", animationFile);
+  cmd.AddValue ("strategy", "CCNx forwarding strategy", strategy);
   cmd.Parse (argc, argv);
     
   // ------------------------------------------------------------
   // -- Read topology data.
   // --------------------------------------------
     
-  Ptr<AnnotatedTopologyReader> reader = CreateObject<AnnotatedTopologyReader> ();
-  reader->SetFileName (input);
+  AnnotatedTopologyReader reader ("/abilene");
+  reader.SetFileName (input);
+  reader.SetBoundingBox (100.0, 100.0, 5000.0, 5000.0;
     
-  NodeContainer nodes;
-  if (reader != 0)
-    {
-      nodes = reader->Read ();
-    }
+  NodeContainer nodes = reader.Read ();
     
-  if (reader->LinksSize () == 0)
+  if (reader.LinksSize () == 0)
     {
       NS_LOG_ERROR ("Problems reading the topology file. Failing.");
       return -1;
     }
 
   NS_LOG_INFO("Nodes = " << nodes.GetN());
-  NS_LOG_INFO("Links = " << 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++ )
-    {
-      nc[i] = NodeContainer (iter->GetFromNode (), iter->GetToNode ());
-    }
-    
-  NetDeviceContainer* ndc = new NetDeviceContainer[totlinks];
-  reader->ApplySettings(ndc,nc);
-  reader->BoundingBox(nc, 100.0, 100.0, 5000.0,5000.0);
+  NS_LOG_INFO("Links = " << reader.LinksSize ());
     
   // Install CCNx stack
   NS_LOG_INFO ("Installing CCNx stack");
   CcnxStackHelper ccnxHelper;
-  // ccnxHelper.SetForwardingStrategy (strategy);
-  ccnxHelper.EnableLimits (true, Seconds(0.1));
+  ccnxHelper.SetForwardingStrategy (strategy);
+  ccnxHelper.EnableLimits (false, Seconds(0.1));
+  ccnxHelper.SetDefaultRoutes (true);
   ccnxHelper.InstallAll ();
     
   NS_LOG_INFO ("Installing Applications");
-  CcnxConsumerHelper consumerHelper ("preved");
-  ApplicationContainer consumers = consumerHelper.Install (nc[0]);
+  CcnxConsumerHelper consumerHelper ("tralala");
+  ApplicationContainer consumers = consumerHelper.Install (Names::Find<Node> ("/abilene", "1"));
     
-  consumers.Start (Seconds (0));
-  consumers.Stop (Seconds (20));
+  CcnxProducerHelper producerHelper ("tralala",1024);
+  ApplicationContainer producers = producerHelper.Install (Names::Find<Node> ("/abilene", "6"));
 
-  Simulator::Stop (Seconds (20));
+  // Simulator::Schedule (Seconds (1.0), PrintFIBs);
+  PrintFIBs ();
+
+  Simulator::Schedule (Seconds (10.0), PrintTime);
+
+  Simulator::Stop (finishTime);
+
+  AnimationInterface *anim = 0;
+  if (animationFile != "")
+    {
+      anim = new AnimationInterface (animationFile);
+      anim->SetMobilityPollInterval (Seconds (1));
+    }
+
   NS_LOG_INFO ("Run Simulation.");
   Simulator::Run ();
   Simulator::Destroy ();
diff --git a/examples/annotated-topology-read-example.cc b/examples/annotated-topology-read-example.cc
index 50c9d13..c220873 100644
--- a/examples/annotated-topology-read-example.cc
+++ b/examples/annotated-topology-read-example.cc
@@ -41,100 +41,53 @@
 
 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 ("./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);
+  // Time finishTime;
+  // string animationFile;
+  string strategy = "ns3::CcnxFloodingStrategy";
+  CommandLine cmd;
+  // cmd.AddValue ("finish", "Finish time", finishTime);
+  // cmd.AddValue ("netanim", "NetAnim filename", animationFile);
+  cmd.AddValue ("strategy", "CCNx forwarding strategy", strategy);
+  cmd.Parse (argc, argv);
     
     
   // ------------------------------------------------------------
   // -- Read topology data.
   // --------------------------------------------
-    
-    
-  Ptr<AnnotatedTopologyReader> reader = CreateObject<AnnotatedTopologyReader> ();
-  reader->SetFileName (input);
-    
-  NodeContainer nodes;
-  if (reader != 0)
-    {
-      nodes = reader->Read ();
-    }
-    
-  if (reader->LinksSize () == 0)
+  AnnotatedTopologyReader reader;
+  reader.SetFileName (input);
+
+  NodeContainer nodes = reader.Read ();
+
+  if (reader.LinksSize () == 0)
     {
       NS_LOG_ERROR ("Problems reading the topology file. Failing.");
       return -1;
     }
-    
-    
-  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());
-    }
- 
+
   // ------------------------------------------------------------
   // -- 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);
-    
-  Ipv4GlobalRoutingHelper ipv4RoutingHelper;
-  // Ptr<Ipv4RoutingHelper> ipv4RoutingHelper = stack.GetRoutingHelper ();
+  Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
   stack.SetRoutingHelper (ipv4RoutingHelper);
   stack.Install(nodes);
     
-  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.
+  NS_LOG_INFO ("Assigning IPv4 addresses");
+  reader.AssignIpv4Addresses (Ipv4Address ("10.0.0.0")); // will assign metrics
+     
   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
-    
-  /*grid.AssignIpv4Addresses (
-    Ipv4AddressHelper("10.1.0.0", "255.255.255.0"),
-    Ipv4AddressHelper("10.2.0.0", "255.255.255.0")
-    );
-  */
-    
-  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++ )
-    {
-      nc[i] = NodeContainer (iter->GetFromNode (), iter->GetToNode ());
-    }
-    
-  NetDeviceContainer* ndc = new NetDeviceContainer[totlinks];
-  reader->ApplySettings(ndc,nc);
-  ///*** settings applied
-    
+
+  
   NS_LOG_INFO("installing ccnx stack");
   CcnxStackHelper ccnx;
-  ccnx.SetForwardingStrategy ("ns3::CcnxFloodingStrategy");
+  ccnx.SetForwardingStrategy (strategy);
   ccnx.EnableLimits (false);
     
   Ptr<CcnxFaceContainer> cf = ccnx.Install (nodes);
@@ -145,38 +98,10 @@
   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));
-  */
-
-  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++)
-    {
-      ipic[i] = address.Assign (ndc[i]);
-      address.NewNetwork ();
-    }
     
   // ------------------------------------------------------------
   // -- Run the simulation
@@ -186,10 +111,6 @@
   Simulator::Run ();
   Simulator::Destroy ();
     
-  delete[] ipic;
-  delete[] ndc;
-  delete[] nc;
-    
   NS_LOG_INFO ("Done.");
     
   return 0;
diff --git a/examples/interest-header-example.cc b/examples/interest-header-example.cc
index 6964440..e068feb 100644
--- a/examples/interest-header-example.cc
+++ b/examples/interest-header-example.cc
@@ -28,6 +28,7 @@
 #include "ns3/nstime.h"
 #include "ns3/buffer.h"
 #include "ns3/log.h"
+#include "ns3/packet.h"
 
 using namespace ns3;
 #include <fstream>
diff --git a/helper/ccnx-stack-helper.cc b/helper/ccnx-stack-helper.cc
index d9f9d6b..074bdde 100644
--- a/helper/ccnx-stack-helper.cc
+++ b/helper/ccnx-stack-helper.cc
@@ -126,6 +126,8 @@
 
     
 CcnxStackHelper::CcnxStackHelper ()
+  : m_limitsEnabled (false)
+  , m_needSetDefaultRoutes (false)
 {
   m_strategyFactory.SetTypeId ("ns3::CcnxFloodingStrategy");
 }
@@ -140,6 +142,14 @@
   m_strategyFactory.SetTypeId (strategy);
 }
 
+
+void
+CcnxStackHelper::SetDefaultRoutes (bool needSet)
+{
+  NS_LOG_FUNCTION (this << needSet);
+  m_needSetDefaultRoutes = needSet;
+}
+
 void
 CcnxStackHelper::EnableLimits (bool enable/* = true*/, Time avgRtt/*=Seconds(0.1)*/, uint32_t avgContentObject/*=1100*/, uint32_t avgInterest/*=40*/)
 {
@@ -197,9 +207,15 @@
 
       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);
+      ccnx->AddFace (face);
+      NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << *face);
 
+      if (m_needSetDefaultRoutes)
+        {
+          // default route with lowest priority possible
+          AddRoute (node, "/", face, std::numeric_limits<int32_t>::max ()); 
+        }
+      
       if (m_limitsEnabled)
         {
           NS_LOG_INFO ("Limits are enabled");
@@ -242,8 +258,10 @@
 
 
 void
-CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric)
+CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const
 {
+  NS_LOG_LOGIC ("[" << node->GetId () << "]$ route add " << prefix << " via " << *face << " metric " << metric);
+
   Ptr<CcnxFib>  fib  = node->GetObject<CcnxFib> ();
 
   CcnxNameComponentsValue prefixValue;
@@ -252,10 +270,8 @@
 }
 
 void
-CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric)
+CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const
 {
-  NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
-  
   Ptr<Node> node = Names::Find<Node> (nodeName);
   NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
   
@@ -267,6 +283,7 @@
 
   AddRoute (node, prefix, face, metric);
 }
+
 /*
   void
   CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
diff --git a/helper/ccnx-stack-helper.h b/helper/ccnx-stack-helper.h
index ee166fc..bcfab3f 100644
--- a/helper/ccnx-stack-helper.h
+++ b/helper/ccnx-stack-helper.h
@@ -156,7 +156,7 @@
    * \param metric Routing metric
    */
   void
-  AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric);
+  AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const;
 
   /**
    * \brief Add forwarding entry in FIB
@@ -167,8 +167,13 @@
    * \param metric Routing metric
    */
   void
-  AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric);
-  
+  AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const;
+
+  /**
+   * \brief Set flag indicating necessity to install default routes in FIB
+   */
+  void
+  SetDefaultRoutes (bool needSet);
 
   /**
    * \brief Install fake IPv4 routes that could be used to find nexthops for CCNx routes
@@ -207,6 +212,7 @@
   Time     m_avgRtt;
   uint32_t m_avgContentObjectSize;
   uint32_t m_avgInterestSize;
+  bool m_needSetDefaultRoutes;
   
   // /**
   //  * @brief Enable pcap output the indicated Ccnx and interface pair.
diff --git a/model/annotated-topology-reader.cc b/model/annotated-topology-reader.cc
index 51fadfe..4b17ba4 100644
--- a/model/annotated-topology-reader.cc
+++ b/model/annotated-topology-reader.cc
@@ -20,6 +20,30 @@
 
 #include "annotated-topology-reader.h"
 
+#include "ns3/nstime.h"
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/names.h"
+#include "ns3/net-device-container.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/drop-tail-queue.h"
+#include "ns3/ipv4-interface.h"
+#include "ns3/ipv4.h"
+#include "ns3/string.h"
+#include "ns3/pointer.h"
+#include "ns3/uinteger.h"
+#include "ns3/ipv4-address.h"
+
+#include "ns3/constant-position-mobility-model.h"
+#include "ns3/random-variable.h"
+
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+
 using namespace std;
 
 namespace ns3 
@@ -37,11 +61,27 @@
     return tid;
 }
     
-AnnotatedTopologyReader::AnnotatedTopologyReader ()
+AnnotatedTopologyReader::AnnotatedTopologyReader (const std::string &path)
+  : m_path (path)
+  , m_ulx (0)
+  , m_uly (0)
+  , m_lrx (100.0)
+  , m_lry (100.0)
 {
     NS_LOG_FUNCTION (this);
 }
     
+void
+AnnotatedTopologyReader::SetBoundingBox (double ulx, double uly, double lrx, double lry)
+{
+  NS_LOG_FUNCTION (this << ulx << uly << lrx << lry);
+  
+  m_ulx = ulx;
+  m_uly = uly;
+  m_lrx = lrx;
+  m_lry = lry;
+}
+
 AnnotatedTopologyReader::~AnnotatedTopologyReader ()
 {
     NS_LOG_FUNCTION (this);
@@ -52,475 +92,215 @@
 {
     ifstream topgen;
     topgen.open (GetFileName ().c_str ());
-    map<string, Ptr<Node> > nodeMap;
     NodeContainer nodes;
         
     if ( !topgen.is_open () )
     {
+      NS_LOG_ERROR ("Cannot open file " << GetFileName () << " for reading");
         return nodes;
     }
         
-    string from;
-    string to;
-    string linkAttr;
-        
     int linksNumber = 0;
     int nodesNumber = 0;
         
-    int totnode = 0;
-    int totlink = 0;
-        
-    istringstream lineBuffer;
     string line;
-        
     getline (topgen,line);
-    lineBuffer.str (line);
+  istringstream headerLineBuffer (line);
         
-    lineBuffer >> totnode;
-    lineBuffer >> totlink;
+  int totnode;
+  int totlink;
+  headerLineBuffer >> totnode;
+  headerLineBuffer >> totlink;
+  
     NS_LOG_INFO ("Annotated topology should have " << totnode << " nodes and " << totlink << " links");
         
-    if(!topgen.eof ())
-        NS_LOG_INFO("!EOF");
-
-        
     for (int i = 0; i < totlink && !topgen.eof (); i++)
     {
-        //NS_LOG_INFO("Line #" <<i);
         getline (topgen,line);
-        lineBuffer.clear ();
-        lineBuffer.str (line);
+      istringstream lineBuffer (line);
             
+      string from;
+      string to;
         lineBuffer >> from;
         lineBuffer >> to;
             
-            
         if ( (!from.empty ()) && (!to.empty ()) )
         {
             NS_LOG_INFO ( linksNumber << " From: " << from << " to: " << to );
                 
-            if ( nodeMap[from] == 0 )
+          Ptr<Node> fromNode = Names::Find<Node> (m_path, from);
+          Ptr<Node> toNode   = Names::Find<Node> (m_path, to);
+          
+          if (fromNode == 0)
             {
-                Ptr<Node> tmpNode = CreateObject<Node> ();
-                nodeMap[from] = tmpNode;
-                nodes.Add (tmpNode);
+              fromNode = CreateObject<Node> ();
+              Names::Add (m_path, from, fromNode);
+              nodes.Add (fromNode);
                 nodesNumber++;
             }
                 
-            if (nodeMap[to] == 0)
+          if (toNode == 0)
             {
-                Ptr<Node> tmpNode = CreateObject<Node> ();
-                nodeMap[to] = tmpNode;
-                nodes.Add (tmpNode);
+              toNode = CreateObject<Node> ();
+              Names::Add (m_path, to, toNode);
+              nodes.Add (toNode);
                 nodesNumber++;
             }
                 
-            Link link ( nodeMap[from], from, nodeMap[to], to );
+          Link link (fromNode, from, toNode, to);
                 
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("DataRate", linkAttr);
-            }
+          string dataRate;
+          lineBuffer >> dataRate;
             
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("OSPF", linkAttr);
-            }
+          string ospf;
+          lineBuffer >> ospf;
                 
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("Delay", linkAttr);
-            }
+          string delay;
+          lineBuffer >> delay;
                 
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("QueueSizeNode1", linkAttr);
-            }
+          string queueSizeNode1;
+          lineBuffer >> queueSizeNode1;
                 
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("QueueSizeNode2", linkAttr);
-            }
-            
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("X1", linkAttr);
-            }
-            
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("Y1", linkAttr);
-            }
-            
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("X2", linkAttr);
-            }
-            
-            lineBuffer >> linkAttr;
-            if ( !linkAttr.empty () )
-            {
-                link.SetAttribute ("Y2", linkAttr);
-            }
+          string queueSizeNode2;
+          lineBuffer >> queueSizeNode2;
 
+          if (dataRate.empty () ||
+              ospf.empty () ||
+              delay.empty () ||
+              queueSizeNode1.empty () ||
+              queueSizeNode2.empty ())
+            {
+              NS_LOG_ERROR ("File [" << GetFileName () << ":" << i+2 << " wrong format, skipping");
+              continue;
+            }
+            
+          link.SetAttribute ("DataRate", dataRate);
+          link.SetAttribute ("OSPF", ospf);
+          link.SetAttribute ("Delay", delay);
+          link.SetAttribute ("QueueSizeNode1", queueSizeNode1);
+          link.SetAttribute ("QueueSizeNode2", queueSizeNode2);
+                
             AddLink (link);
                 
             linksNumber++;
         }
     }
         
+  NS_ASSERT (nodesNumber == totnode && linksNumber == totlink);
+        
     NS_LOG_INFO ("Annotated topology created with " << nodesNumber << " nodes and " << linksNumber << " links");
     topgen.close ();
         
+  ApplySettings ();
+  AssignCoordinates ();
+  
     return nodes;
 }
     
 void
-AnnotatedTopologyReader::ApplySettings(NetDeviceContainer* ndc, NodeContainer* nc)
+AnnotatedTopologyReader::AssignIpv4Addresses (Ipv4Address base)
 {
-    InternetStackHelper stack;
-    Ipv4AddressHelper address;
-    address.SetBase ("10.1.0.0", "255.255.255.0");
+  Ipv4AddressHelper address (base, Ipv4Mask ("/24"));
     
-    Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
-    stack.SetRoutingHelper (ipv4RoutingHelper);
-    
-    
-    
-    //This loop passes all links and checks if ipv4 is installed on the node
-    // if not, it installs. 
-    // We can't use stack.Install(nc) because in nc there are duplicates and assertion fails
-    TopologyReader::ConstLinksIterator iter;
-    int j = 0;
-    for ( iter = this->LinksBegin (); iter != this->LinksEnd (); iter++, j++ )
+  BOOST_FOREACH (const Link &link, m_linksList)
     {
-        NodeContainer twoNodes = nc[j];
+      address.Assign (NetDeviceContainer (link.GetFromNetDevice (),
+                                          link.GetToNetDevice ()));
         
-        Ptr<Node> nd = twoNodes.Get(0);
-        if(nd==NULL)
-            NS_LOG_INFO("nd = null");
-        
-        Ptr<Node> nd2 = twoNodes.Get(1);
-        if(nd2==NULL)
-            NS_LOG_INFO("nd2 = null");
-        
-        Ptr<Ipv4> ipv4 = nd->GetObject<Ipv4>();
-        if(ipv4 == 0)
-        {
-            NS_LOG_INFO("ipv4 = null");
-            stack.Install(nd);
+      base = Ipv4Address (base.Get () + 256);
+      address.SetBase (base, Ipv4Mask ("/24"));
         }
         
-        Ptr<Ipv4> ipv42 = nd2->GetObject<Ipv4>();
-        if(ipv42 == 0)
-        {
-            NS_LOG_INFO("ipv42 = null");
-            stack.Install(nd2);
+  ApplyOspfMetric ();
         }
         
-        //NS_LOG_INFO("#netdevices = " << nd->GetNDevices());
-        //NS_LOG_INFO("#netdevices = " << nd2->GetNDevices());
-    }
-    
-    NS_LOG_INFO("ITER2");
-    uint32_t base = 0;
-    PointToPointHelper p2p;
-    TopologyReader::ConstLinksIterator iter2;
-    int i = 0;
-    for ( iter2 = this->LinksBegin (); iter2 != this->LinksEnd (); iter2++, i++ )
+void
+AnnotatedTopologyReader::ApplyOspfMetric ()
     {
-        p2p.SetDeviceAttribute("DataRate", StringValue(iter2->GetAttribute("DataRate")+"Kbps"));
-        NS_LOG_INFO("DataRate = " + iter2->GetAttribute("DataRate")+"Kbps");
-        p2p.SetChannelAttribute("Delay", StringValue(iter2->GetAttribute("Delay")+"ms"));
-        NS_LOG_INFO("Delay = " + iter2->GetAttribute("Delay")+"ms");
-        p2p.SetQueue("ns3::DropTailQueue","MaxPackets",StringValue("100"));
-        ndc[i] = p2p.Install(nc[i]);
-        
-        Ipv4Address address1(base+i*256 + 1);
-        Ipv4Address address2(base+i*256 + 2);
-        
-        NodeContainer twoNodes = nc[i];
-            
-        Ptr<Node> nd = twoNodes.Get(0);
-        if(nd==NULL)
-            NS_LOG_INFO("nd = null");
-        
-        
-        
-        Ptr<Node> nd2 = twoNodes.Get(1);
-        if(nd2==NULL)
-            NS_LOG_INFO("nd2 = null");
-        
-        //NS_LOG_INFO("1");
-        NS_LOG_INFO("#netdevices = " << nd->GetNDevices());
-        NS_LOG_INFO("#netdevices = " << nd2->GetNDevices());
-            
-        Ptr<NetDevice> device = nd->GetDevice(nd->GetNDevices()-1)->GetObject<PointToPointNetDevice> ();
-        
-        if(device==NULL)
-            NS_LOG_INFO("device = 0");
-        
-        std::string ospf = iter2->GetAttribute("OSPF");
-        uint16_t metric = atoi(ospf.c_str());
-        NS_LOG_INFO("OSPF metric = " << metric);
+  BOOST_FOREACH (const Link &link, m_linksList)
+        {
+      uint16_t metric = boost::lexical_cast<uint16_t> (link.GetAttribute ("OSPF"));
         
         {
-        NetDeviceContainer* temp = new NetDeviceContainer[1];
-        temp->Add(device);
-        address.Assign (*temp);
+        Ptr<Ipv4> ipv4 = link.GetFromNode ()->GetObject<Ipv4> ();
+        NS_ASSERT (ipv4 != 0);
+        
+        int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetFromNetDevice ());
+        NS_ASSERT (interfaceId >= 0);
+        
+        ipv4->SetMetric (interfaceId,metric);
         }
         
-        Ptr<Ipv4> ipv4 = nd->GetObject<Ipv4>();
-        if(ipv4 == 0)
         {
-            NS_LOG_INFO("ipv4 = null");
-            //stack.Install(nd);
-            /*NetDeviceContainer* temp = new NetDeviceContainer[1];
-            temp->Add(device);
-            address.Assign (*temp);
-            ipv4 = nd->GetObject<Ipv4>();*/
-        }
+        Ptr<Ipv4> ipv4 = link.GetToNode ()->GetObject<Ipv4> ();
+        NS_ASSERT (ipv4 != 0);
         
-        NS_LOG_INFO("Before GetID");
-        int32_t interfaceId = ipv4->GetInterfaceForDevice(device);
-        NS_LOG_INFO("InterfaceID = " << interfaceId);
-        ipv4->SetMetric(interfaceId,metric);
-        
-        
-        
+        int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetToNetDevice ());
+        NS_ASSERT (interfaceId >= 0);
 
-        
-        /*Ptr<Ipv4> ipv4 = nd->GetObject<Ipv4>();
-        
-        if(ipv4 == 0)
-            NS_LOG_INFO("ipv4 = null");
-        int32_t interfaceId = ipv4->GetInterfaceForDevice(device);
-        ipv4->SetMetric(interfaceId,metric);*/
-        
-        //Ptr<Ipv4Interface> interface = nd->GetDevice(nd->GetNDevices()-1)->GetObject<Ipv4Interface> ();
-        //ipv4->SetMetric(metric);
-            
-        //NS_LOG_INFO("2");
-            
-        Ptr<NetDevice> device2 = nd2->GetDevice(nd2->GetNDevices()-1)->GetObject<PointToPointNetDevice> ();
-            
-        if(device2==NULL)
-            NS_LOG_INFO("device2 = 0");
-            
-        {
-            NetDeviceContainer* temp = new NetDeviceContainer[1];
-            temp->Add(device2);
-            address.Assign (*temp);
-        }
-        
-        Ptr<Ipv4> ipv42 = nd2->GetObject<Ipv4>();
-        if(ipv42 == 0)
-        {
-            NS_LOG_INFO("ipv42 = null");
-            /*stack.Install(nd2);
-            NetDeviceContainer* temp = new NetDeviceContainer[1];
-            temp->Add(device2);
-            address.Assign (*temp);
-            ipv42 = nd2->GetObject<Ipv4>();*/
-        }
-        
-        NS_LOG_INFO("Before GetID");
-        interfaceId = ipv42->GetInterfaceForDevice(device2);
-        NS_LOG_INFO("InterfaceID = " << interfaceId);
-        ipv42->SetMetric(interfaceId,metric);
-
-        
-        
-        PointerValue tmp1;
-        device->GetAttribute ("TxQueue", tmp1);
-        //NS_LOG_INFO("2.5");
-        Ptr<Object> txQueue1 = tmp1.GetObject ();
-            
-        PointerValue tmp2;
-        device2->GetAttribute ("TxQueue", tmp2);
-        Ptr<Object> txQueue2 = tmp2.GetObject ();
-        //NS_LOG_INFO("3");
-        Ptr<DropTailQueue> dtq1 = txQueue1->GetObject <DropTailQueue> ();
-        NS_ASSERT (dtq1 != 0);
-            
-        Ptr<DropTailQueue> dtq2 = txQueue2->GetObject <DropTailQueue> ();
-        NS_ASSERT (dtq2 != 0);
-            
-        std::string queuesize1 = iter2->GetAttribute("QueueSizeNode1");
-        std::string queuesize2 = iter2->GetAttribute("QueueSizeNode2");
-        //NS_LOG_INFO("4");
-        txQueue1->SetAttribute("MaxPackets", UintegerValue (atoi(queuesize1.c_str())));
-        txQueue2->SetAttribute("MaxPackets", UintegerValue (atoi(queuesize2.c_str())));
-            
-        UintegerValue limit;
-        txQueue1->GetAttribute ("MaxPackets", limit);
-        NS_LOG_INFO ("NetDevice #"<< device->GetIfIndex() << "has queue limit " << limit.Get () << " packets");
-            
-        txQueue2->GetAttribute ("MaxPackets", limit);
-        NS_LOG_INFO ("NetDevice #"<< device2->GetIfIndex() << "has queue limit " << limit.Get () << " packets");
+        ipv4->SetMetric (interfaceId,metric);
     }
 }
+}
 
-    /*
 void
-AnnotatedTopologyReader::ApplyOspfMetric(NetDeviceContainer* ndc, NodeContainer* nc)
+AnnotatedTopologyReader::ApplySettings ()
 {
-    InternetStackHelper stack;
-    Ipv4AddressHelper address;
-    address.SetBase ("10.0.0.0", "255.255.255.252");
+  PointToPointHelper p2p;
     
-    Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingOrderedNexthops");
-    stack.SetRoutingHelper (ipv4RoutingHelper);
+  // temporary queue, will be changed later
+  p2p.SetQueue ("ns3::DropTailQueue",
+                "MaxPackets", StringValue("100"));
 
-    
-    TopologyReader::ConstLinksIterator iter2;
-    int i = 0;
-    for ( iter2 = this->LinksBegin (); iter2 != this->LinksEnd (); iter2++, i++ )
+  BOOST_FOREACH (Link &link, m_linksList)
     {
-        NodeContainer twoNodes = nc[i];
-        Ptr<NetDevice> device = ndc[i].Get(0);
-        Ptr<NetDevice> device2 = ndc[i].Get(1);
+      NS_LOG_INFO ("DataRate = " + link.GetAttribute("DataRate")+"Kbps");
+      p2p.SetDeviceAttribute ("DataRate", StringValue(link.GetAttribute("DataRate")+"Kbps"));
         
-        //Ptr<Node> nd = twoNodes.Get(0);
-        Ptr<Node> nd = device->GetNode();
-        if(nd==NULL)
-            NS_LOG_INFO("nd = null");
+      NS_LOG_INFO ("Delay = " + link.GetAttribute("Delay")+"ms");
+      p2p.SetChannelAttribute ("Delay", StringValue(link.GetAttribute("Delay")+"ms"));
         
-        //Ptr<Node> nd2 = twoNodes.Get(1);
-        Ptr<Node> nd2 = device->GetNode();
-        if(nd2==NULL)
-            NS_LOG_INFO("nd2 = null");
+      NetDeviceContainer nd = p2p.Install(link.GetFromNode (), link.GetToNode ());
+      link.SetNetDevices (nd.Get (0), nd.Get (1));
 
+      NS_LOG_INFO ("Queue: " << link.GetAttribute("QueueSizeNode1") << " <==> " << link.GetAttribute("QueueSizeNode2"));
         
+      PointerValue txQueueFrom;
+      link.GetFromNetDevice ()->GetAttribute ("TxQueue", txQueueFrom);
+      NS_ASSERT (txQueueFrom.Get<DropTailQueue> () != 0);
         
-        std::string ospf = iter2->GetAttribute("OSPF");
-        uint16_t metric = atoi(ospf.c_str());
-        NS_LOG_INFO("OSPF metric = " << metric);
+      PointerValue txQueueTo;
+      link.GetToNetDevice ()->GetAttribute ("TxQueue", txQueueTo);
+      NS_ASSERT (txQueueTo.Get<DropTailQueue> () != 0);
         
-        Ptr<Ipv4> ipv4 = nd->GetObject<Ipv4>();
-        
-        if(ipv4 == 0)
-        {
-            NS_LOG_INFO("ipv4 = null");
-            stack.Install(nd);
-            NetDeviceContainer* temp = new NetDeviceContainer[1];
-            temp->Add(device);
-            address.Assign (*temp);
-            ipv4 = nd->GetObject<Ipv4>();
+      txQueueFrom.Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode1")));
+      txQueueTo.  Get<DropTailQueue> ()->SetAttribute ("MaxPackets", StringValue (link.GetAttribute("QueueSizeNode2")));
         }
-        
-        NS_LOG_INFO("Before GetID");
-        int32_t interfaceId = ipv4->GetInterfaceForDevice(device);
-        NS_LOG_INFO("InterfaceID = " << interfaceId);
-        ipv4->SetMetric(interfaceId,metric);
-        
-        
-        
-        Ptr<Ipv4> ipv42 = nd2->GetObject<Ipv4>();
-        if(ipv42 == 0)
-        {
-            NS_LOG_INFO("ipv42 = null");
-            stack.Install(nd2);
-            NetDeviceContainer* temp = new NetDeviceContainer[1];
-            temp->Add(device2);
-            address.Assign (*temp);
-            ipv42 = nd2->GetObject<Ipv4>();
         }
 
-        //if(ipv4 == 0)
-        //    NS_LOG_INFO("ipv4 = null");
-        
-        NS_LOG_INFO("Before GetID");
-        interfaceId = ipv42->GetInterfaceForDevice(device2);
-        if(interfaceId == -1)
-        {
-            NS_LOG_INFO("interfaceID = -1");
-            stack.Install(nd2);
-            NetDeviceContainer* temp = new NetDeviceContainer[1];
-            temp->Add(device2);
-            address.Assign (*temp);
-            ipv42 = nd2->GetObject<Ipv4>();
-            interfaceId = ipv42->GetInterfaceForDevice(device2);
-        }
-        NS_LOG_INFO("InterfaceID = " << interfaceId);
-        ipv42->SetMetric(interfaceId,metric);
-
-    }
-}*/
-
 void
-AnnotatedTopologyReader::BoundingBox (NodeContainer* nc, double ulx, double uly, double lrx, double lry)
+AnnotatedTopologyReader::AssignCoordinates ()
 {
-    
-    UniformVariable randX(ulx, lrx);
+  UniformVariable randX (m_ulx, m_lrx);
     double x = 0.0;
-    UniformVariable randY(uly, lry);
+  UniformVariable randY (m_uly, m_lry);
     double y = 0.0;
 
-
-    PointToPointHelper p2p;
-    TopologyReader::ConstLinksIterator iter2;
-    int i = 0;
-    for ( iter2 = this->LinksBegin (); iter2 != this->LinksEnd (); iter2++, i++ )
+  BOOST_FOREACH (Link &link, m_linksList)
     {
-        std::string x1str = iter2->GetAttribute("X1");
-        uint16_t x1 = atoi(x1str.c_str());
+      Ptr<ConstantPositionMobilityModel> loc = link.GetFromNode ()->GetObject<ConstantPositionMobilityModel> ();
+      if (loc != 0)
+        continue; // no need to assign twice
         
-        std::string x2str = iter2->GetAttribute("X2");
-        uint16_t x2 = atoi(x2str.c_str());
-        
-        
-        std::string y1str = iter2->GetAttribute("Y1");
-        uint16_t y1 = atoi(y1str.c_str());
-        
-        std::string y2str = iter2->GetAttribute("Y2");
-        uint16_t y2 = atoi(y2str.c_str());
-        
-        NodeContainer twoNodes = nc[i];
-        
-        Ptr<Node> nd = twoNodes.Get(0);
-        if(nd==NULL)
-            NS_LOG_INFO("nd = null");
-        
-        Ptr<Node> nd2 = twoNodes.Get(1);
-        if(nd2==NULL)
-            NS_LOG_INFO("nd2 = null");
-        
-        Ptr<ConstantPositionMobilityModel> loc = nd->GetObject<ConstantPositionMobilityModel> ();
-        if (loc ==0)
-        {
             loc = CreateObject<ConstantPositionMobilityModel> ();
-            nd->AggregateObject (loc);
-        }
+      link.GetFromNode ()->AggregateObject (loc);
         
-        x = -x1; //randX.GetValue();
-        y = -y1; //randY.GetValue();
+      x = randX.GetValue();
+      y = randY.GetValue();
         NS_LOG_INFO("X = "<<x <<"Y = "<<y);
-        Vector locVec (x, y, 0);
-        loc->SetPosition (locVec);
         
-        
-        Ptr<ConstantPositionMobilityModel> loc2 = nd2->GetObject<ConstantPositionMobilityModel> ();
-        if (loc2 ==0)
-        {
-            loc2 = CreateObject<ConstantPositionMobilityModel> ();
-            nd2->AggregateObject (loc2);
+      loc->SetPosition (Vector (x, y, 0));
         }
-        
-        x = -x2; //randX.GetValue();
-        y = -y2; //randY.GetValue();
-        NS_LOG_INFO("X = "<<x <<"Y = "<<y);
-        Vector locVec2 (x, y, 0);
-        loc2->SetPosition (locVec2);
     }
-}
-}
 
+}
diff --git a/model/annotated-topology-reader.h b/model/annotated-topology-reader.h
index 174330a..6346b6a 100644
--- a/model/annotated-topology-reader.h
+++ b/model/annotated-topology-reader.h
@@ -22,30 +22,6 @@
 #define __ANNOTATED_TOPOLOGY_READER_H__
 
 #include "ns3/topology-reader.h"
-#include "ns3/nstime.h"
-#include "ns3/log.h"
-#include "ns3/net-device-container.h"
-#include "ns3/point-to-point-helper.h"
-#include "ns3/point-to-point-net-device.h"
-#include "ns3/internet-stack-helper.h"
-#include "ns3/ipv4-address-helper.h"
-#include "ns3/ipv4-global-routing-helper.h"
-#include "ns3/drop-tail-queue.h"
-#include "ns3/ipv4-interface.h"
-#include "ns3/ipv4.h"
-#include "ns3/string.h"
-#include "ns3/pointer.h"
-#include "ns3/uinteger.h"
-#include "ns3/ipv4-address.h"
-#include <string>
-#include <fstream>
-#include <cstdlib>
-#include <iostream>
-#include <sstream>
-
-#include "ns3/animation-interface.h"
-#include "ns3/constant-position-mobility-model.h"
-#include "ns3/random-variable.h"
 
 namespace ns3 
 {
@@ -63,10 +39,16 @@
     typedef std::list< Link >::iterator LinksIterator;
     static TypeId GetTypeId (void);
         
-    AnnotatedTopologyReader ();
+  /**
+   * \brief Constructor
+   *
+   * \param path ns3::Names path
+   *
+   * \see ns3::Names class
+   */
+  AnnotatedTopologyReader (const std::string &path="");
     virtual ~AnnotatedTopologyReader ();
         
-        
     /**
     * \brief Main annotated topology reading function.
     *
@@ -74,21 +56,46 @@
     *
     * \return the container of the nodes created (or empty container if there was an error)
     */
-    virtual NodeContainer Read (void);
+  virtual
+  NodeContainer Read (void);
     
     /**
+   * \brief Set bounding box for the nodes
+   */
+  void
+  SetBoundingBox (double ulx, double uly, double lrx, double lry);
+
+  /**
+   * \brief Assign IPv4 addresses to all links
+   *
+   * Note, IPv4 stack should be installed on all nodes prior this call
+   *
+   * Every link will receive /24 netmask
+   *
+   * \param base Starting IPv4 address (second link will have base+256)
+   */
+  void
+  AssignIpv4Addresses (Ipv4Address base);
+  
+private:
+  /**
      * \brief This method applies setting to corresponding nodes and links
      * NetDeviceContainer must be allocated
      * NodeContainer from Read method
      */
-    void ApplySettings(NetDeviceContainer *ndc, NodeContainer* nc);
+  void ApplySettings ();
+  void AssignCoordinates ();
+  void ApplyOspfMetric ();
     
-    //void ApplyOspfMetric(NetDeviceContainer* ndc, NodeContainer* nc);
-    void BoundingBox (NodeContainer* nc, double ulx, double uly, double lrx, double lry);
-        
 private:
     AnnotatedTopologyReader (const AnnotatedTopologyReader&);
     AnnotatedTopologyReader& operator= (const AnnotatedTopologyReader&);
+
+  std::string m_path;
+  double m_ulx;
+  double m_uly;
+  double m_lrx;
+  double m_lry;
 };
 }
 
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index 0df2ded..89e5231 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -182,7 +182,7 @@
 {
   const CcnxNameComponents &name = interest.GetName ();
   for (size_t componentsCount = name.GetComponents ().size ();
-       componentsCount > 0;
+       componentsCount >= 0;
        componentsCount--)
     {
       CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index 17dc335..49031c7 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -176,7 +176,7 @@
   face->RegisterProtocolHandler (MakeNullCallback<void,const Ptr<CcnxFace>&,const Ptr<const Packet>&> ());
 
   // just to be on a safe side. Do the process in two steps
-  std::list<CcnxPitEntryContainer::type::iterator> entriesToRemoves; 
+  std::list<boost::reference_wrapper<const CcnxPitEntry> > entriesToRemoves;
   BOOST_FOREACH (const CcnxPitEntry &pitEntry, *m_pit)
     {
       m_pit->modify (m_pit->iterator_to (pitEntry),
@@ -187,12 +187,12 @@
       if (pitEntry.m_fibEntry.m_faces.size () == 1 &&
           pitEntry.m_fibEntry.m_faces.begin ()->m_face == face)
         {
-          entriesToRemoves.push_back (m_pit->iterator_to (pitEntry));
+          entriesToRemoves.push_back (boost::cref (pitEntry));
         }
     }
-  BOOST_FOREACH (CcnxPitEntryContainer::type::iterator entry, entriesToRemoves)
+  BOOST_FOREACH (const CcnxPitEntry &removedEntry, entriesToRemoves)
     {
-      m_pit->erase (entry);
+      m_pit->erase (m_pit->iterator_to (removedEntry));
     }
 
   CcnxFaceList::iterator face_it = find (m_faces.begin(), m_faces.end(), face);
diff --git a/model/ccnx-name-components.cc b/model/ccnx-name-components.cc
index b551733..a7066de 100644
--- a/model/ccnx-name-components.cc
+++ b/model/ccnx-name-components.cc
@@ -58,7 +58,7 @@
 std::list<boost::reference_wrapper<const std::string> >
 CcnxNameComponents::GetSubComponents (size_t num) const
 {
-  NS_ASSERT_MSG (1<=num && num<=m_prefix.size (), "Invalid number of subcomponents requested");
+  NS_ASSERT_MSG (0<=num && num<=m_prefix.size (), "Invalid number of subcomponents requested");
   
   std::list<boost::reference_wrapper<const std::string> > subComponents;
   std::list<std::string>::const_iterator component = m_prefix.begin();