diff --git a/plugins/topology/rocketfuel-map-reader.cc b/plugins/topology/rocketfuel-map-reader.cc
new file mode 100644
index 0000000..bc44f14
--- /dev/null
+++ b/plugins/topology/rocketfuel-map-reader.cc
@@ -0,0 +1,788 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * 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:  Ilya Moiseenko <iliamo@cs.ucla.edu>
+ *          Hajime Tazaki (tazaki@sfc.wide.ad.jp)
+ *          Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ *
+ */
+
+#include "rocketfuel-map-reader.h"
+
+#include "ns3/nstime.h"
+#include "ns3/log.h"
+#include "ns3/fatal-error.h"
+#include "ns3/assert.h"
+#include "ns3/names.h"
+#include "ns3/net-device-container.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/drop-tail-queue.h"
+#include "ns3/ipv4-interface.h"
+#include "ns3/ipv4.h"
+#include "ns3/string.h"
+#include "ns3/pointer.h"
+#include "ns3/uinteger.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/node-list.h"
+#include "ns3/random-variable.h"
+
+#include "ns3/mobility-model.h"
+
+#include <regex.h>
+
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <boost/graph/graphviz.hpp>
+#include <boost/graph/connected_components.hpp>
+
+#include <iomanip>
+
+using namespace std;
+using namespace boost;
+
+NS_LOG_COMPONENT_DEFINE ("RocketfuelMapReader");
+
+namespace ns3 {
+
+RocketfuelMapReader::RocketfuelMapReader (const std::string &path/*=""*/, double scale/*=1.0*/, const std::string &referenceOspfRate)
+  : AnnotatedTopologyReader (path, scale)
+  , m_referenceOspfRate (boost::lexical_cast<DataRate> (referenceOspfRate))
+{
+}
+
+RocketfuelMapReader::~RocketfuelMapReader ()
+{
+}
+
+NodeContainer
+RocketfuelMapReader::Read ()
+{
+  NS_FATAL_ERROR ("Deprecated call. Use the other overloaded method instead");
+  return NodeContainer ();
+}
+
+
+/* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
+
+#define REGMATCH_MAX 16
+
+#define START "^"
+#define END "$"
+#define SPACE "[ \t]+"
+#define MAYSPACE "[ \t]*"
+
+#define ROCKETFUEL_MAPS_LINE \
+START "(-*[0-9]+)" SPACE "(@[?A-Za-z0-9,+]+)" SPACE \
+"(\\+)*" MAYSPACE "(bb)*" MAYSPACE \
+"\\(([0-9]+)\\)" SPACE "(&[0-9]+)*" MAYSPACE \
+"->" MAYSPACE "(<[0-9 \t<>]+>)*" MAYSPACE \
+"(\\{-[0-9\\{\\} \t-]+\\})*" SPACE \
+"=([A-Za-z0-9.!-]+)" SPACE "r([0-9])" \
+MAYSPACE END
+
+void
+RocketfuelMapReader::CreateLink (string nodeName1, string nodeName2,
+                                 double averageRtt,
+                                 const string &minBw, const string &maxBw,
+                                 const string &minDelay, const string &maxDelay)
+{
+  Ptr<Node> node1 = Names::Find<Node> (m_path, nodeName1);
+  Ptr<Node> node2 = Names::Find<Node> (m_path, nodeName2);
+  Link link (node1, nodeName1, node2, nodeName2);
+
+  DataRate randBandwidth
+    (m_randVar.GetInteger (static_cast<uint32_t> (lexical_cast<DataRate> (minBw).GetBitRate ()),
+                           static_cast<uint32_t> (lexical_cast<DataRate> (maxBw).GetBitRate ())));
+
+  int32_t metric = std::max (1, static_cast<int32_t> (1.0 * m_referenceOspfRate.GetBitRate () / randBandwidth.GetBitRate ()));
+
+  Time randDelay =
+    Time::FromDouble ((m_randVar.GetValue (lexical_cast<Time> (minDelay).ToDouble (Time::US),
+                                           lexical_cast<Time> (maxDelay).ToDouble (Time::US))),
+                      Time::US);
+
+  uint32_t queue = ceil (averageRtt * (randBandwidth.GetBitRate () / 8.0 / 1100.0));
+
+  link.SetAttribute ("DataRate",   boost::lexical_cast<string> (randBandwidth));
+  link.SetAttribute ("OSPF",       boost::lexical_cast<string> (metric));
+  link.SetAttribute ("Delay",      boost::lexical_cast<string> (ceil (randDelay.ToDouble (Time::US)))+"us");
+  link.SetAttribute ("MaxPackets", boost::lexical_cast<string> (queue));
+
+  AddLink (link);
+}
+
+// NodeContainer
+void
+RocketfuelMapReader::GenerateFromMapsFile (int argc, char *argv[])
+{
+  string uid;
+  string loc;
+  string ptr;
+  string name;
+  string nuid;
+  bool dns = false;
+  bool bb = false;
+  int num_neigh_s = 0;
+  unsigned int num_neigh = 0;
+  int radius = 0;
+  vector <string> neigh_list;
+
+  uid = argv[0];
+  loc = argv[1];
+
+  if (argv[2])
+  {
+    dns = true;
+  }
+
+  if (argv[3])
+  {
+    bb = true;
+  }
+
+  num_neigh_s = ::atoi (argv[4]);
+  if (num_neigh_s < 0)
+  {
+    num_neigh = 0;
+    NS_LOG_WARN ("Negative number of neighbors given");
+  }
+  else
+  {
+    num_neigh = num_neigh_s;
+  }
+
+  /* neighbors */
+  if (argv[6])
+  {
+    char *nbr;
+    char *stringp = argv[6];
+    while ((nbr = strsep (&stringp, " \t")) != NULL)
+    {
+      nbr[strlen (nbr) - 1] = '\0';
+      neigh_list.push_back (nbr + 1);
+    }
+  }
+
+  if (num_neigh != neigh_list.size ())
+  {
+    NS_LOG_WARN ("Given number of neighbors = " << num_neigh << " != size of neighbors list = " << neigh_list.size ());
+  }
+
+  /* externs */
+  if (argv[7])
+  {
+    //      euid = argv[7];
+  }
+
+  /* name */
+  if (argv[8])
+  {
+    name = argv[8];
+  }
+
+  radius = ::atoi (&argv[9][1]);
+  if (radius > 0)
+  {
+    return;
+  }
+
+  // Create node and link
+  if (uid.empty ())
+    return;
+
+
+  node_map_t::iterator node = m_graphNodes.find (uid);
+  if (node == m_graphNodes.end ())
+    {
+      bool ok;
+      tie (node, ok) = m_graphNodes.insert (make_pair (uid, add_vertex (nodeProperty (uid), m_graph)));
+      NS_ASSERT (ok == true);
+
+      put (vertex_index, m_graph, node->second, m_maxNodeId);
+      m_maxNodeId ++;
+    }
+
+  for (uint32_t i = 0; i < neigh_list.size (); ++i)
+    {
+      nuid = neigh_list[i];
+
+      if (nuid.empty ())
+        {
+          continue;
+        }
+
+      node_map_t::iterator otherNode = m_graphNodes.find (nuid);
+      if (otherNode == m_graphNodes.end ())
+        {
+          bool ok;
+          tie (otherNode, ok) = m_graphNodes.insert (make_pair (nuid, add_vertex(nodeProperty (nuid), m_graph)));
+          NS_ASSERT (ok == true);
+
+          put (vertex_index, m_graph, otherNode->second, m_maxNodeId);
+          m_maxNodeId ++;
+        }
+
+      // cout << node->second << " <-> " << otherNode->second << endl;
+      // parallel edges are disabled in the graph, so no need to worry
+      add_edge (node->second, otherNode->second, m_graph);
+    }
+}
+
+void RocketfuelMapReader::assignGw (Traits::vertex_descriptor vertex, uint32_t degree, node_type_t nodeType)
+{
+  graph_traits<Graph>::adjacency_iterator u, endu;
+  for (tie (u, endu) = adjacent_vertices (vertex, m_graph); u != endu; u++)
+    {
+      if (get (vertex_rank,  m_graph, *u) != UNKNOWN)
+        continue;
+
+      put (vertex_rank,  m_graph, *u, nodeType);
+      put (vertex_color, m_graph, *u, "green");
+
+      uint32_t u_degree = out_degree (*u, m_graph);
+      if (u_degree < degree)
+        assignGw (*u, degree, BACKBONE);
+    }
+};
+
+void
+RocketfuelMapReader::AssignClients (uint32_t clientDegree, uint32_t gwDegree)
+{
+  graph_traits<Graph>::vertex_iterator v, endv;
+  for (tie(v, endv) = vertices(m_graph); v != endv; v++)
+    {
+      uint32_t degree = out_degree (*v, m_graph);
+      if (degree == clientDegree)
+        {
+          put (vertex_rank,  m_graph, *v, CLIENT);
+          put (vertex_color, m_graph, *v, "red");
+
+          assignGw (*v, gwDegree+1, GATEWAY);
+        }
+    }
+};
+
+NodeContainer
+RocketfuelMapReader::Read (RocketfuelParams params, bool keepOneComponent/*=true*/, bool connectBackbones/*=true*/)
+{
+  m_maxNodeId = 0;
+
+  ifstream topgen;
+  topgen.open (GetFileName ().c_str ());
+  //NodeContainer nodes;
+  UniformVariable var;
+
+  istringstream lineBuffer;
+  string line;
+  int lineNumber = 0;
+  char errbuf[512];
+
+  if (!topgen.is_open ())
+  {
+    NS_LOG_WARN ("Couldn't open the file " << GetFileName ());
+    return m_nodes;
+  }
+
+  while (!topgen.eof ())
+  {
+    int ret;
+    int argc;
+    char *argv[REGMATCH_MAX];
+    char *buf;
+
+    lineNumber++;
+    line.clear ();
+    lineBuffer.clear ();
+
+    getline (topgen, line);
+    buf = (char *)line.c_str ();
+
+    regmatch_t regmatch[REGMATCH_MAX];
+    regex_t regex;
+
+    ret = regcomp (&regex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED | REG_NEWLINE);
+    if (ret != 0)
+    {
+      regerror (ret, &regex, errbuf, sizeof (errbuf));
+      regfree (&regex);
+      continue;
+    }
+
+    ret = regexec (&regex, buf, REGMATCH_MAX, regmatch, 0);
+    if (ret == REG_NOMATCH)
+    {
+      NS_LOG_WARN ("match failed (maps file): %s" << buf);
+      regfree (&regex);
+      continue;
+    }
+
+    line = buf;
+    argc = 0;
+
+    /* regmatch[0] is the entire strings that matched */
+    for (int i = 1; i < REGMATCH_MAX; i++)
+    {
+      if (regmatch[i].rm_so == -1)
+      {
+        argv[i - 1] = NULL;
+      }
+      else
+      {
+        line[regmatch[i].rm_eo] = '\0';
+        argv[i - 1] = &line[regmatch[i].rm_so];
+        argc = i;
+      }
+    }
+
+    GenerateFromMapsFile (argc, argv);
+    regfree (&regex);
+  }
+
+  if (keepOneComponent)
+    {
+      NS_LOG_DEBUG ("Before eliminating disconnected nodes: " << num_vertices(m_graph));
+      KeepOnlyBiggestConnectedComponent ();
+      NS_LOG_DEBUG ("After eliminating disconnected nodes:  " << num_vertices(m_graph));
+    }
+
+  for (int clientDegree = 1; clientDegree <= params.clientNodeDegrees; clientDegree++)
+    {
+      AssignClients (clientDegree, std::min (clientDegree, 3));
+    }
+
+  graph_traits<Graph>::vertex_iterator v, endv;
+  for (tie(v, endv) = vertices(m_graph); v != endv; v++)
+    {
+      node_type_t type = get (vertex_rank, m_graph, *v);
+      if (type == UNKNOWN)
+        {
+          put (vertex_rank,  m_graph, *v, BACKBONE);
+          put (vertex_color, m_graph, *v, "blue");
+        }
+    }
+
+  if (connectBackbones)
+    {
+      ConnectBackboneRouters ();
+    }
+
+  graph_traits<Graph>::edge_iterator e, ende;
+  for (tie (e, ende) = edges (m_graph); e != ende; )
+    {
+      Traits::vertex_descriptor
+        u = source (*e, m_graph),
+        v = target (*e, m_graph);
+
+      node_type_t
+        u_type = get (vertex_rank, m_graph, u),
+        v_type = get (vertex_rank, m_graph, v);
+
+      if (u_type == BACKBONE && v_type == BACKBONE)
+        {
+          // ok
+        }
+      else if ((u_type == GATEWAY  && v_type == BACKBONE) ||
+               (u_type == BACKBONE && v_type == GATEWAY ))
+        {
+          // ok
+        }
+      else if (u_type == GATEWAY  && v_type == GATEWAY)
+        {
+          // ok
+        }
+      else if ((u_type == GATEWAY  && v_type == CLIENT) ||
+               (u_type == CLIENT   && v_type == GATEWAY ))
+        {
+          // ok
+        }
+      else
+        {
+          // not ok
+          NS_LOG_DEBUG ("Wrong link type between nodes: " << u_type << " <-> " << v_type << " (deleting the link)");
+
+          graph_traits<Graph>::edge_iterator tmp = e;
+          tmp++;
+
+          remove_edge (*e, m_graph);
+          e = tmp;
+          continue;
+        }
+      e++;
+    }
+
+  if (keepOneComponent)
+    {
+      NS_LOG_DEBUG ("Before 2 eliminating disconnected nodes: " << num_vertices(m_graph));
+      KeepOnlyBiggestConnectedComponent ();
+      NS_LOG_DEBUG ("After 2 eliminating disconnected nodes:  " << num_vertices(m_graph));
+    }
+
+  for (tie(v, endv) = vertices(m_graph); v != endv; v++)
+    {
+      string nodeName = get (vertex_name, m_graph, *v);
+      Ptr<Node> node = CreateNode (nodeName, 0);
+
+      node_type_t type = get (vertex_rank, m_graph, *v);
+      switch (type)
+        {
+        case BACKBONE:
+          Names::Rename (nodeName, "bb-" + nodeName);
+          put (vertex_name, m_graph, *v, "bb-" + nodeName);
+          m_backboneRouters.Add (node);
+          break;
+        case CLIENT:
+          Names::Rename (nodeName, "leaf-" + nodeName);
+          put (vertex_name, m_graph, *v, "leaf-" + nodeName);
+          m_customerRouters.Add (node);
+          break;
+        case GATEWAY:
+          Names::Rename (nodeName, "gw-" + nodeName);
+          put (vertex_name, m_graph, *v, "gw-" + nodeName);
+          m_gatewayRouters.Add (node);
+          break;
+        case UNKNOWN:
+          NS_FATAL_ERROR ("Should not happen");
+          break;
+        }
+    }
+
+  for (tie (e, ende) = edges (m_graph); e != ende; e++)
+    {
+      Traits::vertex_descriptor
+        u = source (*e, m_graph),
+        v = target (*e, m_graph);
+
+      node_type_t
+        u_type = get (vertex_rank, m_graph, u),
+        v_type = get (vertex_rank, m_graph, v);
+
+      string
+        u_name = get (vertex_name, m_graph, u),
+        v_name = get (vertex_name, m_graph, v);
+
+      if (u_type == BACKBONE && v_type == BACKBONE)
+        {
+          CreateLink (u_name, v_name,
+                      params.averageRtt,
+                      params.minb2bBandwidth, params.maxb2bBandwidth,
+                      params.minb2bDelay,     params.maxb2bDelay);
+        }
+      else if ((u_type == GATEWAY  && v_type == BACKBONE) ||
+               (u_type == BACKBONE && v_type == GATEWAY ))
+        {
+          CreateLink (u_name, v_name,
+                      params.averageRtt,
+                      params.minb2gBandwidth, params.maxb2gBandwidth,
+                      params.minb2gDelay,     params.maxb2gDelay);
+        }
+      else if (u_type == GATEWAY  && v_type == GATEWAY)
+        {
+          CreateLink (u_name, v_name,
+                      params.averageRtt,
+                      params.minb2gBandwidth, params.maxb2gBandwidth,
+                      params.minb2gDelay,     params.maxb2gDelay);
+        }
+      else if ((u_type == GATEWAY  && v_type == CLIENT) ||
+               (u_type == CLIENT   && v_type == GATEWAY ))
+        {
+          CreateLink (u_name, v_name,
+                      params.averageRtt,
+                      params.ming2cBandwidth, params.maxg2cBandwidth,
+                      params.ming2cDelay,     params.maxg2cDelay);
+        }
+      else
+        {
+          NS_FATAL_ERROR ("Wrong link type between nodes: " << u_type << " <-> " << v_type);
+        }
+    }
+
+  ApplySettings ();
+
+  NS_LOG_INFO ("Clients:   " << m_customerRouters.GetN ());
+  NS_LOG_INFO ("Gateways:  " << m_gatewayRouters.GetN ());
+  NS_LOG_INFO ("Backbones: " << m_backboneRouters.GetN ());
+  NS_LOG_INFO ("Links:     " << GetLinks ().size ());
+
+  return m_nodes;
+}
+
+const NodeContainer &
+RocketfuelMapReader::GetBackboneRouters () const
+{
+  return m_backboneRouters;
+}
+
+const NodeContainer &
+RocketfuelMapReader::GetGatewayRouters () const
+{
+  return m_gatewayRouters;
+}
+
+const NodeContainer &
+RocketfuelMapReader::GetCustomerRouters () const
+{
+  return m_customerRouters;
+}
+
+void
+RocketfuelMapReader::SaveTopology (const std::string &file)
+{
+  ofstream os (file.c_str (), ios::trunc);
+  os << "# any empty lines and lines starting with '#' symbol is ignored\n"
+     << "\n"
+     << "# The file should contain exactly two sections: router and link, each starting with the corresponding keyword\n"
+     << "\n"
+     << "# router section defines topology nodes and their relative positions (e.g., to use in visualizer)\n"
+     << "router\n"
+     << "\n"
+     << "# each line in this section represents one router and should have the following data\n"
+     << "# node  comment     yPos    xPos\n";
+
+  auto nodeWriter = [&os](NodeContainer& m) {
+    for_each (m.Begin (), m.End (), [&os](Ptr<Node> node)
+    {
+      std::string name = Names::FindName (node);
+
+      os << name << "\t" << "NA" << "\t" << 0 << "\t" << 0 << "\n";
+    });
+  };
+
+  nodeWriter (m_backboneRouters);
+  nodeWriter (m_gatewayRouters);
+  nodeWriter (m_customerRouters);
+
+  os << "# link section defines point-to-point links between nodes and characteristics of these links\n"
+     << "\n"
+     << "link\n"
+     << "\n"
+     << "# Each line should be in the following format (only first two are required, the rest can be omitted)\n"
+     << "# srcNode   dstNode     bandwidth   metric  delay   queue\n"
+     << "# bandwidth: link bandwidth\n"
+     << "# metric: routing metric\n"
+     << "# delay:  link delay\n"
+     << "# queue:  MaxPackets for transmission queue on the link (both directions)\n";
+
+  for_each (m_linksList.begin (), m_linksList.end (), [&](const Link &link) {
+      string src = Names::FindName (link.GetFromNode ());
+      string dst = Names::FindName (link.GetToNode ());
+      os << src << "\t";
+      os << dst << "\t";
+
+      string tmp;
+      if (link.GetAttributeFailSafe ("DataRate", tmp))
+        os << link.GetAttribute("DataRate") << "\t";
+      else
+        NS_FATAL_ERROR ("DataRate must be specified for the link");
+
+      if (link.GetAttributeFailSafe ("OSPF", tmp))
+        os << link.GetAttribute("OSPF") << "\t";
+      else
+        {
+          DataRate rate = boost::lexical_cast<DataRate> (link.GetAttribute("DataRate"));
+
+          int32_t cost = std::max (1, static_cast<int32_t> (1.0 * m_referenceOspfRate.GetBitRate () / rate.GetBitRate ()));
+
+          os << cost << "\t";
+        }
+
+      if (link.GetAttributeFailSafe ("Delay", tmp))
+        {
+          os << link.GetAttribute("Delay") << "\t";
+
+          if (link.GetAttributeFailSafe ("MaxPackets", tmp))
+            {
+              os << link.GetAttribute("MaxPackets") << "\t";
+            }
+        }
+      os << "\n";
+    });
+}
+
+
+template <class Names, class Colors>
+class name_color_writer {
+public:
+  name_color_writer(Names _names, Colors _colors) : names(_names), colors(_colors) {}
+
+  template <class VertexOrEdge>
+  void operator()(std::ostream& out, const VertexOrEdge& v) const {
+    // out << "[label=\"" << names[v] << "\",style=filled,fillcolor=\"" << colors[v] << "\"]";
+    out << "[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"" << colors[v] << "\"]";
+  }
+private:
+  Names names;
+  Colors colors;
+};
+
+template <class Names, class Colors>
+inline name_color_writer<Names, Colors>
+make_name_color_writer(Names n, Colors c) {
+  return name_color_writer<Names, Colors>(n, c);
+}
+
+
+void
+RocketfuelMapReader::SaveGraphviz (const std::string &file)
+{
+  ofstream of (file.c_str ());
+  property_map<Graph, vertex_name_t>::type names = get (vertex_name, m_graph);
+  property_map<Graph, vertex_color_t>::type colors = get (vertex_color, m_graph);
+  write_graphviz(of, m_graph, make_name_color_writer (names, colors));
+}
+
+
+void
+RocketfuelMapReader::KeepOnlyBiggestConnectedComponent ()
+{
+  std::map<graph_traits<Graph>::vertex_descriptor, int> temp;
+  associative_property_map< std::map<graph_traits<Graph>::vertex_descriptor, int> > components (temp);
+
+  // //check if topology has breaks in its structure and trim it if yes
+  // property_map<Graph, vertex_index1_t>::type components = get (vertex_index1, m_graph);
+
+  int num = connected_components (m_graph, components);
+  NS_LOG_DEBUG ("Topology has " << num << " components");
+
+  vector<int> sizes (num, 0);
+
+  graph_traits<Graph>::vertex_iterator v, endv;
+  for (tie(v, endv) = vertices(m_graph); v != endv; v++)
+    {
+      sizes[ get (components, *v) ] ++;
+    }
+  int largestComponent = max_element (sizes.begin (), sizes.end ()) - sizes.begin ();
+  // cout << "Largest: " << largestComponent << endl;
+
+  // for (int i =0 ; i < num; i++) cout << sizes[i] << " ";
+  // cout << endl;
+
+  ////////////////////////////////////////////////////
+  // remove nodes and edges from smaller components //
+  ////////////////////////////////////////////////////
+  for (tie(v, endv) = vertices(m_graph); v != endv; v++)
+    {
+      if (get (components, *v) == largestComponent)
+        continue;
+
+      clear_vertex (*v, m_graph);
+    }
+
+  // this works only if vertices are organized in listS or setS (iterator is not invalidated on remove)
+  for (tie(v, endv) = vertices(m_graph); v != endv; )
+    {
+      if (get (components, *v) == largestComponent)
+        {
+          v++;
+          continue;
+        }
+
+      graph_traits<Graph>::vertex_iterator tmp = v;
+      tmp++;
+
+      remove_vertex (*v, m_graph);
+      v = tmp;
+    }
+
+  int index = 0;
+  // renumber nodes
+  for (tie(v, endv) = vertices(m_graph); v != endv; v++)
+    {
+      put (vertex_index, m_graph, *v, index++);
+    }
+}
+
+void
+RocketfuelMapReader::ConnectBackboneRouters ()
+{
+  // not the tricky part.  we want backbone to be a fully connected component,
+  // so traffic doesn't bounce from backbone to gateway and back
+
+  typedef adjacency_list< setS, setS, boost::undirectedS,
+                          property<vertex_name_t, Traits::vertex_descriptor, property
+                                   < vertex_index_t, int, property
+                                     < vertex_index1_t, int > > > > BbGraph;
+  BbGraph bbGraph;
+  map<Traits::vertex_descriptor, graph_traits<BbGraph>::vertex_descriptor> nodeMap;
+
+  int index = 0;
+
+  graph_traits<Graph>::vertex_iterator v, endv;
+  for (tie(v, endv) = vertices(m_graph); v != endv; v++)
+    {
+      node_type_t type = get (vertex_rank, m_graph, *v);
+      if (type == BACKBONE)
+        {
+          graph_traits<BbGraph>::vertex_descriptor newv = add_vertex (*v, bbGraph);
+          put (vertex_index, bbGraph, newv, index++);
+          nodeMap[*v] = newv;
+        }
+    }
+
+  graph_traits<BbGraph>::vertex_iterator bb, endBb;
+  for (tie (bb, endBb) = vertices (bbGraph); bb != endBb; bb++)
+    {
+      Traits::vertex_descriptor actualVertex = get (vertex_name, bbGraph, *bb);
+
+      graph_traits<Graph>::adjacency_iterator u, endu;
+      for (tie (u, endu) = adjacent_vertices (actualVertex, m_graph); u != endu; u++)
+        {
+          if (nodeMap.find (*u) != nodeMap.end ())
+            {
+              add_edge (nodeMap [actualVertex], nodeMap[*u], bbGraph);
+            }
+        }
+    }
+
+  property_map<BbGraph, vertex_index1_t>::type components = get (vertex_index1, bbGraph);
+
+  int num = connected_components (bbGraph, components);
+  NS_LOG_DEBUG ("Backbone has " << num << " components");
+  if (num == 1)
+    return; // nothing to do
+
+  vector< vector<graph_traits<BbGraph>::vertex_descriptor> > subgraphs (num);
+  for (tie (bb, endBb) = vertices (bbGraph); bb != endBb; bb++)
+    {
+      int component = get (vertex_index1, bbGraph, *bb);
+      subgraphs [component].push_back (*bb);
+    }
+
+  UniformVariable randVar;
+
+  for (int i = 1; i < num; i++)
+    {
+      int node1 = randVar.GetInteger (0, subgraphs[i-1].size ()-1);
+      int node2 = randVar.GetInteger (0, subgraphs[i].size ()-1);
+
+      Traits::vertex_descriptor
+        v1 = get (vertex_name, bbGraph, subgraphs[i-1][node1]),
+        v2 = get (vertex_name, bbGraph, subgraphs[i  ][node2]);
+
+      NS_LOG_DEBUG ("Connecting " << get (vertex_name, m_graph, v1) << "[" << node1 << "] with "
+                    << get (vertex_name, m_graph, v2) << "[" << node2 << "]");
+
+      add_edge (v1, v2, m_graph);
+    }
+}
+
+
+} /* namespace ns3 */
diff --git a/plugins/topology/rocketfuel-map-reader.h b/plugins/topology/rocketfuel-map-reader.h
new file mode 100644
index 0000000..34677d2
--- /dev/null
+++ b/plugins/topology/rocketfuel-map-reader.h
@@ -0,0 +1,184 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * 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:  Ilya Moiseenko <iliamo@cs.ucla.edu>
+ *          Hajime Tazaki (tazaki@sfc.wide.ad.jp)
+ *          Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#ifndef ROCKETFUEL_MAP_READER_H
+#define ROCKETFUEL_MAP_READER_H
+
+#include "ns3/annotated-topology-reader.h"
+#include "ns3/net-device-container.h"
+#include "ns3/random-variable.h"
+#include <set>
+#include "ns3/data-rate.h"
+
+#include <boost/graph/adjacency_list.hpp>
+
+using namespace std;
+
+namespace ns3 {
+
+struct RocketfuelParams
+{
+  double averageRtt;
+  int    clientNodeDegrees;
+
+  //parameters for links Backbone <->Backbone
+  string minb2bBandwidth;
+  string minb2bDelay;
+
+  string maxb2bBandwidth;
+  string maxb2bDelay;
+
+  //parameters for links Backbone<->Gateway and Gateway <-> Gateway
+  string minb2gBandwidth;
+  string minb2gDelay;
+
+  string maxb2gBandwidth;
+  string maxb2gDelay;
+
+  //parameters for links Gateway <-> Customer
+  string ming2cBandwidth;
+  string ming2cDelay;
+
+  string maxg2cBandwidth;
+  string maxg2cDelay;
+};
+
+/**
+ * \brief Topology file reader and topology estimator (extension of Rocketfuel-format type).
+ *
+ * http://www.cs.washington.edu/research/networking/rocketfuel/
+ *
+ * Only map file (.cch) is supported
+ *
+ * In addition to reading specified topology from the .cch file, this class divides nodes into three categories:
+ * - client nodes (nodes with degrees less or equal to RocketfuelParams.clientNodeDegrees
+ * - gateway nodes (nodes that directly connected to client nodes)
+ * - backbone nodes (all the rest)
+ *
+ * As some of the .cch files do not give a connected network graph, this reader also allows to keep only the largest connected
+ * network graph component.
+ */
+class RocketfuelMapReader : public AnnotatedTopologyReader
+{
+public:
+  RocketfuelMapReader (const std::string &path="", double scale=1.0, const string &referenceOspfRate="100Mbps");
+  virtual ~RocketfuelMapReader ();
+
+  /**
+   * @brief Deprecated call. Read (RocketfuelParams params, bool keepOneComponent=true, bool connectBackbones=true) should be used instead
+   */
+  virtual
+  NodeContainer
+  Read ();
+
+  /**
+   * \brief Main topology reading function.
+   *
+   * @param params parameters specifying range from which link bandwidths and delays should be assigned
+   * @param keepOneComponent if true, then only the largest connected component will be kept
+   * @param connectBackbones if true, then extra links will be added to ensure connectivity of estimated backbone
+   *
+   * This method opens an input stream and reads the Rocketfuel-format file.
+   * Every row represents a topology link (the ids of a couple of nodes),
+   * so the input file is read line by line to figure out how many links
+   * and nodes are in the topology.
+   *
+   * \return the container of the nodes created (or empty container if there was an error)
+   */
+  virtual NodeContainer
+  Read (RocketfuelParams params, bool keepOneComponent=true, bool connectBackbones=true);
+
+  const NodeContainer&
+  GetBackboneRouters() const;
+
+  const NodeContainer&
+  GetGatewayRouters() const;
+
+  const NodeContainer&
+  GetCustomerRouters() const;
+
+  void
+  SaveTopology (const std::string &file);
+
+  void
+  SaveGraphviz (const std::string &file);
+
+private:
+  RocketfuelMapReader (const RocketfuelMapReader&);
+  RocketfuelMapReader& operator= (const RocketfuelMapReader&);
+
+  // NodeContainer
+  void
+  GenerateFromMapsFile (int argc, char *argv[]);
+
+  void
+  CreateLink (string nodeName1, string nodeName2,
+              double averageRtt,
+              const string &minBw, const string &maxBw,
+              const string &minDelay, const string &maxDelay);
+  void
+  KeepOnlyBiggestConnectedComponent ();
+
+  void AssignClients(uint32_t clientDegree, uint32_t gwDegree);
+
+  void
+  ConnectBackboneRouters ();
+
+private:
+  UniformVariable m_randVar;
+
+  NodeContainer m_backboneRouters;
+  NodeContainer m_gatewayRouters;
+  NodeContainer m_customerRouters;
+
+  typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;
+
+  enum node_type_t {UNKNOWN = 0, CLIENT = 1, GATEWAY = 2, BACKBONE = 3};
+
+  typedef boost::property< boost::vertex_name_t, std::string, boost::property
+                           < boost::vertex_index_t, uint32_t, boost::property
+                             < boost::vertex_rank_t, node_type_t, boost::property
+                               < boost::vertex_color_t, std::string > > > > nodeProperty;
+
+  typedef boost::no_property edgeProperty;
+
+  typedef boost::adjacency_list< boost::setS, boost::setS, boost::undirectedS,
+                                 nodeProperty, edgeProperty > Graph;
+
+  typedef map<string, Traits::vertex_descriptor> node_map_t;
+  node_map_t m_graphNodes;
+
+  Graph      m_graph;
+  uint32_t     m_maxNodeId;
+
+  const DataRate m_referenceOspfRate; // reference rate of OSPF metric calculation
+
+
+private:
+  void
+  assignGw (Traits::vertex_descriptor vertex, uint32_t degree, node_type_t nodeType);
+}; // end class RocketfuelMapReader
+
+}; // end namespace ns3
+
+
+#endif /* ROCKETFUEL_MAP_READER_H */
diff --git a/tools/rocketfuel-maps-cch-to-annotaded.cc b/tools/rocketfuel-maps-cch-to-annotaded.cc
new file mode 100644
index 0000000..d9fa17e
--- /dev/null
+++ b/tools/rocketfuel-maps-cch-to-annotaded.cc
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * 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>
+ *         Ilya Moiseenko <iliamo@ucla.edu>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/log.h"
+#include "ns3/ndnSIM-module.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/random-variable.h"
+
+#include <boost/foreach.hpp>
+
+#include "ns3/ndnSIM/plugins/topology/rocketfuel-map-reader.h"
+
+using namespace ns3;
+using namespace std;
+
+int main (int argc, char**argv)
+{
+  string topology = "";
+  string output_prefix = "";
+  uint32_t run = 0;
+  int clientNodeDegrees = -1;
+  bool buildGraphvizGraph = false;
+  bool keepLargestComponent = false;
+  bool connectBackbones = false;
+
+  CommandLine cmd;
+  cmd.AddValue ("topology", "Topology filename (.ccn)", topology);
+  cmd.AddValue ("output",   "Prefix for output files", output_prefix);
+  cmd.AddValue ("run", "Run for ranged parameter randomization", run);
+  cmd.AddValue ("clients", "Maximum degree of client nodes", clientNodeDegrees);
+  cmd.AddValue ("buildGraph", "Whether or not build a graphviz graph (using neato)", buildGraphvizGraph);
+  cmd.AddValue ("keepLargestComponent", "Keep only largest connected component of the network graph", keepLargestComponent);
+  cmd.AddValue ("connectBackbones", "Make sure that ``backbone'' nodes are connected (adding extra links)", connectBackbones);
+  cmd.Parse (argc, argv);
+
+  /**
+   * @todo Make range parameters as command line arguments
+   */
+
+  if (topology == "")
+    {
+      cerr << "ERROR: topology needs to be specified" << endl;
+      cerr << endl;
+
+      cerr << cmd;
+      return 1;
+    }
+
+  if (output_prefix == "")
+    {
+      cerr << "ERROR: output needs to be specified" << endl;
+      cerr << endl;
+
+      cerr << cmd;
+      return 1;
+    }
+
+  if (run == 0)
+    {
+      cerr << "ERROR: run needs to be specified" << endl;
+      cerr << endl;
+
+      cerr << cmd;
+      return 1;
+    }
+
+  if (clientNodeDegrees < 0)
+    {
+      cerr << "ERROR: clients needs to be specified" << endl;
+      cerr << endl;
+
+      cerr << cmd;
+      return 1;
+    }
+
+  Config::SetGlobal ("RngRun", IntegerValue (run));
+  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::VisualSimulatorImpl"));
+
+  string input = topology;
+  string output = output_prefix+"-conv-annotated.txt";
+  string graph  = output_prefix+"-conv-annotated.dot";
+  string graph_pdf  = output_prefix+"-conv-annotated.pdf";
+
+  RocketfuelParams params;
+  params.clientNodeDegrees = clientNodeDegrees;
+  params.averageRtt = 0.25; // 250ms
+  //parameters for links Backbone<->Backbone
+  params.minb2bBandwidth = "40Mbps";
+  params.minb2bDelay = "5ms";
+
+  params.maxb2bBandwidth = "100Mbps";
+  params.maxb2bDelay = "10ms";
+
+  //parameters for links Backbone<->Gateway and Gateway <-> Gateway
+  params.minb2gBandwidth = "10Mbps";
+  params.minb2gDelay = "5ms";
+
+  params.maxb2gBandwidth = "20Mbps";
+  params.maxb2gDelay = "10ms";
+
+  //parameters for links Gateway <-> Customer
+  params.ming2cBandwidth ="1Mbps";
+  params.ming2cDelay = "70ms";
+
+  params.maxg2cBandwidth ="3Mbps";
+  params.maxg2cDelay = "10ms";
+
+  RocketfuelMapReader topologyReader ("/", 1.0);
+  topologyReader.SetFileName (input);
+  NodeContainer nodes = topologyReader.Read (params, keepLargestComponent, connectBackbones);
+  NodeContainer backboneRouters = topologyReader.GetBackboneRouters();
+  NodeContainer gatewayRouters = topologyReader.GetGatewayRouters();
+  NodeContainer customerRouters = topologyReader.GetCustomerRouters();
+  list<TopologyReader::Link> links = topologyReader.GetLinks();
+
+  topologyReader.SaveGraphviz (graph);
+  if (buildGraphvizGraph)
+    {
+      system (("neato -Tpdf \"" + graph + "\" > \"" + graph_pdf + "\"").c_str ());
+    }
+
+  topologyReader.SaveTopology (output);
+
+  // Names::Clear ();
+  // Simulator::Destroy ();
+
+  // // assign weights
+  // AnnotatedTopologyReader topologyReader2 ("", 1.0);
+  // topologyReader2.SetFileName (output);
+  // topologyReader2.Read ();
+
+  // char env[] = "NS_VIS_ASSIGN=1";
+  // putenv (env);
+
+  // Simulator::Stop (Seconds (0.0));
+  // Simulator::Run ();
+
+  // topologyReader2.SaveTopology (output);
+
+  // Simulator::Destroy ();
+  return 0;
+}
diff --git a/tools/wscript b/tools/wscript
new file mode 100644
index 0000000..6ebf98e
--- /dev/null
+++ b/tools/wscript
@@ -0,0 +1,6 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+    if 'topology' in bld.env['NDN_plugins']:
+        obj = bld.create_ns3_program('rocketfuel-maps-cch-to-annotaded', ['ndnSIM'])
+        obj.source = 'rocketfuel-maps-cch-to-annotaded.cc'
diff --git a/wscript b/wscript
index a48ff80..2460084 100644
--- a/wscript
+++ b/wscript
@@ -52,7 +52,7 @@
 
     if Options.options.disable_ndn_plugins:
         conf.env['NDN_plugins'] = conf.env['NDN_plugins'] - Options.options.disable_ndn_plugins.split(',')
