Moving around path weight tagging. Now CcnxFace owns metric field, which is used for tagging.

Correcting bugs in blackhole-sprint scenario.  This time it should be
the right one:
- instead of a hijacker app, all faces on hijacked node are turned down
- there was a trick with RTT estimation (when batch, it is necessary to
  reset history upon a new batch)
- instead of random runs, trying all possible combinations of
  producer/hijacker
diff --git a/apps/ccnx-consumer-batches.cc b/apps/ccnx-consumer-batches.cc
index deb4a0d..da95d48 100644
--- a/apps/ccnx-consumer-batches.cc
+++ b/apps/ccnx-consumer-batches.cc
@@ -72,6 +72,7 @@
 {
   // std::cout << Simulator::Now () << " adding batch of " << amount << "\n";
   m_seqMax += amount;
+  m_rtt->ClearSent (); // this is important, otherwise RTT estimation for the new batch will be affected by previous batch history
   ScheduleNextPacket ();
 }
 
diff --git a/apps/ccnx-consumer.cc b/apps/ccnx-consumer.cc
index 9fe2f64..0f3ed01 100644
--- a/apps/ccnx-consumer.cc
+++ b/apps/ccnx-consumer.cc
@@ -284,8 +284,8 @@
   if (tag != 0)
     {
       // Notify trace about path weights vector (e.g., for path-stretch calculation)
-      m_pathWeightsTrace (GetNode (), tag->GetDestinationNode (), seq, tag->GetTotalWeight ()); 
-      // std::cout << boost::cref(*tag) << "\n";
+      m_pathWeightsTrace (GetNode (), tag->GetSourceNode (), seq, tag->GetTotalWeight ()); 
+      // std::cout << Simulator::Now () << "\t" << boost::cref(*tag) << "\n";
     }
 }
 
@@ -316,8 +316,9 @@
 void
 CcnxConsumer::OnTimeout (uint32_t sequenceNumber)
 {
-  std::cout << Simulator::Now () << ", TO: " << sequenceNumber << ", current RTO: " << m_rtt->RetransmitTimeout ().ToDouble (Time::S) << "s\n";
+  // std::cout << Simulator::Now () << ", TO: " << sequenceNumber << ", current RTO: " << m_rtt->RetransmitTimeout ().ToDouble (Time::S) << "s\n";
 
+  m_rtt->SentSeq (SequenceNumber32 (sequenceNumber), 1); // make sure to disable RTT calculation for this sample
   m_retxSeqs.insert (sequenceNumber);
   ScheduleNextPacket (); 
 }
diff --git a/apps/ccnx-producer.cc b/apps/ccnx-producer.cc
index 291fb82..1148767 100644
--- a/apps/ccnx-producer.cc
+++ b/apps/ccnx-producer.cc
@@ -23,7 +23,7 @@
 #include "ns3/log.h"
 #include "ns3/ccnx-interest-header.h"
 #include "ns3/ccnx-content-object-header.h"
-#include "ns3/ccnx-path-stretch-tag.h"
+// #include "ns3/ccnx-path-stretch-tag.h"
 #include "ns3/string.h"
 #include "ns3/uinteger.h"
 #include "ns3/packet.h"
@@ -114,18 +114,18 @@
   NS_LOG_INFO ("Respodning with ContentObject:\n" << boost::cref(*header));
   
   Ptr<Packet> packet = Create<Packet> (m_virtualPayloadSize);
-  Ptr<const WeightsPathStretchTag> tag = origPacket->RemovePacketTag<WeightsPathStretchTag> ();
-  if (tag != 0)
-    {
-      // std::cout << Simulator::Now () << ", " << m_app->GetInstanceTypeId ().GetName () << "\n";
+  // Ptr<const WeightsPathStretchTag> tag = origPacket->RemovePacketTag<WeightsPathStretchTag> ();
+  // if (tag != 0)
+  //   {
+  //     // std::cout << Simulator::Now () << ", " << m_app->GetInstanceTypeId ().GetName () << "\n";
 
-      // echo back WeightsPathStretchTag
-      packet->AddPacketTag (CreateObject<WeightsPathStretchTag> (*tag));
+  //     // echo back WeightsPathStretchTag
+  //     packet->AddPacketTag (CreateObject<WeightsPathStretchTag> (*tag));
 
-      // \todo
-      // packet->AddPacketTag should actually accept Ptr<const WeightsPathStretchTag> instead of
-      // Ptr<WeightsPathStretchTag>.  Echoing will be simplified after change is done
-    }
+  //     // \todo
+  //     // packet->AddPacketTag should actually accept Ptr<const WeightsPathStretchTag> instead of
+  //     // Ptr<WeightsPathStretchTag>.  Echoing will be simplified after change is done
+  //   }
   
   m_transmittedContentObjects (header, packet, this, m_face);
   
diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
index b208b55..1a84764 100644
--- a/bindings/modulegen__gcc_ILP32.py
+++ b/bindings/modulegen__gcc_ILP32.py
@@ -1354,10 +1354,6 @@
     cls.add_method('TcpConnect', 
                    'void', 
                    [param('ns3::Ptr< ns3::Node >', 'node')])
-    ## ccnx-trace-helper.h (module 'NDNabstraction'): void ns3::CcnxTraceHelper::WeightsConnect(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::Application> AppId) [member function]
-    cls.add_method('WeightsConnect', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::Application >', 'AppId')])
     return
 
 def register_Ns3CcnxUnknownHeaderException_methods(root_module, cls):
@@ -4104,6 +4100,10 @@
     cls.add_method('SetMobilityModel', 
                    'void', 
                    [param('std::string const &', 'model')])
+    ## annotated-topology-reader.h (module 'NDNabstraction'): void ns3::AnnotatedTopologyReader::ApplyOspfMetric() [member function]
+    cls.add_method('ApplyOspfMetric', 
+                   'void', 
+                   [])
     ## annotated-topology-reader.h (module 'NDNabstraction'): ns3::Ptr<ns3::Node> ns3::AnnotatedTopologyReader::CreateNode(std::string const name) [member function]
     cls.add_method('CreateNode', 
                    'ns3::Ptr< ns3::Node >', 
@@ -4119,11 +4119,6 @@
                    'void', 
                    [], 
                    visibility='protected')
-    ## annotated-topology-reader.h (module 'NDNabstraction'): void ns3::AnnotatedTopologyReader::ApplyOspfMetric() [member function]
-    cls.add_method('ApplyOspfMetric', 
-                   'void', 
-                   [], 
-                   visibility='protected')
     return
 
 def register_Ns3Application_methods(root_module, cls):
@@ -4600,6 +4595,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True)
+    ## ccnx-face.h (module 'NDNabstraction'): uint16_t ns3::CcnxFace::GetMetric() const [member function]
+    cls.add_method('GetMetric', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## ccnx-face.h (module 'NDNabstraction'): ns3::Ptr<ns3::Node> ns3::CcnxFace::GetNode() const [member function]
     cls.add_method('GetNode', 
                    'ns3::Ptr< ns3::Node >', 
@@ -4653,6 +4653,11 @@
     cls.add_method('SetId', 
                    'void', 
                    [param('uint32_t', 'id')])
+    ## ccnx-face.h (module 'NDNabstraction'): void ns3::CcnxFace::SetMetric(uint16_t metric) [member function]
+    cls.add_method('SetMetric', 
+                   'void', 
+                   [param('uint16_t', 'metric')], 
+                   is_virtual=True)
     ## ccnx-face.h (module 'NDNabstraction'): void ns3::CcnxFace::SetUp(bool up=true) [member function]
     cls.add_method('SetUp', 
                    'void', 
@@ -5081,17 +5086,17 @@
 def register_Ns3CcnxPathWeightTracer_methods(root_module, cls):
     ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): ns3::CcnxPathWeightTracer::CcnxPathWeightTracer(ns3::CcnxPathWeightTracer const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::CcnxPathWeightTracer const &', 'arg0')])
-    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): ns3::CcnxPathWeightTracer::CcnxPathWeightTracer(std::ostream & os, ns3::Ptr<ns3::Node> node, std::string appId) [constructor]
-    cls.add_constructor([param('std::ostream &', 'os'), param('ns3::Ptr< ns3::Node >', 'node'), param('std::string', 'appId')])
+    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): ns3::CcnxPathWeightTracer::CcnxPathWeightTracer(std::ostream & os, ns3::Ptr<ns3::Node> node) [constructor]
+    cls.add_constructor([param('std::ostream &', 'os'), param('ns3::Ptr< ns3::Node >', 'node')])
     ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): void ns3::CcnxPathWeightTracer::Connect() [member function]
     cls.add_method('Connect', 
                    'void', 
                    [])
