diff --git a/daemon/fw/ncc-strategy.cpp b/daemon/fw/ncc-strategy.cpp
deleted file mode 100644
index 060821a..0000000
--- a/daemon/fw/ncc-strategy.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2020,  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 "ncc-strategy.hpp"
-#include "algorithm.hpp"
-#include "common/global.hpp"
-
-#include <ndn-cxx/util/random.hpp>
-
-namespace nfd {
-namespace fw {
-
-NFD_REGISTER_STRATEGY(NccStrategy);
-
-const time::microseconds NccStrategy::DEFER_FIRST_WITHOUT_BEST_FACE = 4_ms;
-const time::microseconds NccStrategy::DEFER_RANGE_WITHOUT_BEST_FACE = 75_ms;
-const time::nanoseconds NccStrategy::MEASUREMENTS_LIFETIME = 16_s;
-
-NccStrategy::NccStrategy(Forwarder& forwarder, const Name& name)
-  : Strategy(forwarder)
-{
-  ParsedInstanceName parsed = parseInstanceName(name);
-  if (!parsed.parameters.empty()) {
-    NDN_THROW(std::invalid_argument("NccStrategy does not accept parameters"));
-  }
-  if (parsed.version && *parsed.version != getStrategyName()[-1].toVersion()) {
-    NDN_THROW(std::invalid_argument(
-      "NccStrategy does not support version " + to_string(*parsed.version)));
-  }
-  this->setInstanceName(makeInstanceName(name, getStrategyName()));
-}
-
-const Name&
-NccStrategy::getStrategyName()
-{
-  static Name strategyName("/localhost/nfd/strategy/ncc/%FD%01");
-  return strategyName;
-}
-
-void
-NccStrategy::afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
-                                  const shared_ptr<pit::Entry>& pitEntry)
-{
-  const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
-  const fib::NextHopList& nexthops = fibEntry.getNextHops();
-  if (nexthops.size() == 0) {
-    this->rejectPendingInterest(pitEntry);
-    return;
-  }
-
-  PitEntryInfo* pitEntryInfo = pitEntry->insertStrategyInfo<PitEntryInfo>().first;
-  bool isNewPitEntry = !hasPendingOutRecords(*pitEntry);
-  if (!isNewPitEntry) {
-    return;
-  }
-
-  MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
-
-  time::microseconds deferFirst = DEFER_FIRST_WITHOUT_BEST_FACE;
-  time::microseconds deferRange = DEFER_RANGE_WITHOUT_BEST_FACE;
-  size_t nUpstreams = nexthops.size();
-
-  shared_ptr<Face> bestFace = meInfo.getBestFace();
-  if (bestFace != nullptr && fibEntry.hasNextHop(*bestFace) &&
-      !wouldViolateScope(ingress.face, interest, *bestFace) &&
-      canForwardToLegacy(*pitEntry, *bestFace)) {
-    // TODO Should we use `randlow = 100 + nrand48(h->seed) % 4096U;` ?
-    deferFirst = meInfo.prediction;
-    deferRange = time::microseconds((deferFirst.count() + 1) / 2);
-    --nUpstreams;
-    this->sendInterest(pitEntry, *bestFace, interest);
-    pitEntryInfo->bestFaceTimeout = getScheduler().schedule(meInfo.prediction,
-      bind(&NccStrategy::timeoutOnBestFace, this, weak_ptr<pit::Entry>(pitEntry)));
-  }
-  else {
-    // use first eligible nexthop
-    auto firstEligibleNexthop = std::find_if(nexthops.begin(), nexthops.end(),
-        [&] (const fib::NextHop& nexthop) {
-          Face& outFace = nexthop.getFace();
-          return !wouldViolateScope(ingress.face, interest, outFace) &&
-                 canForwardToLegacy(*pitEntry, outFace);
-        });
-    if (firstEligibleNexthop != nexthops.end()) {
-      this->sendInterest(pitEntry, firstEligibleNexthop->getFace(), interest);
-    }
-    else {
-      this->rejectPendingInterest(pitEntry);
-      return;
-    }
-  }
-
-  shared_ptr<Face> previousFace = meInfo.previousFace.lock();
-  if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
-      !wouldViolateScope(ingress.face, interest, *previousFace) &&
-      canForwardToLegacy(*pitEntry, *previousFace)) {
-    --nUpstreams;
-  }
-
-  if (nUpstreams > 0) {
-    pitEntryInfo->maxInterval = std::max(1_us,
-      time::microseconds((2 * deferRange.count() + nUpstreams - 1) / nUpstreams));
-  }
-  else {
-    // Normally, maxInterval is unused if there aren't any face beyond best and previousBest.
-    // However, in case FIB entry gains a new nexthop before doPropagate executes (bug 1853),
-    // this maxInterval would be used to determine when the next doPropagate would happen.
-    pitEntryInfo->maxInterval = deferFirst;
-  }
-  pitEntryInfo->propagateTimer = getScheduler().schedule(deferFirst,
-    bind(&NccStrategy::doPropagate, this, ingress.face.getId(), weak_ptr<pit::Entry>(pitEntry)));
-}
-
-void
-NccStrategy::doPropagate(FaceId inFaceId, weak_ptr<pit::Entry> pitEntryWeak)
-{
-  Face* inFace = this->getFace(inFaceId);
-  if (inFace == nullptr) {
-    return;
-  }
-  shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
-  if (pitEntry == nullptr) {
-    return;
-  }
-  auto inRecord = pitEntry->getInRecord(*inFace);
-  if (inRecord == pitEntry->in_end()) {
-    return;
-  }
-  const Interest& interest = inRecord->getInterest();
-  const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
-
-  PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
-  // pitEntryInfo is guaranteed to exist here, because doPropagate is triggered
-  // from a timer set by NccStrategy.
-  BOOST_ASSERT(pitEntryInfo != nullptr);
-
-  MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
-
-  shared_ptr<Face> previousFace = meInfo.previousFace.lock();
-  if (previousFace != nullptr && fibEntry.hasNextHop(*previousFace) &&
-      !wouldViolateScope(*inFace, interest, *previousFace) &&
-      canForwardToLegacy(*pitEntry, *previousFace)) {
-    this->sendInterest(pitEntry, *previousFace, interest);
-  }
-
-  bool isForwarded = false;
-  for (const auto& nexthop : fibEntry.getNextHops()) {
-    Face& face = nexthop.getFace();
-    if (!wouldViolateScope(*inFace, interest, face) &&
-        canForwardToLegacy(*pitEntry, face)) {
-      isForwarded = true;
-      this->sendInterest(pitEntry, face, interest);
-      break;
-    }
-  }
-
-  if (isForwarded) {
-    std::uniform_int_distribution<time::nanoseconds::rep> dist(0, pitEntryInfo->maxInterval.count() - 1);
-    time::nanoseconds deferNext(dist(ndn::random::getRandomNumberEngine()));
-    pitEntryInfo->propagateTimer = getScheduler().schedule(deferNext,
-      bind(&NccStrategy::doPropagate, this, inFaceId, weak_ptr<pit::Entry>(pitEntry)));
-  }
-}
-
-void
-NccStrategy::timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak)
-{
-  shared_ptr<pit::Entry> pitEntry = pitEntryWeak.lock();
-  if (pitEntry == nullptr) {
-    return;
-  }
-  measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
-
-  for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (measurementsEntry == nullptr) {
-      // going out of this strategy's namespace
-      break;
-    }
-    this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
-
-    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
-    meInfo.adjustPredictUp();
-
-    measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
-  }
-}
-
-void
-NccStrategy::beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
-                                   const FaceEndpoint& ingress, const Data& data)
-{
-  if (!pitEntry->hasInRecords()) {
-    // PIT entry has already been satisfied (and is now waiting for straggler timer to expire)
-    // NCC does not collect measurements for non-best face
-    return;
-  }
-
-  measurements::Entry* measurementsEntry = this->getMeasurements().get(*pitEntry);
-
-  for (int i = 0; i < UPDATE_MEASUREMENTS_N_LEVELS; ++i) {
-    if (measurementsEntry == nullptr) {
-      // going out of this strategy's namespace
-      return;
-    }
-    this->getMeasurements().extendLifetime(*measurementsEntry, MEASUREMENTS_LIFETIME);
-
-    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(measurementsEntry);
-    meInfo.updateBestFace(ingress.face);
-
-    measurementsEntry = this->getMeasurements().getParent(*measurementsEntry);
-  }
-
-  PitEntryInfo* pitEntryInfo = pitEntry->getStrategyInfo<PitEntryInfo>();
-  if (pitEntryInfo != nullptr) {
-    pitEntryInfo->propagateTimer.cancel();
-
-    // Verify that the best face satisfied the interest before canceling the timeout call
-    MeasurementsEntryInfo& meInfo = this->getMeasurementsEntryInfo(pitEntry);
-    shared_ptr<Face> bestFace = meInfo.getBestFace();
-
-    if (bestFace.get() == &ingress.face)
-      pitEntryInfo->bestFaceTimeout.cancel();
-  }
-}
-
-NccStrategy::MeasurementsEntryInfo&
-NccStrategy::getMeasurementsEntryInfo(const shared_ptr<pit::Entry>& entry)
-{
-  measurements::Entry* measurementsEntry = this->getMeasurements().get(*entry);
-  return this->getMeasurementsEntryInfo(measurementsEntry);
-}
-
-NccStrategy::MeasurementsEntryInfo&
-NccStrategy::getMeasurementsEntryInfo(measurements::Entry* entry)
-{
-  BOOST_ASSERT(entry != nullptr);
-  MeasurementsEntryInfo* info = nullptr;
-  bool isNew = false;
-  std::tie(info, isNew) = entry->insertStrategyInfo<MeasurementsEntryInfo>();
-  if (!isNew) {
-    return *info;
-  }
-
-  measurements::Entry* parentEntry = this->getMeasurements().getParent(*entry);
-  if (parentEntry != nullptr) {
-    MeasurementsEntryInfo& parentInfo = this->getMeasurementsEntryInfo(parentEntry);
-    info->inheritFrom(parentInfo);
-  }
-
-  return *info;
-}
-
-const time::microseconds NccStrategy::MeasurementsEntryInfo::INITIAL_PREDICTION = 8192_us;
-const time::microseconds NccStrategy::MeasurementsEntryInfo::MIN_PREDICTION = 127_us;
-const time::microseconds NccStrategy::MeasurementsEntryInfo::MAX_PREDICTION = 160_ms;
-
-NccStrategy::MeasurementsEntryInfo::MeasurementsEntryInfo()
-  : prediction(INITIAL_PREDICTION)
-{
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::inheritFrom(const MeasurementsEntryInfo& other)
-{
-  this->operator=(other);
-}
-
-shared_ptr<Face>
-NccStrategy::MeasurementsEntryInfo::getBestFace()
-{
-  shared_ptr<Face> best = this->bestFace.lock();
-  if (best != nullptr) {
-    return best;
-  }
-  this->bestFace = best = this->previousFace.lock();
-  return best;
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::updateBestFace(const Face& face)
-{
-  if (this->bestFace.expired()) {
-    this->bestFace = const_cast<Face&>(face).shared_from_this();
-    return;
-  }
-  shared_ptr<Face> bestFace = this->bestFace.lock();
-  if (bestFace.get() == &face) {
-    this->adjustPredictDown();
-  }
-  else {
-    this->previousFace = this->bestFace;
-    this->bestFace = const_cast<Face&>(face).shared_from_this();
-  }
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::adjustPredictDown()
-{
-  prediction = std::max(MIN_PREDICTION,
-    time::microseconds(prediction.count() - (prediction.count() >> ADJUST_PREDICT_DOWN_SHIFT)));
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::adjustPredictUp()
-{
-  prediction = std::min(MAX_PREDICTION,
-    time::microseconds(prediction.count() + (prediction.count() >> ADJUST_PREDICT_UP_SHIFT)));
-}
-
-void
-NccStrategy::MeasurementsEntryInfo::ageBestFace()
-{
-  this->previousFace = this->bestFace;
-  this->bestFace.reset();
-}
-
-NccStrategy::PitEntryInfo::~PitEntryInfo()
-{
-  bestFaceTimeout.cancel();
-  propagateTimer.cancel();
-}
-
-} // namespace fw
-} // namespace nfd
diff --git a/daemon/fw/ncc-strategy.hpp b/daemon/fw/ncc-strategy.hpp
deleted file mode 100644
index 3ba5019..0000000
--- a/daemon/fw/ncc-strategy.hpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2021,  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_DAEMON_FW_NCC_STRATEGY_HPP
-#define NFD_DAEMON_FW_NCC_STRATEGY_HPP
-
-#include "strategy.hpp"
-
-namespace nfd {
-namespace fw {
-
-/** \brief A forwarding strategy similar to CCNx 0.7.2
- */
-class NccStrategy : public Strategy
-{
-public:
-  explicit
-  NccStrategy(Forwarder& forwarder, const Name& name = getStrategyName());
-
-  static const Name&
-  getStrategyName();
-
-  void
-  afterReceiveInterest(const FaceEndpoint& ingress, const Interest& interest,
-                       const shared_ptr<pit::Entry>& pitEntry) override;
-
-  void
-  beforeSatisfyInterest(const shared_ptr<pit::Entry>& pitEntry,
-                        const FaceEndpoint& ingress, const Data& data) override;
-
-NFD_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
-  /// StrategyInfo on measurements::Entry
-  class MeasurementsEntryInfo : public StrategyInfo
-  {
-  public:
-    static constexpr int
-    getTypeId()
-    {
-      return 1000;
-    }
-
-    MeasurementsEntryInfo();
-
-    void
-    inheritFrom(const MeasurementsEntryInfo& other);
-
-    shared_ptr<Face>
-    getBestFace();
-
-    void
-    updateBestFace(const Face& face);
-
-    void
-    adjustPredictUp();
-
-  private:
-    void
-    adjustPredictDown();
-
-    void
-    ageBestFace();
-
-  public:
-    weak_ptr<Face> bestFace;
-    weak_ptr<Face> previousFace;
-    time::microseconds prediction;
-
-    static const time::microseconds INITIAL_PREDICTION;
-    static const time::microseconds MIN_PREDICTION;
-    static const int ADJUST_PREDICT_DOWN_SHIFT = 7;
-    static const time::microseconds MAX_PREDICTION;
-    static const int ADJUST_PREDICT_UP_SHIFT = 3;
-  };
-
-  /// StrategyInfo on pit::Entry
-  class PitEntryInfo : public StrategyInfo
-  {
-  public:
-    static constexpr int
-    getTypeId()
-    {
-      return 1001;
-    }
-
-    ~PitEntryInfo() override;
-
-  public:
-    /// timer that expires when best face does not respond within predicted time
-    scheduler::EventId bestFaceTimeout;
-    /// timer for propagating to another face
-    scheduler::EventId propagateTimer;
-    /// maximum interval between forwarding to two nexthops except best and previous
-    time::microseconds maxInterval;
-  };
-
-protected:
-  MeasurementsEntryInfo&
-  getMeasurementsEntryInfo(measurements::Entry* entry);
-
-  MeasurementsEntryInfo&
-  getMeasurementsEntryInfo(const shared_ptr<pit::Entry>& entry);
-
-  /// propagate to another upstream
-  void
-  doPropagate(FaceId inFaceId, weak_ptr<pit::Entry> pitEntryWeak);
-
-  /// best face did not reply within prediction
-  void
-  timeoutOnBestFace(weak_ptr<pit::Entry> pitEntryWeak);
-
-protected:
-  static const time::microseconds DEFER_FIRST_WITHOUT_BEST_FACE;
-  static const time::microseconds DEFER_RANGE_WITHOUT_BEST_FACE;
-  static const int UPDATE_MEASUREMENTS_N_LEVELS = 2;
-  static const time::nanoseconds MEASUREMENTS_LIFETIME;
-};
-
-} // namespace fw
-} // namespace nfd
-
-#endif // NFD_DAEMON_FW_NCC_STRATEGY_HPP
diff --git a/tests/daemon/fw/ncc-strategy.t.cpp b/tests/daemon/fw/ncc-strategy.t.cpp
deleted file mode 100644
index 3c3f4d4..0000000
--- a/tests/daemon/fw/ncc-strategy.t.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2019,  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 "fw/ncc-strategy.hpp"
-
-#include "tests/daemon/face/dummy-face.hpp"
-#include "strategy-tester.hpp"
-#include "topology-tester.hpp"
-
-namespace nfd {
-namespace fw {
-namespace tests {
-
-using NccStrategyTester = StrategyTester<NccStrategy>;
-NFD_REGISTER_STRATEGY(NccStrategyTester);
-
-BOOST_AUTO_TEST_SUITE(Fw)
-BOOST_FIXTURE_TEST_SUITE(TestNccStrategy, GlobalIoTimeFixture)
-
-BOOST_AUTO_TEST_CASE(FavorRespondingUpstream)
-{
-  // NccStrategy is fairly complex.
-  // The most important property is: it remembers which upstream is the fastest to return Data,
-  // and favors this upstream in subsequent Interests.
-
-  LimitedIo limitedIo(this);
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-  strategy.afterAction.connect(bind(&LimitedIo::afterOp, &limitedIo));
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-  faceTable.add(face3);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10);
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy knows nothing and follows routing
-  shared_ptr<Interest> interest1p = makeInterest("ndn:/0Jm1ajrW/%00");
-  Interest& interest1 = *interest1p;
-  interest1.setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face3, interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), interest1, pitEntry1);
-
-  // forwards to face1 because routing says it's best
-  // (no io run here: afterReceiveInterest has already sent the Interest)
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face1->getId());
-
-  // forwards to face2 because face1 doesn't respond
-  limitedIo.run(1, 500_ms, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 2);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[1].outFaceId, face2->getId());
-
-  // face2 responds
-  shared_ptr<Data> data1p = makeData("ndn:/0Jm1ajrW/%00");
-  Data& data1 = *data1p;
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face2, 0), data1);
-  this->advanceClocks(10_ms, 500_ms);
-
-  // second Interest: strategy knows face2 is best
-  shared_ptr<Interest> interest2p = makeInterest("ndn:/0Jm1ajrW/%00%01");
-  Interest& interest2 = *interest2p;
-  interest2.setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry2 = pit.insert(interest2).first;
-
-  pitEntry2->insertOrUpdateInRecord(*face3, interest2);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), interest2, pitEntry2);
-
-  // forwards to face2 because it responds previously
-  this->advanceClocks(1_ms);
-  BOOST_REQUIRE_GE(strategy.sendInterestHistory.size(), 3);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[2].outFaceId, face2->getId());
-}
-
-BOOST_AUTO_TEST_CASE(Bug1853)
-{
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-  faceTable.add(face3);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy follows routing and forwards to face1
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/nztwIvHX/%00");
-  interest1->setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face3, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest1, pitEntry1);
-
-  this->advanceClocks(1_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face1->getId());
-
-  // face1 responds
-  shared_ptr<Data> data1 = makeData("ndn:/nztwIvHX/%00");
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face1, 0), *data1);
-  this->advanceClocks(10_ms, 500_ms);
-
-  // second Interest: bestFace is face1, nUpstreams becomes 0,
-  // therefore pitEntryInfo->maxInterval cannot be calculated from deferRange and nUpstreams
-  shared_ptr<Interest> interest2 = makeInterest("ndn:/nztwIvHX/%01");
-  interest2->setInterestLifetime(8_s);
-  shared_ptr<pit::Entry> pitEntry2 = pit.insert(*interest2).first;
-
-  pitEntry2->insertOrUpdateInRecord(*face3, *interest2);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest2, pitEntry2);
-
-  // FIB entry is changed before doPropagate executes
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-  this->advanceClocks(10_ms, 1_s);// should not crash
-}
-
-BOOST_AUTO_TEST_CASE(Bug1961)
-{
-  LimitedIo limitedIo(this);
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-  strategy.afterAction.connect(bind(&LimitedIo::afterOp, &limitedIo));
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-  faceTable.add(face3);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10);
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy forwards to face1 and face2
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/seRMz5a6/%00");
-  interest1->setInterestLifetime(2_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face3, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest1, pitEntry1);
-  limitedIo.run(2 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 2);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face1->getId());
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[1].outFaceId, face2->getId());
-
-  // face1 responds
-  shared_ptr<Data> data1 = makeData("ndn:/seRMz5a6/%00");
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face1, 0), *data1);
-  pitEntry1->clearInRecords();
-  this->advanceClocks(10_ms);
-  // face2 also responds
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face2, 0), *data1);
-  this->advanceClocks(10_ms);
-
-  // second Interest: bestFace should be face 1
-  shared_ptr<Interest> interest2 = makeInterest("ndn:/seRMz5a6/%01");
-  interest2->setInterestLifetime(2_s);
-  shared_ptr<pit::Entry> pitEntry2 = pit.insert(*interest2).first;
-
-  pitEntry2->insertOrUpdateInRecord(*face3, *interest2);
-  strategy.afterReceiveInterest(FaceEndpoint(*face3, 0), *interest2, pitEntry2);
-  limitedIo.run(3 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-
-  BOOST_REQUIRE_GE(strategy.sendInterestHistory.size(), 3);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[2].outFaceId, face1->getId());
-}
-
-BOOST_AUTO_TEST_CASE(Bug1971)
-{
-  LimitedIo limitedIo(this);
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-  strategy.afterAction.connect(bind(&LimitedIo::afterOp, &limitedIo));
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face2, 10);
-
-  Pit& pit = forwarder.getPit();
-
-  // first Interest: strategy forwards to face2
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/M4mBXCsd");
-  interest1->setInterestLifetime(2_s);
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-
-  pitEntry1->insertOrUpdateInRecord(*face1, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face1, 0), *interest1, pitEntry1);
-  limitedIo.run(1 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face2->getId());
-
-  // face2 responds
-  shared_ptr<Data> data1 = makeData("ndn:/M4mBXCsd");
-  data1->setFreshnessPeriod(5_ms);
-  strategy.beforeSatisfyInterest(pitEntry1, FaceEndpoint(*face2, 0), *data1);
-  pitEntry1->deleteOutRecord(*face2);
-  pitEntry1->clearInRecords();
-  this->advanceClocks(10_ms);
-
-  // similar Interest: strategy should still forward it
-  pitEntry1->insertOrUpdateInRecord(*face1, *interest1);
-  strategy.afterReceiveInterest(FaceEndpoint(*face1, 0), *interest1, pitEntry1);
-  limitedIo.run(2 - strategy.sendInterestHistory.size(), 2_s, 10_ms);
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 2);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[1].outFaceId, face2->getId());
-}
-
-BOOST_AUTO_TEST_CASE(Bug1998)
-{
-  FaceTable faceTable;
-  Forwarder forwarder(faceTable);
-  NccStrategyTester& strategy = choose<NccStrategyTester>(forwarder);
-
-  shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
-  shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
-  faceTable.add(face1);
-  faceTable.add(face2);
-
-  Fib& fib = forwarder.getFib();
-  fib::Entry& fibEntry = *fib.insert(Name()).first;
-  fib.addOrUpdateNextHop(fibEntry, *face1, 10); // face1 is top-ranked nexthop
-  fib.addOrUpdateNextHop(fibEntry, *face2, 20);
-
-  Pit& pit = forwarder.getPit();
-
-  // Interest comes from face1, which is sole downstream
-  shared_ptr<Interest> interest1 = makeInterest("ndn:/tFy5HzUzD4");
-  shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
-  pitEntry1->insertOrUpdateInRecord(*face1, *interest1);
-
-  strategy.afterReceiveInterest(FaceEndpoint(*face1, 0), *interest1, pitEntry1);
-
-  // Interest shall go to face2, not loop back to face1
-  BOOST_REQUIRE_EQUAL(strategy.sendInterestHistory.size(), 1);
-  BOOST_CHECK_EQUAL(strategy.sendInterestHistory[0].outFaceId, face2->getId());
-}
-
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(PredictionAdjustment, 1)
-BOOST_AUTO_TEST_CASE(PredictionAdjustment) // Bug 3411
-{
-  /*
-   * /----------\
-   * | consumer |
-   * \----------/
-   *     |
-   *     |
-   *   +---+  5ms  +---+
-   *   | A |-------| B |
-   *   +---+       +---+
-   *     |           |
-   *     | 5ms       | 15ms/5ms
-   *     |           |
-   *   +---+       +---+
-   *   | C |-------| D |
-   *   +---+ 15ms  +---+
-   *         /5ms    |
-   *                 |
-   *         /----------\
-   *         | producer |
-   *         \----------/
-   */
-
-  TopologyTester topo;
-  TopologyNode nodeA = topo.addForwarder("A"),
-               nodeB = topo.addForwarder("B"),
-               nodeC = topo.addForwarder("C"),
-               nodeD = topo.addForwarder("D");
-
-  for (TopologyNode node : {nodeA, nodeB, nodeC, nodeD}) {
-    topo.setStrategy<NccStrategy>(node);
-  }
-
-  shared_ptr<TopologyLink> linkAB = topo.addLink("AB", 5_ms, {nodeA, nodeB}),
-                           linkAC = topo.addLink("AC", 5_ms, {nodeA, nodeC}),
-                           linkBD = topo.addLink("BD", 15_ms, {nodeB, nodeD}),
-                           linkCD = topo.addLink("CD", 15_ms, {nodeC, nodeD});
-
-  topo.registerPrefix(nodeA, linkAB->getFace(nodeA), "ndn:/P");
-  topo.registerPrefix(nodeA, linkAC->getFace(nodeA), "ndn:/P");
-  topo.registerPrefix(nodeB, linkBD->getFace(nodeB), "ndn:/P");
-  topo.registerPrefix(nodeC, linkCD->getFace(nodeC), "ndn:/P");
-
-  shared_ptr<TopologyAppLink> producer = topo.addAppFace("producer", nodeD, "ndn:/P");
-  topo.addEchoProducer(producer->getClientFace());
-
-  shared_ptr<TopologyAppLink> consumer = topo.addAppFace("consumer", nodeA);
-  topo.addIntervalConsumer(consumer->getClientFace(), "ndn:/P",
-                           100_ms, 300);
-
-  auto getMeInfo = [&] () -> NccStrategy::MeasurementsEntryInfo* {
-    Measurements& measurements = topo.getForwarder(nodeA).getMeasurements();
-    measurements::Entry* me = measurements.findExactMatch("ndn:/P");
-    return me == nullptr ? nullptr : me->getStrategyInfo<NccStrategy::MeasurementsEntryInfo>();
-  };
-
-  // NccStrategy starts with an exploration period when the algorithm adjusts
-  // its prediction to converge near the path RTT.
-  bool isExplorationFinished = false;
-  const time::milliseconds TRUE_RTT1(40);
-  bool isLastPredictionUnder = true;
-  int nPredictionCrossings = 0;
-  for (int i = 0; i < 10000; ++i) {
-    this->advanceClocks(5_ms);
-    auto meInfo = getMeInfo();
-    if (meInfo == nullptr) {
-      continue;
-    }
-
-    if ((isLastPredictionUnder && meInfo->prediction > TRUE_RTT1) ||
-        (!isLastPredictionUnder && meInfo->prediction < TRUE_RTT1)) {
-      isLastPredictionUnder = !isLastPredictionUnder;
-      if (++nPredictionCrossings > 6) {
-        isExplorationFinished = true;
-        BOOST_TEST_MESSAGE("exploration finishes after " << (i * 5) << "ms");
-        break;
-      }
-    }
-  }
-  BOOST_REQUIRE_MESSAGE(isExplorationFinished, "exploration did not finish within 50s");
-
-  // NccStrategy has selected one path as the best.
-  // When we reduce the RTT of the other path, ideally it should be selected as the best face.
-  // However, this won't happen due to a weakness in NccStrategy.
-  // See  https://redmine.named-data.net/issues/3411#note-4
-  shared_ptr<Face> bestFace1 = getMeInfo()->bestFace.lock();
-  if (bestFace1.get() == &linkAB->getFace(nodeA)) {
-    linkCD->setDelay(5_ms);
-  }
-  else if (bestFace1.get() == &linkAC->getFace(nodeA)) {
-    linkBD->setDelay(5_ms);
-  }
-  else {
-    BOOST_FAIL("unexpected best face");
-  }
-
-  bool isNewBestChosen = false;
-  for (int i = 0; i < 10000; ++i) {
-    this->advanceClocks(5_ms);
-    auto meInfo = getMeInfo();
-    if (meInfo == nullptr) {
-      continue;
-    }
-
-    if (meInfo->bestFace.lock() != bestFace1) {
-      isNewBestChosen = true;
-      BOOST_TEST_MESSAGE("new best face is found after " << (i * 5) << "ms");
-      break;
-    }
-  }
-  BOOST_CHECK_MESSAGE(isNewBestChosen, "new best face is not found in 50000ms"); // expected failure
-}
-
-BOOST_AUTO_TEST_SUITE_END() // TestNccStrategy
-BOOST_AUTO_TEST_SUITE_END() // Fw
-
-} // namespace tests
-} // namespace fw
-} // namespace nfd
diff --git a/tests/daemon/fw/strategy-instantiation.t.cpp b/tests/daemon/fw/strategy-instantiation.t.cpp
index 4ea9bb3..cd057bc 100644
--- a/tests/daemon/fw/strategy-instantiation.t.cpp
+++ b/tests/daemon/fw/strategy-instantiation.t.cpp
@@ -33,19 +33,17 @@
 #include "fw/best-route-strategy.hpp"
 #include "fw/best-route-strategy2.hpp"
 #include "fw/multicast-strategy.hpp"