-    
+
     conf.env['ENABLE_NDNSIM']=True;
     conf.env['MODULES_BUILT'].append('ndnSIM')
 
@@ -82,7 +82,7 @@
     if not bld.env['ENABLE_NDNSIM']:
         bld.env['MODULES_NOT_BUILT'].append('ndnSIM')
         return
-   
+
     module.source = bld.path.ant_glob(['model/**/*.cc',
                                        'apps/*.cc',
                                        'utils/**/*.cc',
@@ -116,12 +116,12 @@
 
         "model/fib/ndn-fib.h",
         "model/fib/ndn-fib-entry.h",
-        
+
         "model/pit/ndn-pit.h",
         "model/pit/ndn-pit-entry.h",
         "model/pit/ndn-pit-entry-incoming-face.h",
         "model/pit/ndn-pit-entry-outgoing-face.h",
-        
+
         "model/fw/ndn-forwarding-strategy.h",
         "model/fw/ndn-fw-tag.h",
 
@@ -137,6 +137,7 @@
             "plugins/topology/annotated-topology-reader.h",
             ])
         module.source.extend (bld.path.ant_glob(['plugins/topology/*.cc']))
+        module.full_headers.extend ([p.path_from(bld.path) for p in bld.path.ant_glob(['plugins/topology/**/*.h'])])
 
     if 'mobility' in bld.env['NDN_plugins']:
         headers.source.extend ([
@@ -144,16 +145,19 @@
             "plugins/mobility/spring-mobility-helper.h",
             ])
         module.source.extend (bld.path.ant_glob(['plugins/mobility/*.cc']))