-    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): void ns3::CcnxPathWeightTracer::PrintHeader(std::ostream & os) const [member function]
+    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): static void ns3::CcnxPathWeightTracer::PrintHeader(std::ostream & os) [member function]
     cls.add_method('PrintHeader', 
                    'void', 
                    [param('std::ostream &', 'os')], 
-                   is_const=True, is_virtual=True)
+                   is_static=True)
     ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): void ns3::CcnxPathWeightTracer::InLocalFace(std::string context, ns3::Ptr<ns3::Node> src, ns3::Ptr<ns3::Node> dst, uint32_t seqno, uint32_t weight) [member function]
     cls.add_method('InLocalFace', 
                    'void', 
diff --git a/bindings/modulegen__gcc_LP64.py b/bindings/modulegen__gcc_LP64.py
index b208b55..1a84764 100644
--- a/bindings/modulegen__gcc_LP64.py
+++ b/bindings/modulegen__gcc_LP64.py
@@ -1354,10 +1354,6 @@
     cls.add_method('TcpConnect', 
                    'void', 
                    [param('ns3::Ptr< ns3::Node >', 'node')])
-    ## ccnx-trace-helper.h (module 'NDNabstraction'): void ns3::CcnxTraceHelper::WeightsConnect(ns3::Ptr<ns3::Node> node, ns3::Ptr<ns3::Application> AppId) [member function]
-    cls.add_method('WeightsConnect', 
-                   'void', 
-                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Ptr< ns3::Application >', 'AppId')])
     return
 
 def register_Ns3CcnxUnknownHeaderException_methods(root_module, cls):
@@ -4104,6 +4100,10 @@
     cls.add_method('SetMobilityModel', 
                    'void', 
                    [param('std::string const &', 'model')])
+    ## annotated-topology-reader.h (module 'NDNabstraction'): void ns3::AnnotatedTopologyReader::ApplyOspfMetric() [member function]
+    cls.add_method('ApplyOspfMetric', 
+                   'void', 
+                   [])
     ## annotated-topology-reader.h (module 'NDNabstraction'): ns3::Ptr<ns3::Node> ns3::AnnotatedTopologyReader::CreateNode(std::string const name) [member function]
     cls.add_method('CreateNode', 
                    'ns3::Ptr< ns3::Node >', 
@@ -4119,11 +4119,6 @@
                    'void', 
                    [], 
                    visibility='protected')
-    ## annotated-topology-reader.h (module 'NDNabstraction'): void ns3::AnnotatedTopologyReader::ApplyOspfMetric() [member function]
-    cls.add_method('ApplyOspfMetric', 
-                   'void', 
-                   [], 
-                   visibility='protected')
     return
 
 def register_Ns3Application_methods(root_module, cls):
@@ -4600,6 +4595,11 @@
                    'uint32_t', 
                    [], 
                    is_const=True)
+    ## ccnx-face.h (module 'NDNabstraction'): uint16_t ns3::CcnxFace::GetMetric() const [member function]
+    cls.add_method('GetMetric', 
+                   'uint16_t', 
+                   [], 
+                   is_const=True, is_virtual=True)
     ## ccnx-face.h (module 'NDNabstraction'): ns3::Ptr<ns3::Node> ns3::CcnxFace::GetNode() const [member function]
     cls.add_method('GetNode', 
                    'ns3::Ptr< ns3::Node >', 
@@ -4653,6 +4653,11 @@
     cls.add_method('SetId', 
                    'void', 
                    [param('uint32_t', 'id')])
+    ## ccnx-face.h (module 'NDNabstraction'): void ns3::CcnxFace::SetMetric(uint16_t metric) [member function]
+    cls.add_method('SetMetric', 
+                   'void', 
+                   [param('uint16_t', 'metric')], 
+                   is_virtual=True)
     ## ccnx-face.h (module 'NDNabstraction'): void ns3::CcnxFace::SetUp(bool up=true) [member function]
     cls.add_method('SetUp', 
                    'void', 
@@ -5081,17 +5086,17 @@
 def register_Ns3CcnxPathWeightTracer_methods(root_module, cls):
     ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): ns3::CcnxPathWeightTracer::CcnxPathWeightTracer(ns3::CcnxPathWeightTracer const & arg0) [copy constructor]
     cls.add_constructor([param('ns3::CcnxPathWeightTracer const &', 'arg0')])
-    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): ns3::CcnxPathWeightTracer::CcnxPathWeightTracer(std::ostream & os, ns3::Ptr<ns3::Node> node, std::string appId) [constructor]
-    cls.add_constructor([param('std::ostream &', 'os'), param('ns3::Ptr< ns3::Node >', 'node'), param('std::string', 'appId')])
+    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): ns3::CcnxPathWeightTracer::CcnxPathWeightTracer(std::ostream & os, ns3::Ptr<ns3::Node> node) [constructor]
+    cls.add_constructor([param('std::ostream &', 'os'), param('ns3::Ptr< ns3::Node >', 'node')])
     ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): void ns3::CcnxPathWeightTracer::Connect() [member function]
     cls.add_method('Connect', 
                    'void', 
                    [])
-    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): void ns3::CcnxPathWeightTracer::PrintHeader(std::ostream & os) const [member function]
+    ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): static void ns3::CcnxPathWeightTracer::PrintHeader(std::ostream & os) [member function]
     cls.add_method('PrintHeader', 
                    'void', 
                    [param('std::ostream &', 'os')], 
-                   is_const=True, is_virtual=True)
+                   is_static=True)
     ## ccnx-path-weight-tracer.h (module 'NDNabstraction'): void ns3::CcnxPathWeightTracer::InLocalFace(std::string context, ns3::Ptr<ns3::Node> src, ns3::Ptr<ns3::Node> dst, uint32_t seqno, uint32_t weight) [member function]
     cls.add_method('InLocalFace', 
                    'void', 
diff --git a/examples/base-experiment.h b/examples/base-experiment.h
index fd8c1f0..c77760d 100644
--- a/examples/base-experiment.h
+++ b/examples/base-experiment.h
@@ -87,6 +87,8 @@
         // // Populate FIB based on IPv4 global routing controller
         ccnxHelper.InstallRoutesToAll ();
       }
