diff --git a/examples/ndn-simple-for-nrt-helper.cpp b/examples/ndn-simple-for-nrt-helper.cpp
new file mode 100644
index 0000000..af67ac6
--- /dev/null
+++ b/examples/ndn-simple-for-nrt-helper.cpp
@@ -0,0 +1,131 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2016  Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/ndnSIM-module.h"
+
+/**
+ * This scenario simulates a very simple network topology:
+ *
+ *
+ *
+ *                             ----------------------------- (Producer)
+ *                            /                                   |
+ *                           /                                    |
+ *    (Consumer) ------ (Non-Producer-Region Router) ----- (Produer-Region-Network Router)
+ *                                                                |
+ *                                                                |
+ *                                                               ( )
+ *
+ *
+ *
+ *
+ * Consumer sends interest with Link object attatched. Non-Producer-Region Router will
+ * forward the interest based on Forwarding Hint(dalegationName in Link object) toward
+ * delegationName direction because the router is not in
+ * ProducerRegion. Producer-Region-Network checks incomming interests and finds out the
+ * interest has reached ProducerRegion, thus the router will forward the incoming interest
+ * based on interestName.
+ *
+ * For every received interest, producer replies with a data packet, containing 1024 bytes
+ * of virtual payload.
+ *
+ * To run scenario and see what is happening, use the following command:
+ *
+ *     NS_LOG=nfd.Forwarder=logic ./waf --run=ndn-simple-for-nrt-helper
+ */
+
+namespace ns3 {
+
+int
+main(int argc, char* argv[])
+{
+  // setting default parameters for PointToPoint links and channels
+  Config::SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("1Mbps"));
+  Config::SetDefault("ns3::PointToPointChannel::Delay", StringValue("10ms"));
+  Config::SetDefault("ns3::DropTailQueue::MaxPackets", StringValue("20"));
+
+  // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize
+  CommandLine cmd;
+  cmd.Parse(argc, argv);
+
+  // Creating nodes
+  Ptr<Node> consumer = CreateObject<Node>();
+  Ptr<Node> intRouter = CreateObject<Node>();
+  NodeContainer uclaRegion;
+  uclaRegion.Create(3);
+
+  // Connecting nodes using two links
+  PointToPointHelper p2p;
+  p2p.Install(consumer, intRouter);
+  p2p.Install(intRouter, uclaRegion.Get(0));
+  p2p.Install(intRouter, uclaRegion.Get(1));
+  p2p.Install(uclaRegion.Get(0), uclaRegion.Get(1));
+  p2p.Install(uclaRegion.Get(1), uclaRegion.Get(2));
+
+  // Install NDN stack on all nodes
+  ndn::StackHelper ndnHelper;
+  ndnHelper.SetDefaultRoutes(true);
+  ndnHelper.InstallAll();
+
+  // Install Routes Manually
+  ndn::FibHelper::AddRoute(intRouter, ndn::Name("/ucla"), uclaRegion.Get(1), 1);
+
+  // Configure NetworkRegionTable
+  ndn::NetworkRegionTableHelper::AddRegionName(uclaRegion, ndn::Name("/ucla"));
+
+  // Installing applications
+
+  // Consumer
+  ndn::AppHelper requesterHelper("RequesterApp");
+  requesterHelper.SetAttribute("Name", StringValue("/ndnSIM/someData"));
+  requesterHelper.SetAttribute("Delegation", StringValue("/ucla1"));
+  requesterHelper.Install(consumer).Start(Seconds(1));
+
+  requesterHelper.SetAttribute("Name", StringValue("/ndnSIM/anotherData"));
+  requesterHelper.Install(consumer).Start(Seconds(2));
+
+  requesterHelper.SetAttribute("Name", StringValue("/ndnSIM/yetAnotherData"));
+  requesterHelper.SetAttribute("Delegation", StringValue("/non-existing"));
+  requesterHelper.Install(consumer).Start(Seconds(3));
+
+  // Producer
+  ndn::AppHelper producerHelper("ns3::ndn::Producer");
+  producerHelper.SetPrefix("/ndnSIM");
+  producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
+  producerHelper.Install(uclaRegion.Get(0));
+
+  Simulator::Stop(Seconds(20.0));
+
+  Simulator::Run();
+  Simulator::Destroy();
+
+  return 0;
+}
+
+} // namespace ns3
+
+int
+main(int argc, char* argv[])
+{
+  return ns3::main(argc, argv);
+}
+
diff --git a/examples/ndn-simple-for-nrt-helper/requester-app.cpp b/examples/ndn-simple-for-nrt-helper/requester-app.cpp
new file mode 100644
index 0000000..6eee63c
--- /dev/null
+++ b/examples/ndn-simple-for-nrt-helper/requester-app.cpp
@@ -0,0 +1,111 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2016  Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "ns3/core-module.h"
+#include "ns3/ndnSIM/helper/ndn-stack-helper.hpp"
+#include "ns3/ndnSIM/apps/ndn-app.hpp"
+#include "ns3/ndnSIM/ndn-cxx/link.hpp"
+#include "ns3/ndnSIM/ndn-cxx/interest.hpp"
+
+NS_LOG_COMPONENT_DEFINE("RequesterApp");
+
+namespace ns3 {
+namespace ndn {
+
+class RequesterApp : public App
+{
+public:
+  static TypeId
+  GetTypeId()
+  {
+    static TypeId tid = TypeId("RequesterApp")
+      .SetParent<App>()
+      .AddConstructor<RequesterApp>()
+      .AddAttribute("Name", "Name of data to request",
+                    StringValue("/data/name"),
+                    MakeNameAccessor(&RequesterApp::m_name), MakeNameChecker())
+      .AddAttribute("Delegation", "Delegation name to attach to Interest",
+                    StringValue("/"),
+                    MakeNameAccessor(&RequesterApp::getDelegation, &RequesterApp::setDelegation), MakeNameChecker())
+      ;
+
+    return tid;
+  }
+
+protected:
+  virtual void
+  StartApplication() override
+  {
+    App::StartApplication();
+
+    Simulator::Schedule(Seconds(1.0), &RequesterApp::sendInterest, this);
+  }
+
+  virtual void
+  StopApplication() override
+  {
+    // do cleanup
+    App::StopApplication();
+    m_face->close();
+  }
+
+private:
+  void
+  setDelegation(const Name& delegation)
+  {
+    m_delegation = delegation;
+
+    m_link = ::ndn::Link(Name(m_name).append("/LINK"));
+    m_link.addDelegation(1, m_delegation);
+    ndn::StackHelper::getKeyChain().sign(m_link, ::ndn::security::SigningInfo(::ndn::security::SigningInfo::SIGNER_TYPE_SHA256));
+
+    NS_LOG_DEBUG("Created Link Object "<< m_link);
+  }
+
+  Name
+  getDelegation() const
+  {
+    return m_delegation;
+  }
+
+  void
+  sendInterest()
+  {
+    auto interest = make_shared<Interest>(m_name);
+    interest->setInterestLifetime(time::seconds(1));
+    if (m_delegation.size() > 0) {
+      interest->setLink(m_link.wireEncode());
+    }
+
+    NS_LOG_DEBUG("Sending an Interest for "<< *interest);
+
+    m_transmittedInterests(interest, this, m_face);
+    m_appLink->onReceiveInterest(*interest);
+  }
+
+private:
+  Name m_name;
+  Name m_delegation;
+  ::ndn::Link m_link;
+};
+
+NS_OBJECT_ENSURE_REGISTERED(RequesterApp);
+
+} // namespace ndn
+} // namespace ns3
diff --git a/helper/ndn-network-region-table-helper.cpp b/helper/ndn-network-region-table-helper.cpp
new file mode 100644
index 0000000..b9185bb
--- /dev/null
+++ b/helper/ndn-network-region-table-helper.cpp
@@ -0,0 +1,119 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2016  Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "ndn-network-region-table-helper.hpp"
+#include "ns3/ndnSIM/model/ndn-l3-protocol.hpp"
+#include "ns3/ndnSIM/NFD/daemon/fw/forwarder.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+NS_LOG_COMPONENT_DEFINE("ndn.NetworkRegionTableHelper");
+
+void
+NetworkRegionTableHelper::AddRegionName(Ptr<Node> node, const Name& region)
+{
+  NS_LOG_LOGIC("Node [" << node->GetId() << "]$ RegionName " << region << " is added into NetworkRegionTable ");
+
+  Ptr<L3Protocol> l3protocol = node->GetObject<L3Protocol>();
+  NS_ASSERT_MSG(l3protocol != 0, "Ndn stack should be installed on the node");
+
+  node->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().insert(region);
+}
+
+void
+NetworkRegionTableHelper::AddRegionName(NodeContainer& nodes, const ndn::Name& region)
+{
+  for (auto nodeIt = nodes.Begin(); nodeIt != nodes.End(); ++nodeIt) {
+    AddRegionName(*nodeIt, region);
+  }
+}
+
+void
+NetworkRegionTableHelper::AddRegionName(Ptr<Node> node, std::initializer_list<Name> regions)
+{
+  for (const auto& region : regions) {
+    AddRegionName(node, region);
+  }
+}
+
+void
+NetworkRegionTableHelper::AddRegionName(const NodeContainer& nodes, std::initializer_list<Name> regions)
+{
+  for (auto nodeIt = nodes.begin(); nodeIt != nodes.End(); ++nodeIt) {
+    AddRegionName(*nodeIt, regions);
+  }
+}
+
+void
+NetworkRegionTableHelper::RemoveRegionName(Ptr<Node> node, const Name& region)
+{
+  NS_LOG_LOGIC("Node [" << node->GetId() << "]$ RegionName " << region << " is removed from NetworkRegionTable ");
+
+  Ptr<L3Protocol> l3protocol = node->GetObject<L3Protocol>();
+  NS_ASSERT_MSG(l3protocol != 0, "Ndn stack should be installed on the node");
+
+  node->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().erase(region);
+}
+
+void
+NetworkRegionTableHelper::RemoveRegionName(const NodeContainer& nodes, const ndn::Name &region)
+{
+  for (auto nodeIt = nodes.begin(); nodeIt != nodes.End(); ++nodeIt) {
+    RemoveRegionName(*nodeIt, region);
+  }
+}
+
+void
+NetworkRegionTableHelper::RemoveRegionName(Ptr<Node> node, std::initializer_list<Name> regions)
+{
+  for (const auto& region : regions) {
+    RemoveRegionName(node, region);
+  }
+}
+
+void
+NetworkRegionTableHelper::RemoveRegionName(const NodeContainer& nodes, std::initializer_list<Name> regions)
+{
+  for (auto nodeIt = nodes.begin(); nodeIt != nodes.End(); ++nodeIt) {
+    RemoveRegionName(*nodeIt, regions);
+  }
+}
+
+void
+NetworkRegionTableHelper::EmptyNetworkRegionTable(Ptr<Node> node)
+{
+  NS_LOG_LOGIC("Node [" << node->GetId() << "]$ NetworkRegionTable is cleared");
+
+  Ptr<L3Protocol> l3protocol = node->GetObject<L3Protocol>();
+  NS_ASSERT_MSG(l3protocol != 0, "Ndn stack should be installed on the node");
+
+  node->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().clear();
+}
+
+void
+NetworkRegionTableHelper::EmptyNetworkRegionTable(const NodeContainer& nodes)
+{
+  for (auto nodeIt = nodes.begin(); nodeIt != nodes.End(); ++nodeIt) {
+    EmptyNetworkRegionTable(*nodeIt);
+  }
+}
+
+} // namespace ndn
+} // namespace ns3
diff --git a/helper/ndn-network-region-table-helper.hpp b/helper/ndn-network-region-table-helper.hpp
new file mode 100644
index 0000000..f087536
--- /dev/null
+++ b/helper/ndn-network-region-table-helper.hpp
@@ -0,0 +1,75 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2016  Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#ifndef NDNSIM_HELPER_NDN_NETWORK_REGION_TABLE_HELPER_HPP
+#define NDNSIM_HELPER_NDN_NETWORK_REGION_TABLE_HELPER_HPP
+
+#include "ns3/node-container.h"
+
+#include "ns3/ndnSIM/model/ndn-common.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+/**
+ * @ingroup ndn-helpers
+ * @brief Network Region Table Helper
+ *
+ * The NRT Helper interacts directly with Network Region Table by using set-like API
+ * in order to add/remove a prefix to/from the table or empty it in one node or
+ * a node container
+ */
+class NetworkRegionTableHelper
+{
+public:
+  static void
+  AddRegionName(Ptr<Node> node, const Name& regionName);
+
+  static void
+  AddRegionName(NodeContainer& c, const Name& regionName);
+
+  static void
+  AddRegionName(Ptr<Node> node, std::initializer_list<Name> regionNames);
+
+  static void
+  AddRegionName(const NodeContainer& c, std::initializer_list<Name> regionNames);
+
+  static void
+  RemoveRegionName(Ptr<Node> node, const Name& regionName);
+
+  static void
+  RemoveRegionName(const NodeContainer& c, const Name& regionName);
+
+  static void
+  RemoveRegionName(Ptr<Node> node, std::initializer_list<Name> regionNames);
+
+  static void
+  RemoveRegionName(const NodeContainer& c, std::initializer_list<Name> regionNames);
+
+  static void
+  EmptyNetworkRegionTable(Ptr<Node> node);
+
+  static void
+  EmptyNetworkRegionTable(const NodeContainer& c);
+};
+
+} // namespace ndn
+} // namespace ns3
+
+#endif // NDNSIM_HELPER_NDN_NETWORK_REGION_TABLE_HELPER_HPP
diff --git a/ndn-all.hpp b/ndn-all.hpp
index 3d531f5..30d97cd 100644
--- a/ndn-all.hpp
+++ b/ndn-all.hpp
@@ -23,6 +23,7 @@
 #include "ns3/ndnSIM/helper/ndn-stack-helper.hpp"
 #include "ns3/ndnSIM/helper/ndn-app-helper.hpp"
 #include "ns3/ndnSIM/helper/ndn-global-routing-helper.hpp"