+        module.full_headers.extend ([p.path_from(bld.path) for p in bld.path.ant_glob(['plugins/mobility/**/*.h'])])
 
     # bld.install_files('${INCLUDEDIR}/%s%s/ns3/ndnSIM' % (wutils.APPNAME, wutils.VERSION), ndnSIM_headers, relative_trick=True)
     # bld.install_files('$PREFIX/include', ndnSIM_headers)
-    
+
     tests = bld.create_ns3_module_test_library('ndnSIM')
     tests.source = bld.path.ant_glob('test/*.cc')
 
     if bld.env.ENABLE_EXAMPLES:
         bld.add_subdirs('examples')
 
+    bld.add_subdirs('tools')
+
     bld.ns3_python_bindings()
 
 
@@ -177,7 +181,7 @@
         task = self.create_task('ns3header')
         task.mode = getattr(self, 'mode', 'install')
         if task.mode == 'install':
-            self.bld.install_files('${INCLUDEDIR}/%s%s/ns3/%s' % (wutils.APPNAME, wutils.VERSION, relpath), 
+            self.bld.install_files('${INCLUDEDIR}/%s%s/ns3/%s' % (wutils.APPNAME, wutils.VERSION, relpath),
                                    [src_node])
             task.set_inputs([src_node])
             task.set_outputs([dst_node])