+    
+    reader->ApplyOspfMetric ();
   }
   
   void InstallIpStack ()
@@ -94,6 +96,7 @@
     InternetStackHelper stack;
     stack.Install (reader->GetNodes ());
     reader->AssignIpv4Addresses (Ipv4Address ("10.0.0.0"));
+    reader->ApplyOspfMetric ();
 
     Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
   }
@@ -132,6 +135,29 @@
   }
 
   void
+  SetPair (uint32_t pairId)
+  {
+    m_pairs.clear ();
+    m_usedNodes.clear ();
+
+    uint32_t i = 0;
+    for (uint32_t node1_num = 0; node1_num < 52; node1_num++)
+      for (uint32_t node2_num = 0; node2_num < 52; node2_num++)
+        {
+          if (node1_num == node2_num) continue;
+
+          // std::cout << "i = " << i << ", pairId = " << pairId << "\n";
+          if (i++ != pairId) continue;
+          
+          m_usedNodes.insert (node1_num);
+          m_usedNodes.insert (node2_num);
+
+          m_pairs.push_back (make_tuple (node1_num, node2_num));
+          return;
+        }
+  }
+
+  void
   Run (const Time &finishTime)
   {
     cout << "Run Simulation.\n";
diff --git a/examples/blackhole-sprint.cc b/examples/blackhole-sprint.cc
index 3901d70..d4884d5 100644
--- a/examples/blackhole-sprint.cc
+++ b/examples/blackhole-sprint.cc
@@ -240,6 +240,19 @@
     return d[destinationNode];
   }
 
+  // hijacker is more than an application. just disable all faces
+  static void
+  InstallHijacker (std::string prefix, Ptr<Node> node)
+  {
+    Ptr<Ccnx> ccnx = node->GetObject<Ccnx> ();
+    for (uint32_t i = 0; i < ccnx->GetNFaces (); i++)
+      {
+        Ptr<CcnxFace> face = ccnx->GetFace (i);
+        face->SetUp (false);
+      }
+    CcnxStackHelper::InstallRouteTo (prefix, node);
+  }
+
   //We are creating 10 pairs of producer-hijacker and everybody else is a consumer
   ApplicationContainer
   AddApplications ()
@@ -271,23 +284,12 @@
         apps.Add
           (legitimateProducerHelper.Install (node1));
         
-        CcnxAppHelper fakeProducerHelper ("ns3::CcnxHijacker");
-        fakeProducerHelper.SetPrefix (prefix);
-        ApplicationContainer hijacker = fakeProducerHelper.Install (node2);
-        apps.Add (hijacker);
-        hijacker.Start (Seconds(1.0));
-        
         // one more trick. Need to install route to hijacker (aka "hijacker announces itself as a legitimate producer")
         CcnxStackHelper::InstallRouteTo (prefix, node1);
-        Simulator::Schedule (Seconds(1.0), CcnxStackHelper::InstallRouteTo, prefix, node2);
-        // CcnxStackHelper::InstallRouteTo (prefix, node2);
+        Simulator::Schedule (Seconds(10.0), Experiment::InstallHijacker, 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 ();
@@ -299,7 +301,7 @@
 
         CcnxAppHelper consumerHelper ("ns3::CcnxConsumerBatches");
         consumerHelper.SetAttribute ("LifeTime", StringValue("100s"));
-        consumerHelper.SetAttribute ("Batches", StringValue("0s 10 0.5s 1 2s 1"));
+        consumerHelper.SetAttribute ("Batches", StringValue("0s 10 6s 1 20s 1"));
         BOOST_FOREACH (const string &prefix, prefixes)
           {
             consumerHelper.SetPrefix (prefix + "/" + lexical_cast<string> (namedId)); // make sure we're requesting unique prefixes... this was a huge bug before                 
@@ -344,7 +346,8 @@
       cout << "seed = " << SeedManager::GetSeed () << ", run = " << SeedManager::GetRun () << endl;
 
       Experiment experiment;
-      experiment.GenerateRandomPairs (1);
+      // experiment.GenerateRandomPairs (1);
+      experiment.SetPair (run);
       experiment.ComputeShortestWeightsPath(1,12);
       experiment.ComputeShortestDelayPath(1,12);
       cout << "Run " << run << endl;
@@ -360,12 +363,9 @@
       // traceHelper.EnableRateL3All (prefix + "rate-trace.log");
       traceHelper.EnableSeqsAppAll ("ns3::CcnxConsumerBatches", prefix + "consumers-seqs.log");
 
-      traceHelper.EnablePathWeights (prefix + "weights.log");
+      // enable path weights some time from now (ensure that all faces are created)
+      Simulator::Schedule (Seconds (4.5), &CcnxTraceHelper::EnablePathWeights, &traceHelper, prefix + "weights.log");
       std::cout << "Total " << apps.GetN () << " applications\n";
-      for (ApplicationContainer::Iterator i = apps.Begin (); i != apps.End (); i++)
-        {
-          Simulator::Schedule (Seconds (0.45), &CcnxTraceHelper::WeightsConnect, &traceHelper, (*i)->GetNode (), *i);
-        }
 
       experiment.Run (Seconds(40.0));
     }
diff --git a/helper/ccnx-trace-helper.cc b/helper/ccnx-trace-helper.cc
index f5df0cb..0e958fa 100644
--- a/helper/ccnx-trace-helper.cc
+++ b/helper/ccnx-trace-helper.cc
@@ -372,23 +372,15 @@
 
   CcnxPathWeightTracer::PrintHeader (*m_pathWeightsTrace);
   *m_pathWeightsTrace << "\n";
-}
 
