diff --git a/.jenkins.d/20-tests.sh b/.jenkins.d/20-tests.sh
index f12ee59..89ff5da 100755
--- a/.jenkins.d/20-tests.sh
+++ b/.jenkins.d/20-tests.sh
@@ -18,6 +18,7 @@
   sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-core || true
   sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-daemon || true
   sudo setcap cap_net_raw,cap_net_admin=eip `pwd`/build/unit-tests-rib || true
+  # unit-tests-tools does not need capabilities
 fi
 
 ndnsec-keygen "/tmp/jenkins/$NODE_NAME" | ndnsec-install-cert -
@@ -31,6 +32,8 @@
   ./build/unit-tests-daemon -l all -- --log_format2=XML --log_sink2=build/xunit-daemon-report.xml
 
   ./build/unit-tests-rib -l all -- --log_format2=XML --log_sink2=build/xunit-rib-report.xml
+
+  ./build/unit-tests-tools -l all -- --log_format2=XML --log_sink2=build/xunit-tools-report.xml
 else
   ./build/unit-tests-core -l test_suite
   sudo ./build/unit-tests-core -t TestPrivilegeHelper -l test_suite
@@ -38,4 +41,6 @@
   ./build/unit-tests-daemon -l test_suite
 
   ./build/unit-tests-rib -l test_suite
+
+  ./build/unit-tests-tools -l test_suite
 fi
diff --git a/tests/identity-management-fixture.hpp b/tests/identity-management-fixture.hpp
index 9774363..0f7d3c4 100644
--- a/tests/identity-management-fixture.hpp
+++ b/tests/identity-management-fixture.hpp
@@ -1,22 +1,26 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2014 Regents of the University of California.
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
  *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
  *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
+ * NFD 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.
  *
- * ndn-cxx library 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 Lesser General Public License for more details.
+ * NFD 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 copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef NFD_TESTS_IDENTITY_MANAGEMENT_FIXTURE_HPP
@@ -55,6 +59,11 @@
   std::vector<ndn::Name> m_identities;
 };
 
+class IdentityManagementTimeFixture : public UnitTestTimeFixture
+                                    , public IdentityManagementFixture
+{
+};
+
 } // namespace tests
 } // namespace nfd
 