+#include "ns3/ndnSIM/helper/ndn-network-region-table-helper.hpp"
 // #include "ns3/ndnSIM/helper/ndn-ip-faces-helper.hpp"
 // #include "ns3/ndnSIM/helper/ndn-link-control-helper.hpp"
 
diff --git a/tests/unit-tests/helper/ndn-network-region-table-helper.t.cpp b/tests/unit-tests/helper/ndn-network-region-table-helper.t.cpp
new file mode 100644
index 0000000..c683ae4
--- /dev/null
+++ b/tests/unit-tests/helper/ndn-network-region-table-helper.t.cpp
@@ -0,0 +1,228 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2016  Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "helper/ndn-network-region-table-helper.hpp"
+#include "helper/ndn-app-helper.hpp"
+
+#include "../tests-common.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+BOOST_AUTO_TEST_SUITE(HelperNdnNetworkRegionTableHelper)
+
+class BasicFixture : public ScenarioHelperWithCleanupFixture
+{
+public:
+  BasicFixture()
+  {
+    createTopology({
+     {"1"}
+    });
+  }
+
+  ~BasicFixture()
+  {
+  }
+};
+
+BOOST_FIXTURE_TEST_SUITE(Basic, BasicFixture)
+
+BOOST_AUTO_TEST_CASE(AddBase)
+{
+  NetworkRegionTableHelper::AddRegionName(getNode("1"), Name("/ucla"));
+  BOOST_CHECK_EQUAL(getNode("1")->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().count("/ucla"), 1);
+}
+
+BOOST_AUTO_TEST_CASE(RemoveBase){
+  NetworkRegionTableHelper::AddRegionName(getNode("1"), Name("/ucla"));
+  NetworkRegionTableHelper::RemoveRegionName(getNode("1"), Name("/ucla"));
+  BOOST_CHECK_EQUAL(getNode("1")->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().count("/ucla"), 0);
+}
+
+BOOST_AUTO_TEST_CASE(AddSet)
+{
+  NetworkRegionTableHelper::AddRegionName(getNode("1"), { Name("/ucla"), Name("/att") });
+  BOOST_CHECK_EQUAL(getNode("1")->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().count("/ucla"), 1);
+  BOOST_CHECK_EQUAL(getNode("1")->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().count("/att"), 1);
+  BOOST_CHECK_EQUAL(getNode("1")->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().size(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(RemoveSet)
+{
+  NetworkRegionTableHelper::AddRegionName(getNode("1"), { "/ucla", "/att" });
+  NetworkRegionTableHelper::RemoveRegionName(getNode("1"), { "/att", "/ucla" });
+  BOOST_CHECK_EQUAL(getNode("1")->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().empty(), true);
+}
+
+BOOST_AUTO_TEST_CASE(Empty)
+{
+  NetworkRegionTableHelper::AddRegionName(getNode("1"), { Name("/ucla"), Name("/att") });
+  NetworkRegionTableHelper::AddRegionName(getNode("1"), Name("/ndnSIM"));
+  NetworkRegionTableHelper::EmptyNetworkRegionTable(getNode("1"));
+  BOOST_CHECK_EQUAL(getNode("1")->GetObject<L3Protocol>()->getForwarder()->getNetworkRegionTable().empty(), true);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Basic
+
+class MultiNodeWithAppFixture;
+class TesterApp
+{
+public:
+  TesterApp(const Interest& interest, MultiNodeWithAppFixture* fixture);
+
+protected:
+  ::ndn::Face m_face;
+};
+
+Block
+makeLink(const Name& delegation)
+{
+  ::ndn::Link link("/LINK");
+  link.addDelegation(1, delegation);
+  ndn::StackHelper::getKeyChain().sign(link, ::ndn::security::SigningInfo(::ndn::security::SigningInfo::SIGNER_TYPE_SHA256));
+  return link.wireEncode();
+}
+
+class MultiNodeWithAppFixture : public ScenarioHelperWithCleanupFixture
+{
+public:
+  MultiNodeWithAppFixture()
+    : m_nData(0)
+    , m_nTimeouts(0)
+    , m_nNacks(0)
+  {
+    createTopology({
+        {"1", "2"}
+      });
+
+    addApps({
+        {"2", "ns3::ndn::Producer",
+            {{"Prefix", "/prefix"}, {"PayloadSize", "1024"}},
+            "0s", "100s"}
+      });
+
+    addRoutes({
+        {"1", "2", "/otherPrefix", 1},
+      });
+  }
+
+public:
+  size_t m_nData;
+  size_t m_nTimeouts;
+  size_t m_nNacks;
+};
+
+TesterApp::TesterApp(const Interest& interest, MultiNodeWithAppFixture* fixture)
+{
+  m_face.expressInterest(interest,
+                         std::bind([fixture] {
+                             ++fixture->m_nData;
+                           }),
+                         std::bind([fixture] {
+                             ++fixture->m_nTimeouts;
+                           }),
+                         std::bind([fixture] {
+                             ++fixture->m_nNacks;
+                           }));
+}
+
+
+BOOST_FIXTURE_TEST_SUITE(MultiNode, MultiNodeWithAppFixture)
+
+BOOST_AUTO_TEST_CASE(WithoutNetworkRegion)
+{
+  FactoryCallbackApp::Install(getNode("1"), [this] () -> shared_ptr<void> {
+      Interest i("/prefix/someData");
+      i.setLink(makeLink("/otherPrefix"));
+      return make_shared<TesterApp>(i, this);
+    })
+    .Start(Seconds(0.01));
+
+  Simulator::Stop(Seconds(20.001));
+  Simulator::Run();
+
+  BOOST_CHECK_EQUAL(this->m_nData, 0);
+  BOOST_CHECK_EQUAL(m_nTimeouts, 0);
+  BOOST_CHECK_EQUAL(m_nNacks, 1);
+}
+
+BOOST_AUTO_TEST_CASE(WithNetworkRegion)
+{
+  NetworkRegionTableHelper::AddRegionName(getNode("2"), Name("/otherPrefix"));
+
+  FactoryCallbackApp::Install(getNode("1"), [this] () -> shared_ptr<void> {
+      Interest i("/prefix/someData");
+      i.setLink(makeLink("/otherPrefix"));
+      return make_shared<TesterApp>(i, this);
+    })
+    .Start(Seconds(0.01));
+
+  Simulator::Stop(Seconds(20.001));
+  Simulator::Run();
+
+  BOOST_CHECK_EQUAL(m_nData, 1);
+  BOOST_CHECK_EQUAL(m_nTimeouts, 0);
+  BOOST_CHECK_EQUAL(m_nNacks, 0);
+}
+
+BOOST_AUTO_TEST_CASE(WithMoreSpecificNetworkRegion)
+{
+  NetworkRegionTableHelper::AddRegionName(getNode("2"), Name("/otherPrefix/moreSpecific"));
+
+  FactoryCallbackApp::Install(getNode("1"), [this] () -> shared_ptr<void> {
+      Interest i("/prefix/someData");
+      i.setLink(makeLink("/otherPrefix"));
+      return make_shared<TesterApp>(i, this);
+    })
+    .Start(Seconds(0.01));
+
+  Simulator::Stop(Seconds(20.001));
+  Simulator::Run();
+
+  BOOST_CHECK_EQUAL(m_nData, 1);
+  BOOST_CHECK_EQUAL(m_nTimeouts, 0);
+  BOOST_CHECK_EQUAL(m_nNacks, 0);
+}
+
+BOOST_AUTO_TEST_CASE(WithLessSpecificLink)
+{
+  NetworkRegionTableHelper::AddRegionName(getNode("2"), Name("/otherPrefix"));
+
+  FactoryCallbackApp::Install(getNode("1"), [this] () -> shared_ptr<void> {
+      Interest i("/prefix/someData");
+      i.setLink(makeLink("/otherPrefix/moreSpecific"));
+      return make_shared<TesterApp>(i, this);
+    })
+    .Start(Seconds(0.01));
+
+  Simulator::Stop(Seconds(20.001));
+  Simulator::Run();
+
+  BOOST_CHECK_EQUAL(m_nData, 0);
+  BOOST_CHECK_EQUAL(m_nTimeouts, 0);
+  BOOST_CHECK_EQUAL(m_nNacks, 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // MultiNode
+
+BOOST_AUTO_TEST_SUITE_END() // HelperNdnNetworkRegionTableHelper
+
+} // namespace ndn
+} // namespace ns3