-void
-CcnxTraceHelper::WeightsConnect (Ptr<Node> node, Ptr<Application> app)
-{
-  // small hack to find out app index
-  uint32_t appId = 0;
-  for (uint32_t appId = 0; appId < node->GetNApplications (); appId++)
+  for (NodeList::Iterator node = NodeList::Begin ();
+       node != NodeList::End ();
+       node++)
     {
-      if (app == node->GetApplication (appId)) break;
+      Ptr<CcnxPathWeightTracer> trace = Create<CcnxPathWeightTracer> (boost::ref(*m_pathWeightsTrace),
+                                                                      *node);
+      m_pathWeights.push_back (trace);
     }
-  NS_ASSERT (appId != node->GetNApplications ());
-
-  Ptr<CcnxPathWeightTracer> trace = Create<CcnxPathWeightTracer> (boost::ref(*m_pathWeightsTrace),
-                                                                  node,
-                                                                  lexical_cast<string> (appId));
-  m_pathWeights.push_back (trace);
 }
 
 } // namespace ns3
diff --git a/helper/ccnx-trace-helper.h b/helper/ccnx-trace-helper.h
index 37565f5..59f0a53 100644
--- a/helper/ccnx-trace-helper.h
+++ b/helper/ccnx-trace-helper.h
@@ -123,13 +123,6 @@
   void
   EnablePathWeights (const std::string &pathWeights);
 
-  /**
-   * @brief Should be called with node pointer after TCP application
-   *
-   * Workaround because NS-3 needs object to exist before connecting trace
-   */
-  void WeightsConnect (Ptr<Node> node, Ptr<Application> AppId);
-
 private:
   std::string m_appTrace;
   std::list<Ptr<CcnxAppTracer> > m_apps;