-#include "fw/ncc-strategy.hpp"
 #include "fw/self-learning-strategy.hpp"
 #include "fw/random-strategy.hpp"
 
 #include "tests/test-common.hpp"
+
 #include <boost/mpl/vector.hpp>
 
 namespace nfd {
 namespace fw {
 namespace tests {
 
-using namespace nfd::tests;
-
 BOOST_AUTO_TEST_SUITE(Fw)
 BOOST_AUTO_TEST_SUITE(TestStrategyInstantiation)
 
@@ -80,7 +78,6 @@
   Test<BestRouteStrategy, false, 1>,
   Test<BestRouteStrategy2, false, 5>,
   Test<MulticastStrategy, false, 4>,
-  Test<NccStrategy, false, 1>,
   Test<SelfLearningStrategy, false, 1>,
   Test<RandomStrategy, false, 1>
 >;
diff --git a/tests/daemon/fw/strategy-scope-control.t.cpp b/tests/daemon/fw/strategy-scope-control.t.cpp
index 123a4f8..a707a46 100644
--- a/tests/daemon/fw/strategy-scope-control.t.cpp
+++ b/tests/daemon/fw/strategy-scope-control.t.cpp
@@ -33,7 +33,6 @@
 #include "fw/best-route-strategy.hpp"
 #include "fw/best-route-strategy2.hpp"
 #include "fw/multicast-strategy.hpp"
-#include "fw/ncc-strategy.hpp"
 #include "fw/random-strategy.hpp"
 
 #include "tests/test-common.hpp"
@@ -41,7 +40,6 @@
 #include "choose-strategy.hpp"
 #include "strategy-tester.hpp"
 
-#include <boost/mpl/copy_if.hpp>
 #include <boost/mpl/vector.hpp>
 
 namespace nfd {
@@ -87,7 +85,7 @@
 BOOST_AUTO_TEST_SUITE(Fw)
 BOOST_AUTO_TEST_SUITE(TestStrategyScopeControl)
 
-template<typename S, bool WillSendNackNoRoute, bool CanProcessNack, bool WillRejectPitEntry = true>
+template<typename S, bool WillSendNackNoRoute, bool CanProcessNack, bool WillRejectPitEntry>
 class Test
 {
 public:
@@ -113,13 +111,12 @@
 };
 
 using Tests = boost::mpl::vector<
-  Test<AccessStrategy, false, false>,
-  Test<AsfStrategy, true, false>,
-  Test<BestRouteStrategy, false, false>,
-  Test<BestRouteStrategy2, true, true>,
+  Test<AccessStrategy, false, false, true>,
+  Test<AsfStrategy, true, false, true>,
+  Test<BestRouteStrategy, false, false, true>,
+  Test<BestRouteStrategy2, true, true, true>,
   Test<MulticastStrategy, false, false, false>,
-  Test<NccStrategy, false, false>,
-  Test<RandomStrategy, true, true>
+  Test<RandomStrategy, true, true, true>
 >;
 
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhostInterestToLocal,
@@ -259,7 +256,7 @@
   this->fib.addOrUpdateNextHop(*fibEntry, *this->localFace4, 10);
   this->fib.addOrUpdateNextHop(*fibEntry, *this->nonLocalFace2, 20);
 
-  auto interest = makeInterest("/localhop/A/1", 1377);
+  auto interest = makeInterest("/localhop/A/1", false, nullopt, 1377);
   shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
   pitEntry->insertOrUpdateInRecord(*this->nonLocalFace1, *interest);
   lp::Nack nack = makeNack(*interest, lp::NackReason::NO_ROUTE);
