utils: Fixes compilation of tracers

This commit also replaces use of boost::tuple with std::tuple and
boost::shared_ptr with std::shared_ptr

L3AggregateTracer is completely removed, as its functionality is
duplicated and extended by L3RateTracer
diff --git a/utils/tracers/l2-rate-tracer.cpp b/utils/tracers/l2-rate-tracer.cpp
index f5c4d22..c0ccdc0 100644
--- a/utils/tracers/l2-rate-tracer.cpp
+++ b/utils/tracers/l2-rate-tracer.cpp
@@ -19,6 +19,7 @@
  */
 
 #include "l2-rate-tracer.hpp"
+
 #include "ns3/node.h"
 #include "ns3/packet.h"
 #include "ns3/config.h"
@@ -31,22 +32,13 @@
 #include <boost/lexical_cast.hpp>
 #include <fstream>
 
-using namespace boost;
-using namespace std;
-
 NS_LOG_COMPONENT_DEFINE("L2RateTracer");
 
 namespace ns3 {
 
-static std::list<boost::tuple<boost::shared_ptr<std::ostream>, std::list<Ptr<L2RateTracer>>>>
+static std::list<std::tuple<std::shared_ptr<std::ostream>, std::list<Ptr<L2RateTracer>>>>
   g_tracers;
 
-template<class T>
-static inline void
-NullDeleter(T* ptr)
-{
-}
-
 void
 L2RateTracer::Destroy()
 {
@@ -57,9 +49,9 @@
 L2RateTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
 {
   std::list<Ptr<L2RateTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  std::shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    std::shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -70,11 +62,11 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = std::shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
-    NS_LOG_DEBUG("Node: " << lexical_cast<string>((*node)->GetId()));
+    NS_LOG_DEBUG("Node: " << boost::lexical_cast<std::string>((*node)->GetId()));
 
     Ptr<L2RateTracer> trace = Create<L2RateTracer>(outputStream, *node);
     trace->SetAveragingPeriod(averagingPeriod);
@@ -87,10 +79,10 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
-L2RateTracer::L2RateTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node)
+L2RateTracer::L2RateTracer(std::shared_ptr<std::ostream> os, Ptr<Node> node)
   : L2Tracer(node)
   , m_os(os)
 {
@@ -144,13 +136,13 @@
 void
 L2RateTracer::Reset()
 {
-  m_stats.get<0>().Reset();
-  m_stats.get<1>().Reset();
+  std::get<0>(m_stats).Reset();
+  std::get<1>(m_stats).Reset();
 }
 
 const double alpha = 0.8;
 
-#define STATS(INDEX) m_stats.get<INDEX>()
+#define STATS(INDEX) std::get<INDEX>(m_stats)
 #define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble(Time::S)
 
 #define PRINTER(printName, fieldName, interface)                                                   \
@@ -176,8 +168,8 @@
 {
   // no interface information... this should be part of this L2Tracer object data
 
-  m_stats.get<0>().m_drop++;
-  m_stats.get<1>().m_drop += packet->GetSize();
+  std::get<0>(m_stats).m_drop++;
+  std::get<1>(m_stats).m_drop += packet->GetSize();
 }
 
 } // namespace ns3
diff --git a/utils/tracers/l2-rate-tracer.hpp b/utils/tracers/l2-rate-tracer.hpp
index 79f16c4..c1a5372 100644
--- a/utils/tracers/l2-rate-tracer.hpp
+++ b/utils/tracers/l2-rate-tracer.hpp
@@ -26,8 +26,7 @@
 #include "ns3/nstime.h"
 #include "ns3/event-id.h"
 
-#include <boost/tuple/tuple.hpp>
-#include <boost/shared_ptr.hpp>
+#include <tuple>
 #include <map>
 
 namespace ns3 {
@@ -43,7 +42,7 @@
   /**
    * @brief Network layer tracer constructor
    */
-  L2RateTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node);
+  L2RateTracer(std::shared_ptr<std::ostream> os, Ptr<Node> node);
   virtual ~L2RateTracer();
 
   /**
@@ -91,11 +90,11 @@
   Reset();
 
 private:
-  boost::shared_ptr<std::ostream> m_os;
+  std::shared_ptr<std::ostream> m_os;
   Time m_period;
   EventId m_printEvent;
 
-  mutable boost::tuple<Stats, Stats, Stats, Stats> m_stats;
+  mutable std::tuple<Stats, Stats, Stats, Stats> m_stats;
 };
 
 } // namespace ns3
diff --git a/utils/tracers/l2-tracer.cpp b/utils/tracers/l2-tracer.cpp
index bf1fcf1..47c208b 100644
--- a/utils/tracers/l2-tracer.cpp
+++ b/utils/tracers/l2-tracer.cpp
@@ -19,6 +19,7 @@
  */
 
 #include "l2-tracer.hpp"
+
 #include "ns3/node.h"
 #include "ns3/config.h"
 #include "ns3/names.h"
@@ -28,18 +29,16 @@
 #include "ns3/queue.h"
 #include <boost/lexical_cast.hpp>
 
-using namespace std;
-
 namespace ns3 {
 
 L2Tracer::L2Tracer(Ptr<Node> node)
   : m_nodePtr(node)
 {
-  m_node = boost::lexical_cast<string>(m_nodePtr->GetId());
+  m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
 
   Connect();
 
-  string name = Names::FindName(node);
+  std::string name = Names::FindName(node);
   if (!name.empty()) {
     m_node = name;
   }
diff --git a/utils/tracers/ndn-app-delay-tracer.cpp b/utils/tracers/ndn-app-delay-tracer.cpp
index fa9ab3a..1c135a6 100644
--- a/utils/tracers/ndn-app-delay-tracer.cpp
+++ b/utils/tracers/ndn-app-delay-tracer.cpp
@@ -25,7 +25,7 @@
 #include "ns3/names.h"
 #include "ns3/callback.h"
 
-#include "ns3/ndn-app.hpp"
+#include "apps/ndn-app.hpp"
 #include "ns3/simulator.h"
 #include "ns3/node-list.h"
 #include "ns3/log.h"
@@ -37,20 +37,12 @@
 
 NS_LOG_COMPONENT_DEFINE("ndn.AppDelayTracer");
 
-using namespace std;
-
 namespace ns3 {
 namespace ndn {
 
-static std::list<boost::tuple<boost::shared_ptr<std::ostream>, std::list<Ptr<AppDelayTracer>>>>
+static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<AppDelayTracer>>>>
   g_tracers;
 
-template<class T>
-static inline void
-NullDeleter(T* ptr)
-{
-}
-
 void
 AppDelayTracer::Destroy()
 {
@@ -64,9 +56,9 @@
   using namespace std;
 
   std::list<Ptr<AppDelayTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -77,7 +69,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
@@ -91,7 +83,7 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 void
@@ -101,9 +93,9 @@
   using namespace std;
 
   std::list<Ptr<AppDelayTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -114,7 +106,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
@@ -128,7 +120,7 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 void
@@ -138,9 +130,9 @@
   using namespace std;
 
   std::list<Ptr<AppDelayTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -151,7 +143,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   Ptr<AppDelayTracer> trace = Install(node, outputStream);
@@ -163,11 +155,11 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 Ptr<AppDelayTracer>
-AppDelayTracer::Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream)
+AppDelayTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream)
 {
   NS_LOG_DEBUG("Node: " << node->GetId());
 
@@ -180,21 +172,21 @@
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-AppDelayTracer::AppDelayTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node)
+AppDelayTracer::AppDelayTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
   : m_nodePtr(node)
   , m_os(os)
 {
-  m_node = boost::lexical_cast<string>(m_nodePtr->GetId());
+  m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
 
   Connect();
 
-  string name = Names::FindName(node);
+  std::string name = Names::FindName(node);
   if (!name.empty()) {
     m_node = name;
   }
 }
 
-AppDelayTracer::AppDelayTracer(boost::shared_ptr<std::ostream> os, const std::string& node)
+AppDelayTracer::AppDelayTracer(shared_ptr<std::ostream> os, const std::string& node)
   : m_node(node)
   , m_os(os)
 {
diff --git a/utils/tracers/ndn-app-delay-tracer.hpp b/utils/tracers/ndn-app-delay-tracer.hpp
index 72cccec..b9c110c 100644
--- a/utils/tracers/ndn-app-delay-tracer.hpp
+++ b/utils/tracers/ndn-app-delay-tracer.hpp
@@ -29,8 +29,7 @@
 #include <ns3/event-id.h>
 #include <ns3/node-container.h>
 
-#include <boost/tuple/tuple.hpp>
-#include <boost/shared_ptr.hpp>
+#include <tuple>
 #include <list>
 
 namespace ns3 {
@@ -104,7 +103,7 @@
    *          for the lifetime of simulation, otherwise SEGFAULTs are inevitable
    */
   static Ptr<AppDelayTracer>
-  Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream);
+  Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream);
 
   /**
    * @brief Explicit request to remove all statically created tracers
@@ -120,14 +119,14 @@
    * @param os    reference to the output stream
    * @param node  pointer to the node
    */
-  AppDelayTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node);
+  AppDelayTracer(shared_ptr<std::ostream> os, Ptr<Node> node);
 
   /**
    * @brief Trace constructor that attaches to all applications on the node using node's name
    * @param os        reference to the output stream
    * @param nodeName  name of the node registered using Names::Add
    */
-  AppDelayTracer(boost::shared_ptr<std::ostream> os, const std::string& node);
+  AppDelayTracer(shared_ptr<std::ostream> os, const std::string& node);
 
   /**
    * @brief Destructor
@@ -157,7 +156,7 @@
   std::string m_node;
   Ptr<Node> m_nodePtr;
 
-  boost::shared_ptr<std::ostream> m_os;
+  shared_ptr<std::ostream> m_os;
 };
 
 } // namespace ndn
diff --git a/utils/tracers/ndn-cs-tracer.cpp b/utils/tracers/ndn-cs-tracer.cpp
index f470aae..11fd803 100644
--- a/utils/tracers/ndn-cs-tracer.cpp
+++ b/utils/tracers/ndn-cs-tracer.cpp
@@ -26,8 +26,8 @@
 #include "ns3/names.h"
 #include "ns3/callback.h"
 
-#include "ns3/ndn-app.hpp"
-#include "ns3/ndn-content-store.hpp"
+#include "apps/ndn-app.hpp"
+#include "model/cs/ndn-content-store.hpp"
 #include "ns3/simulator.h"
 #include "ns3/node-list.h"
 #include "ns3/log.h"
@@ -38,18 +38,10 @@
 
 NS_LOG_COMPONENT_DEFINE("ndn.CsTracer");
 
-using namespace std;
-
 namespace ns3 {
 namespace ndn {
 
-static std::list<boost::tuple<boost::shared_ptr<std::ostream>, std::list<Ptr<CsTracer>>>> g_tracers;
-
-template<class T>
-static inline void
-NullDeleter(T* ptr)
-{
-}
+static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<CsTracer>>>> g_tracers;
 
 void
 CsTracer::Destroy()
@@ -64,9 +56,9 @@
   using namespace std;
 
   std::list<Ptr<CsTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -77,7 +69,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
@@ -91,7 +83,7 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 void
@@ -102,9 +94,9 @@
   using namespace std;
 
   std::list<Ptr<CsTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -115,7 +107,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
@@ -129,7 +121,7 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 void
@@ -140,9 +132,9 @@
   using namespace std;
 
   std::list<Ptr<CsTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -153,7 +145,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   Ptr<CsTracer> trace = Install(node, outputStream, averagingPeriod);
@@ -165,11 +157,11 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 Ptr<CsTracer>
-CsTracer::Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream,
+CsTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
                   Time averagingPeriod /* = Seconds (0.5)*/)
 {
   NS_LOG_DEBUG("Node: " << node->GetId());
@@ -184,21 +176,21 @@
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-CsTracer::CsTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node)
+CsTracer::CsTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
   : m_nodePtr(node)
   , m_os(os)
 {
-  m_node = boost::lexical_cast<string>(m_nodePtr->GetId());
+  m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
 
   Connect();
 
-  string name = Names::FindName(node);
+  std::string name = Names::FindName(node);
   if (!name.empty()) {
     m_node = name;
   }
 }
 
-CsTracer::CsTracer(boost::shared_ptr<std::ostream> os, const std::string& node)
+CsTracer::CsTracer(shared_ptr<std::ostream> os, const std::string& node)
   : m_node(node)
   , m_os(os)
 {
diff --git a/utils/tracers/ndn-cs-tracer.hpp b/utils/tracers/ndn-cs-tracer.hpp
index d14d005..c898b16 100644
--- a/utils/tracers/ndn-cs-tracer.hpp
+++ b/utils/tracers/ndn-cs-tracer.hpp
@@ -30,8 +30,7 @@
 #include <ns3/event-id.h>
 #include <ns3/node-container.h>
 
-#include <boost/tuple/tuple.hpp>
-#include <boost/shared_ptr.hpp>
+#include <tuple>
 #include <map>
 #include <list>
 
@@ -124,7 +123,7 @@
    *          for the lifetime of simulation, otherwise SEGFAULTs are inevitable
    */
   static Ptr<CsTracer>
-  Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream,
+  Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
           Time averagingPeriod = Seconds(0.5));
 
   /**
@@ -141,14 +140,14 @@
    * @param os    reference to the output stream
    * @param node  pointer to the node
    */
-  CsTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node);
+  CsTracer(shared_ptr<std::ostream> os, Ptr<Node> node);
 
   /**
    * @brief Trace constructor that attaches to the node using node name
    * @param os        reference to the output stream
    * @param nodeName  name of the node registered using Names::Add
    */
-  CsTracer(boost::shared_ptr<std::ostream> os, const std::string& node);
+  CsTracer(shared_ptr<std::ostream> os, const std::string& node);
 
   /**
    * @brief Destructor
@@ -195,7 +194,7 @@
   std::string m_node;
   Ptr<Node> m_nodePtr;
 
-  boost::shared_ptr<std::ostream> m_os;
+  shared_ptr<std::ostream> m_os;
 
   Time m_period;
   EventId m_printEvent;
diff --git a/utils/tracers/ndn-l3-aggregate-tracer.cpp b/utils/tracers/ndn-l3-aggregate-tracer.cpp
deleted file mode 100644
index 5f0dca6..0000000
--- a/utils/tracers/ndn-l3-aggregate-tracer.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 UCLA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author:  Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "ndn-l3-aggregate-tracer.hpp"
-
-#include "ns3/node.h"
-#include "ns3/packet.h"
-#include "ns3/config.h"
-#include "ns3/callback.h"
-#include "apps/ndn-app.hpp"
-#include "model/ndn-face.hpp"
-
-#include "ns3/simulator.h"
-#include "ns3/node-list.h"
-#include "ns3/log.h"
-
-#include <fstream>
-
-NS_LOG_COMPONENT_DEFINE("ndn.L3AggregateTracer");
-
-namespace ns3 {
-namespace ndn {
-
-static std::list<boost::tuple<boost::shared_ptr<std::ostream>, std::list<Ptr<L3AggregateTracer>>>>
-  g_tracers;
-
-template<class T>
-static inline void
-NullDeleter(T* ptr)
-{
-}
-
-void
-L3AggregateTracer::Destroy()
-{
-  g_tracers.clear();
-}
-
-void
-L3AggregateTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
-{
-  using namespace boost;
-  using namespace std;
-
-  std::list<Ptr<L3AggregateTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
-  if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
-    os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
-
-    if (!os->is_open()) {
-      NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
-      return;
-    }
-
-    outputStream = os;
-  }
-  else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
-  }
-
-  for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
-    Ptr<L3AggregateTracer> trace = Install(*node, outputStream, averagingPeriod);
-    tracers.push_back(trace);
-  }
-
-  if (tracers.size() > 0) {
-    // *m_l3RateTrace << "# "; // not necessary for R's read.table
-    tracers.front()->PrintHeader(*outputStream);
-    *outputStream << "\n";
-  }
-
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
-}
-
-void
-L3AggregateTracer::Install(const NodeContainer& nodes, const std::string& file,
-                           Time averagingPeriod /* = Seconds (0.5)*/)
-{
-  using namespace boost;
-  using namespace std;
-
-  std::list<Ptr<L3AggregateTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
-  if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
-    os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
-
-    if (!os->is_open()) {
-      NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
-      return;
-    }
-
-    outputStream = os;
-  }
-  else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
-  }
-
-  for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
-    Ptr<L3AggregateTracer> trace = Install(*node, outputStream, averagingPeriod);
-    tracers.push_back(trace);
-  }
-
-  if (tracers.size() > 0) {
-    // *m_l3RateTrace << "# "; // not necessary for R's read.table
-    tracers.front()->PrintHeader(*outputStream);
-    *outputStream << "\n";
-  }
-
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
-}
-
-void
-L3AggregateTracer::Install(Ptr<Node> node, const std::string& file,
-                           Time averagingPeriod /* = Seconds (0.5)*/)
-{
-  using namespace boost;
-  using namespace std;
-
-  std::list<Ptr<L3AggregateTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
-  if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
-    os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
-
-    if (!os->is_open()) {
-      NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
-      return;
-    }
-
-    outputStream = os;
-  }
-  else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
-  }
-
-  Ptr<L3AggregateTracer> trace = Install(node, outputStream, averagingPeriod);
-  tracers.push_back(trace);
-
-  if (tracers.size() > 0) {
-    // *m_l3RateTrace << "# "; // not necessary for R's read.table
-    tracers.front()->PrintHeader(*outputStream);
-    *outputStream << "\n";
-  }
-
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
-}
-
-Ptr<L3AggregateTracer>
-L3AggregateTracer::Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream,
-                           Time averagingPeriod /* = Seconds (0.5)*/)
-{
-  NS_LOG_DEBUG("Node: " << node->GetId());
-
-  Ptr<L3AggregateTracer> trace = Create<L3AggregateTracer>(outputStream, node);
-  trace->SetAveragingPeriod(averagingPeriod);
-
-  return trace;
-}
-
-L3AggregateTracer::L3AggregateTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node)
-  : L3Tracer(node)
-  , m_os(os)
-{
-  Reset();
-}
-
-L3AggregateTracer::L3AggregateTracer(boost::shared_ptr<std::ostream> os, const std::string& node)
-  : L3Tracer(node)
-  , m_os(os)
-{
-  Reset();
-}
-
-L3AggregateTracer::~L3AggregateTracer(){};
-
-void
-L3AggregateTracer::SetAveragingPeriod(const Time& period)
-{
-  m_period = period;
-  m_printEvent.Cancel();
-  m_printEvent = Simulator::Schedule(m_period, &L3AggregateTracer::PeriodicPrinter, this);
-}
-
-void
-L3AggregateTracer::PeriodicPrinter()
-{
-  Print(*m_os);
-  Reset();
-
-  m_printEvent = Simulator::Schedule(m_period, &L3AggregateTracer::PeriodicPrinter, this);
-}
-
-void
-L3AggregateTracer::PrintHeader(std::ostream& os) const
-{
-  os << "Time"
-     << "\t"
-
-     << "Node"
-     << "\t"
-     << "FaceId"
-     << "\t"
-     << "FaceDescr"
-     << "\t"
-
-     << "Type"
-     << "\t"
-     << "Packets"
-     << "\t"
-     << "Kilobytes";
-}
-
-void
-L3AggregateTracer::Reset()
-{
-  for (std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats>>::iterator stats = m_stats.begin();
-       stats != m_stats.end(); stats++) {
-    stats->second.get<0>().Reset();
-    stats->second.get<1>().Reset();
-  }
-}
-
-#define STATS(INDEX) stats->second.get<INDEX>()
-
-#define PRINTER(printName, fieldName)                                                              \
-  os << time.ToDouble(Time::S) << "\t" << m_node << "\t";                                          \
-  if (stats->first) {                                                                              \
-    os << stats->first->GetId() << "\t" << *stats->first << "\t";                                  \
-  }                                                                                                \
-  else {                                                                                           \
-    os << "-1\tall\t";                                                                             \
-  }                                                                                                \
-  os << printName << "\t" << STATS(0).fieldName << "\t" << STATS(1).fieldName / 1024.0 << "\n";
-
-void
-L3AggregateTracer::Print(std::ostream& os) const
-{
-  Time time = Simulator::Now();
-
-  for (std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats>>::iterator stats = m_stats.begin();
-       stats != m_stats.end(); stats++) {
-    if (!stats->first)
-      continue;
-
-    PRINTER("InInterests", m_inInterests);
-    PRINTER("OutInterests", m_outInterests);
-    PRINTER("DropInterests", m_dropInterests);
-
-    PRINTER("InNacks", m_inNacks);
-    PRINTER("OutNacks", m_outNacks);
-    PRINTER("DropNacks", m_dropNacks);
-
-    PRINTER("InData", m_inData);
-    PRINTER("OutData", m_outData);
-    PRINTER("DropData", m_dropData);
-  }
-
-  {
-    std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats>>::iterator stats =
-      m_stats.find(shared_ptr<const Face>(0));
-    if (stats != m_stats.end()) {
-      PRINTER("SatisfiedInterests", m_satisfiedInterests);
-      PRINTER("TimedOutInterests", m_timedOutInterests);
-    }
-  }
-}
-
-void
-L3AggregateTracer::OutInterests(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_outInterests++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_outInterests += interest->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::InInterests(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_inInterests++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_inInterests += interest->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::DropInterests(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_dropInterests++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_dropInterests += interest->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::OutNacks(shared_ptr<const Interest> nack, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_outNacks++;
-  if (nack->GetWire()) {
-    m_stats[face].get<1>().m_outNacks += nack->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::InNacks(shared_ptr<const Interest> nack, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_inNacks++;
-  if (nack->GetWire()) {
-    m_stats[face].get<1>().m_inNacks += nack->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::DropNacks(shared_ptr<const Interest> nack, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_dropNacks++;
-  if (nack->GetWire()) {
-    m_stats[face].get<1>().m_dropNacks += nack->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::OutData(shared_ptr<const Data> data, bool fromCache, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_outData++;
-  if (data->GetWire()) {
-    m_stats[face].get<1>().m_outData += data->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::InData(shared_ptr<const Data> data, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_inData++;
-  if (data->GetWire()) {
-    m_stats[face].get<1>().m_inData += data->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::DropData(shared_ptr<const Data> data, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_dropData++;
-  if (data->GetWire()) {
-    m_stats[face].get<1>().m_dropData += data->GetWire()->GetSize();
-  }
-}
-
-void
-L3AggregateTracer::SatisfiedInterests(Ptr<const pit::Entry>)
-{
-  m_stats[0].get<0>().m_satisfiedInterests++;
-  // no "size" stats
-}
-
-void
-L3AggregateTracer::TimedOutInterests(Ptr<const pit::Entry>)
-{
-  m_stats[0].get<0>().m_timedOutInterests++;
-  // no "size" stats
-}
-
-} // namespace ndn
-} // namespace ns3
diff --git a/utils/tracers/ndn-l3-aggregate-tracer.hpp b/utils/tracers/ndn-l3-aggregate-tracer.hpp
deleted file mode 100644
index 35bf917..0000000
--- a/utils/tracers/ndn-l3-aggregate-tracer.hpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2011 UCLA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author:  Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef NDN_L3_AGGREGATE_TRACER_H
-#define NDN_L3_AGGREGATE_TRACER_H
-
-#include "ns3/ndnSIM/model/ndn-common.hpp"
-
-#include "ndn-l3-tracer.hpp"
-
-#include <ns3/nstime.h>
-#include <ns3/event-id.h>
-#include <ns3/node-container.h>
-
-#include <boost/tuple/tuple.hpp>
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <list>
-
-namespace ns3 {
-namespace ndn {
-
-/**
- * @ingroup ndn-tracers
- * @brief NDN network-layer tracer for aggregate packet counts
- */
-class L3AggregateTracer : public L3Tracer {
-public:
-  /**
-   * @brief Helper method to install tracers on all simulation nodes
-   *
-   * @param file File to which traces will be written.  If filename is -, then std::out is used
-   * @param averagingPeriod How often data will be written into the trace file (default, every half
-   *second)
-   *
-   * @returns a tuple of reference to output stream and list of tracers. !!! Attention !!! This
-   *tuple needs to be preserved
-   *          for the lifetime of simulation, otherwise SEGFAULTs are inevitable
-   *
-   */
-  static void
-  InstallAll(const std::string& file, Time averagingPeriod = Seconds(0.5));
-
-  /**
-   * @brief Helper method to install tracers on the selected simulation nodes
-   *
-   * @param nodes Nodes on which to install tracer
-   * @param file File to which traces will be written.  If filename is -, then std::out is used
-   * @param averagingPeriod How often data will be written into the trace file (default, every half
-   *second)
-   *
-   * @returns a tuple of reference to output stream and list of tracers. !!! Attention !!! This
-   *tuple needs to be preserved
-   *          for the lifetime of simulation, otherwise SEGFAULTs are inevitable
-   *
-   */
-  static void
-  Install(const NodeContainer& nodes, const std::string& file, Time averagingPeriod = Seconds(0.5));
-
-  /**
-   * @brief Helper method to install tracers on a specific simulation node
-   *
-   * @param nodes Nodes on which to install tracer
-   * @param file File to which traces will be written.  If filename is -, then std::out is used
-   * @param averagingPeriod How often data will be written into the trace file (default, every half
-   *second)
-   *
-   * @returns a tuple of reference to output stream and list of tracers. !!! Attention !!! This
-   *tuple needs to be preserved
-   *          for the lifetime of simulation, otherwise SEGFAULTs are inevitable
-   *
-   */
-  static void
-  Install(Ptr<Node> node, const std::string& file, Time averagingPeriod = Seconds(0.5));
-
-  /**
-   * @brief Explicit request to remove all statically created tracers
-   *
-   * This method can be helpful if simulation scenario contains several independent run,
-   * or if it is desired to do a postprocessing of the resulting data
-   */
-  static void
-  Destroy();
-
-  /**
-   * @brief Trace constructor that attaches to the node using node pointer
-   * @param os    reference to the output stream
-   * @param node  pointer to the node
-   */
-  L3AggregateTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node);
-
-  /**
-   * @brief Trace constructor that attaches to the node using node name
-   * @param os        reference to the output stream
-   * @param nodeName  name of the node registered using Names::Add
-   */
-  L3AggregateTracer(boost::shared_ptr<std::ostream> os, const std::string& nodeName);
-
-  /**
-   * @brief Destructor
-   */
-  virtual ~L3AggregateTracer();
-
-  /**
-   * @brief Helper method to install tracers on a specific simulation node
-   *
-   * @param nodes Nodes on which to install tracer
-   * @param outputStream Smart pointer to a stream
-   * @param averagingPeriod How often data will be written into the trace file (default, every half
-   *second)
-   *
-   * @returns a tuple of reference to output stream and list of tracers. !!! Attention !!! This
-   *tuple needs to be preserved
-   *          for the lifetime of simulation, otherwise SEGFAULTs are inevitable
-   */
-  static Ptr<L3AggregateTracer>
-  Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream,
-          Time averagingPeriod = Seconds(0.5));
-
-protected:
-  // from L3Tracer
-  virtual void
-  PrintHeader(std::ostream& os) const;
-
-  virtual void
-  Print(std::ostream& os) const;
-
-  virtual void
-  OutInterests(shared_ptr<const Interest>, shared_ptr<const Face>);
-
-  virtual void
-  InInterests(shared_ptr<const Interest>, shared_ptr<const Face>);
-
-  virtual void
-  DropInterests(shared_ptr<const Interest>, shared_ptr<const Face>);
-
-  virtual void
-  OutNacks(shared_ptr<const Interest>, shared_ptr<const Face>);
-
-  virtual void
-  InNacks(shared_ptr<const Interest>, shared_ptr<const Face>);
-
-  virtual void
-  DropNacks(shared_ptr<const Interest>, shared_ptr<const Face>);
-
-  virtual void
-  OutData(shared_ptr<const Data>, bool fromCache, shared_ptr<const Face>);
-
-  virtual void
-  InData(shared_ptr<const Data>, shared_ptr<const Face>);
-
-  virtual void
-  DropData(shared_ptr<const Data>, shared_ptr<const Face>);
-
-  virtual void
-  SatisfiedInterests(Ptr<const pit::Entry>);
-
-  virtual void
-  TimedOutInterests(Ptr<const pit::Entry>);
-
-protected:
-  void
-  SetAveragingPeriod(const Time& period);
-
-  void
-  Reset();
-
-  void
-  PeriodicPrinter();
-
-protected:
-  boost::shared_ptr<std::ostream> m_os;
-
-  Time m_period;
-  EventId m_printEvent;
-
-  mutable std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats>> m_stats;
-};
-
-} // namespace ndn
-} // namespace ns3
-
-#endif // NDN_L3_AGGREGATE_TRACER_H
diff --git a/utils/tracers/ndn-l3-rate-tracer.cpp b/utils/tracers/ndn-l3-rate-tracer.cpp
index 1b91c46..7ef3387 100644
--- a/utils/tracers/ndn-l3-rate-tracer.cpp
+++ b/utils/tracers/ndn-l3-rate-tracer.cpp
@@ -27,30 +27,17 @@
 #include "ns3/log.h"
 #include "ns3/node-list.h"
 
-#include "ns3/ndn-app.hpp"
-#include "ns3/ndn-face.hpp"
-#include "ns3/ndn-pit-entry.hpp"
-
 #include <fstream>
 #include <boost/lexical_cast.hpp>
 
-using namespace boost;
-using namespace std;
-
 NS_LOG_COMPONENT_DEFINE("ndn.L3RateTracer");
 
 namespace ns3 {
 namespace ndn {
 
-static std::list<boost::tuple<boost::shared_ptr<std::ostream>, std::list<Ptr<L3RateTracer>>>>
+static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<L3RateTracer>>>>
   g_tracers;
 
-template<class T>
-static inline void
-NullDeleter(T* ptr)
-{
-}
-
 void
 L3RateTracer::Destroy()
 {
@@ -61,9 +48,9 @@
 L3RateTracer::InstallAll(const std::string& file, Time averagingPeriod /* = Seconds (0.5)*/)
 {
   std::list<Ptr<L3RateTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -74,7 +61,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
@@ -88,7 +75,7 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 void
@@ -99,9 +86,9 @@
   using namespace std;
 
   std::list<Ptr<L3RateTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -112,7 +99,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
@@ -126,7 +113,7 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 void
@@ -137,9 +124,9 @@
   using namespace std;
 
   std::list<Ptr<L3RateTracer>> tracers;
-  boost::shared_ptr<std::ostream> outputStream;
+  shared_ptr<std::ostream> outputStream;
   if (file != "-") {
-    boost::shared_ptr<std::ofstream> os(new std::ofstream());
+    shared_ptr<std::ofstream> os(new std::ofstream());
     os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
 
     if (!os->is_open()) {
@@ -150,7 +137,7 @@
     outputStream = os;
   }
   else {
-    outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
+    outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
   }
 
   Ptr<L3RateTracer> trace = Install(node, outputStream, averagingPeriod);
@@ -162,11 +149,11 @@
     *outputStream << "\n";
   }
 
-  g_tracers.push_back(boost::make_tuple(outputStream, tracers));
+  g_tracers.push_back(std::make_tuple(outputStream, tracers));
 }
 
 Ptr<L3RateTracer>
-L3RateTracer::Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream,
+L3RateTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
                       Time averagingPeriod /* = Seconds (0.5)*/)
 {
   NS_LOG_DEBUG("Node: " << node->GetId());
@@ -177,14 +164,14 @@
   return trace;
 }
 
-L3RateTracer::L3RateTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node)
+L3RateTracer::L3RateTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
   : L3Tracer(node)
   , m_os(os)
 {
   SetAveragingPeriod(Seconds(1.0));
 }
 
-L3RateTracer::L3RateTracer(boost::shared_ptr<std::ostream> os, const std::string& node)
+L3RateTracer::L3RateTracer(shared_ptr<std::ostream> os, const std::string& node)
   : L3Tracer(node)
   , m_os(os)
 {
@@ -240,17 +227,17 @@
 void
 L3RateTracer::Reset()
 {
-  for (std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats>>::iterator stats =
+  for (std::map<shared_ptr<const Face>, std::tuple<Stats, Stats, Stats, Stats>>::iterator stats =
          m_stats.begin();
        stats != m_stats.end(); stats++) {
-    stats->second.get<0>().Reset();
-    stats->second.get<1>().Reset();
+    std::get<0>(stats->second).Reset();
+    std::get<1>(stats->second).Reset();
   }
 }
 
 const double alpha = 0.8;
 
-#define STATS(INDEX) stats->second.get<INDEX>()
+#define STATS(INDEX) std::get<INDEX>(stats->second)
 #define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble(Time::S)
 
 #define PRINTER(printName, fieldName)                                                              \
@@ -260,8 +247,8 @@
                        + /*old value*/ (1 - alpha) * STATS(3).fieldName;                           \
                                                                                                    \
   os << time.ToDouble(Time::S) << "\t" << m_node << "\t";                                          \
-  if (stats->first) {                                                                              \
-    os << stats->first->GetId() << "\t" << *stats->first << "\t";                                  \
+  if (stats->first != nullptr) {                                                                   \
+    os << stats->first->getId() << "\t" << stats->first->getLocalUri() << "\t";                    \
   }                                                                                                \
   else {                                                                                           \
     os << "-1\tall\t";                                                                             \
@@ -274,155 +261,116 @@
 {
   Time time = Simulator::Now();
 
-  for (std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats>>::iterator stats =
+  for (std::map<shared_ptr<const Face>, std::tuple<Stats, Stats, Stats, Stats>>::iterator stats =
          m_stats.begin();
        stats != m_stats.end(); stats++) {
-    if (!stats->first)
+    if (stats->first == nullptr)
       continue;
 
     PRINTER("InInterests", m_inInterests);
     PRINTER("OutInterests", m_outInterests);
-    PRINTER("DropInterests", m_dropInterests);
-
-    PRINTER("InNacks", m_inNacks);
-    PRINTER("OutNacks", m_outNacks);
-    PRINTER("DropNacks", m_dropNacks);
 
     PRINTER("InData", m_inData);
     PRINTER("OutData", m_outData);
-    PRINTER("DropData", m_dropData);
 
-    PRINTER("InSatisfiedInterests", m_satisfiedInterests);
-    PRINTER("InTimedOutInterests", m_timedOutInterests);
+    // PRINTER("InSatisfiedInterests", m_satisfiedInterests);
+    // PRINTER("InTimedOutInterests", m_timedOutInterests);
 
-    PRINTER("OutSatisfiedInterests", m_outSatisfiedInterests);
-    PRINTER("OutTimedOutInterests", m_outTimedOutInterests);
+    // PRINTER("OutSatisfiedInterests", m_outSatisfiedInterests);
+    // PRINTER("OutTimedOutInterests", m_outTimedOutInterests);
   }
 
   {
-    std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats>>::iterator stats =
-      m_stats.find(shared_ptr<const Face>(0));
-    if (stats != m_stats.end()) {
-      PRINTER("SatisfiedInterests", m_satisfiedInterests);
-      PRINTER("TimedOutInterests", m_timedOutInterests);
-    }
+    // std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats>>::iterator stats =
+    //   m_stats.find(shared_ptr<const Face>(0));
+    // if (stats != m_stats.end()) {
+    //   PRINTER("SatisfiedInterests", m_satisfiedInterests);
+    //   PRINTER("TimedOutInterests", m_timedOutInterests);
+    // }
   }
 }
 
 void
-L3RateTracer::OutInterests(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
+L3RateTracer::OutInterests(const Interest& interest, const Face& face)
 {
-  m_stats[face].get<0>().m_outInterests++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_outInterests += interest->GetWire()->GetSize();
+  std::get<0>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_outInterests++;
+  if (interest.hasWire()) {
+    std::get<1>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_outInterests +=
+      interest.wireEncode().size();
   }
 }
 
 void
-L3RateTracer::InInterests(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
+L3RateTracer::InInterests(const Interest& interest, const Face& face)
 {
-  m_stats[face].get<0>().m_inInterests++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_inInterests += interest->GetWire()->GetSize();
+  std::get<0>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_inInterests++;
+  if (interest.hasWire()) {
+    std::get<1>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_inInterests +=
+      interest.wireEncode().size();
   }
 }
 
 void
-L3RateTracer::DropInterests(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
+L3RateTracer::OutData(const Data& data, const Face& face)
 {
-  m_stats[face].get<0>().m_dropInterests++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_dropInterests += interest->GetWire()->GetSize();
+  std::get<0>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_outData++;
+  if (data.hasWire()) {
+    std::get<1>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_outData +=
+      data.wireEncode().size();
   }
 }
 
 void
-L3RateTracer::OutNacks(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
+L3RateTracer::InData(const Data& data, const Face& face)
 {
-  m_stats[face].get<0>().m_outNacks++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_outNacks += interest->GetWire()->GetSize();
+  std::get<0>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_inData++;
+  if (data.hasWire()) {
+    std::get<1>(m_stats[(const_cast<Face*>(&face))->shared_from_this()]).m_inData +=
+      data.wireEncode().size();
   }
 }
 
-void
-L3RateTracer::InNacks(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_inNacks++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_inNacks += interest->GetWire()->GetSize();
-  }
-}
+// void
+// L3RateTracer::SatisfiedInterests (Ptr<const pit::Entry> entry)
+// {
+//   m_stats[0].std::get<0> ().m_satisfiedInterests ++;
+//   // no "size" stats
 
-void
-L3RateTracer::DropNacks(shared_ptr<const Interest> interest, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_dropNacks++;
-  if (interest->GetWire()) {
-    m_stats[face].get<1>().m_dropNacks += interest->GetWire()->GetSize();
-  }
-}
+//   for (::nfd::pit::Entry::in_container::const_iterator i = entry->GetIncoming ().begin ();
+//        i != entry->GetIncoming ().end ();
+//        i++)
+//     {
+//       m_stats[i->m_face].std::get<0> ().m_satisfiedInterests ++;
+// }
 
-void
-L3RateTracer::OutData(shared_ptr<const Data> data, bool fromCache, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_outData++;
-  if (data->GetWire()) {
-    m_stats[face].get<1>().m_outData += data->GetWire()->GetSize();
-  }
-}
+//   for (::nfd::pit::Entry::out_container::const_iterator i = entry->GetOutgoing ().begin ();
+//        i != entry->GetOutgoing ().end ();
+//        i++)
+//     {
+//       m_stats[i->m_face].std::get<0> ().m_outSatisfiedInterests ++;
+//     }
+// }
 
-void
-L3RateTracer::InData(shared_ptr<const Data> data, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_inData++;
-  if (data->GetWire()) {
-    m_stats[face].get<1>().m_inData += data->GetWire()->GetSize();
-  }
-}
+// void
+// L3RateTracer::TimedOutInterests (Ptr<const pit::Entry> entry)
+// {
+//   m_stats[0].std::get<0> ().m_timedOutInterests ++;
+//   // no "size" stats
 
-void
-L3RateTracer::DropData(shared_ptr<const Data> data, shared_ptr<const Face> face)
-{
-  m_stats[face].get<0>().m_dropData++;
-  if (data->GetWire()) {
-    m_stats[face].get<1>().m_dropData += data->GetWire()->GetSize();
-  }
-}
+//   for (pit::Entry::in_container::const_iterator i = entry->GetIncoming ().begin ();
+//        i != entry->GetIncoming ().end ();
+//        i++)
+//     {
+//       m_stats[i->m_face].std::get<0> ().m_timedOutInterests ++;
+// }
 
-void
-L3RateTracer::SatisfiedInterests(Ptr<const pit::Entry> entry)
-{
-  m_stats[0].get<0>().m_satisfiedInterests++;
-  // no "size" stats
-
-  for (pit::Entry::in_container::const_iterator i = entry->GetIncoming().begin();
-       i != entry->GetIncoming().end(); i++) {
-    m_stats[i->m_face].get<0>().m_satisfiedInterests++;
-  }
-
-  for (pit::Entry::out_container::const_iterator i = entry->GetOutgoing().begin();
-       i != entry->GetOutgoing().end(); i++) {
-    m_stats[i->m_face].get<0>().m_outSatisfiedInterests++;
-  }
-}
-
-void
-L3RateTracer::TimedOutInterests(Ptr<const pit::Entry> entry)
-{
-  m_stats[0].get<0>().m_timedOutInterests++;
-  // no "size" stats
-
-  for (pit::Entry::in_container::const_iterator i = entry->GetIncoming().begin();
-       i != entry->GetIncoming().end(); i++) {
-    m_stats[i->m_face].get<0>().m_timedOutInterests++;
-  }
-
-  for (pit::Entry::out_container::const_iterator i = entry->GetOutgoing().begin();
-       i != entry->GetOutgoing().end(); i++) {
-    m_stats[i->m_face].get<0>().m_outTimedOutInterests++;
-  }
-}
+//   for (pit::Entry::out_container::const_iterator i = entry->GetOutgoing ().begin ();
+//        i != entry->GetOutgoing ().end ();
+//        i++)
+//     {
+//       m_stats[i->m_face].std::get<0> ().m_outTimedOutInterests ++;
+//     }
+// }
 
 } // namespace ndn
 } // namespace ns3
diff --git a/utils/tracers/ndn-l3-rate-tracer.hpp b/utils/tracers/ndn-l3-rate-tracer.hpp
index 1dc8118..c433a17 100644
--- a/utils/tracers/ndn-l3-rate-tracer.hpp
+++ b/utils/tracers/ndn-l3-rate-tracer.hpp
@@ -27,10 +27,9 @@
 
 #include "ns3/nstime.h"
 #include "ns3/event-id.h"
-#include <ns3/node-container.h>
+#include "ns3/node-container.h"
 
-#include <boost/tuple/tuple.hpp>
-#include <boost/shared_ptr.hpp>
+#include <tuple>
 #include <map>
 #include <list>
 
@@ -90,14 +89,14 @@
    * @param os    reference to the output stream
    * @param node  pointer to the node
    */
-  L3RateTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node);
+  L3RateTracer(shared_ptr<std::ostream> os, Ptr<Node> node);
 
   /**
    * @brief Trace constructor that attaches to the node using node name
    * @param os        reference to the output stream
    * @param nodeName  name of the node registered using Names::Add
    */
-  L3RateTracer(boost::shared_ptr<std::ostream> os, const std::string& node);
+  L3RateTracer(shared_ptr<std::ostream> os, const std::string& node);
 
   /**
    * @brief Destructor
@@ -117,7 +116,7 @@
    *          for the lifetime of simulation, otherwise SEGFAULTs are inevitable
    */
   static Ptr<L3RateTracer>
-  Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream,
+  Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream,
           Time averagingPeriod = Seconds(0.5));
 
   // from L3Tracer
@@ -130,37 +129,22 @@
 protected:
   // from L3Tracer
   virtual void
-  OutInterests(shared_ptr<const Interest>, shared_ptr<const Face>);
+  OutInterests(const Interest& interest, const Face& face);
 
   virtual void
-  InInterests(shared_ptr<const Interest>, shared_ptr<const Face>);
+  InInterests(const Interest& interest, const Face& face);
 
   virtual void
-  DropInterests(shared_ptr<const Interest>, shared_ptr<const Face>);
+  OutData(const Data& data, const Face& face);
 
   virtual void
-  OutNacks(shared_ptr<const Interest>, shared_ptr<const Face>);
+  InData(const Data& data, const Face& face);
 
-  virtual void
-  InNacks(shared_ptr<const Interest>, shared_ptr<const Face>);
+  // virtual void
+  // SatisfiedInterests(Ptr<const pit::Entry>);
 
-  virtual void
-  DropNacks(shared_ptr<const Interest>, shared_ptr<const Face>);
-
-  virtual void
-  OutData(shared_ptr<const Data>, bool fromCache, shared_ptr<const Face>);
-
-  virtual void
-  InData(shared_ptr<const Data>, shared_ptr<const Face>);
-
-  virtual void
-  DropData(shared_ptr<const Data>, shared_ptr<const Face>);
-
-  virtual void
-  SatisfiedInterests(Ptr<const pit::Entry>);
-
-  virtual void
-  TimedOutInterests(Ptr<const pit::Entry>);
+  // virtual void
+  // TimedOutInterests(Ptr<const pit::Entry>);
 
 private:
   void
@@ -173,11 +157,11 @@
   Reset();
 
 private:
-  boost::shared_ptr<std::ostream> m_os;
+  shared_ptr<std::ostream> m_os;
   Time m_period;
   EventId m_printEvent;
 
-  mutable std::map<shared_ptr<const Face>, boost::tuple<Stats, Stats, Stats, Stats>> m_stats;
+  mutable std::map<shared_ptr<const Face>, std::tuple<Stats, Stats, Stats, Stats>> m_stats;
 };
 
 } // namespace ndn
diff --git a/utils/tracers/ndn-l3-tracer.cpp b/utils/tracers/ndn-l3-tracer.cpp
index 25e9f07..619b76e 100644
--- a/utils/tracers/ndn-l3-tracer.cpp
+++ b/utils/tracers/ndn-l3-tracer.cpp
@@ -24,14 +24,10 @@
 #include "ns3/config.h"
 #include "ns3/names.h"
 #include "ns3/callback.h"
-#include "ns3/ndn-forwarding-strategy.hpp"
 
 #include <boost/lexical_cast.hpp>
 
-#include "ns3/ndn-face.hpp"
-#include "ns3/ndn-pit-entry.hpp"
-
-using namespace std;
+#include "ns3/ndnSIM/model/ndn-l3-protocol.hpp"
 
 namespace ns3 {
 namespace ndn {
@@ -39,11 +35,11 @@
 L3Tracer::L3Tracer(Ptr<Node> node)
   : m_nodePtr(node)
 {
-  m_node = boost::lexical_cast<string>(m_nodePtr->GetId());
+  m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
 
   Connect();
 
-  string name = Names::FindName(node);
+  std::string name = Names::FindName(node);
   if (!name.empty()) {
     m_node = name;
   }
@@ -60,26 +56,18 @@
 void
 L3Tracer::Connect()
 {
-  Ptr<ForwardingStrategy> fw = m_nodePtr->GetObject<ForwardingStrategy>();
+  Ptr<L3Protocol> l3 = m_nodePtr->GetObject<L3Protocol>();
 
-  fw->TraceConnectWithoutContext("OutInterests", MakeCallback(&L3Tracer::OutInterests, this));
-  fw->TraceConnectWithoutContext("InInterests", MakeCallback(&L3Tracer::InInterests, this));
-  fw->TraceConnectWithoutContext("DropInterests", MakeCallback(&L3Tracer::DropInterests, this));
+  l3->TraceConnectWithoutContext("OutInterests", MakeCallback(&L3Tracer::OutInterests, this));
+  l3->TraceConnectWithoutContext("InInterests", MakeCallback(&L3Tracer::InInterests, this));
+  l3->TraceConnectWithoutContext("OutData", MakeCallback(&L3Tracer::OutData, this));
+  l3->TraceConnectWithoutContext("InData", MakeCallback(&L3Tracer::InData, this));
 
-  fw->TraceConnectWithoutContext("OutData", MakeCallback(&L3Tracer::OutData, this));
-  fw->TraceConnectWithoutContext("InData", MakeCallback(&L3Tracer::InData, this));
-  fw->TraceConnectWithoutContext("DropData", MakeCallback(&L3Tracer::DropData, this));
-
-  // only for some strategies
-  fw->TraceConnectWithoutContext("OutNacks", MakeCallback(&L3Tracer::OutNacks, this));
-  fw->TraceConnectWithoutContext("InNacks", MakeCallback(&L3Tracer::InNacks, this));
-  fw->TraceConnectWithoutContext("DropNacks", MakeCallback(&L3Tracer::DropNacks, this));
-
-  // satisfied/timed out PIs
-  fw->TraceConnectWithoutContext("SatisfiedInterests",
-                                 MakeCallback(&L3Tracer::SatisfiedInterests, this));
-  fw->TraceConnectWithoutContext("TimedOutInterests",
-                                 MakeCallback(&L3Tracer::TimedOutInterests, this));
+  // // satisfied/timed out PIs
+  // l3->TraceConnectWithoutContext("SatisfiedInterests",
+  //                                MakeCallback(&L3Tracer::SatisfiedInterests, this));
+  // l3->TraceConnectWithoutContext("TimedOutInterests",
+  //                                MakeCallback(&L3Tracer::TimedOutInterests, this));
 }
 
 } // namespace ndn
diff --git a/utils/tracers/ndn-l3-tracer.hpp b/utils/tracers/ndn-l3-tracer.hpp
index 4b2cc5a..2f3a3a7 100644
--- a/utils/tracers/ndn-l3-tracer.hpp
+++ b/utils/tracers/ndn-l3-tracer.hpp
@@ -22,15 +22,11 @@
 #define NDN_L3_TRACER_H
 
 #include "ns3/ndnSIM/model/ndn-common.hpp"
+#include "ns3/ndnSIM/model/ndn-face.hpp"
 
 #include "ns3/ptr.h"
 #include "ns3/simple-ref-count.h"
 
-/**
- * @ingroup ndn-helpers
- * @defgroup ndn-tracers Helpers to simplify metric collection
- */
-
 namespace ns3 {
 
 class Node;
@@ -38,12 +34,6 @@
 
 namespace ndn {
 
-namespace pit {
-class Entry;
-}
-
-class Face;
-
 /**
  * @ingroup ndn-tracers
  * @brief Base class for network-layer (incoming/outgoing Interests and Data) tracing of NDN stack
@@ -88,22 +78,22 @@
   Connect();
 
   virtual void
-  OutInterests(shared_ptr<const Interest>, shared_ptr<const Face>) = 0;
+  OutInterests(const Interest&, const Face&) = 0;
 
   virtual void
-  InInterests(shared_ptr<const Interest>, shared_ptr<const Face>) = 0;
+  InInterests(const Interest&, const Face&) = 0;
 
   virtual void
-  OutData(shared_ptr<const Data>, bool fromCache, shared_ptr<const Face>) = 0;
+  OutData(const Data&, const Face&) = 0;
 
   virtual void
-  InData(shared_ptr<const Data>, shared_ptr<const Face>) = 0;
+  InData(const Data&, const Face&) = 0;
 
-  virtual void
-  SatisfiedInterests(Ptr<const pit::Entry>) = 0;
+  // virtual void
+  // SatisfiedInterests(Ptr<const pit::Entry>) = 0;
 
-  virtual void
-  TimedOutInterests(Ptr<const pit::Entry>) = 0;
+  // virtual void
+  // TimedOutInterests(Ptr<const pit::Entry>) = 0;
 
 protected:
   std::string m_node;
@@ -117,21 +107,21 @@
       m_outInterests = 0;
       m_inData = 0;
       m_outData = 0;
-      m_satisfiedInterests = 0;
-      m_timedOutInterests = 0;
+      // m_satisfiedInterests = 0;
+      // m_timedOutInterests = 0;
 
-      m_outSatisfiedInterests = 0;
-      m_outTimedOutInterests = 0;
+      // m_outSatisfiedInterests = 0;
+      // m_outTimedOutInterests = 0;
     }
 
     double m_inInterests;
     double m_outInterests;
     double m_inData;
     double m_outData;
-    double m_satisfiedInterests;
-    double m_timedOutInterests;
-    double m_outSatisfiedInterests;
-    double m_outTimedOutInterests;
+    // double m_satisfiedInterests;
+    // double m_timedOutInterests;
+    // double m_outSatisfiedInterests;
+    // double m_outTimedOutInterests;
   };
 };
 
diff --git a/wscript b/wscript
index 9e378fe..0f078ca 100644
--- a/wscript
+++ b/wscript
@@ -85,7 +85,7 @@
     
     module.source = bld.path.ant_glob(['%s/**/*.cpp' % dir for dir in module_dirs],
                                       excl=['model/ip-faces/*',
-                                            'utils/*/*'])
+                                            'utils/topology/*'])
 
     module.full_headers = [p.path_from(bld.path) for p in bld.path.ant_glob(
         ['%s/**/*.hpp' % dir for dir in module_dirs])]