diff --git a/tests/tools/nfd-status/channel-module.t.cpp b/tests/tools/nfd-status/channel-module.t.cpp
new file mode 100644
index 0000000..f524907
--- /dev/null
+++ b/tests/tools/nfd-status/channel-module.t.cpp
@@ -0,0 +1,75 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/channel-module.hpp"
+
+#include "module-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_FIXTURE_TEST_SUITE(TestChannelModule, ModuleFixture<ChannelModule>)
+
+const std::string STATUS_XML = stripXmlSpaces(R"XML(
+  <channels>
+    <channel>
+      <localUri>tcp4://192.0.2.1:6363</localUri>
+    </channel>
+    <channel>
+      <localUri>ws://[::]:9696/NFD</localUri>
+    </channel>
+  </channels>
+)XML");
+
+const std::string STATUS_TEXT = std::string(R"TEXT(
+Channels:
+  tcp4://192.0.2.1:6363
+  ws://[::]:9696/NFD
+)TEXT").substr(1);
+
+BOOST_AUTO_TEST_CASE(Status)
+{
+  this->fetchStatus();
+  ChannelStatus payload1;
+  payload1.setLocalUri("tcp4://192.0.2.1:6363");
+  ChannelStatus payload2;
+  payload2.setLocalUri("ws://[::]:9696/NFD");
+  this->sendDataset("/localhost/nfd/faces/channels", payload1, payload2);
+  this->prepareStatusOutput();
+
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestChannelModule
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/tools/nfd-status/face-module.t.cpp b/tests/tools/nfd-status/face-module.t.cpp
new file mode 100644
index 0000000..292ccd8
--- /dev/null
+++ b/tests/tools/nfd-status/face-module.t.cpp
@@ -0,0 +1,146 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/face-module.hpp"
+
+#include "module-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_FIXTURE_TEST_SUITE(TestFaceModule, ModuleFixture<FaceModule>)
+
+const std::string STATUS_XML = stripXmlSpaces(R"XML(
+  <faces>
+    <face>
+      <faceId>134</faceId>
+      <remoteUri>udp4://233.252.0.4:6363</remoteUri>
+      <localUri>udp4://192.0.2.1:6363</localUri>
+      <faceScope>non-local</faceScope>
+      <facePersistency>permanent</facePersistency>
+      <linkType>multi-access</linkType>
+      <packetCounters>
+        <incomingPackets>
+          <nInterests>22562</nInterests>
+          <nDatas>22031</nDatas>
+          <nNacks>63</nNacks>
+        </incomingPackets>
+        <outgoingPackets>
+          <nInterests>30121</nInterests>
+          <nDatas>20940</nDatas>
+          <nNacks>1218</nNacks>
+        </outgoingPackets>
+      </packetCounters>
+      <byteCounters>
+        <incomingBytes>2522915</incomingBytes>
+        <outgoingBytes>1353592</outgoingBytes>
+      </byteCounters>
+    </face>
+    <face>
+      <faceId>745</faceId>
+      <remoteUri>fd://75</remoteUri>
+      <localUri>unix:///var/run/nfd.sock</localUri>
+      <faceScope>local</faceScope>
+      <facePersistency>on-demand</facePersistency>
+      <linkType>point-to-point</linkType>
+      <packetCounters>
+        <incomingPackets>
+          <nInterests>18998</nInterests>
+          <nDatas>26701</nDatas>
+          <nNacks>147</nNacks>
+        </incomingPackets>
+        <outgoingPackets>
+          <nInterests>34779</nInterests>
+          <nDatas>17028</nDatas>
+          <nNacks>1176</nNacks>
+        </outgoingPackets>
+      </packetCounters>
+      <byteCounters>
+        <incomingBytes>4672308</incomingBytes>
+        <outgoingBytes>8957187</outgoingBytes>
+      </byteCounters>
+    </face>
+  </faces>
+)XML");
+
+const std::string STATUS_TEXT =
+  "Faces:\n"
+  "  faceid=134 remote=udp4://233.252.0.4:6363 local=udp4://192.0.2.1:6363"
+    " counters={in={22562i 22031d 63n 2522915B} out={30121i 20940d 1218n 1353592B}}"
+    " non-local permanent multi-access\n"
+  "  faceid=745 remote=fd://75 local=unix:///var/run/nfd.sock"
+    " counters={in={18998i 26701d 147n 4672308B} out={34779i 17028d 1176n 8957187B}}"
+    " local on-demand point-to-point\n";
+
+BOOST_AUTO_TEST_CASE(Status)
+{
+  this->fetchStatus();
+  FaceStatus payload1;
+  payload1.setFaceId(134)
+          .setRemoteUri("udp4://233.252.0.4:6363")
+          .setLocalUri("udp4://192.0.2.1:6363")
+          .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
+          .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT)
+          .setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS)
+          .setNInInterests(22562)
+          .setNInDatas(22031)
+          .setNInNacks(63)
+          .setNOutInterests(30121)
+          .setNOutDatas(20940)
+          .setNOutNacks(1218)
+          .setNInBytes(2522915)
+          .setNOutBytes(1353592);
+  FaceStatus payload2;
+  payload2.setFaceId(745)
+          .setRemoteUri("fd://75")
+          .setLocalUri("unix:///var/run/nfd.sock")
+          .setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL)
+          .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
+          .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
+          .setNInInterests(18998)
+          .setNInDatas(26701)
+          .setNInNacks(147)
+          .setNOutInterests(34779)
+          .setNOutDatas(17028)
+          .setNOutNacks(1176)
+          .setNInBytes(4672308)
+          .setNOutBytes(8957187);
+  this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
+  this->prepareStatusOutput();
+
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestFaceModule
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/tools/nfd-status/fib-module.t.cpp b/tests/tools/nfd-status/fib-module.t.cpp
new file mode 100644
index 0000000..f509461
--- /dev/null
+++ b/tests/tools/nfd-status/fib-module.t.cpp
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/fib-module.hpp"
+
+#include "module-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_FIXTURE_TEST_SUITE(TestFibModule, ModuleFixture<FibModule>)
+
+const std::string STATUS_XML = stripXmlSpaces(R"XML(
+  <fib>
+    <fibEntry>
+      <prefix>/</prefix>
+      <nextHops>
+        <nextHop>
+          <faceId>262</faceId>
+          <cost>9</cost>
+        </nextHop>
+        <nextHop>
+          <faceId>272</faceId>
+          <cost>50</cost>
+        </nextHop>
+        <nextHop>
+          <faceId>274</faceId>
+          <cost>78</cost>
+        </nextHop>
+      </nextHops>
+    </fibEntry>
+    <fibEntry>
+      <prefix>/localhost/nfd</prefix>
+      <nextHops>
+        <nextHop>
+          <faceId>1</faceId>
+          <cost>0</cost>
+        </nextHop>
+        <nextHop>
+          <faceId>274</faceId>
+          <cost>0</cost>
+        </nextHop>
+      </nextHops>
+    </fibEntry>
+  </fib>
+)XML");
+
+const std::string STATUS_TEXT = std::string(R"TEXT(
+FIB:
+  / nexthops={faceid=262 (cost=9), faceid=272 (cost=50), faceid=274 (cost=78)}
+  /localhost/nfd nexthops={faceid=1 (cost=0), faceid=274 (cost=0)}
+)TEXT").substr(1);
+
+BOOST_AUTO_TEST_CASE(Status)
+{
+  this->fetchStatus();
+  FibEntry payload1;
+  payload1.setPrefix("/")
+          .addNextHopRecord(NextHopRecord().setFaceId(262).setCost(9))
+          .addNextHopRecord(NextHopRecord().setFaceId(272).setCost(50))
+          .addNextHopRecord(NextHopRecord().setFaceId(274).setCost(78));
+  FibEntry payload2;
+  payload2.setPrefix("/localhost/nfd")
+          .addNextHopRecord(NextHopRecord().setFaceId(1).setCost(0))
+          .addNextHopRecord(NextHopRecord().setFaceId(274).setCost(0));
+  this->sendDataset("/localhost/nfd/fib/list", payload1, payload2);
+  this->prepareStatusOutput();
+
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestFibModule
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/tools/nfd-status/format-helpers.t.cpp b/tests/tools/nfd-status/format-helpers.t.cpp
new file mode 100644
index 0000000..01d7f47
--- /dev/null
+++ b/tests/tools/nfd-status/format-helpers.t.cpp
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/format-helpers.hpp"
+
+#include "tests/test-common.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+using boost::test_tools::output_test_stream;
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_AUTO_TEST_SUITE(TestFormatHelpers)
+
+BOOST_AUTO_TEST_SUITE(Xml)
+
+BOOST_AUTO_TEST_CASE(TextEscaping)
+{
+  output_test_stream os;
+  os << xml::Text{"\"less than\" & 'greater than' surround XML <element> tag name"};
+
+  BOOST_CHECK(os.is_equal("&quot;less than&quot; &amp; &apos;greater than&apos;"
+                          " surround XML &lt;element&gt; tag name"));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Xml
+
+BOOST_AUTO_TEST_SUITE(Text)
+
+BOOST_AUTO_TEST_CASE(Sep)
+{
+  output_test_stream os;
+  text::Separator sep(",");
+  for (int i = 1; i <= 3; ++i) {
+    os << sep << i;
+  }
+
+  BOOST_CHECK(os.is_equal("1,2,3"));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Text
+
+BOOST_AUTO_TEST_SUITE_END() // TestFormatHelpers
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/tools/nfd-status/forwarder-general-module.t.cpp b/tests/tools/nfd-status/forwarder-general-module.t.cpp
new file mode 100644
index 0000000..e9c881b
--- /dev/null
+++ b/tests/tools/nfd-status/forwarder-general-module.t.cpp
@@ -0,0 +1,156 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/forwarder-general-module.hpp"
+#include <ndn-cxx/security/signing-helpers.hpp>
+
+#include "module-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_FIXTURE_TEST_SUITE(TestForwarderGeneralModule, ModuleFixture<ForwarderGeneralModule>)
+
+class MakeNfdIdCollector
+{
+public:
+  unique_ptr<NfdIdCollector>
+  operator()(Face&, KeyChain&) const
+  {
+    return make_unique<NfdIdCollector>(make_unique<ValidatorNull>());
+  };
+};
+
+class ForwarderGeneralStatusFixture : public ModuleFixture<ForwarderGeneralModule,
+                                                           MakeNfdIdCollector>
+{
+protected:
+  ForwarderGeneralStatusFixture()
+  {
+    module.setNfdIdCollector(*validator);
+
+    this->systemClock->setNow(time::seconds(1468784936));
+    BOOST_REQUIRE(this->addIdentity("/nfd-status/test-nfdid"));
+  }
+
+private:
+  virtual void
+  signDatasetReply(Data& data) override
+  {
+    m_keyChain.sign(data, ndn::security::signingByIdentity("/nfd-status/test-nfdid"));
+  }
+};
+
+const std::string STATUS_XML = stripXmlSpaces(R"XML(
+  <generalStatus>
+    <nfdId>/nfd-status/test-nfdid/KEY/ksk-1468784936000/ID-CERT</nfdId>
+    <version>0.4.1-1-g704430c</version>
+    <startTime>2016-06-24T15:13:46.856000</startTime>
+    <currentTime>2016-07-17T17:55:54.109000</currentTime>
+    <uptime>PT1996927S</uptime>
+    <nNameTreeEntries>668</nNameTreeEntries>
+    <nFibEntries>70</nFibEntries>
+    <nPitEntries>7</nPitEntries>
+    <nMeasurementsEntries>1</nMeasurementsEntries>
+    <nCsEntries>65536</nCsEntries>
+    <packetCounters>
+      <incomingPackets>
+        <nInterests>20699052</nInterests>
+        <nDatas>5598070</nDatas>
+        <nNacks>7230</nNacks>
+      </incomingPackets>
+      <outgoingPackets>
+        <nInterests>36501092</nInterests>
+        <nDatas>5671942</nDatas>
+        <nNacks>26762</nNacks>
+      </outgoingPackets>
+    </packetCounters>
+  </generalStatus>
+)XML");
+
+const std::string STATUS_TEXT = std::string(R"TEXT(
+General NFD status:
+                 nfdId=/nfd-status/test-nfdid/KEY/ksk-1468784936000/ID-CERT
+               version=0.4.1-1-g704430c
+             startTime=20160624T151346.856000
+           currentTime=20160717T175554.109000
+                uptime=1996927 seconds
+      nNameTreeEntries=668
+           nFibEntries=70
+           nPitEntries=7
+  nMeasurementsEntries=1
+            nCsEntries=65536
+          nInInterests=20699052
+         nOutInterests=36501092
+              nInDatas=5598070
+             nOutDatas=5671942
+              nInNacks=7230
+             nOutNacks=26762
+)TEXT").substr(1);
+
+BOOST_FIXTURE_TEST_CASE(Status, ForwarderGeneralStatusFixture)
+{
+  this->fetchStatus();
+  ForwarderStatus payload;
+  payload.setNfdVersion("0.4.1-1-g704430c")
+         .setStartTimestamp(time::fromUnixTimestamp(time::milliseconds(1466781226856)))
+         .setCurrentTimestamp(time::fromUnixTimestamp(time::milliseconds(1468778154109)))
+         .setNNameTreeEntries(668)
+         .setNFibEntries(70)
+         .setNPitEntries(7)
+         .setNMeasurementsEntries(1)
+         .setNCsEntries(65536)
+         .setNInInterests(20699052)
+         .setNInDatas(5598070)
+         .setNInNacks(7230)
+         .setNOutInterests(36501092)
+         .setNOutDatas(5671942)
+         .setNOutNacks(26762);
+  this->sendDataset("/localhost/nfd/status/general", payload);
+  this->prepareStatusOutput();
+
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_CASE(StatusNoNfdId)
+{
+  this->fetchStatus();
+  ForwarderStatus payload;
+  payload.setNfdVersion("0.4.1-1-g704430c");
+  this->sendDataset("/localhost/nfd/status/general", payload);
+  BOOST_CHECK_NO_THROW(this->prepareStatusOutput());
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestForwarderGeneralModule
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/tools/nfd-status/module-fixture.hpp b/tests/tools/nfd-status/module-fixture.hpp
new file mode 100644
index 0000000..38d0d64
--- /dev/null
+++ b/tests/tools/nfd-status/module-fixture.hpp
@@ -0,0 +1,236 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TESTS_TOOLS_NFD_STATUS_MODULE_FIXTURE_HPP
+#define NFD_TESTS_TOOLS_NFD_STATUS_MODULE_FIXTURE_HPP
+
+#include "nfd-status/module.hpp"
+#include <ndn-cxx/security/validator-null.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+#include "tests/test-common.hpp"
+#include "tests/identity-management-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+using namespace nfd::tests;
+using ndn::Face;
+using ndn::KeyChain;
+using ndn::Validator;
+using ndn::ValidatorNull;
+using ndn::util::DummyClientFace;
+using boost::test_tools::output_test_stream;
+
+class MakeValidatorNull
+{
+public:
+  unique_ptr<ValidatorNull>
+  operator()(Face&, KeyChain&) const
+  {
+    return make_unique<ValidatorNull>();
+  };
+};
+
+/** \brief fixture to test a \p Module
+ *  \tparam MODULE a subclass of \p Module
+ *  \tparam MakeValidator a callable to make a Validator for use in \p controller;
+ *                        MakeValidator()(Face&, KeyChain&) should return a unique_ptr
+ *                        to Validator or its subclass
+ */
+template<typename MODULE, typename MakeValidator = MakeValidatorNull>
+class ModuleFixture : public UnitTestTimeFixture
+                    , public IdentityManagementFixture
+{
+protected:
+  typedef typename std::result_of<MakeValidator(Face&, KeyChain&)>::type ValidatorUniquePtr;
+
+  ModuleFixture()
+    : face(g_io, m_keyChain)
+    , validator(MakeValidator()(face, m_keyChain))
+    , controller(face, m_keyChain, *validator)
+    , nFetchStatusSuccess(0)
+  {
+  }
+
+protected: // status fetching
+  /** \brief start fetching status
+   *
+   *  A test case should call \p fetchStatus, \p sendDataset, and \p prepareStatusOutput
+   *  in this order, and then check \p statusXml and \p statusText contain the correct outputs.
+   *  No advanceClocks is needed in between, as they are handled by the fixture.
+   */
+  void
+  fetchStatus()
+  {
+    nFetchStatusSuccess = 0;
+    module.fetchStatus(controller, [this] { ++nFetchStatusSuccess; },
+                       [this] (uint32_t code, const std::string& reason) {
+                         BOOST_FAIL("fetchStatus failure " << code << " " << reason);
+                       },
+                       CommandOptions());
+    this->advanceClocks(time::milliseconds(1));
+  }
+
+  /** \brief send one WireEncodable in reply to StatusDataset request
+   *  \param prefix dataset prefix without version and segment
+   *  \param payload payload block
+   *  \note payload must fit in one Data
+   *  \pre fetchStatus has been invoked, sendDataset has not been invoked
+   */
+  template<typename T>
+  void
+  sendDataset(const Name& prefix, const T& payload)
+  {
+    BOOST_CONCEPT_ASSERT((ndn::WireEncodable<T>));
+
+    this->sendDatasetReply(prefix, payload.wireEncode());
+  }
+
+  /** \brief send two WireEncodables in reply to StatusDataset request
+   *  \param prefix dataset prefix without version and segment
+   *  \param payload1 first vector item
+   *  \param payload2 second vector item
+   *  \note all payloads must fit in one Data
+   *  \pre fetchStatus has been invoked, sendDataset has not been invoked
+   */
+  template<typename T1, typename T2>
+  void
+  sendDataset(const Name& prefix, const T1& payload1, const T2& payload2)
+  {
+    BOOST_CONCEPT_ASSERT((ndn::WireEncodable<T1>));
+    BOOST_CONCEPT_ASSERT((ndn::WireEncodable<T2>));
+
+    ndn::encoding::EncodingBuffer buffer;
+    payload2.wireEncode(buffer);
+    payload1.wireEncode(buffer);
+
+    this->sendDatasetReply(prefix, buffer.buf(), buffer.size());
+  }
+
+  /** \brief prepare status output as XML and text
+   *  \pre sendDataset has been invoked
+   */
+  void
+  prepareStatusOutput()
+  {
+    this->advanceClocks(time::milliseconds(1));
+    BOOST_REQUIRE_EQUAL(nFetchStatusSuccess, 1);
+
+    statusXml.str("");
+    module.formatStatusXml(statusXml);
+    statusText.str("");
+    module.formatStatusText(statusText);
+  }
+
+private:
+  /** \brief send a payload in reply to StatusDataset request
+   *  \param prefix dataset prefix without version and segment
+   *  \param contentArgs passed to Data::setContent
+   */
+  template<typename ...ContentArgs>
+  void
+  sendDatasetReply(const Name& prefix, ContentArgs&&...contentArgs)
+  {
+    Name name = prefix;
+    name.appendVersion().appendSegment(0);
+
+    // These warnings assist in debugging a `nFetchStatusSuccess != 1` check failure.
+    // They usually indicate a misspelled prefix or incorrect timing in the test case.
+    if (face.sentInterests.size() < 1) {
+      BOOST_WARN_MESSAGE(false, "no Interest expressed");
+    }
+    else {
+      BOOST_WARN_MESSAGE(face.sentInterests.back().getName().isPrefixOf(name),
+                         "last Interest " << face.sentInterests.back().getName() <<
+                         " cannot be satisfied by this Data " << name);
+    }
+
+    auto data = make_shared<Data>(name);
+    data->setFinalBlockId(name[-1]);
+    data->setContent(std::forward<ContentArgs>(contentArgs)...);
+    this->signDatasetReply(*data);
+    face.receive(*data);
+  }
+
+  virtual void
+  signDatasetReply(Data& data)
+  {
+    signData(data);
+  }
+
+protected:
+  DummyClientFace face;
+  ValidatorUniquePtr validator;
+  Controller controller;
+
+  MODULE module;
+
+  int nFetchStatusSuccess;
+  output_test_stream statusXml;
+  output_test_stream statusText;
+};
+
+/** \brief strips leading spaces on every line in expected XML
+ *
+ *  This allows expected XML to be written as:
+ *  \code
+ *  const std::string STATUS_XML = stripXmlSpaces(R"XML(
+ *    <rootElement>
+ *      <element>value</element>
+ *    </rootElement>
+ *  )XML");
+ *  \endcode
+ *  And \p STATUS_XML would be assigned:
+ *  \code
+ *  "<rootElement><element>value</element></rootElement>"
+ *  \endcode
+ */
+inline std::string
+stripXmlSpaces(const std::string& xml)
+{
+  std::string s;
+  bool isSkipping = true;
+  std::copy_if(xml.begin(), xml.end(), std::back_inserter(s),
+               [&isSkipping] (char ch) {
+                 if (ch == '\n') {
+                   isSkipping = true;
+                 }
+                 else if (ch != ' ') {
+                   isSkipping = false;
+                 }
+                 return !isSkipping;
+               });
+  return s;
+}
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TESTS_TOOLS_NFD_STATUS_MODULE_FIXTURE_HPP
diff --git a/tests/tools/nfd-status/rib-module.t.cpp b/tests/tools/nfd-status/rib-module.t.cpp
new file mode 100644
index 0000000..bfd663c
--- /dev/null
+++ b/tests/tools/nfd-status/rib-module.t.cpp
@@ -0,0 +1,141 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/rib-module.hpp"
+
+#include "module-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_FIXTURE_TEST_SUITE(TestRibModule, ModuleFixture<RibModule>)
+
+const std::string STATUS_XML = stripXmlSpaces(R"XML(
+  <rib>
+    <ribEntry>
+      <prefix>/</prefix>
+      <routes>
+        <route>
+          <faceId>262</faceId>
+          <origin>255</origin>
+          <cost>9</cost>
+          <flags>
+            <ribCapture/>
+          </flags>
+        </route>
+        <route>
+          <faceId>272</faceId>
+          <origin>255</origin>
+          <cost>50</cost>
+          <flags/>
+        </route>
+        <route>
+          <faceId>274</faceId>
+          <origin>255</origin>
+          <cost>78</cost>
+          <flags>
+            <childInherit/>
+            <ribCapture/>
+          </flags>
+        </route>
+        <route>
+          <faceId>276</faceId>
+          <origin>255</origin>
+          <cost>79</cost>
+          <flags>
+            <childInherit/>
+          </flags>
+          <expirationPeriod>PT47S</expirationPeriod>
+        </route>
+      </routes>
+    </ribEntry>
+    <ribEntry>
+      <prefix>/localhost/nfd</prefix>
+      <routes>
+        <route>
+          <faceId>258</faceId>
+          <origin>0</origin>
+          <cost>0</cost>
+          <flags>
+            <childInherit/>
+          </flags>
+        </route>
+      </routes>
+    </ribEntry>
+  </rib>
+)XML");
+
+const std::string STATUS_TEXT =
+  "RIB:\n"
+  "  / route={faceid=262 (origin=255 cost=9 RibCapture), faceid=272 (origin=255 cost=50), "
+    "faceid=274 (origin=255 cost=78 ChildInherit RibCapture), "
+    "faceid=276 (origin=255 cost=79 expires=47s ChildInherit)}\n"
+  "  /localhost/nfd route={faceid=258 (origin=0 cost=0 ChildInherit)}\n";
+
+BOOST_AUTO_TEST_CASE(Status)
+{
+  this->fetchStatus();
+  RibEntry payload1;
+  payload1.setName("/")
+          .addRoute(Route().setFaceId(262)
+                           .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
+                           .setCost(9)
+                           .setFlags(ndn::nfd::ROUTE_FLAG_CAPTURE))
+          .addRoute(Route().setFaceId(272)
+                           .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
+                           .setCost(50)
+                           .setFlags(ndn::nfd::ROUTE_FLAGS_NONE))
+          .addRoute(Route().setFaceId(274)
+                           .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
+                           .setCost(78)
+                           .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE))
+          .addRoute(Route().setFaceId(276)
+                           .setOrigin(ndn::nfd::ROUTE_ORIGIN_STATIC)
+                           .setCost(79)
+                           .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
+                           .setExpirationPeriod(time::milliseconds(47292)));
+  RibEntry payload2;
+  payload2.setName("/localhost/nfd")
+          .addRoute(Route().setFaceId(258)
+                           .setOrigin(ndn::nfd::ROUTE_ORIGIN_APP)
+                           .setCost(0)
+                           .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT));
+  this->sendDataset("/localhost/nfd/rib/list", payload1, payload2);
+  this->prepareStatusOutput();
+
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestRibModule
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/tools/nfd-status/status-report.t.cpp b/tests/tools/nfd-status/status-report.t.cpp
new file mode 100644
index 0000000..309c83a
--- /dev/null
+++ b/tests/tools/nfd-status/status-report.t.cpp
@@ -0,0 +1,220 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/status-report.hpp"
+#include "core/scheduler.hpp"
+
+#include "module-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+const std::string STATUS_XML = stripXmlSpaces(R"XML(
+  <?xml version="1.0"?>
+  <nfdStatus xmlns="ndn:/localhost/nfd/status/1">
+    <module1/>
+    <module2/>
+  </nfdStatus>
+)XML");
+
+const std::string STATUS_TEXT = std::string(R"TEXT(
+module1
+module2
+)TEXT").substr(1);
+
+class DummyModule : public Module
+{
+public:
+  explicit
+  DummyModule(const std::string& moduleName)
+    : m_moduleName(moduleName)
+    , m_res(0)
+    , m_delay(time::milliseconds(1))
+  {
+  }
+
+  /** \brief cause fetchStatus to succeed or fail
+   *  \param res zero to succeed, non-zero to fail with specific code
+   *  \param delay duration from fetchStatus invocation to succeed or fail; must be positive
+   */
+  void
+  setResult(uint32_t res, time::nanoseconds delay)
+  {
+    BOOST_ASSERT(delay > time::nanoseconds::zero());
+    m_res = res;
+    m_delay = delay;
+  }
+
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) override
+  {
+    ++nFetchStatusCalls;
+    scheduler::schedule(m_delay, [=] {
+      if (m_res == 0) {
+        onSuccess();
+      }
+      else {
+        onFailure(m_res, m_moduleName + " fails with code " + to_string(m_res));
+      }
+    });
+  }
+
+  virtual void
+  formatStatusXml(std::ostream& os) const override
+  {
+    os << '<' << m_moduleName << "/>";
+  }
+
+  virtual void
+  formatStatusText(std::ostream& os) const override
+  {
+    os << m_moduleName << '\n';
+  }
+
+public:
+  int nFetchStatusCalls = 0;
+
+private:
+  std::string m_moduleName;
+  uint32_t m_res;
+  time::nanoseconds m_delay;
+};
+
+class StatusReportTester : public StatusReport
+{
+private:
+  virtual void
+  processEvents(Face&) override
+  {
+    processEventsFunc();
+  }
+
+public:
+  std::function<void()> processEventsFunc;
+};
+
+class StatusReportModulesFixture : public IdentityManagementTimeFixture
+{
+protected:
+  StatusReportModulesFixture()
+    : face(g_io, m_keyChain)
+    , controller(face, m_keyChain, validator)
+    , res(0)
+  {
+  }
+
+  DummyModule&
+  addModule(const std::string& moduleName)
+  {
+    report.sections.push_back(make_unique<DummyModule>(moduleName));
+    return static_cast<DummyModule&>(*report.sections.back());
+  }
+
+  void
+  collect(time::nanoseconds tick, size_t nTicks)
+  {
+    report.processEventsFunc = [=] {
+      this->advanceClocks(tick, nTicks);
+    };
+    res = report.collect(face, m_keyChain, validator, CommandOptions());
+
+    if (res == 0) {
+      statusXml.str("");
+      report.formatXml(statusXml);
+      statusText.str("");
+      report.formatText(statusText);
+    }
+  }
+
+protected:
+  DummyClientFace face;
+  ValidatorNull validator;
+  Controller controller;
+  StatusReportTester report;
+
+  uint32_t res;
+  output_test_stream statusXml;
+  output_test_stream statusText;
+};
+
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)
+
+BOOST_AUTO_TEST_CASE(Normal)
+{
+  DummyModule& m1 = addModule("module1");
+  m1.setResult(0, time::milliseconds(10));
+  DummyModule& m2 = addModule("module2");
+  m2.setResult(0, time::milliseconds(20));
+
+  this->collect(time::milliseconds(5), 6);
+
+  BOOST_CHECK_EQUAL(m1.nFetchStatusCalls, 1);
+  BOOST_CHECK_EQUAL(m2.nFetchStatusCalls, 1);
+
+  BOOST_CHECK_EQUAL(res, 0);
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_CASE(Reorder)
+{
+  DummyModule& m1 = addModule("module1");
+  m1.setResult(0, time::milliseconds(20));
+  DummyModule& m2 = addModule("module2");
+  m2.setResult(0, time::milliseconds(10)); // module2 completes earlier than module1
+
+  this->collect(time::milliseconds(5), 6);
+
+  BOOST_CHECK_EQUAL(res, 0);
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML)); // output is still in order
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_CASE(Error)
+{
+  DummyModule& m1 = addModule("module1");
+  m1.setResult(0, time::milliseconds(20));
+  DummyModule& m2 = addModule("module2");
+  m2.setResult(500, time::milliseconds(10));
+
+  this->collect(time::milliseconds(5), 6);
+
+  BOOST_CHECK_EQUAL(res, 1000500);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestRibModule
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/tools/nfd-status/strategy-choice-module.t.cpp b/tests/tools/nfd-status/strategy-choice-module.t.cpp
new file mode 100644
index 0000000..a41ba1f
--- /dev/null
+++ b/tests/tools/nfd-status/strategy-choice-module.t.cpp
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-status/strategy-choice-module.hpp"
+
+#include "module-fixture.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(NfdStatus)
+BOOST_FIXTURE_TEST_SUITE(TestStrategyChoiceModule, ModuleFixture<StrategyChoiceModule>)
+
+const std::string STATUS_XML = stripXmlSpaces(R"XML(
+  <strategyChoices>
+    <strategyChoice>
+      <namespace>/</namespace>
+      <strategy>
+        <name>/localhost/nfd/strategy/best-route/%FD%04</name>
+      </strategy>
+    </strategyChoice>
+    <strategyChoice>
+      <namespace>/localhost</namespace>
+      <strategy>
+        <name>/localhost/nfd/strategy/multicast/%FD%01</name>
+      </strategy>
+    </strategyChoice>
+  </strategyChoices>
+)XML");
+
+const std::string STATUS_TEXT = std::string(R"TEXT(
+Strategy choices:
+  / strategy=/localhost/nfd/strategy/best-route/%FD%04
+  /localhost strategy=/localhost/nfd/strategy/multicast/%FD%01
+)TEXT").substr(1);
+
+BOOST_AUTO_TEST_CASE(Status)
+{
+  this->fetchStatus();
+  StrategyChoice payload1;
+  payload1.setName("/")
+          .setStrategy("/localhost/nfd/strategy/best-route/%FD%04");
+  StrategyChoice payload2;
+  payload2.setName("/localhost")
+          .setStrategy("/localhost/nfd/strategy/multicast/%FD%01");
+  this->sendDataset("/localhost/nfd/strategy-choice/list", payload1, payload2);
+  this->prepareStatusOutput();
+
+  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
+  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoiceModule
+BOOST_AUTO_TEST_SUITE_END() // NfdStatus
+
+} // namespace tests
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tests/wscript b/tests/wscript
index 3d080aa..dc82fe6 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -40,9 +40,10 @@
             defines='UNIT_TEST_CONFIG_PATH=\"%s/tmp-files/\"' % bld.bldnode,
           )
 
-        for module, name in {"core": "NFD Core Tests",
-                             "daemon": "NFD Daemon Tests",
-                             "rib": "NFD RIB Tests"}.items():
+        for module, name in {"core": "Core Tests",
+                             "daemon": "Daemon Tests",
+                             "rib": "RIB Tests",
+                             "tools": "Tools Tests"}.items():
             # main()
             bld(target='unit-tests-%s-main' % module,
                 name='unit-tests-%s-main' % module,
diff --git a/tools/nfd-status.cpp b/tools/nfd-status.cpp
deleted file mode 100644
index 21c62a1..0000000
--- a/tools/nfd-status.cpp
+++ /dev/null
@@ -1,926 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
- *                           Arizona Board of Regents,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University,
- *                           Washington University in St. Louis,
- *                           Beijing Institute of Technology,
- *                           The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD 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.
- *
- * NFD 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
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
- */
-
-#include "version.hpp"
-#include "common.hpp"
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/name.hpp>
-#include <ndn-cxx/interest.hpp>
-#include <ndn-cxx/encoding/buffer-stream.hpp>
-
-#include <ndn-cxx/management/nfd-forwarder-status.hpp>
-#include <ndn-cxx/management/nfd-channel-status.hpp>
-#include <ndn-cxx/management/nfd-face-status.hpp>
-#include <ndn-cxx/management/nfd-fib-entry.hpp>
-#include <ndn-cxx/management/nfd-rib-entry.hpp>
-#include <ndn-cxx/management/nfd-strategy-choice.hpp>
-#include <ndn-cxx/util/segment-fetcher.hpp>
-#include <ndn-cxx/security/validator-null.hpp>
-
-#include <boost/algorithm/string/replace.hpp>
-#include <list>
-
-namespace ndn {
-
-using util::SegmentFetcher;
-
-/** \brief custom validator for the purpose of obtaining nfdId.
- */
-class ForwarderStatusValidator : public Validator
-{
-protected:
-  virtual void
-  checkPolicy(const Data& data,
-              int nSteps,
-              const OnDataValidated& onValidated,
-              const OnDataValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override
-  {
-    const ndn::KeyLocator& locator = data.getSignature().getKeyLocator();
-    if (nfdId.empty() && locator.getType() == KeyLocator::KeyLocator_Name)
-      nfdId = locator.getName();
-    onValidated(data.shared_from_this());
-  }
-
-  virtual void
-  checkPolicy(const Interest& interest,
-              int nSteps,
-              const OnInterestValidated& onValidated,
-              const OnInterestValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ValidationRequest>>& nextSteps) override
-  {
-    BOOST_ASSERT(false);
-  }
-
-public:
-  Name nfdId;
-};
-
-
-class NfdStatus
-{
-public:
-  explicit
-  NfdStatus(char* toolName)
-    : m_toolName(toolName)
-    , m_needVersionRetrieval(false)
-    , m_needChannelStatusRetrieval(false)
-    , m_needFaceStatusRetrieval(false)
-    , m_needFibEnumerationRetrieval(false)
-    , m_needRibStatusRetrieval(false)
-    , m_needStrategyChoiceRetrieval(false)
-    , m_isOutputXml(false)
-  {
-  }
-
-  void
-  usage()
-  {
-    std::cout << "Usage: \n  " << m_toolName << " [options]\n\n"
-      "Show NFD version and status information\n\n"
-      "Options:\n"
-      "  [-h] - print this help message\n"
-      "  [-v] - retrieve version information\n"
-      "  [-c] - retrieve channel status information\n"
-      "  [-f] - retrieve face status information\n"
-      "  [-b] - retrieve FIB information\n"
-      "  [-r] - retrieve RIB information\n"
-      "  [-s] - retrieve configured strategy choice for NDN namespaces\n"
-      "  [-x] - output NFD status information in XML format\n"
-      "\n"
-      "  [-V] - show version information of nfd-status and exit\n"
-      "\n"
-      "If no options are provided, all information is retrieved.\n"
-      "If -x is provided, other options(-v, -c, etc.) are ignored, and all information is printed in XML format.\n"
-      ;
-  }
-
-  void
-  enableVersionRetrieval()
-  {
-    m_needVersionRetrieval = true;
-  }
-
-  void
-  enableChannelStatusRetrieval()
-  {
-    m_needChannelStatusRetrieval = true;
-  }
-
-  void
-  enableFaceStatusRetrieval()
-  {
-    m_needFaceStatusRetrieval = true;
-  }
-
-  void
-  enableFibEnumerationRetrieval()
-  {
-    m_needFibEnumerationRetrieval = true;
-  }
-
-  void
-  enableStrategyChoiceRetrieval()
-  {
-    m_needStrategyChoiceRetrieval = true;
-  }
-
-  void
-  enableRibStatusRetrieval()
-  {
-    m_needRibStatusRetrieval = true;
-  }
-
-  void
-  enableXmlOutput()
-  {
-    m_isOutputXml = true;
-  }
-
-  void
-  onTimeout()
-  {
-    std::cerr << "Request timed out" << std::endl;
-
-    runNextStep();
-  }
-
-
-  void
-  onFetchError(uint32_t errorCode, const std::string& errorMsg)
-  {
-    std::cerr << "Error code:" << errorCode << ", message:" << errorMsg << std::endl;
-
-    runNextStep();
-  }
-
-  void
-  escapeSpecialCharacters(std::string *data)
-  {
-    using boost::algorithm::replace_all;
-    replace_all(*data, "&",  "&amp;");
-    replace_all(*data, "\"", "&quot;");
-    replace_all(*data, "\'", "&apos;");
-    replace_all(*data, "<",  "&lt;");
-    replace_all(*data, ">",  "&gt;");
-  }
-
-  //////////////////////////////////////////////////////////////////////////////////
-  //////////////////////////////////////////////////////////////////////////////////
-
-  void
-  fetchVersionInformation()
-  {
-    Interest interest("/localhost/nfd/status/general");
-    interest.setChildSelector(1);
-    interest.setMustBeFresh(true);
-    SegmentFetcher::fetch(m_face, interest,
-                          m_forwarderStatusValidator,
-                          bind(&NfdStatus::afterFetchedVersionInformation, this, _1),
-                          bind(&NfdStatus::onFetchError, this, _1, _2));
-  }
-
-  void
-  afterFetchedVersionInformation(const ConstBufferPtr& dataset)
-  {
-    Block block(tlv::Content, dataset);
-    nfd::ForwarderStatus status(block);
-
-    if (m_isOutputXml) {
-      std::cout << "<generalStatus>";
-      std::cout << "<nfdId>"
-                << m_forwarderStatusValidator.nfdId << "</nfdId>";
-      std::cout << "<version>"
-                << status.getNfdVersion() << "</version>";
-      std::cout << "<startTime>"
-                << time::toString(status.getStartTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
-                << "</startTime>";
-      std::cout << "<currentTime>"
-                << time::toString(status.getCurrentTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
-                << "</currentTime>";
-      std::cout << "<uptime>PT"
-                << time::duration_cast<time::seconds>(status.getCurrentTimestamp() -
-                                                      status.getStartTimestamp()).count()
-                << "S</uptime>";
-      std::cout << "<nNameTreeEntries>"     << status.getNNameTreeEntries()
-                << "</nNameTreeEntries>";
-      std::cout << "<nFibEntries>"          << status.getNFibEntries()
-                << "</nFibEntries>";
-      std::cout << "<nPitEntries>"          << status.getNPitEntries()
-                << "</nPitEntries>";
-      std::cout << "<nMeasurementsEntries>" << status.getNMeasurementsEntries()
-                << "</nMeasurementsEntries>";
-      std::cout << "<nCsEntries>"           << status.getNCsEntries()
-                << "</nCsEntries>";
-      std::cout << "<packetCounters>";
-      std::cout << "<incomingPackets>";
-      std::cout << "<nInterests>"           << status.getNInInterests()
-                << "</nInterests>";
-      std::cout << "<nDatas>"               << status.getNInDatas()
-                << "</nDatas>";
-      std::cout << "<nNacks>"               << status.getNInNacks()
-                << "</nNacks>";
-      std::cout << "</incomingPackets>";
-      std::cout << "<outgoingPackets>";
-      std::cout << "<nInterests>"           << status.getNOutInterests()
-                << "</nInterests>";
-      std::cout << "<nDatas>"               << status.getNOutDatas()
-                << "</nDatas>";
-      std::cout << "<nNacks>"               << status.getNOutNacks()
-                << "</nNacks>";
-      std::cout << "</outgoingPackets>";
-      std::cout << "</packetCounters>";
-      std::cout << "</generalStatus>";
-    }
-    else {
-      std::cout << "General NFD status:" << std::endl;
-      std::cout << "                 nfdId="
-                << m_forwarderStatusValidator.nfdId << std::endl;
-      std::cout << "               version="
-                << status.getNfdVersion() << std::endl;
-      std::cout << "             startTime="
-                << time::toIsoString(status.getStartTimestamp()) << std::endl;
-      std::cout << "           currentTime="
-                << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
-      std::cout << "                uptime="
-                << time::duration_cast<time::seconds>(status.getCurrentTimestamp() -
-                                                      status.getStartTimestamp()) << std::endl;
-
-      std::cout << "      nNameTreeEntries=" << status.getNNameTreeEntries()     << std::endl;
-      std::cout << "           nFibEntries=" << status.getNFibEntries()          << std::endl;
-      std::cout << "           nPitEntries=" << status.getNPitEntries()          << std::endl;
-      std::cout << "  nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
-      std::cout << "            nCsEntries=" << status.getNCsEntries()           << std::endl;
-      std::cout << "          nInInterests=" << status.getNInInterests()         << std::endl;
-      std::cout << "         nOutInterests=" << status.getNOutInterests()        << std::endl;
-      std::cout << "              nInDatas=" << status.getNInDatas()             << std::endl;
-      std::cout << "             nOutDatas=" << status.getNOutDatas()            << std::endl;
-      std::cout << "              nInNacks=" << status.getNInNacks()             << std::endl;
-      std::cout << "             nOutNacks=" << status.getNOutNacks()            << std::endl;
-    }
-
-    runNextStep();
-  }
-
-  //////////////////////////////////////////////////////////////////////////////////
-  //////////////////////////////////////////////////////////////////////////////////
-
-  void
-  fetchChannelStatusInformation()
-  {
-    m_buffer = make_shared<OBufferStream>();
-
-    Interest interest("/localhost/nfd/faces/channels");
-    interest.setChildSelector(1);
-    interest.setMustBeFresh(true);
-
-    SegmentFetcher::fetch(m_face, interest,
-                          m_validator,
-                          bind(&NfdStatus::afterFetchedChannelStatusInformation, this, _1),
-                          bind(&NfdStatus::onFetchError, this, _1, _2));
-  }
-
-  void
-  afterFetchedChannelStatusInformation(const ConstBufferPtr& dataset)
-  {
-    if (m_isOutputXml) {
-      std::cout << "<channels>";
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
-          break;
-        }
-
-        offset += block.size();
-
-        nfd::ChannelStatus channelStatus(block);
-
-        std::cout << "<channel>";
-        std::string localUri(channelStatus.getLocalUri());
-        escapeSpecialCharacters(&localUri);
-        std::cout << "<localUri>" << localUri << "</localUri>";
-        std::cout << "</channel>";
-      }
-
-      std::cout << "</channels>";
-    }
-    else {
-      std::cout << "Channels:" << std::endl;
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
-          break;
-        }
-
-        offset += block.size();
-
-        nfd::ChannelStatus channelStatus(block);
-        std::cout << "  " << channelStatus.getLocalUri() << std::endl;
-      }
-    }
-
-    runNextStep();
-  }
-
-  //////////////////////////////////////////////////////////////////////////////////
-  //////////////////////////////////////////////////////////////////////////////////
-
-  void
-  fetchFaceStatusInformation()
-  {
-    m_buffer = make_shared<OBufferStream>();
-
-    Interest interest("/localhost/nfd/faces/list");
-    interest.setChildSelector(1);
-    interest.setMustBeFresh(true);
-
-    SegmentFetcher::fetch(m_face, interest,
-                          m_validator,
-                          bind(&NfdStatus::afterFetchedFaceStatusInformation, this, _1),
-                          bind(&NfdStatus::onFetchError, this, _1, _2));
-  }
-
-  void
-  afterFetchedFaceStatusInformation(const ConstBufferPtr& dataset)
-  {
-    if (m_isOutputXml) {
-      std::cout << "<faces>";
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
-          break;
-        }
-
-        offset += block.size();
-
-        nfd::FaceStatus faceStatus(block);
-
-        std::cout << "<face>";
-        std::cout << "<faceId>" << faceStatus.getFaceId() << "</faceId>";
-
-        std::string remoteUri(faceStatus.getRemoteUri());
-        escapeSpecialCharacters(&remoteUri);
-        std::cout << "<remoteUri>" << remoteUri << "</remoteUri>";
-
-        std::string localUri(faceStatus.getLocalUri());
-        escapeSpecialCharacters(&localUri);
-        std::cout << "<localUri>" << localUri << "</localUri>";
-
-        if (faceStatus.hasExpirationPeriod()) {
-          std::cout << "<expirationPeriod>PT"
-                    << time::duration_cast<time::seconds>(faceStatus.getExpirationPeriod())
-                       .count() << "S"
-                    << "</expirationPeriod>";
-        }
-
-        std::cout << "<faceScope>" << faceStatus.getFaceScope()
-                  << "</faceScope>";
-        std::cout << "<facePersistency>" << faceStatus.getFacePersistency()
-                  << "</facePersistency>";
-        std::cout << "<linkType>" << faceStatus.getLinkType()
-                  << "</linkType>";
-
-        std::cout << "<packetCounters>";
-        std::cout << "<incomingPackets>";
-        std::cout << "<nInterests>"       << faceStatus.getNInInterests()
-                  << "</nInterests>";
-        std::cout << "<nDatas>"           << faceStatus.getNInDatas()
-                  << "</nDatas>";
-        std::cout << "<nNacks>"           << faceStatus.getNInNacks()
-                  << "</nNacks>";
-        std::cout << "</incomingPackets>";
-        std::cout << "<outgoingPackets>";
-        std::cout << "<nInterests>"       << faceStatus.getNOutInterests()
-                  << "</nInterests>";
-        std::cout << "<nDatas>"           << faceStatus.getNOutDatas()
-                  << "</nDatas>";
-        std::cout << "<nNacks>"           << faceStatus.getNOutNacks()
-                  << "</nNacks>";
-        std::cout << "</outgoingPackets>";
-        std::cout << "</packetCounters>";
-
-        std::cout << "<byteCounters>";
-        std::cout << "<incomingBytes>"    << faceStatus.getNInBytes()
-                  << "</incomingBytes>";
-        std::cout << "<outgoingBytes>"    << faceStatus.getNOutBytes()
-                  << "</outgoingBytes>";
-        std::cout << "</byteCounters>";
-
-        std::cout << "</face>";
-      }
-      std::cout << "</faces>";
-    }
-    else {
-      std::cout << "Faces:" << std::endl;
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
-          break;
-        }
-
-        offset += block.size();
-
-        nfd::FaceStatus faceStatus(block);
-
-        std::cout << "  faceid=" << faceStatus.getFaceId()
-                  << " remote=" << faceStatus.getRemoteUri()
-                  << " local=" << faceStatus.getLocalUri();
-        if (faceStatus.hasExpirationPeriod()) {
-          std::cout  << " expires="
-                     << time::duration_cast<time::seconds>(faceStatus.getExpirationPeriod())
-                        .count() << "s";
-        }
-        std::cout << " counters={"
-                  << "in={" << faceStatus.getNInInterests() << "i "
-                  << faceStatus.getNInDatas() << "d "
-                  << faceStatus.getNInNacks() << "n "
-                  << faceStatus.getNInBytes() << "B}"
-                  << " out={" << faceStatus.getNOutInterests() << "i "
-                  << faceStatus.getNOutDatas() << "d "
-                  << faceStatus.getNOutNacks() << "n "
-                  << faceStatus.getNOutBytes() << "B}"
-                  << "}";
-        std::cout << " " << faceStatus.getFaceScope()
-                  << " " << faceStatus.getFacePersistency()
-                  << " " << faceStatus.getLinkType();
-        std::cout << std::endl;
-      }
-    }
-
-    runNextStep();
-  }
-
-  //////////////////////////////////////////////////////////////////////////////////
-  //////////////////////////////////////////////////////////////////////////////////
-
-  void
-  fetchFibEnumerationInformation()
-  {
-    m_buffer = make_shared<OBufferStream>();
-
-    Interest interest("/localhost/nfd/fib/list");
-    interest.setChildSelector(1);
-    interest.setMustBeFresh(true);
-
-    SegmentFetcher::fetch(m_face, interest,
-                          m_validator,
-                          bind(&NfdStatus::afterFetchedFibEnumerationInformation, this, _1),
-                          bind(&NfdStatus::onFetchError, this, _1, _2));
-  }
-
-  void
-  afterFetchedFibEnumerationInformation(const ConstBufferPtr& dataset)
-  {
-    if (m_isOutputXml) {
-      std::cout << "<fib>";
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode FibEntry TLV";
-          break;
-        }
-        offset += block.size();
-
-        nfd::FibEntry fibEntry(block);
-
-        std::cout << "<fibEntry>";
-        std::string prefix(fibEntry.getPrefix().toUri());
-        escapeSpecialCharacters(&prefix);
-        std::cout << "<prefix>" << prefix << "</prefix>";
-        std::cout << "<nextHops>";
-        for (const nfd::NextHopRecord& nextHop : fibEntry.getNextHopRecords()) {
-          std::cout << "<nextHop>" ;
-          std::cout << "<faceId>"  << nextHop.getFaceId() << "</faceId>";
-          std::cout << "<cost>"    << nextHop.getCost()   << "</cost>";
-          std::cout << "</nextHop>";
-        }
-        std::cout << "</nextHops>";
-        std::cout << "</fibEntry>";
-      }
-
-      std::cout << "</fib>";
-    }
-    else {
-      std::cout << "FIB:" << std::endl;
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
-          break;
-        }
-        offset += block.size();
-
-        nfd::FibEntry fibEntry(block);
-
-        std::cout << "  " << fibEntry.getPrefix() << " nexthops={";
-        bool isFirst = true;
-        for (const nfd::NextHopRecord& nextHop : fibEntry.getNextHopRecords()) {
-          if (isFirst)
-            isFirst = false;
-          else
-            std::cout << ", ";
-
-          std::cout << "faceid=" << nextHop.getFaceId()
-                    << " (cost=" << nextHop.getCost() << ")";
-        }
-        std::cout << "}" << std::endl;
-      }
-    }
-
-    runNextStep();
-  }
-
-  //////////////////////////////////////////////////////////////////////////////////
-  //////////////////////////////////////////////////////////////////////////////////
-
-  void
-  fetchStrategyChoiceInformation()
-  {
-    m_buffer = make_shared<OBufferStream>();
-
-    Interest interest("/localhost/nfd/strategy-choice/list");
-    interest.setChildSelector(1);
-    interest.setMustBeFresh(true);
-
-    SegmentFetcher::fetch(m_face, interest,
-                          m_validator,
-                          bind(&NfdStatus::afterFetchedStrategyChoiceInformationInformation, this, _1),
-                          bind(&NfdStatus::onFetchError, this, _1, _2));
-  }
-
-  void
-  afterFetchedStrategyChoiceInformationInformation(const ConstBufferPtr& dataset)
-  {
-    if (m_isOutputXml) {
-      std::cout << "<strategyChoices>";
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode StrategyChoice TLV";
-          break;
-        }
-        offset += block.size();
-
-        nfd::StrategyChoice strategyChoice(block);
-
-        std::cout << "<strategyChoice>";
-
-        std::string name(strategyChoice.getName().toUri());
-        escapeSpecialCharacters(&name);
-        std::cout << "<namespace>" << name << "</namespace>";
-        std::cout << "<strategy>";
-
-        std::string strategy(strategyChoice.getStrategy().toUri());
-        escapeSpecialCharacters(&strategy);
-
-        std::cout << "<name>" << strategy << "</name>";
-        std::cout << "</strategy>";
-        std::cout << "</strategyChoice>";
-      }
-
-      std::cout << "</strategyChoices>";
-    }
-    else {
-      std::cout << "Strategy choices:" << std::endl;
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode StrategyChoice TLV" << std::endl;
-          break;
-        }
-        offset += block.size();
-
-        nfd::StrategyChoice strategyChoice(block);
-
-        std::cout << "  " << strategyChoice.getName()
-                  << " strategy=" << strategyChoice.getStrategy() << std::endl;
-      }
-    }
-
-    runNextStep();
-  }
-
-  void
-  fetchRibStatusInformation()
-  {
-    m_buffer = make_shared<OBufferStream>();
-
-    Interest interest("/localhost/nfd/rib/list");
-    interest.setChildSelector(1);
-    interest.setMustBeFresh(true);
-
-    SegmentFetcher::fetch(m_face, interest,
-                          m_validator,
-                          bind(&NfdStatus::afterFetchedRibStatusInformation, this, _1),
-                          bind(&NfdStatus::onFetchError, this, _1, _2));
-  }
-
-  void
-  afterFetchedRibStatusInformation(const ConstBufferPtr& dataset)
-  {
-    if (m_isOutputXml) {
-      std::cout << "<rib>";
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode RibEntry TLV";
-          break;
-        }
-        offset += block.size();
-
-        nfd::RibEntry ribEntry(block);
-
-        std::cout << "<ribEntry>";
-        std::string prefix(ribEntry.getName().toUri());
-        escapeSpecialCharacters(&prefix);
-        std::cout << "<prefix>" << prefix << "</prefix>";
-        std::cout << "<routes>";
-        for (const nfd::Route& nextRoute : ribEntry) {
-          std::cout << "<route>" ;
-          std::cout << "<faceId>"  << nextRoute.getFaceId() << "</faceId>";
-          std::cout << "<origin>"  << nextRoute.getOrigin() << "</origin>";
-          std::cout << "<cost>"    << nextRoute.getCost()   << "</cost>";
-
-          std::cout << "<flags>";
-          if (nextRoute.isChildInherit())
-            std::cout << "<childInherit/>";
-          if (nextRoute.isRibCapture())
-            std::cout << "<ribCapture/>";
-          std::cout << "</flags>";
-
-          if (!nextRoute.hasInfiniteExpirationPeriod()) {
-            std::cout << "<expirationPeriod>PT"
-                      << time::duration_cast<time::seconds>(nextRoute.getExpirationPeriod())
-                         .count() << "S"
-                      << "</expirationPeriod>";
-          }
-          std::cout << "</route>";
-        }
-        std::cout << "</routes>";
-        std::cout << "</ribEntry>";
-      }
-
-      std::cout << "</rib>";
-    }
-    else {
-      std::cout << "RIB:" << std::endl;
-
-      size_t offset = 0;
-      while (offset < dataset->size()) {
-        bool isOk = false;
-        Block block;
-        std::tie(isOk, block) = Block::fromBuffer(dataset, offset);
-        if (!isOk) {
-          std::cerr << "ERROR: cannot decode RibEntry TLV" << std::endl;
-          break;
-        }
-
-        offset += block.size();
-
-        nfd::RibEntry ribEntry(block);
-
-        std::cout << "  " << ribEntry.getName().toUri() << " route={";
-        bool isFirst = true;
-        for (const nfd::Route& nextRoute : ribEntry) {
-          if (isFirst)
-            isFirst = false;
-          else
-            std::cout << ", ";
-
-          std::cout << "faceid="   << nextRoute.getFaceId()
-                    << " (origin="  << nextRoute.getOrigin()
-                    << " cost="    << nextRoute.getCost();
-          if (!nextRoute.hasInfiniteExpirationPeriod()) {
-            std::cout << " expires="
-                      << time::duration_cast<time::seconds>(nextRoute.getExpirationPeriod())
-                         .count() << "s";
-          }
-
-          if (nextRoute.isChildInherit())
-            std::cout << " ChildInherit";
-          if (nextRoute.isRibCapture())
-            std::cout << " RibCapture";
-
-          std::cout << ")";
-        }
-        std::cout << "}" << std::endl;
-      }
-    }
-
-    runNextStep();
-  }
-
-
-  void
-  fetchInformation()
-  {
-    if (m_isOutputXml ||
-        (!m_needVersionRetrieval &&
-         !m_needChannelStatusRetrieval &&
-         !m_needFaceStatusRetrieval &&
-         !m_needFibEnumerationRetrieval &&
-         !m_needRibStatusRetrieval &&
-         !m_needStrategyChoiceRetrieval))
-      {
-        enableVersionRetrieval();
-        enableChannelStatusRetrieval();
-        enableFaceStatusRetrieval();
-        enableFibEnumerationRetrieval();
-        enableRibStatusRetrieval();
-        enableStrategyChoiceRetrieval();
-      }
-
-    if (m_isOutputXml)
-      m_fetchSteps.push_back(bind(&NfdStatus::printXmlHeader, this));
-
-    if (m_needVersionRetrieval)
-      m_fetchSteps.push_back(bind(&NfdStatus::fetchVersionInformation, this));
-
-    if (m_needChannelStatusRetrieval)
-      m_fetchSteps.push_back(bind(&NfdStatus::fetchChannelStatusInformation, this));
-
-    if (m_needFaceStatusRetrieval)
-      m_fetchSteps.push_back(bind(&NfdStatus::fetchFaceStatusInformation, this));
-
-    if (m_needFibEnumerationRetrieval)
-      m_fetchSteps.push_back(bind(&NfdStatus::fetchFibEnumerationInformation, this));
-
-    if (m_needRibStatusRetrieval)
-      m_fetchSteps.push_back(bind(&NfdStatus::fetchRibStatusInformation, this));
-
-    if (m_needStrategyChoiceRetrieval)
-      m_fetchSteps.push_back(bind(&NfdStatus::fetchStrategyChoiceInformation, this));
-
-    if (m_isOutputXml)
-      m_fetchSteps.push_back(bind(&NfdStatus::printXmlFooter, this));
-
-    runNextStep();
-    m_face.processEvents();
-  }
-
-private:
-  void
-  printXmlHeader()
-  {
-    std::cout << "<?xml version=\"1.0\"?>";
-    std::cout << "<nfdStatus xmlns=\"ndn:/localhost/nfd/status/1\">";
-
-    runNextStep();
-  }
-
-  void
-  printXmlFooter()
-  {
-    std::cout << "</nfdStatus>";
-
-    runNextStep();
-  }
-
-  void
-  runNextStep()
-  {
-    if (m_fetchSteps.empty())
-      return;
-
-    function<void()> nextStep = m_fetchSteps.front();
-    m_fetchSteps.pop_front();
-    nextStep();
-  }
-
-private:
-  std::string m_toolName;
-  bool m_needVersionRetrieval;
-  bool m_needChannelStatusRetrieval;
-  bool m_needFaceStatusRetrieval;
-  bool m_needFibEnumerationRetrieval;
-  bool m_needRibStatusRetrieval;
-  bool m_needStrategyChoiceRetrieval;
-  bool m_isOutputXml;
-  Face m_face;
-
-  shared_ptr<OBufferStream> m_buffer;
-
-  std::deque<function<void()>> m_fetchSteps;
-
-  ndn::ValidatorNull m_validator;
-
-  ForwarderStatusValidator m_forwarderStatusValidator;
-};
-
-} // namespace ndn
-
-int main(int argc, char* argv[])
-{
-  int option;
-  ndn::NfdStatus nfdStatus(argv[0]);
-
-  while ((option = getopt(argc, argv, "hvcfbrsxV")) != -1) {
-    switch (option) {
-    case 'h':
-      nfdStatus.usage();
-      return 0;
-    case 'v':
-      nfdStatus.enableVersionRetrieval();
-      break;
-    case 'c':
-      nfdStatus.enableChannelStatusRetrieval();
-      break;
-    case 'f':
-      nfdStatus.enableFaceStatusRetrieval();
-      break;
-    case 'b':
-      nfdStatus.enableFibEnumerationRetrieval();
-      break;
-    case 'r':
-      nfdStatus.enableRibStatusRetrieval();
-      break;
-    case 's':
-      nfdStatus.enableStrategyChoiceRetrieval();
-      break;
-    case 'x':
-      nfdStatus.enableXmlOutput();
-      break;
-    case 'V':
-      std::cout << NFD_VERSION_BUILD_STRING << std::endl;
-      return 0;
-    default:
-      nfdStatus.usage();
-      return 1;
-    }
-  }
-
-  try {
-    nfdStatus.fetchInformation();
-  }
-  catch (std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
-    return 2;
-  }
-
-  return 0;
-}
diff --git a/tools/nfd-status/channel-module.cpp b/tools/nfd-status/channel-module.cpp
new file mode 100644
index 0000000..4cd5484
--- /dev/null
+++ b/tools/nfd-status/channel-module.cpp
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "channel-module.hpp"
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+void
+ChannelModule::fetchStatus(Controller& controller,
+                           const function<void()>& onSuccess,
+                           const Controller::CommandFailCallback& onFailure,
+                           const CommandOptions& options)
+{
+  controller.fetch<ndn::nfd::ChannelDataset>(
+    [this, onSuccess] (const std::vector<ChannelStatus>& result) {
+      m_status = result;
+      onSuccess();
+    },
+    onFailure, options);
+}
+
+void
+ChannelModule::formatStatusXml(std::ostream& os) const
+{
+  os << "<channels>";
+  for (const ChannelStatus& item : m_status) {
+    this->formatItemXml(os, item);
+  }
+  os << "</channels>";
+}
+
+void
+ChannelModule::formatItemXml(std::ostream& os, const ChannelStatus& item) const
+{
+  os << "<channel>";
+  os << "<localUri>" << xml::Text{item.getLocalUri()} << "</localUri>";
+  os << "</channel>";
+}
+
+void
+ChannelModule::formatStatusText(std::ostream& os) const
+{
+  os << "Channels:\n";
+  for (const ChannelStatus& item : m_status) {
+    this->formatItemText(os, item);
+  }
+}
+
+void
+ChannelModule::formatItemText(std::ostream& os, const ChannelStatus& item) const
+{
+  os << "  " << item.getLocalUri();
+  os << "\n";
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/channel-module.hpp b/tools/nfd-status/channel-module.hpp
new file mode 100644
index 0000000..1230554
--- /dev/null
+++ b/tools/nfd-status/channel-module.hpp
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_CHANNEL_MODULE_HPP
+#define NFD_TOOLS_NFD_STATUS_CHANNEL_MODULE_HPP
+
+#include "module.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::nfd::ChannelStatus;
+
+/** \brief provides access to NFD channel dataset
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/FaceMgmt#Channel-Dataset
+ */
+class ChannelModule : public Module, noncopyable
+{
+public:
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) override;
+
+  virtual void
+  formatStatusXml(std::ostream& os) const override;
+
+  /** \brief format a single status item as XML
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemXml(std::ostream& os, const ChannelStatus& item) const;
+
+  virtual void
+  formatStatusText(std::ostream& os) const override;
+
+  /** \brief format a single status item as text
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemText(std::ostream& os, const ChannelStatus& item) const;
+
+private:
+  std::vector<ChannelStatus> m_status;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_CHANNEL_MODULE_HPP
diff --git a/tools/nfd-status/face-module.cpp b/tools/nfd-status/face-module.cpp
new file mode 100644
index 0000000..3ec0467
--- /dev/null
+++ b/tools/nfd-status/face-module.cpp
@@ -0,0 +1,154 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \todo
+ *  #2542 plans to merge nfd-status with nfdc.
+ *  FaceModule class should be changed as follows:
+ *  (1) move into ndn::nfd::nfdc namespace
+ *  (2) assuming command syntax is similar to Windows NT \p netsh ,
+ *      this class can handle command argument parsing as soon as
+ *      'face' sub-command is detected
+ *  (3) introduce methods to create and destroy faces, and update face attributes
+ *
+ *  \todo
+ *  #3444 aims at improving output texts of nfdc.
+ *  Assuming it's worked with or after #2542:
+ *  (1) introduce an \p style parameter on formatItemText method to specify desired text style,
+ *      such as human friendly style vs. porcelain style for script consumption
+ *  (2) upon successful command execute, convert the command result into FaceStatus type,
+ *      and use formatItemText to render the result, so that output from status retrieval
+ *      and command execution have consistent styles
+ *  }
+ */
+
+#include "face-module.hpp"
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+void
+FaceModule::fetchStatus(Controller& controller,
+                        const function<void()>& onSuccess,
+                        const Controller::CommandFailCallback& onFailure,
+                        const CommandOptions& options)
+{
+  controller.fetch<ndn::nfd::FaceDataset>(
+    [this, onSuccess] (const std::vector<FaceStatus>& result) {
+      m_status = result;
+      onSuccess();
+    },
+    onFailure, options);
+}
+
+void
+FaceModule::formatStatusXml(std::ostream& os) const
+{
+  os << "<faces>";
+  for (const FaceStatus& item : m_status) {
+    this->formatItemXml(os, item);
+  }
+  os << "</faces>";
+}
+
+void
+FaceModule::formatItemXml(std::ostream& os, const FaceStatus& item) const
+{
+  os << "<face>";
+
+  os << "<faceId>" << item.getFaceId() << "</faceId>";
+  os << "<remoteUri>" << xml::Text{item.getRemoteUri()} << "</remoteUri>";
+  os << "<localUri>" << xml::Text{item.getLocalUri()} << "</localUri>";
+
+  if (item.hasExpirationPeriod()) {
+    os << "<expirationPeriod>" << xml::formatDuration(item.getExpirationPeriod())
+       << "</expirationPeriod>";
+  }
+  os << "<faceScope>" << item.getFaceScope() << "</faceScope>";
+  os << "<facePersistency>" << item.getFacePersistency() << "</facePersistency>";
+  os << "<linkType>" << item.getLinkType() << "</linkType>";
+
+  os << "<packetCounters>";
+  os << "<incomingPackets>"
+     << "<nInterests>" << item.getNInInterests() << "</nInterests>"
+     << "<nDatas>" << item.getNInDatas() << "</nDatas>"
+     << "<nNacks>" << item.getNInNacks() << "</nNacks>"
+     << "</incomingPackets>";
+  os << "<outgoingPackets>"
+     << "<nInterests>" << item.getNOutInterests() << "</nInterests>"
+     << "<nDatas>" << item.getNOutDatas() << "</nDatas>"
+     << "<nNacks>" << item.getNOutNacks() << "</nNacks>"
+     << "</outgoingPackets>";
+  os << "</packetCounters>";
+
+  os << "<byteCounters>";
+  os << "<incomingBytes>" << item.getNInBytes() << "</incomingBytes>";
+  os << "<outgoingBytes>" << item.getNOutBytes() << "</outgoingBytes>";
+  os << "</byteCounters>";
+
+  os << "</face>";
+}
+
+void
+FaceModule::formatStatusText(std::ostream& os) const
+{
+  os << "Faces:\n";
+  for (const FaceStatus& item : m_status) {
+    this->formatItemText(os, item);
+  }
+}
+
+void
+FaceModule::formatItemText(std::ostream& os, const FaceStatus& item) const
+{
+  os << "  faceid=" << item.getFaceId();
+  os << " remote=" << item.getRemoteUri();
+  os << " local=" << item.getLocalUri();
+
+  if (item.hasExpirationPeriod()) {
+    os << " expires=" << text::formatDuration(item.getExpirationPeriod());
+  }
+
+  os << " counters={in={"
+     << item.getNInInterests() << "i "
+     << item.getNInDatas() << "d "
+     << item.getNInNacks() << "n "
+     << item.getNInBytes() << "B} ";
+  os << "out={"
+     << item.getNOutInterests() << "i "
+     << item.getNOutDatas() << "d "
+     << item.getNOutNacks() << "n "
+     << item.getNOutBytes() << "B}}";
+
+  os << " " << item.getFaceScope();
+  os << " " << item.getFacePersistency();
+  os << " " << item.getLinkType();
+  os << "\n";
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/face-module.hpp b/tools/nfd-status/face-module.hpp
new file mode 100644
index 0000000..58bb5ee
--- /dev/null
+++ b/tools/nfd-status/face-module.hpp
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_FACE_MODULE_HPP
+#define NFD_TOOLS_NFD_STATUS_FACE_MODULE_HPP
+
+#include "module.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::nfd::FaceStatus;
+
+/** \brief provides access to NFD face management
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/FaceMgmt
+ */
+class FaceModule : public Module, noncopyable
+{
+public:
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) override;
+
+  virtual void
+  formatStatusXml(std::ostream& os) const override;
+
+  /** \brief format a single status item as XML
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemXml(std::ostream& os, const FaceStatus& item) const;
+
+  virtual void
+  formatStatusText(std::ostream& os) const override;
+
+  /** \brief format a single status item as text
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemText(std::ostream& os, const FaceStatus& item) const;
+
+private:
+  std::vector<FaceStatus> m_status;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_FACE_MODULE_HPP
diff --git a/tools/nfd-status/fib-module.cpp b/tools/nfd-status/fib-module.cpp
new file mode 100644
index 0000000..a1c7f94
--- /dev/null
+++ b/tools/nfd-status/fib-module.cpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "fib-module.hpp"
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+void
+FibModule::fetchStatus(Controller& controller,
+                       const function<void()>& onSuccess,
+                       const Controller::CommandFailCallback& onFailure,
+                       const CommandOptions& options)
+{
+  controller.fetch<ndn::nfd::FibDataset>(
+    [this, onSuccess] (const std::vector<FibEntry>& result) {
+      m_status = result;
+      onSuccess();
+    },
+    onFailure, options);
+}
+
+void
+FibModule::formatStatusXml(std::ostream& os) const
+{
+  os << "<fib>";
+  for (const FibEntry& item : m_status) {
+    this->formatItemXml(os, item);
+  }
+  os << "</fib>";
+}
+
+void
+FibModule::formatItemXml(std::ostream& os, const FibEntry& item) const
+{
+  os << "<fibEntry>";
+
+  os << "<prefix>" << xml::Text{item.getPrefix().toUri()} << "</prefix>";
+
+  os << "<nextHops>";
+  for (const NextHopRecord& nh : item.getNextHopRecords()) {
+    os << "<nextHop>"
+       << "<faceId>" << nh.getFaceId() << "</faceId>"
+       << "<cost>" << nh.getCost() << "</cost>"
+       << "</nextHop>";
+  }
+  os << "</nextHops>";
+
+  os << "</fibEntry>";
+}
+
+void
+FibModule::formatStatusText(std::ostream& os) const
+{
+  os << "FIB:\n";
+  for (const FibEntry& item : m_status) {
+    this->formatItemText(os, item);
+  }
+}
+
+void
+FibModule::formatItemText(std::ostream& os, const FibEntry& item) const
+{
+  os << "  " << item.getPrefix() << " nexthops={";
+
+  text::Separator sep(", ");
+  for (const NextHopRecord& nh : item.getNextHopRecords()) {
+    os << sep
+       << "faceid=" << nh.getFaceId()
+       << " (cost=" << nh.getCost() << ")";
+  }
+
+  os << "}";
+  os << "\n";
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/fib-module.hpp b/tools/nfd-status/fib-module.hpp
new file mode 100644
index 0000000..353e594
--- /dev/null
+++ b/tools/nfd-status/fib-module.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_FIB_MODULE_HPP
+#define NFD_TOOLS_NFD_STATUS_FIB_MODULE_HPP
+
+#include "module.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::nfd::FibEntry;
+using ndn::nfd::NextHopRecord;
+
+/** \brief provides access to NFD FIB management
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/FibMgmt
+ */
+class FibModule : public Module, noncopyable
+{
+public:
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) override;
+
+  virtual void
+  formatStatusXml(std::ostream& os) const override;
+
+  /** \brief format a single status item as XML
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemXml(std::ostream& os, const FibEntry& item) const;
+
+  virtual void
+  formatStatusText(std::ostream& os) const override;
+
+  /** \brief format a single status item as text
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemText(std::ostream& os, const FibEntry& item) const;
+
+private:
+  std::vector<FibEntry> m_status;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_FIB_MODULE_HPP
diff --git a/tools/nfd-status/format-helpers.cpp b/tools/nfd-status/format-helpers.cpp
new file mode 100644
index 0000000..c7e595b
--- /dev/null
+++ b/tools/nfd-status/format-helpers.cpp
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+namespace xml {
+
+void
+printHeader(std::ostream& os)
+{
+  os << "<?xml version=\"1.0\"?>"
+     << "<nfdStatus xmlns=\"ndn:/localhost/nfd/status/1\">";
+}
+
+void
+printFooter(std::ostream& os)
+{
+  os << "</nfdStatus>";
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Text& text)
+{
+  for (char ch : text.s) {
+    switch (ch) {
+      case '"':
+        os << "&quot;";
+        break;
+      case '&':
+        os << "&amp;";
+        break;
+      case '\'':
+        os << "&apos;";
+        break;
+      case '<':
+        os << "&lt;";
+        break;
+      case '>':
+        os << "&gt;";
+        break;
+      default:
+        os << ch;
+        break;
+    }
+  }
+  return os;
+}
+
+std::string
+formatSeconds(time::seconds d)
+{
+  return "PT" + to_string(d.count()) + "S";
+}
+
+std::string
+formatTimestamp(time::system_clock::TimePoint t)
+{
+  return time::toString(t, "%Y-%m-%dT%H:%M:%S%F");
+}
+
+} // namespace xml
+
+namespace text {
+
+Separator::Separator(const std::string& first, const std::string& subsequent)
+  : m_first(first)
+  , m_subsequent(subsequent)
+  , m_count(0)
+{
+}
+
+Separator::Separator(const std::string& subsequent)
+  : Separator("", subsequent)
+{
+}
+
+std::ostream&
+operator<<(std::ostream& os, Separator& sep)
+{
+  if (++sep.m_count == 1) {
+    return os << sep.m_first;
+  }
+  return os << sep.m_subsequent;
+}
+
+std::string
+formatSeconds(time::seconds d, bool isLong)
+{
+  return to_string(d.count()) + (isLong ? " seconds" : "s");
+}
+
+std::string
+formatTimestamp(time::system_clock::TimePoint t)
+{
+  return time::toIsoString(t);
+}
+
+} // namespace text
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/format-helpers.hpp b/tools/nfd-status/format-helpers.hpp
new file mode 100644
index 0000000..11d3d5a
--- /dev/null
+++ b/tools/nfd-status/format-helpers.hpp
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_FORMAT_HELPERS_HPP
+#define NFD_TOOLS_NFD_STATUS_FORMAT_HELPERS_HPP
+
+#include "common.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+namespace xml {
+
+void
+printHeader(std::ostream& os);
+
+void
+printFooter(std::ostream& os);
+
+struct Text
+{
+  const std::string& s;
+};
+
+/** \brief print XML text with special character represented as predefined entities
+ */
+std::ostream&
+operator<<(std::ostream& os, const Text& text);
+
+std::string
+formatSeconds(time::seconds d);
+
+template<typename DURATION>
+std::string
+formatDuration(DURATION d)
+{
+  return formatSeconds(time::duration_cast<time::seconds>(d));
+}
+
+std::string
+formatTimestamp(time::system_clock::TimePoint t);
+
+} // namespace xml
+
+namespace text {
+
+/** \brief print different string on first and subsequent usage
+ *
+ *  \code
+ *  Separator sep(",");
+ *  for (int i = 1; i <= 3; ++i) {
+ *    os << sep << i;
+ *  }
+ *  // prints: 1,2,3
+ *  \endcode
+ */
+class Separator
+{
+public:
+  Separator(const std::string& first, const std::string& subsequent);
+
+  explicit
+  Separator(const std::string& subsequent);
+
+private:
+  std::string m_first;
+  std::string m_subsequent;
+  int m_count;
+
+  friend std::ostream& operator<<(std::ostream& os, Separator& sep);
+};
+
+std::ostream&
+operator<<(std::ostream& os, Separator& sep);
+
+std::string
+formatSeconds(time::seconds d, bool isLong = false);
+
+template<typename DURATION>
+std::string
+formatDuration(DURATION d, bool isLong = false)
+{
+  return formatSeconds(time::duration_cast<time::seconds>(d), isLong);
+}
+
+std::string
+formatTimestamp(time::system_clock::TimePoint t);
+
+} // namespace text
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_FORMAT_HELPERS_HPP
diff --git a/tools/nfd-status/forwarder-general-module.cpp b/tools/nfd-status/forwarder-general-module.cpp
new file mode 100644
index 0000000..41b715a
--- /dev/null
+++ b/tools/nfd-status/forwarder-general-module.cpp
@@ -0,0 +1,190 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "forwarder-general-module.hpp"
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+ForwarderGeneralModule::ForwarderGeneralModule()
+  : m_nfdIdCollector(nullptr)
+{
+}
+
+void
+ForwarderGeneralModule::fetchStatus(Controller& controller,
+                                    const function<void()>& onSuccess,
+                                    const Controller::CommandFailCallback& onFailure,
+                                    const CommandOptions& options)
+{
+  controller.fetch<ndn::nfd::ForwarderGeneralStatusDataset>(
+    [this, onSuccess] (const ForwarderStatus& result) {
+      m_status = result;
+      onSuccess();
+    },
+    onFailure, options);
+}
+
+static time::system_clock::Duration
+calculateUptime(const ForwarderStatus& status)
+{
+  return status.getCurrentTimestamp() - status.getStartTimestamp();
+}
+
+const Name&
+ForwarderGeneralModule::getNfdId() const
+{
+  if (m_nfdIdCollector != nullptr && m_nfdIdCollector->hasNfdId()) {
+    return m_nfdIdCollector->getNfdId();
+  }
+
+  static Name unavailable("/nfdId-unavailable");
+  return unavailable;
+}
+
+void
+ForwarderGeneralModule::formatStatusXml(std::ostream& os) const
+{
+  this->formatItemXml(os, m_status, this->getNfdId());
+}
+
+void
+ForwarderGeneralModule::formatItemXml(std::ostream& os, const ForwarderStatus& item,
+                                      const Name& nfdId) const
+{
+  os << "<generalStatus>";
+
+  os << "<nfdId>" << nfdId << "</nfdId>";
+  os << "<version>" << xml::Text{item.getNfdVersion()} << "</version>";
+  os << "<startTime>" << xml::formatTimestamp(item.getStartTimestamp()) << "</startTime>";
+  os << "<currentTime>" << xml::formatTimestamp(item.getCurrentTimestamp()) << "</currentTime>";
+  os << "<uptime>" << xml::formatDuration(calculateUptime(item)) << "</uptime>";
+
+  os << "<nNameTreeEntries>" << item.getNNameTreeEntries() << "</nNameTreeEntries>";
+  os << "<nFibEntries>" << item.getNFibEntries() << "</nFibEntries>";
+  os << "<nPitEntries>" << item.getNPitEntries() << "</nPitEntries>";
+  os << "<nMeasurementsEntries>" << item.getNMeasurementsEntries() << "</nMeasurementsEntries>";
+  os << "<nCsEntries>" << item.getNCsEntries() << "</nCsEntries>";
+
+  os << "<packetCounters>";
+  os << "<incomingPackets>"
+     << "<nInterests>" << item.getNInInterests() << "</nInterests>"
+     << "<nDatas>" << item.getNInDatas() << "</nDatas>"
+     << "<nNacks>" << item.getNInNacks() << "</nNacks>"
+     << "</incomingPackets>";
+  os << "<outgoingPackets>"
+     << "<nInterests>" << item.getNOutInterests() << "</nInterests>"
+     << "<nDatas>" << item.getNOutDatas() << "</nDatas>"
+     << "<nNacks>" << item.getNOutNacks() << "</nNacks>"
+     << "</outgoingPackets>";
+  os << "</packetCounters>";
+
+  os << "</generalStatus>";
+}
+
+void
+ForwarderGeneralModule::formatStatusText(std::ostream& os) const
+{
+  os << "General NFD status:\n";
+  this->formatItemText(os, m_status, this->getNfdId());
+}
+
+void
+ForwarderGeneralModule::formatItemText(std::ostream& os, const ForwarderStatus& item,
+                                       const Name& nfdId) const
+{
+  os << "                 nfdId=" << nfdId << "\n";
+  os << "               version=" << item.getNfdVersion() << "\n";
+  os << "             startTime=" << text::formatTimestamp(item.getStartTimestamp()) << "\n";
+  os << "           currentTime=" << text::formatTimestamp(item.getCurrentTimestamp()) << "\n";
+  os << "                uptime=" << text::formatDuration(calculateUptime(item), true) << "\n";
+
+  os << "      nNameTreeEntries=" << item.getNNameTreeEntries() << "\n";
+  os << "           nFibEntries=" << item.getNFibEntries() << "\n";
+  os << "           nPitEntries=" << item.getNPitEntries() << "\n";
+  os << "  nMeasurementsEntries=" << item.getNMeasurementsEntries() << "\n";
+  os << "            nCsEntries=" << item.getNCsEntries() << "\n";
+
+  os << "          nInInterests=" << item.getNInInterests() << "\n";
+  os << "         nOutInterests=" << item.getNOutInterests() << "\n";
+  os << "              nInDatas=" << item.getNInDatas() << "\n";
+  os << "             nOutDatas=" << item.getNOutDatas() << "\n";
+  os << "              nInNacks=" << item.getNInNacks() << "\n";
+  os << "             nOutNacks=" << item.getNOutNacks() << "\n";
+}
+
+NfdIdCollector::NfdIdCollector(unique_ptr<ndn::Validator> inner)
+  : m_inner(std::move(inner))
+  , m_hasNfdId(false)
+{
+  BOOST_ASSERT(m_inner != nullptr);
+}
+
+const Name&
+NfdIdCollector::getNfdId() const
+{
+  if (!m_hasNfdId) {
+    BOOST_THROW_EXCEPTION(std::runtime_error("NfdId is unavailable"));
+  }
+
+  return m_nfdId;
+}
+
+void
+NfdIdCollector::checkPolicy(const Data& data, int nSteps,
+                            const ndn::OnDataValidated& accept,
+                            const ndn::OnDataValidationFailed& reject,
+                            std::vector<shared_ptr<ndn::ValidationRequest>>& nextSteps)
+{
+  ndn::OnDataValidated accepted = [this, accept] (const shared_ptr<const Data>& data) {
+    accept(data); // pass the Data to Validator user's validated callback
+
+    if (m_hasNfdId) {
+      return;
+    }
+
+    const ndn::Signature& sig = data->getSignature();
+    if (!sig.hasKeyLocator()) {
+      return;
+    }
+
+    const ndn::KeyLocator& kl = sig.getKeyLocator();
+    if (kl.getType() != ndn::KeyLocator::KeyLocator_Name) {
+      return;
+    }
+
+    m_nfdId = kl.getName();
+    m_hasNfdId = true;
+  };
+
+  BOOST_ASSERT(nSteps == 0);
+  m_inner->validate(data, accepted, reject);
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/forwarder-general-module.hpp b/tools/nfd-status/forwarder-general-module.hpp
new file mode 100644
index 0000000..a55bc21
--- /dev/null
+++ b/tools/nfd-status/forwarder-general-module.hpp
@@ -0,0 +1,140 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_FORWARDER_GENERAL_MODULE_HPP
+#define NFD_TOOLS_NFD_STATUS_FORWARDER_GENERAL_MODULE_HPP
+
+#include "module.hpp"
+#include <ndn-cxx/security/validator.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::nfd::ForwarderStatus;
+
+class NfdIdCollector;
+
+/** \brief provides access to NFD forwarder general status
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/ForwarderStatus
+ */
+class ForwarderGeneralModule : public Module, noncopyable
+{
+public:
+  ForwarderGeneralModule();
+
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) override;
+
+  void
+  setNfdIdCollector(const NfdIdCollector& nfdIdCollector)
+  {
+    m_nfdIdCollector = &nfdIdCollector;
+  }
+
+  virtual void
+  formatStatusXml(std::ostream& os) const override;
+
+  /** \brief format a single status item as XML
+   *  \param os output stream
+   *  \param item status item
+   *  \param nfdId NFD's signing certificate name
+   */
+  void
+  formatItemXml(std::ostream& os, const ForwarderStatus& item, const Name& nfdId) const;
+
+  virtual void
+  formatStatusText(std::ostream& os) const override;
+
+  /** \brief format a single status item as text
+   *  \param os output stream
+   *  \param item status item
+   *  \param nfdId NFD's signing certificate name
+   */
+  void
+  formatItemText(std::ostream& os, const ForwarderStatus& item, const Name& nfdId) const;
+
+private:
+  const Name&
+  getNfdId() const;
+
+private:
+  const NfdIdCollector* m_nfdIdCollector;
+  ForwarderStatus m_status;
+};
+
+
+/** \brief a validator that can collect NFD's signing certificate name
+ *
+ *  This validator redirects all validation requests to an inner validator.
+ *  For the first Data packet accepted by the inner validator that has a Name in KeyLocator,
+ *  this Name is collected as NFD's signing certificate name.
+ */
+class NfdIdCollector : public ndn::Validator
+{
+public:
+  explicit
+  NfdIdCollector(unique_ptr<ndn::Validator> inner);
+
+  bool
+  hasNfdId() const
+  {
+    return m_hasNfdId;
+  }
+
+  const Name&
+  getNfdId() const;
+
+protected:
+  virtual void
+  checkPolicy(const Interest& interest, int nSteps,
+              const ndn::OnInterestValidated& accept,
+              const ndn::OnInterestValidationFailed& reject,
+              std::vector<shared_ptr<ndn::ValidationRequest>>& nextSteps) override
+  {
+    BOOST_ASSERT(nSteps == 0);
+    m_inner->validate(interest, accept, reject);
+  }
+
+  virtual void
+  checkPolicy(const Data& data, int nSteps,
+              const ndn::OnDataValidated& accept,
+              const ndn::OnDataValidationFailed& reject,
+              std::vector<shared_ptr<ndn::ValidationRequest>>& nextSteps) override;
+
+private:
+  unique_ptr<ndn::Validator> m_inner;
+  bool m_hasNfdId;
+  Name m_nfdId;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_FORWARDER_GENERAL_MODULE_HPP
diff --git a/tools/nfd-status/main.cpp b/tools/nfd-status/main.cpp
new file mode 100644
index 0000000..a3033a6
--- /dev/null
+++ b/tools/nfd-status/main.cpp
@@ -0,0 +1,199 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "version.hpp"
+#include <ndn-cxx/security/validator-null.hpp>
+
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+
+#include "status-report.hpp"
+#include "forwarder-general-module.hpp"
+#include "channel-module.hpp"
+#include "face-module.hpp"
+#include "fib-module.hpp"
+#include "rib-module.hpp"
+#include "strategy-choice-module.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+enum class OutputFormat
+{
+  XML = 1,
+  TEXT = 2
+};
+
+struct Options
+{
+  OutputFormat output = OutputFormat::TEXT;
+  bool wantForwarderGeneral = false;
+  bool wantChannels = false;
+  bool wantFaces = false;
+  bool wantFib = false;
+  bool wantRib = false;
+  bool wantStrategyChoice = false;
+};
+
+static void
+showUsage(std::ostream& os, const boost::program_options::options_description& cmdOptions)
+{
+  os << "Usage: nfd-status [options]\n\n"
+     << "Show NFD version and status information.\n\n"
+     << cmdOptions;
+}
+
+/** \brief parse command line, and show usage if necessary
+ *  \return if first item is -1, caller should retrieve and display StatusReport;
+ *          otherwise, caller should immediately exit with the specified exit code
+ */
+static std::tuple<int, Options>
+parseCommandLine(int argc, const char* const* argv)
+{
+  Options options;
+
+  namespace po = boost::program_options;
+  po::options_description cmdOptions("Options");
+  cmdOptions.add_options()
+    ("help,h", "print this help message")
+    ("version,V", "show program version")
+    ("general,v", po::bool_switch(&options.wantForwarderGeneral), "show general status")
+    ("channels,c", po::bool_switch(&options.wantChannels), "show channels")
+    ("faces,f", po::bool_switch(&options.wantFaces), "show faces")
+    ("fib,b", po::bool_switch(&options.wantFib), "show FIB entries")
+    ("rib,r", po::bool_switch(&options.wantRib), "show RIB routes")
+    ("sc,s", po::bool_switch(&options.wantStrategyChoice), "show strategy choice entries")
+    ("xml,x", "output as XML instead of text (implies -vcfbrs)");
+  po::variables_map vm;
+  try {
+    po::store(po::parse_command_line(argc, argv, cmdOptions), vm);
+  }
+  catch (const po::error& e) {
+    std::cerr << e.what() << "\n";
+    showUsage(std::cerr, cmdOptions);
+    return std::make_tuple(2, options);
+  }
+  po::notify(vm);
+
+  if (vm.count("help") > 0) {
+    showUsage(std::cout, cmdOptions);
+    return std::make_tuple(0, options);
+  }
+  if (vm.count("version") > 0) {
+    std::cout << "nfd-status " << NFD_VERSION_BUILD_STRING << "\n";
+    return std::make_tuple(0, options);
+  }
+
+  if (vm.count("xml") > 0) {
+    options.output = OutputFormat::XML;
+  }
+  if (options.output == OutputFormat::XML ||
+      (!options.wantForwarderGeneral && !options.wantChannels && !options.wantFaces &&
+       !options.wantFib && !options.wantRib && !options.wantStrategyChoice)) {
+    options.wantForwarderGeneral = options.wantChannels = options.wantFaces =
+      options.wantFib = options.wantRib = options.wantStrategyChoice = true;
+  }
+
+  return std::make_tuple(-1, options);
+}
+
+static int
+main(int argc, char** argv)
+{
+  int exitCode = -1;
+  Options options;
+  std::tie(exitCode, options) = parseCommandLine(argc, argv);
+  if (exitCode >= 0) {
+    return exitCode;
+  }
+
+  Face face;
+  KeyChain keyChain;
+  unique_ptr<Validator> validator = make_unique<ndn::ValidatorNull>();
+  CommandOptions ctrlOptions;
+
+  StatusReport report;
+
+  if (options.wantForwarderGeneral) {
+    auto nfdIdCollector = make_unique<NfdIdCollector>(std::move(validator));
+    auto forwarderGeneralModule = make_unique<ForwarderGeneralModule>();
+    forwarderGeneralModule->setNfdIdCollector(*nfdIdCollector);
+    report.sections.push_back(std::move(forwarderGeneralModule));
+    validator = std::move(nfdIdCollector);
+  }
+
+  if (options.wantChannels) {
+    report.sections.push_back(make_unique<ChannelModule>());
+  }
+
+  if (options.wantFaces) {
+    report.sections.push_back(make_unique<FaceModule>());
+  }
+
+  if (options.wantFib) {
+    report.sections.push_back(make_unique<FibModule>());
+  }
+
+  if (options.wantRib) {
+    report.sections.push_back(make_unique<RibModule>());
+  }
+
+  if (options.wantStrategyChoice) {
+    report.sections.push_back(make_unique<StrategyChoiceModule>());
+  }
+
+  uint32_t code = report.collect(face, keyChain, *validator, ctrlOptions);
+  if (code != 0) {
+    // Give a simple error code for end user.
+    // Technical support personnel:
+    // 1. get the exact command from end user
+    // 2. code div 1000000 is zero-based section index
+    // 3. code mod 1000000 is a Controller.fetch error code
+    std::cerr << "Error while collecting status report (" << code << ").\n";
+    return 1;
+  }
+
+  switch (options.output) {
+    case OutputFormat::XML:
+      report.formatXml(std::cout);
+      break;
+    case OutputFormat::TEXT:
+      report.formatText(std::cout);
+      break;
+  }
+  return 0;
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+int
+main(int argc, char** argv)
+{
+  return nfd::tools::nfd_status::main(argc, argv);
+}
diff --git a/tools/nfd-status/module.hpp b/tools/nfd-status/module.hpp
new file mode 100644
index 0000000..07d5647
--- /dev/null
+++ b/tools/nfd-status/module.hpp
@@ -0,0 +1,80 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_MODULE_HPP
+#define NFD_TOOLS_NFD_STATUS_MODULE_HPP
+
+#include "common.hpp"
+#include <ndn-cxx/management/nfd-controller.hpp>
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::nfd::Controller;
+using ndn::nfd::CommandOptions;
+
+/** \brief provides access to an NFD management module
+ *  \note This type is an interface. It should not have member fields.
+ */
+class Module
+{
+public:
+  virtual
+  ~Module() = default;
+
+  /** \brief collect status from NFD
+   *  \pre no other fetchStatus is in progress
+   *  \param controller a controller through which StatusDataset can be requested
+   *  \param onSuccess invoked when status has been collected into this instance
+   *  \param onFailure passed to controller.fetch
+   *  \param options passed to controller.fetch
+   */
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) = 0;
+
+  /** \brief format collected status as XML
+   *  \pre fetchStatus has been successful
+   *  \param os output stream
+   */
+  virtual void
+  formatStatusXml(std::ostream& os) const = 0;
+
+  /** \brief format collected status as text
+   *  \pre fetchStatus has been successful
+   *  \param os output stream
+   */
+  virtual void
+  formatStatusText(std::ostream& os) const = 0;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_MODULE_HPP
diff --git a/tools/nfd-status/rib-module.cpp b/tools/nfd-status/rib-module.cpp
new file mode 100644
index 0000000..fe254cc
--- /dev/null
+++ b/tools/nfd-status/rib-module.cpp
@@ -0,0 +1,133 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rib-module.hpp"
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+void
+RibModule::fetchStatus(Controller& controller,
+                       const function<void()>& onSuccess,
+                       const Controller::CommandFailCallback& onFailure,
+                       const CommandOptions& options)
+{
+  controller.fetch<ndn::nfd::RibDataset>(
+    [this, onSuccess] (const std::vector<RibEntry>& result) {
+      m_status = result;
+      onSuccess();
+    },
+    onFailure, options);
+}
+
+void
+RibModule::formatStatusXml(std::ostream& os) const
+{
+  os << "<rib>";
+  for (const RibEntry& item : m_status) {
+    this->formatItemXml(os, item);
+  }
+  os << "</rib>";
+}
+
+void
+RibModule::formatItemXml(std::ostream& os, const RibEntry& item) const
+{
+  os << "<ribEntry>";
+
+  os << "<prefix>" << xml::Text{item.getName().toUri()} << "</prefix>";
+
+  os << "<routes>";
+  for (const Route& route : item.getRoutes()) {
+    os << "<route>"
+       << "<faceId>" << route.getFaceId() << "</faceId>"
+       << "<origin>" << route.getOrigin() << "</origin>"
+       << "<cost>" << route.getCost() << "</cost>";
+    if (route.getFlags() == ndn::nfd::ROUTE_FLAGS_NONE) {
+       os << "<flags/>";
+    }
+    else {
+       os << "<flags>";
+      if (route.isChildInherit()) {
+        os << "<childInherit/>";
+      }
+      if (route.isRibCapture()) {
+        os << "<ribCapture/>";
+      }
+      os << "</flags>";
+    }
+    if (!route.hasInfiniteExpirationPeriod()) {
+      os << "<expirationPeriod>"
+         << xml::formatDuration(route.getExpirationPeriod())
+         << "</expirationPeriod>";
+    }
+    os << "</route>";
+  }
+  os << "</routes>";
+
+  os << "</ribEntry>";
+}
+
+void
+RibModule::formatStatusText(std::ostream& os) const
+{
+  os << "RIB:\n";
+  for (const RibEntry& item : m_status) {
+    this->formatItemText(os, item);
+  }
+}
+
+void
+RibModule::formatItemText(std::ostream& os, const RibEntry& item) const
+{
+  os << "  " << item.getName() << " route={";
+
+  text::Separator sep(", ");
+  for (const Route& route : item.getRoutes()) {
+    os << sep
+       << "faceid=" << route.getFaceId()
+       << " (origin=" << route.getOrigin()
+       << " cost=" << route.getCost();
+    if (!route.hasInfiniteExpirationPeriod()) {
+      os << " expires=" << text::formatDuration(route.getExpirationPeriod());
+    }
+    if (route.isChildInherit()) {
+      os << " ChildInherit";
+    }
+    if (route.isRibCapture()) {
+      os << " RibCapture";
+    }
+    os << ")";
+  }
+
+  os << "}";
+  os << "\n";
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/rib-module.hpp b/tools/nfd-status/rib-module.hpp
new file mode 100644
index 0000000..6a4ddd1
--- /dev/null
+++ b/tools/nfd-status/rib-module.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_RIB_MODULE_HPP
+#define NFD_TOOLS_NFD_STATUS_RIB_MODULE_HPP
+
+#include "module.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::nfd::RibEntry;
+using ndn::nfd::Route;
+
+/** \brief provides access to NFD RIB management
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/RibMgmt
+ */
+class RibModule : public Module, noncopyable
+{
+public:
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) override;
+
+  virtual void
+  formatStatusXml(std::ostream& os) const override;
+
+  /** \brief format a single status item as XML
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemXml(std::ostream& os, const RibEntry& item) const;
+
+  virtual void
+  formatStatusText(std::ostream& os) const override;
+
+  /** \brief format a single status item as text
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemText(std::ostream& os, const RibEntry& item) const;
+
+private:
+  std::vector<RibEntry> m_status;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_RIB_MODULE_HPP
diff --git a/tools/nfd-status/status-report.cpp b/tools/nfd-status/status-report.cpp
new file mode 100644
index 0000000..ff04e1f
--- /dev/null
+++ b/tools/nfd-status/status-report.cpp
@@ -0,0 +1,80 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "status-report.hpp"
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+uint32_t
+StatusReport::collect(Face& face, KeyChain& keyChain, Validator& validator, const CommandOptions& options)
+{
+  Controller controller(face, keyChain, validator);
+  uint32_t errorCode = 0;
+
+  for (size_t i = 0; i < sections.size(); ++i) {
+    Module& module = *sections[i];
+    module.fetchStatus(
+      controller,
+      [] {},
+      [i, &errorCode] (uint32_t code, const std::string& reason) {
+        errorCode = i * 1000000 + code;
+      },
+      options);
+  }
+
+  this->processEvents(face);
+  return errorCode;
+}
+
+void
+StatusReport::processEvents(Face& face)
+{
+  face.processEvents();
+}
+
+void
+StatusReport::formatXml(std::ostream& os) const
+{
+  xml::printHeader(os);
+  for (const unique_ptr<Module>& module : sections) {
+    module->formatStatusXml(os);
+  }
+  xml::printFooter(os);
+}
+
+void
+StatusReport::formatText(std::ostream& os) const
+{
+  for (const unique_ptr<Module>& module : sections) {
+    module->formatStatusText(os);
+  }
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/status-report.hpp b/tools/nfd-status/status-report.hpp
new file mode 100644
index 0000000..80aaee7
--- /dev/null
+++ b/tools/nfd-status/status-report.hpp
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_STATUS_REPORT_HPP
+#define NFD_TOOLS_NFD_STATUS_STATUS_REPORT_HPP
+
+#include "module.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::Face;
+using ndn::security::KeyChain;
+using ndn::Validator;
+
+/** \brief collects and prints NFD status report
+ */
+class StatusReport : noncopyable
+{
+public:
+#ifdef WITH_TESTS
+  virtual
+  ~StatusReport() = default;
+#endif
+
+  /** \brief collect status via chosen \p sections
+   *
+   *  This function is blocking. It has exclusive use of \p face.
+   *
+   *  \return if status has been fetched successfully, 0;
+   *          otherwise, error code from any failed section, plus 1000000 * section index
+   */
+  uint32_t
+  collect(Face& face, KeyChain& keyChain, Validator& validator, const CommandOptions& options);
+
+  /** \brief print an XML report
+   *  \param os output stream
+   */
+  void
+  formatXml(std::ostream& os) const;
+
+  /** \brief print a text report
+   *  \param os output stream
+   */
+  void
+  formatText(std::ostream& os) const;
+
+private:
+  VIRTUAL_WITH_TESTS void
+  processEvents(Face& face);
+
+public:
+  /** \brief modules through which status is collected
+   */
+  std::vector<unique_ptr<Module>> sections;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_STATUS_REPORT_HPP
diff --git a/tools/nfd-status/strategy-choice-module.cpp b/tools/nfd-status/strategy-choice-module.cpp
new file mode 100644
index 0000000..efdff50
--- /dev/null
+++ b/tools/nfd-status/strategy-choice-module.cpp
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "strategy-choice-module.hpp"
+#include "format-helpers.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+void
+StrategyChoiceModule::fetchStatus(Controller& controller,
+                                  const function<void()>& onSuccess,
+                                  const Controller::CommandFailCallback& onFailure,
+                                  const CommandOptions& options)
+{
+  controller.fetch<ndn::nfd::StrategyChoiceDataset>(
+    [this, onSuccess] (const std::vector<StrategyChoice>& result) {
+      m_status = result;
+      onSuccess();
+    },
+    onFailure, options);
+}
+
+void
+StrategyChoiceModule::formatStatusXml(std::ostream& os) const
+{
+  os << "<strategyChoices>";
+  for (const StrategyChoice& item : m_status) {
+    this->formatItemXml(os, item);
+  }
+  os << "</strategyChoices>";
+}
+
+void
+StrategyChoiceModule::formatItemXml(std::ostream& os, const StrategyChoice& item) const
+{
+  os << "<strategyChoice>";
+  os << "<namespace>" << xml::Text{item.getName().toUri()} << "</namespace>";
+  os << "<strategy><name>" << xml::Text{item.getStrategy().toUri()} << "</name></strategy>";
+  os << "</strategyChoice>";
+}
+
+void
+StrategyChoiceModule::formatStatusText(std::ostream& os) const
+{
+  os << "Strategy choices:\n";
+  for (const StrategyChoice& item : m_status) {
+    this->formatItemText(os, item);
+  }
+}
+
+void
+StrategyChoiceModule::formatItemText(std::ostream& os, const StrategyChoice& item) const
+{
+  os << "  " << item.getName()
+     << " strategy=" << item.getStrategy()
+     << "\n";
+}
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
diff --git a/tools/nfd-status/strategy-choice-module.hpp b/tools/nfd-status/strategy-choice-module.hpp
new file mode 100644
index 0000000..be84374
--- /dev/null
+++ b/tools/nfd-status/strategy-choice-module.hpp
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TOOLS_NFD_STATUS_STARTEGY_CHOICE_MODULE_HPP
+#define NFD_TOOLS_NFD_STATUS_STARTEGY_CHOICE_MODULE_HPP
+
+#include "module.hpp"
+
+namespace nfd {
+namespace tools {
+namespace nfd_status {
+
+using ndn::nfd::StrategyChoice;
+
+/** \brief provides access to NFD Strategy Choice management
+ *  \sa https://redmine.named-data.net/projects/nfd/wiki/StrategyChoice
+ */
+class StrategyChoiceModule : public Module, noncopyable
+{
+public:
+  virtual void
+  fetchStatus(Controller& controller,
+              const function<void()>& onSuccess,
+              const Controller::CommandFailCallback& onFailure,
+              const CommandOptions& options) override;
+
+  virtual void
+  formatStatusXml(std::ostream& os) const override;
+
+  /** \brief format a single status item as XML
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemXml(std::ostream& os, const StrategyChoice& item) const;
+
+  virtual void
+  formatStatusText(std::ostream& os) const override;
+
+  /** \brief format a single status item as text
+   *  \param os output stream
+   *  \param item status item
+   */
+  void
+  formatItemText(std::ostream& os, const StrategyChoice& item) const;
+
+private:
+  std::vector<StrategyChoice> m_status;
+};
+
+} // namespace nfd_status
+} // namespace tools
+} // namespace nfd
+
+#endif // NFD_TOOLS_NFD_STATUS_STARTEGY_CHOICE_MODULE_HPP
diff --git a/tools/wscript b/tools/wscript
index ee1909e..f3dd5c9 100644
--- a/tools/wscript
+++ b/tools/wscript
@@ -4,26 +4,59 @@
 
 top = '..'
 
+TOOLS_DEPENDENCY = 'core-objects NDN_CXX BOOST LIBRESOLV'
+
 def build(bld):
-    # List all .cpp files (whole tool should be in one .cpp)
+    # single object tools
+    # tools/example-tool.cpp should a self-contained tool with a main function
+    # and it's built into build/bin/example-tool.
+    # These tools cannot be unit-tested.
     for i in bld.path.ant_glob(['*.cpp']):
         name = str(i)[:-len(".cpp")]
-        bld(features=['cxx', 'cxxprogram'],
+        bld(features='cxx cxxprogram',
             target="../bin/%s" % name,
-            source=[i] + bld.path.ant_glob(['%s/**/*.cpp' % name]),
-            use='core-objects NDN_CXX BOOST LIBRESOLV'
+            source=[i],
+            use=TOOLS_DEPENDENCY
             )
 
-    # List all directories files (tool can has multiple .cpp in the directory)
+
+    # sub-directory tools
+    # tools/example-tool/**/*.cpp is compiled and linked into build/bin/example-tool
+    # tools/example-tool/main.cpp must exist and it should contain the main function.
+    # All other objects are collected into 'tools-objects' and can be unit-tested.
+    testableObjects = []
     for name in bld.path.ant_glob(['*'], dir=True, src=False):
-        srcFiles = bld.path.ant_glob(['%s/**/*.cpp' % name])
+        mainFile = bld.path.find_node(['%s/main.cpp' % name])
+        if mainFile is None:
+          continue # not a C++ tool
+        srcFiles = bld.path.ant_glob(['%s/**/*.cpp' % name], excl=['%s/main.cpp' % name])
         if len(srcFiles) > 0:
-            bld(features=['cxx', 'cxxprogram'],
-                target="../bin/%s" % name,
+            srcObjects = 'tools-%s-objects' % name
+            bld(features='cxx',
+                name=srcObjects,
                 source=srcFiles,
-                use='core-objects NDN_CXX BOOST LIBRESOLV',
+                use=TOOLS_DEPENDENCY,
                 includes='%s' % name,
                 )
+            testableObjects.append(srcObjects)
+
+            bld(features='cxx cxxprogram',
+                target="../bin/%s" % name,
+                source=[mainFile],
+                use=TOOLS_DEPENDENCY + ' ' + srcObjects,
+                includes='%s' % name,
+                )
+        else:
+            bld(features='cxx cxxprogram',
+                target="../bin/%s" % name,
+                source=[mainFile],
+                use=TOOLS_DEPENDENCY,
+                includes='%s' % name,
+                )
+
+    bld(name='tools-objects',
+        export_includes='.',
+        use=testableObjects)
 
     bld(features="subst",
         source=bld.path.ant_glob(['*.sh', '*.py']),