diff --git a/helper/tracers/ccnx-path-weight-tracer.cc b/helper/tracers/ccnx-path-weight-tracer.cc
index 4d6aa7d..b2685bd 100644
--- a/helper/tracers/ccnx-path-weight-tracer.cc
+++ b/helper/tracers/ccnx-path-weight-tracer.cc
@@ -36,10 +36,9 @@
 
 namespace ns3 {
     
-CcnxPathWeightTracer::CcnxPathWeightTracer (std::ostream &os, Ptr<Node> node, std::string appId)
+CcnxPathWeightTracer::CcnxPathWeightTracer (std::ostream &os, Ptr<Node> node)
   : m_os (os)
   , m_nodePtr (node)
-  , m_appId (appId)
 {
   m_node = boost::lexical_cast<string> (m_nodePtr->GetId ());
 
@@ -55,16 +54,13 @@
 void
 CcnxPathWeightTracer::Connect ()
 {
-  Config::Set ("/NodeList/"+m_node+"/$ns3::CcnxL3Protocol/ForwardingStrategy/MetricTagging",
+  Config::Set ("/NodeList/"+m_node+"/$ns3::CcnxL3Protocol/FaceList/*/MetricTagging",
                BooleanValue (true));
 
-  Config::Connect ("/NodeList/"+m_node+"/ApplicationList/"+m_appId+"/PathWeightsTrace",
+  Config::Connect ("/NodeList/"+m_node+"/ApplicationList/*/PathWeightsTrace",
                    MakeCallback (&CcnxPathWeightTracer::InLocalFace, this));
-  // Config::Connect ("/NodeList/"+m_node+"/$ns3::CcnxL3Protocol/FaceList/*/$ns3::CcnxLocalFace/PathWeightsTrace",
-  //                  MakeCallback (&CcnxPathWeightTracer::InLocalFace, this));
 }
 
-
 void
 CcnxPathWeightTracer::PrintHeader (std::ostream &os)
 {
diff --git a/helper/tracers/ccnx-path-weight-tracer.h b/helper/tracers/ccnx-path-weight-tracer.h
index 868e61f..f4bd187 100644
--- a/helper/tracers/ccnx-path-weight-tracer.h
+++ b/helper/tracers/ccnx-path-weight-tracer.h
@@ -35,7 +35,7 @@
 class CcnxPathWeightTracer : public SimpleRefCount<CcnxPathWeightTracer>
 {
 public:
-  CcnxPathWeightTracer (std::ostream &os, Ptr<Node> node, std::string appId);
+  CcnxPathWeightTracer (std::ostream &os, Ptr<Node> node);
   virtual ~CcnxPathWeightTracer () { };
 
   void
@@ -55,7 +55,6 @@
   std::ostream &m_os;
   std::string m_node;
   Ptr<Node> m_nodePtr;
-  std::string m_appId;
 };
 
 } // namespace ns3
diff --git a/model/annotated-topology-reader.cc b/model/annotated-topology-reader.cc
index 345c2f5..a9b66bf 100644
--- a/model/annotated-topology-reader.cc
+++ b/model/annotated-topology-reader.cc
@@ -37,6 +37,8 @@
 #include "ns3/pointer.h"
 #include "ns3/uinteger.h"
 #include "ns3/ipv4-address.h"
+#include "ns3/ccnx.h"
+#include "ns3/ccnx-face.h"
 
 #include "ns3/constant-position-mobility-model.h"
 
@@ -219,8 +221,6 @@
       base = Ipv4Address (base.Get () + 256);
       address.SetBase (base, Ipv4Mask ("/24"));
     }
-        
-  ApplyOspfMetric ();
 }
         
 void
@@ -233,22 +233,42 @@
         
       {
         Ptr<Ipv4> ipv4 = link.GetFromNode ()->GetObject<Ipv4> ();
-        NS_ASSERT (ipv4 != 0);
+        if (ipv4 != 0)
+          {
+            int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetFromNetDevice ());
+            NS_ASSERT (interfaceId >= 0);
         
-        int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetFromNetDevice ());
-        NS_ASSERT (interfaceId >= 0);
-        
-        ipv4->SetMetric (interfaceId,metric);
+            ipv4->SetMetric (interfaceId,metric);
+          }
+
+        Ptr<Ccnx> ccnx = link.GetFromNode ()->GetObject<Ccnx> ();
+        if (ccnx != 0)
+          {
+            Ptr<CcnxFace> face = ccnx->GetFaceByNetDevice (link.GetFromNetDevice ());
+            NS_ASSERT (face != 0);
+            
+            face->SetMetric (metric);
+          }
       }
         
       {
         Ptr<Ipv4> ipv4 = link.GetToNode ()->GetObject<Ipv4> ();
-        NS_ASSERT (ipv4 != 0);
-        
-        int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetToNetDevice ());
-        NS_ASSERT (interfaceId >= 0);
+        if (ipv4 != 0)
+          {
+            int32_t interfaceId = ipv4->GetInterfaceForDevice (link.GetToNetDevice ());
+            NS_ASSERT (interfaceId >= 0);
 
-        ipv4->SetMetric (interfaceId,metric);
+            ipv4->SetMetric (interfaceId,metric);
+          }
+        
+        Ptr<Ccnx> ccnx = link.GetToNode ()->GetObject<Ccnx> ();
+        if (ccnx != 0)
+          {
+            Ptr<CcnxFace> face = ccnx->GetFaceByNetDevice (link.GetToNetDevice ());
+            NS_ASSERT (face != 0);
+            
+            face->SetMetric (metric);
+          }
       }
     }
 }
diff --git a/model/annotated-topology-reader.h b/model/annotated-topology-reader.h
index 6edcb34..91e6d26 100644
--- a/model/annotated-topology-reader.h
+++ b/model/annotated-topology-reader.h
@@ -80,12 +80,28 @@
   void
   AssignIpv4Addresses (Ipv4Address base);
 
+  /**
+   * \brief Set bounding box where nodes will be randomly places (if positions are unspecified)
+   * \param ulx Upper left x coordinate
+   * \param uly Upper left y coordinate
+   * \param lrx Lower right x coordinate
+   * \param lry Lower right y coordinate
+   */
   void
   SetBoundingBox (double ulx, double uly, double lrx, double lry);
 
+  /**
+   * \brief Set mobility model to be used on nodes
+   * \param model class name of the model
+   */
   void
   SetMobilityModel (const std::string &model);
 
+  /**
+   * \brief Apply OSPF metric on Ipv4 (if exists) and Ccnx (if exists) stacks
+   */
+  void ApplyOspfMetric ();
+
 protected:
   Ptr<Node>
   CreateNode (const std::string name);
@@ -100,7 +116,6 @@
    * NodeContainer from Read method
    */
   void ApplySettings ();
-  void ApplyOspfMetric ();
     
 protected:
   std::string m_path;
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index e8be345..2f3057f 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -103,7 +103,6 @@
                      ll::bind(&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
 
       Ptr<Packet> packetToSend = packet->Copy ();
-      TagPacket (packetToSend, metricFace);
 
       //transmission
       metricFace.m_face->Send (packetToSend);
diff --git a/model/ccnx-face.cc b/model/ccnx-face.cc
index b1f7b42..781bb72 100644
--- a/model/ccnx-face.cc
+++ b/model/ccnx-face.cc
@@ -27,8 +27,11 @@
 #include "ns3/assert.h"
 #include "ns3/uinteger.h"
 #include "ns3/double.h"
+#include "ns3/boolean.h"
 #include "ns3/simulator.h"
 
+#include "ccnx-path-stretch-tag.h"
+
 #include <boost/ref.hpp>
 
 NS_LOG_COMPONENT_DEFINE ("CcnxFace");
@@ -56,6 +59,10 @@
                    MakeDoubleAccessor (&CcnxFace::m_bucketLeak),
                    MakeDoubleChecker<double> ())
                    
+    .AddAttribute ("MetricTagging", "Enable metric tagging (path-stretch calculation)",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&CcnxFace::m_enableMetricTagging),
+                   MakeBooleanChecker ())
     ;
   return tid;
 }
@@ -74,6 +81,8 @@
   , m_ifup (false)
   , m_id ((uint32_t)-1)
   , m_lastLeakTime (0)
+  , m_metric (0)
+  , m_enableMetricTagging (false)
 {
   NS_LOG_FUNCTION (this);
 
@@ -145,6 +154,24 @@
   if (!IsUp ())
     return false;
 
+  if (m_enableMetricTagging)
+    {
+      // update path information
+      Ptr<const WeightsPathStretchTag> origTag = packet->RemovePacketTag<WeightsPathStretchTag> ();
+      Ptr<WeightsPathStretchTag> tag;
+      if (origTag == 0)
+        {
+          tag = CreateObject<WeightsPathStretchTag> (); // create a new tag
+        }
+      else
+        {
+          tag = CreateObject<WeightsPathStretchTag> (*origTag); // will update existing tag
+        }
+
+      tag->AddPathInfo (m_node, GetMetric ());
+      packet->AddPacketTag (tag);
+    }
+  
   SendImpl (packet);
   return true;
 }
@@ -198,19 +225,19 @@
   m_bucketLeak = leak;
 }
 
-// void
-// CcnxFace::SetMetric (uint16_t metric)
-// {
-//   NS_LOG_FUNCTION (metric);
-//   m_metric = metric;
-// }
+void
+CcnxFace::SetMetric (uint16_t metric)
+{
+  NS_LOG_FUNCTION (metric);
+  m_metric = metric;
+}
 
-// uint16_t
-// CcnxFace::GetMetric (void) const
-// {
-//   NS_LOG_FUNCTION_NOARGS ();
-//   return m_metric;
-// }
+uint16_t
+CcnxFace::GetMetric (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_metric;
+}
 
 /**
  * These are face states and may be distinct from 
diff --git a/model/ccnx-face.h b/model/ccnx-face.h
index 29ec371..e2100c6 100644
--- a/model/ccnx-face.h
+++ b/model/ccnx-face.h
@@ -111,19 +111,19 @@
   Receive (const Ptr<const Packet> &p);
   ////////////////////////////////////////////////////////////////////
 
-  // /**
-  //  * \Brief Assign routing/forwarding metric with face
-  //  *
-  //  * \param metric configured routing metric (cost) of this face
-  //  */
-  // virtual void SetMetric (uint16_t metric);
+  /**
+   * \Brief Assign routing/forwarding metric with face
+   *
+   * \param metric configured routing metric (cost) of this face
+   */
+  virtual void SetMetric (uint16_t metric);
 
-  // /**
-  //  * \brief Get routing/forwarding metric assigned to the face
-  //  *
-  //  * \returns configured routing/forwarding metric (cost) of this face
-  //  */
-  // virtual uint16_t GetMetric (void) const;
+  /**
+   * \brief Get routing/forwarding metric assigned to the face
+   *
+   * \returns configured routing/forwarding metric (cost) of this face
+   */
+  virtual uint16_t GetMetric (void) const;
 
   /**
    * These are face states and may be distinct from actual lower-layer
@@ -228,7 +228,10 @@
   ProtocolHandler m_protocolHandler; ///< Callback via which packets are getting send to CCNx stack
   bool m_ifup; ///< \brief flag indicating that the interface is UP 
   uint32_t m_id; ///< \brief id of the interface in CCNx stack (per-node uniqueness)
-  Time m_lastLeakTime; 
+  Time m_lastLeakTime;
+  uint32_t m_metric; ///< \brief metric of the face
+
+  bool m_enableMetricTagging; 
 };
 
 std::ostream& operator<< (std::ostream& os, const CcnxFace &face);
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 2a7f2ee..182381e 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -118,7 +118,6 @@
       //   }
 
       Ptr<Packet> packetToSend = packet->Copy ();
-      TagPacket (packetToSend, metricFace);
 
       //transmission
       metricFace.m_face->Send (packetToSend);
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 45e0fd7..a856577 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -25,14 +25,11 @@
 #include "ns3/ptr.h"
 #include "ns3/log.h"
 #include "ns3/simulator.h"
-#include "ns3/double.h"
-#include "ns3/boolean.h"
 
 #include "ccnx-pit.h"
 #include "ccnx-pit-entry.h"
 
 #include "ccnx-interest-header.h"
-#include "ccnx-path-stretch-tag.h"
 
 #include <boost/ref.hpp>
 #include <boost/foreach.hpp>
@@ -54,11 +51,6 @@
     .SetGroupName ("Ccnx")
     .SetParent<Object> ()
 
-    .AddAttribute ("MetricTagging", "Enable metric tagging (path-stretch calculation)",
-                   BooleanValue (false),
-                   MakeBooleanAccessor (&CcnxForwardingStrategy::m_enableMetricTagging),
-                   MakeBooleanChecker ())
-
     .AddTraceSource ("OutInterests", "Interests that were transmitted",
                     MakeTraceSourceAccessor (&CcnxForwardingStrategy::m_transmittedInterestsTrace))
 
@@ -67,7 +59,6 @@
 }
 
 CcnxForwardingStrategy::CcnxForwardingStrategy ()
-  : m_enableMetricTagging (false)
 {
 }
 
@@ -121,7 +112,6 @@
                      ll::bind (&CcnxPitEntry::AddOutgoing, ll::_1, metricFace.m_face));
 
       Ptr<Packet> packetToSend = packet->Copy ();
-      TagPacket (packetToSend, metricFace);
 
       //transmission
       metricFace.m_face->Send (packetToSend);
@@ -134,27 +124,4 @@
   return propagatedCount > 0;
 }
 
-void
-CcnxForwardingStrategy::TagPacket (Ptr<Packet> packet, const CcnxFibFaceMetric &metricFace)
-{
-  // if (m_enableMetricTagging)
-    {
-      // update path information
-
-      Ptr<const WeightsPathStretchTag> origTag = packet->RemovePacketTag<WeightsPathStretchTag> ();
-      Ptr<WeightsPathStretchTag> tag;
-      if (origTag == 0)
-        {
-          tag = CreateObject<WeightsPathStretchTag> (); // create a new tag
-        }
-      else
-        {
-          tag = CreateObject<WeightsPathStretchTag> (*origTag); // will update existing tag
-        }
-
-      tag->AddPathInfo (metricFace.m_face->GetNode (), metricFace.m_routingCost);
-      packet->AddPacketTag (tag);
-    }
-}
-
 } //namespace ns3
diff --git a/model/ccnx-forwarding-strategy.h b/model/ccnx-forwarding-strategy.h
index 7be0450..ea9f692 100644
--- a/model/ccnx-forwarding-strategy.h
+++ b/model/ccnx-forwarding-strategy.h
@@ -93,14 +93,10 @@
                              Ptr<CcnxInterestHeader> &header,
                              const Ptr<const Packet> &packet);
 
-  void
-  TagPacket (Ptr<Packet> packet, const CcnxFibFaceMetric &metricFace);
-  
   TracedCallback<Ptr<const CcnxInterestHeader>, Ptr<const CcnxFace> > m_transmittedInterestsTrace;
   
 protected:  
   Ptr<CcnxPit> m_pit;
-  bool m_enableMetricTagging; 
 };
 
 } //namespace ns3
diff --git a/model/ccnx-path-stretch-tag.cc b/model/ccnx-path-stretch-tag.cc
index c8fc6dd..31adca1 100644
--- a/model/ccnx-path-stretch-tag.cc
+++ b/model/ccnx-path-stretch-tag.cc
@@ -105,11 +105,12 @@
       if (info != m_infos.begin ()) os << ",";
       NS_ASSERT (info->node != 0);
 
-      std::string name = Names::FindName (info->node);
-      if (!name.empty ())
-        os << name;
-      else
-        os << info->node->GetId ();
+      os << info->node->GetId () << "(" << Names::FindName (info->node) << ")";
+      // std::string name = Names::FindName (info->node);
+      // if (!name.empty ())
+      //   os << name;
+      // else
+      //   os << info->node->GetId ();
       os << ":" << info->weight;
     }
 }