Rename ndncatchunks to ndnget

Change-Id: I260e552746e900a73c2ce773bd91d9b6fa384734
diff --git a/tools/chunks/README.md b/tools/chunks/README.md
index 3c73bcf..2c68eed 100644
--- a/tools/chunks/README.md
+++ b/tools/chunks/README.md
@@ -1,45 +1,14 @@
-# ndncatchunks and ndnputchunks
+# ndnputchunks
 
-**ndncatchunks** and **ndnputchunks** are a pair of programs to transfer a file as Data segments.
+**ndnputchunks** is a producer program that reads a file from the standard input, and makes
+it available as a set of NDN Data segments. It appends version and segment number components
+to the specified name as needed, according to the [NDN naming conventions](
+https://named-data.net/publications/techreports/ndn-tr-22-3-ndn-memo-naming-conventions/).
 
-* **ndnputchunks** is a producer program that reads a file from the standard input, and makes
-  it available as a set of NDN Data segments. It appends version and segment number components
-  to the specified name as needed, according to the [NDN naming conventions](
-  https://named-data.net/publications/techreports/ndn-tr-22-3-ndn-memo-naming-conventions/).
-
-* **ndncatchunks** is a consumer program that fetches Data segments of a file, optionally
-  discovering the latest version of the file, and writes the content of the retrieved file to
-  the standard output.
-
-## Version discovery in ndncatchunks
-
-If a version component is present at the end of the user-specified NDN name, the provided version
-number will be used, without any version discovery process. Otherwise, discovery Interest(s) will
-be sent out to fetch metadata of the solicited content from which the Data version will be resolved.
-For more information about the packet format and naming conventions of Interest and Data packets
-used for version discovery in ndncatchunks, please refer to:
-[Realtime Data Retrieval (RDR) protocol](https://redmine.named-data.net/projects/ndn-tlv/wiki/RDR).
-
-## Interest pipeline types in ndncatchunks
-
-* `fixed`: maintains a fixed-size window of Interests in flight; the window size is configurable
-           via a command line option and defaults to 1.
-
-* `aimd` : adjusts the window size via additive-increase/multiplicative-decrease (AIMD).
-           By default, it uses a Conservative Window Adaptation, that is, the congestion window
-           will be decreased at most once per round-trip-time.
-
-* `cubic`: adjusts the window size similar to the TCP CUBIC algorithm.
-           For details about both aimd and cubic please refer to:
-           [A Practical Congestion Control Scheme for Named Data
-           Networking](https://conferences2.sigcomm.org/acm-icn/2016/proceedings/p21-schneider.pdf).
-
-The default Interest pipeline type is `cubic`.
+Files published by ndnputchunks can be fetched with [ndnget](../get/README.md).
 
 ## Usage examples
 
-### Publishing
-
 The following command will publish the text of the GPL-3 license under the `/localhost/demo/gpl3`
 prefix:
 
@@ -60,17 +29,3 @@
 
 If the specified version component is not valid, ndnputchunks will exit with an error. If no version
 component is specified, one will be generated and appended to the name.
-
-### Retrieval
-
-To retrieve the latest version of a published file, the following command can be used:
-
-    ndncatchunks /localhost/demo/gpl3
-
-To fetch a specific version of a published file, you can specify the version number at the end of
-the name. For example, if the version is known to be 1449078495094, the following command
-will fetch that exact version of the file (without version discovery):
-
-    ndncatchunks -Nt /localhost/demo/gpl3/v=1449078495094
-
-For more information, run the programs with `--help` as argument.
diff --git a/tools/chunks/catchunks/consumer.cpp b/tools/chunks/catchunks/consumer.cpp
deleted file mode 100644
index 6d30d70..0000000
--- a/tools/chunks/catchunks/consumer.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- */
-
-#include "consumer.hpp"
-
-#include <ndn-cxx/util/exception.hpp>
-
-namespace ndn::chunks {
-
-Consumer::Consumer(security::Validator& validator, std::ostream& os)
-  : m_validator(validator)
-  , m_outputStream(os)
-{
-}
-
-void
-Consumer::run(std::unique_ptr<DiscoverVersion> discover, std::unique_ptr<PipelineInterests> pipeline)
-{
-  m_discover = std::move(discover);
-  m_pipeline = std::move(pipeline);
-  m_nextToPrint = 0;
-  m_bufferedData.clear();
-
-  m_discover->onDiscoverySuccess.connect([this] (const Name& versionedName) {
-    m_pipeline->run(versionedName,
-                    FORWARD_TO_MEM_FN(handleData),
-                    [] (const std::string& msg) { NDN_THROW(std::runtime_error(msg)); });
-  });
-  m_discover->onDiscoveryFailure.connect([] (const std::string& msg) {
-    NDN_THROW(std::runtime_error(msg));
-  });
-  m_discover->run();
-}
-
-void
-Consumer::handleData(const Data& data)
-{
-  auto dataPtr = data.shared_from_this();
-
-  m_validator.validate(data,
-    [this, dataPtr] (const Data& data) {
-      if (data.getContentType() == ndn::tlv::ContentType_Nack) {
-        NDN_THROW(ApplicationNackError(data));
-      }
-
-      // 'data' passed to callback comes from DataValidationState and was not created with make_shared
-      m_bufferedData[getSegmentFromPacket(data)] = dataPtr;
-      writeInOrderData();
-    },
-    [] (const Data&, const security::ValidationError& error) {
-      NDN_THROW(DataValidationError(error));
-    });
-}
-
-void
-Consumer::writeInOrderData()
-{
-  for (auto it = m_bufferedData.begin();
-       it != m_bufferedData.end() && it->first == m_nextToPrint;
-       it = m_bufferedData.erase(it), ++m_nextToPrint) {
-    const Block& content = it->second->getContent();
-    m_outputStream.write(reinterpret_cast<const char*>(content.value()), content.value_size());
-  }
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/consumer.hpp b/tools/chunks/catchunks/consumer.hpp
deleted file mode 100644
index 980df60..0000000
--- a/tools/chunks/catchunks/consumer.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_CONSUMER_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_CONSUMER_HPP
-
-#include "discover-version.hpp"
-#include "pipeline-interests.hpp"
-
-#include <ndn-cxx/security/validation-error.hpp>
-#include <ndn-cxx/security/validator.hpp>
-
-#include <boost/lexical_cast.hpp>
-#include <iostream>
-#include <map>
-
-namespace ndn::chunks {
-
-/**
- * @brief Segmented version consumer.
- *
- * Discover the latest version of the data published under a specified prefix, and retrieve all the
- * segments associated to that version. The segments are fetched in order and written to a
- * user-specified stream in the same order.
- */
-class Consumer : noncopyable
-{
-public:
-  class ApplicationNackError : public std::runtime_error
-  {
-  public:
-    explicit
-    ApplicationNackError(const Data& data)
-      : std::runtime_error("Application generated Nack: " + boost::lexical_cast<std::string>(data))
-    {
-    }
-  };
-
-  class DataValidationError : public std::runtime_error
-  {
-  public:
-    explicit
-    DataValidationError(const security::ValidationError& error)
-      : std::runtime_error(boost::lexical_cast<std::string>(error))
-    {
-    }
-  };
-
-  /**
-   * @brief Create the consumer
-   */
-  explicit
-  Consumer(security::Validator& validator, std::ostream& os = std::cout);
-
-  /**
-   * @brief Run the consumer
-   */
-  void
-  run(std::unique_ptr<DiscoverVersion> discover, std::unique_ptr<PipelineInterests> pipeline);
-
-private:
-  void
-  handleData(const Data& data);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  writeInOrderData();
-
-private:
-  security::Validator& m_validator;
-  std::ostream& m_outputStream;
-  std::unique_ptr<DiscoverVersion> m_discover;
-  std::unique_ptr<PipelineInterests> m_pipeline;
-  uint64_t m_nextToPrint = 0;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  std::map<uint64_t, std::shared_ptr<const Data>> m_bufferedData;
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_CONSUMER_HPP
diff --git a/tools/chunks/catchunks/data-fetcher.cpp b/tools/chunks/catchunks/data-fetcher.cpp
deleted file mode 100644
index e058ca0..0000000
--- a/tools/chunks/catchunks/data-fetcher.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Andrea Tosatto
- * @author Davide Pesavento
- */
-
-#include "data-fetcher.hpp"
-
-#include <boost/lexical_cast.hpp>
-
-#include <cmath>
-#include <iostream>
-
-namespace ndn::chunks {
-
-std::shared_ptr<DataFetcher>
-DataFetcher::fetch(Face& face, const Interest& interest, int maxNackRetries, int maxTimeoutRetries,
-                   DataCallback onData, FailureCallback onNack, FailureCallback onTimeout,
-                   bool isVerbose)
-{
-  auto dataFetcher = std::shared_ptr<DataFetcher>(new DataFetcher(face,
-                                                                  maxNackRetries,
-                                                                  maxTimeoutRetries,
-                                                                  std::move(onData),
-                                                                  std::move(onNack),
-                                                                  std::move(onTimeout),
-                                                                  isVerbose));
-  dataFetcher->expressInterest(interest, dataFetcher);
-  return dataFetcher;
-}
-
-DataFetcher::DataFetcher(Face& face, int maxNackRetries, int maxTimeoutRetries,
-                         DataCallback onData, FailureCallback onNack, FailureCallback onTimeout,
-                         bool isVerbose)
-  : m_face(face)
-  , m_scheduler(m_face.getIoContext())
-  , m_onData(std::move(onData))
-  , m_onNack(std::move(onNack))
-  , m_onTimeout(std::move(onTimeout))
-  , m_maxNackRetries(maxNackRetries)
-  , m_maxTimeoutRetries(maxTimeoutRetries)
-  , m_isVerbose(isVerbose)
-{
-  BOOST_ASSERT(m_onData != nullptr);
-}
-
-void
-DataFetcher::cancel()
-{
-  if (isRunning()) {
-    m_isStopped = true;
-    m_pendingInterest.cancel();
-    m_scheduler.cancelAllEvents();
-  }
-}
-
-void
-DataFetcher::expressInterest(const Interest& interest, const std::shared_ptr<DataFetcher>& self)
-{
-  m_nCongestionRetries = 0;
-  m_pendingInterest = m_face.expressInterest(interest,
-    [this, self] (auto&&... args) { handleData(std::forward<decltype(args)>(args)..., self); },
-    [this, self] (auto&&... args) { handleNack(std::forward<decltype(args)>(args)..., self); },
-    [this, self] (auto&&... args) { handleTimeout(std::forward<decltype(args)>(args)..., self); });
-}
-
-void
-DataFetcher::handleData(const Interest& interest, const Data& data,
-                        const std::shared_ptr<DataFetcher>& self)
-{
-  if (!isRunning())
-    return;
-
-  m_isStopped = true;
-  m_onData(interest, data);
-}
-
-void
-DataFetcher::handleNack(const Interest& interest, const lp::Nack& nack,
-                        const std::shared_ptr<DataFetcher>& self)
-{
-  if (!isRunning())
-    return;
-
-  if (m_maxNackRetries != MAX_RETRIES_INFINITE)
-    ++m_nNacks;
-
-  if (m_isVerbose)
-    std::cerr << "Received Nack with reason " << nack.getReason()
-              << " for Interest " << interest << "\n";
-
-  if (m_nNacks <= m_maxNackRetries || m_maxNackRetries == MAX_RETRIES_INFINITE) {
-    Interest newInterest(interest);
-    newInterest.refreshNonce();
-
-    switch (nack.getReason()) {
-      case lp::NackReason::DUPLICATE: {
-        expressInterest(newInterest, self);
-        break;
-      }
-      case lp::NackReason::CONGESTION: {
-        time::milliseconds backoffTime(static_cast<uint64_t>(std::pow(2, m_nCongestionRetries)));
-        if (backoffTime > MAX_CONGESTION_BACKOFF_TIME) {
-          backoffTime = MAX_CONGESTION_BACKOFF_TIME;
-        }
-        else {
-          m_nCongestionRetries++;
-        }
-        m_scheduler.schedule(backoffTime, [this, newInterest, self] {
-          expressInterest(newInterest, self);
-        });
-        break;
-      }
-      default: {
-        m_hasError = true;
-        if (m_onNack)
-          m_onNack(interest, "Could not retrieve data for " + interest.getName().toUri() +
-                             ", reason: " + boost::lexical_cast<std::string>(nack.getReason()));
-        break;
-      }
-    }
-  }
-  else {
-    m_hasError = true;
-    if (m_onNack)
-      m_onNack(interest, "Reached the maximum number of nack retries (" + std::to_string(m_maxNackRetries) +
-                         ") while retrieving data for " + interest.getName().toUri());
-  }
-}
-
-void
-DataFetcher::handleTimeout(const Interest& interest, const std::shared_ptr<DataFetcher>& self)
-{
-  if (!isRunning())
-    return;
-
-  if (m_maxTimeoutRetries != MAX_RETRIES_INFINITE)
-    ++m_nTimeouts;
-
-  if (m_isVerbose)
-    std::cerr << "Timeout for Interest " << interest << "\n";
-
-  if (m_nTimeouts <= m_maxTimeoutRetries || m_maxTimeoutRetries == MAX_RETRIES_INFINITE) {
-    Interest newInterest(interest);
-    newInterest.refreshNonce();
-    expressInterest(newInterest, self);
-  }
-  else {
-    m_hasError = true;
-    if (m_onTimeout)
-      m_onTimeout(interest, "Reached the maximum number of timeout retries (" + std::to_string(m_maxTimeoutRetries) +
-                            ") while retrieving data for " + interest.getName().toUri());
-  }
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/data-fetcher.hpp b/tools/chunks/catchunks/data-fetcher.hpp
deleted file mode 100644
index 765963d..0000000
--- a/tools/chunks/catchunks/data-fetcher.hpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Andrea Tosatto
- * @author Davide Pesavento
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_DATA_FETCHER_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_DATA_FETCHER_HPP
-
-#include "core/common.hpp"
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/util/scheduler.hpp>
-
-#include <functional>
-
-namespace ndn::chunks {
-
-/**
- * @brief Fetch data for a given interest and handle timeout or nack error with retries.
- *
- * To instantiate a DataFetcher you need to use the static method fetch, this will also express the
- * interest. After a timeout or nack is received, the same interest with a different nonce will be
- * requested for a maximum number of time specified by the class user. There are separate retry
- * counters for timeouts and nacks.
- *
- * A specified callback is called after the data matching the expressed interest is received. A
- * different callback is called in case one of the retries counter reach the maximum. This callback
- * can be different for timeout and nack. The data callback must be defined but the others callback
- * are optional.
- *
- */
-class DataFetcher
-{
-public:
-  /**
-   * @brief means that there is no maximum number of retries,
-   *        i.e. fetching must be retried indefinitely
-   */
-  static constexpr int MAX_RETRIES_INFINITE = -1;
-
-  /**
-   * @brief ceiling value for backoff time used in congestion handling
-   */
-  static constexpr time::milliseconds MAX_CONGESTION_BACKOFF_TIME = 10_s;
-
-  using FailureCallback = std::function<void(const Interest& interest, const std::string& reason)>;
-
-  /**
-   * @brief instantiate a DataFetcher object and start fetching data
-   *
-   * @param onData callback for segment correctly received, must not be empty
-   */
-  static std::shared_ptr<DataFetcher>
-  fetch(Face& face, const Interest& interest, int maxNackRetries, int maxTimeoutRetries,
-        DataCallback onData, FailureCallback onTimeout, FailureCallback onNack,
-        bool isVerbose);
-
-  /**
-   * @brief stop data fetching without error and calling any callback
-   */
-  void
-  cancel();
-
-  bool
-  isRunning() const
-  {
-    return !m_isStopped && !m_hasError;
-  }
-
-  bool
-  hasError() const
-  {
-    return m_hasError;
-  }
-
-private:
-  DataFetcher(Face& face, int maxNackRetries, int maxTimeoutRetries,
-              DataCallback onData, FailureCallback onNack, FailureCallback onTimeout,
-              bool isVerbose);
-
-  void
-  expressInterest(const Interest& interest, const std::shared_ptr<DataFetcher>& self);
-
-  void
-  handleData(const Interest& interest, const Data& data, const std::shared_ptr<DataFetcher>& self);
-
-  void
-  handleNack(const Interest& interest, const lp::Nack& nack, const std::shared_ptr<DataFetcher>& self);
-
-  void
-  handleTimeout(const Interest& interest, const std::shared_ptr<DataFetcher>& self);
-
-private:
-  Face& m_face;
-  Scheduler m_scheduler;
-  PendingInterestHandle m_pendingInterest;
-  DataCallback m_onData;
-  FailureCallback m_onNack;
-  FailureCallback m_onTimeout;
-
-  int m_maxNackRetries;
-  int m_maxTimeoutRetries;
-  int m_nNacks = 0;
-  int m_nTimeouts = 0;
-  uint32_t m_nCongestionRetries = 0;
-
-  bool m_isVerbose = false;
-  bool m_isStopped = false;
-  bool m_hasError = false;
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_DATA_FETCHER_HPP
diff --git a/tools/chunks/catchunks/discover-version.cpp b/tools/chunks/catchunks/discover-version.cpp
deleted file mode 100644
index 3e75850..0000000
--- a/tools/chunks/catchunks/discover-version.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- * @author Chavoosh Ghasemi
- */
-
-#include "discover-version.hpp"
-#include "data-fetcher.hpp"
-
-#include <ndn-cxx/metadata-object.hpp>
-
-#include <iostream>
-
-namespace ndn::chunks {
-
-DiscoverVersion::DiscoverVersion(Face& face, const Name& prefix, const Options& options)
-  : m_face(face)
-  , m_prefix(prefix)
-  , m_options(options)
-{
-}
-
-void
-DiscoverVersion::run()
-{
-  if (m_options.disableVersionDiscovery || (!m_prefix.empty() && m_prefix[-1].isVersion())) {
-    onDiscoverySuccess(m_prefix);
-    return;
-  }
-
-  Interest interest = MetadataObject::makeDiscoveryInterest(m_prefix)
-                      .setInterestLifetime(m_options.interestLifetime);
-
-  m_fetcher = DataFetcher::fetch(m_face, interest,
-                                 m_options.maxRetriesOnTimeoutOrNack,
-                                 m_options.maxRetriesOnTimeoutOrNack,
-                                 FORWARD_TO_MEM_FN(handleData),
-                                 [this] (const auto&, const auto& reason) {
-                                   onDiscoveryFailure(reason);
-                                 },
-                                 [this] (const auto&, const auto& reason) {
-                                   onDiscoveryFailure(reason);
-                                 },
-                                 m_options.isVerbose);
-}
-
-void
-DiscoverVersion::handleData(const Interest& interest, const Data& data)
-{
-  if (m_options.isVerbose)
-    std::cerr << "Data: " << data << "\n";
-
-  // make a metadata object from received metadata packet
-  MetadataObject mobject;
-  try {
-    mobject = MetadataObject(data);
-  }
-  catch (const tlv::Error& e) {
-    onDiscoveryFailure("Invalid metadata packet: "s + e.what());
-    return;
-  }
-
-  if (mobject.getVersionedName().empty() || !mobject.getVersionedName()[-1].isVersion()) {
-    onDiscoveryFailure(mobject.getVersionedName().toUri() + " is not a valid versioned name");
-    return;
-  }
-
-  if (m_options.isVerbose) {
-    std::cerr << "Discovered Data version: " << mobject.getVersionedName()[-1] << "\n";
-  }
-
-  onDiscoverySuccess(mobject.getVersionedName());
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/discover-version.hpp b/tools/chunks/catchunks/discover-version.hpp
deleted file mode 100644
index 1098d85..0000000
--- a/tools/chunks/catchunks/discover-version.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- * @author Chavoosh Ghasemi
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_HPP
-
-#include "options.hpp"
-
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/util/signal.hpp>
-
-namespace ndn::chunks {
-
-class DataFetcher;
-
-/**
- * @brief Service for discovering the latest Data version.
- *
- * DiscoverVersion's user is notified once after identifying the latest retrievable version or
- * on failure to find any Data version.
- */
-class DiscoverVersion
-{
-public:
-  DiscoverVersion(Face& face, const Name& prefix, const Options& options);
-
-  /**
-   * @brief Signal emitted when the versioned name of Data is found.
-   */
-  signal::Signal<DiscoverVersion, Name> onDiscoverySuccess;
-
-  /**
-   * @brief Signal emitted when a failure occurs.
-   */
-  signal::Signal<DiscoverVersion, std::string> onDiscoveryFailure;
-
-  void
-  run();
-
-private:
-  void
-  handleData(const Interest& interest, const Data& data);
-
-private:
-  Face& m_face;
-  const Name m_prefix;
-  const Options& m_options;
-  std::shared_ptr<DataFetcher> m_fetcher;
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_HPP
diff --git a/tools/chunks/catchunks/main.cpp b/tools/chunks/catchunks/main.cpp
deleted file mode 100644
index 6c763a9..0000000
--- a/tools/chunks/catchunks/main.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- * @author Davide Pesavento
- * @author Weiwei Liu
- * @author Klaus Schneider
- * @author Chavoosh Ghasemi
- */
-
-#include "consumer.hpp"
-#include "discover-version.hpp"
-#include "pipeline-interests-aimd.hpp"
-#include "pipeline-interests-cubic.hpp"
-#include "pipeline-interests-fixed.hpp"
-#include "statistics-collector.hpp"
-#include "core/version.hpp"
-
-#include <ndn-cxx/security/validator-null.hpp>
-#include <ndn-cxx/util/rtt-estimator.hpp>
-
-#include <boost/program_options/options_description.hpp>
-#include <boost/program_options/parsers.hpp>
-#include <boost/program_options/variables_map.hpp>
-
-#include <fstream>
-#include <iostream>
-
-namespace ndn::chunks {
-
-namespace po = boost::program_options;
-
-static int
-main(int argc, char* argv[])
-{
-  const std::string programName(argv[0]);
-
-  Options options;
-  std::string prefix, nameConv, pipelineType("cubic");
-  std::string cwndPath, rttPath;
-  auto rttEstOptions = std::make_shared<util::RttEstimator::Options>();
-  rttEstOptions->k = 8; // increased from the ndn-cxx default of 4
-
-  po::options_description basicDesc("Basic Options");
-  basicDesc.add_options()
-    ("help,h",      "print this help message and exit")
-    ("fresh,f",     po::bool_switch(&options.mustBeFresh),
-                    "only return fresh content (set MustBeFresh on all outgoing Interests)")
-    ("lifetime,l",  po::value<time::milliseconds::rep>()->default_value(options.interestLifetime.count()),
-                    "lifetime of expressed Interests, in milliseconds")
-    ("retries,r",   po::value<int>(&options.maxRetriesOnTimeoutOrNack)->default_value(options.maxRetriesOnTimeoutOrNack),
-                    "maximum number of retries in case of Nack or timeout (-1 = no limit)")
-    ("pipeline-type,p", po::value<std::string>(&pipelineType)->default_value(pipelineType),
-                        "type of Interest pipeline to use; valid values are: 'fixed', 'aimd', 'cubic'")
-    ("no-version-discovery,D", po::bool_switch(&options.disableVersionDiscovery),
-                               "skip version discovery even if the name does not end with a version component")
-    ("naming-convention,N", po::value<std::string>(&nameConv),
-                            "encoding convention to use for name components, either 'marker' or 'typed'")
-    ("quiet,q",     po::bool_switch(&options.isQuiet), "suppress all diagnostic output, except fatal errors")
-    ("verbose,v",   po::bool_switch(&options.isVerbose), "turn on verbose output (per segment information")
-    ("version,V",   "print program version and exit")
-    ;
-
-  po::options_description fixedPipeDesc("Fixed pipeline options");
-  fixedPipeDesc.add_options()
-    ("pipeline-size,s", po::value<size_t>(&options.maxPipelineSize)->default_value(options.maxPipelineSize),
-                        "size of the Interest pipeline")
-    ;
-
-  po::options_description adaptivePipeDesc("Adaptive pipeline options (AIMD & CUBIC)");
-  adaptivePipeDesc.add_options()
-    ("ignore-marks",  po::bool_switch(&options.ignoreCongMarks),
-                      "do not reduce the window after receiving a congestion mark")
-    ("disable-cwa",   po::bool_switch(&options.disableCwa),
-                      "disable Conservative Window Adaptation (reduce the window "
-                      "on each congestion event instead of at most once per RTT)")
-    ("init-cwnd",     po::value<double>(&options.initCwnd)->default_value(options.initCwnd),
-                      "initial congestion window in segments")
-    ("init-ssthresh", po::value<double>(&options.initSsthresh),
-                      "initial slow start threshold in segments (defaults to infinity)")
-    ("rto-alpha", po::value<double>(&rttEstOptions->alpha)->default_value(rttEstOptions->alpha),
-                  "alpha value for RTO calculation")
-    ("rto-beta",  po::value<double>(&rttEstOptions->beta)->default_value(rttEstOptions->beta),
-                  "beta value for RTO calculation")
-    ("rto-k",     po::value<int>(&rttEstOptions->k)->default_value(rttEstOptions->k),
-                  "k value for RTO calculation")
-    ("min-rto",   po::value<time::milliseconds::rep>()->default_value(
-                    time::duration_cast<time::milliseconds>(rttEstOptions->minRto).count()),
-                  "minimum RTO value, in milliseconds")
-    ("max-rto",   po::value<time::milliseconds::rep>()->default_value(
-                    time::duration_cast<time::milliseconds>(rttEstOptions->maxRto).count()),
-                  "maximum RTO value, in milliseconds")
-    ("log-cwnd",  po::value<std::string>(&cwndPath), "log file for congestion window stats")
-    ("log-rtt",   po::value<std::string>(&rttPath), "log file for round-trip time stats")
-    ;
-
-  po::options_description aimdPipeDesc("AIMD pipeline options");
-  aimdPipeDesc.add_options()
-    ("aimd-step", po::value<double>(&options.aiStep)->default_value(options.aiStep),
-                  "additive increase step")
-    ("aimd-beta", po::value<double>(&options.mdCoef)->default_value(options.mdCoef),
-                  "multiplicative decrease factor")
-    ("reset-cwnd-to-init", po::bool_switch(&options.resetCwndToInit),
-                           "after a congestion event, reset the window to the "
-                           "initial value instead of resetting to ssthresh")
-    ;
-
-  po::options_description cubicPipeDesc("CUBIC pipeline options");
-  cubicPipeDesc.add_options()
-    ("cubic-beta", po::value<double>(&options.cubicBeta), "window decrease factor (defaults to 0.7)")
-    ("fast-conv",  po::bool_switch(&options.enableFastConv), "enable fast convergence")
-    ;
-
-  po::options_description visibleDesc;
-  visibleDesc.add(basicDesc)
-             .add(fixedPipeDesc)
-             .add(adaptivePipeDesc)
-             .add(aimdPipeDesc)
-             .add(cubicPipeDesc);
-
-  po::options_description hiddenDesc;
-  hiddenDesc.add_options()
-    ("name", po::value<std::string>(&prefix), "NDN name of the requested content");
-
-  po::options_description optDesc;
-  optDesc.add(visibleDesc).add(hiddenDesc);
-
-  po::positional_options_description p;
-  p.add("name", -1);
-
-  po::variables_map vm;
-  try {
-    po::store(po::command_line_parser(argc, argv).options(optDesc).positional(p).run(), vm);
-    po::notify(vm);
-  }
-  catch (const po::error& e) {
-    std::cerr << "ERROR: " << e.what() << "\n";
-    return 2;
-  }
-  catch (const boost::bad_any_cast& e) {
-    std::cerr << "ERROR: " << e.what() << "\n";
-    return 2;
-  }
-
-  if (vm.count("help") > 0) {
-    std::cout << "Usage: " << programName << " [options] ndn:/name\n";
-    std::cout << visibleDesc;
-    return 0;
-  }
-
-  if (vm.count("version") > 0) {
-    std::cout << "ndncatchunks " << tools::VERSION << "\n";
-    return 0;
-  }
-
-  if (prefix.empty()) {
-    std::cerr << "Usage: " << programName << " [options] ndn:/name\n";
-    std::cerr << visibleDesc;
-    return 2;
-  }
-
-  if (nameConv == "marker" || nameConv == "m" || nameConv == "1") {
-    name::setConventionEncoding(name::Convention::MARKER);
-  }
-  else if (nameConv == "typed" || nameConv == "t" || nameConv == "2") {
-    name::setConventionEncoding(name::Convention::TYPED);
-  }
-  else if (!nameConv.empty()) {
-    std::cerr << "ERROR: '" << nameConv << "' is not a valid naming convention\n";
-    return 2;
-  }
-
-  options.interestLifetime = time::milliseconds(vm["lifetime"].as<time::milliseconds::rep>());
-  if (options.interestLifetime < 0_ms) {
-    std::cerr << "ERROR: --lifetime cannot be negative\n";
-    return 2;
-  }
-
-  if (options.maxRetriesOnTimeoutOrNack < -1 || options.maxRetriesOnTimeoutOrNack > 1024) {
-    std::cerr << "ERROR: --retries must be between -1 and 1024\n";
-    return 2;
-  }
-
-  if (options.isQuiet && options.isVerbose) {
-    std::cerr << "ERROR: cannot be quiet and verbose at the same time\n";
-    return 2;
-  }
-
-  if (options.maxPipelineSize < 1 || options.maxPipelineSize > 1024) {
-    std::cerr << "ERROR: --pipeline-size must be between 1 and 1024\n";
-    return 2;
-  }
-
-  if (rttEstOptions->k < 0) {
-    std::cerr << "ERROR: --rto-k cannot be negative\n";
-    return 2;
-  }
-
-  rttEstOptions->minRto = time::milliseconds(vm["min-rto"].as<time::milliseconds::rep>());
-  if (rttEstOptions->minRto < 0_ms) {
-    std::cerr << "ERROR: --min-rto cannot be negative\n";
-    return 2;
-  }
-
-  rttEstOptions->maxRto = time::milliseconds(vm["max-rto"].as<time::milliseconds::rep>());
-  if (rttEstOptions->maxRto < rttEstOptions->minRto) {
-    std::cerr << "ERROR: --max-rto cannot be smaller than --min-rto\n";
-    return 2;
-  }
-
-  try {
-    Face face;
-    auto discover = std::make_unique<DiscoverVersion>(face, Name(prefix), options);
-    std::unique_ptr<PipelineInterests> pipeline;
-    std::unique_ptr<StatisticsCollector> statsCollector;
-    std::unique_ptr<RttEstimatorWithStats> rttEstimator;
-    std::ofstream statsFileCwnd;
-    std::ofstream statsFileRtt;
-
-    if (pipelineType == "fixed") {
-      pipeline = std::make_unique<PipelineInterestsFixed>(face, options);
-    }
-    else if (pipelineType == "aimd" || pipelineType == "cubic") {
-      if (options.isVerbose) {
-        using namespace ndn::time;
-        std::cerr << "RTT estimator parameters:\n"
-                  << "\tAlpha = " << rttEstOptions->alpha << "\n"
-                  << "\tBeta = " << rttEstOptions->beta << "\n"
-                  << "\tK = " << rttEstOptions->k << "\n"
-                  << "\tInitial RTO = " << duration_cast<milliseconds>(rttEstOptions->initialRto) << "\n"
-                  << "\tMin RTO = " << duration_cast<milliseconds>(rttEstOptions->minRto) << "\n"
-                  << "\tMax RTO = " << duration_cast<milliseconds>(rttEstOptions->maxRto) << "\n"
-                  << "\tBackoff multiplier = " << rttEstOptions->rtoBackoffMultiplier << "\n";
-      }
-      rttEstimator = std::make_unique<RttEstimatorWithStats>(std::move(rttEstOptions));
-
-      std::unique_ptr<PipelineInterestsAdaptive> adaptivePipeline;
-      if (pipelineType == "aimd") {
-        adaptivePipeline = std::make_unique<PipelineInterestsAimd>(face, *rttEstimator, options);
-      }
-      else {
-        adaptivePipeline = std::make_unique<PipelineInterestsCubic>(face, *rttEstimator, options);
-      }
-
-      if (!cwndPath.empty() || !rttPath.empty()) {
-        if (!cwndPath.empty()) {
-          statsFileCwnd.open(cwndPath);
-          if (statsFileCwnd.fail()) {
-            std::cerr << "ERROR: failed to open '" << cwndPath << "'\n";
-            return 4;
-          }
-        }
-        if (!rttPath.empty()) {
-          statsFileRtt.open(rttPath);
-          if (statsFileRtt.fail()) {
-            std::cerr << "ERROR: failed to open '" << rttPath << "'\n";
-            return 4;
-          }
-        }
-        statsCollector = std::make_unique<StatisticsCollector>(*adaptivePipeline, statsFileCwnd, statsFileRtt);
-      }
-
-      pipeline = std::move(adaptivePipeline);
-    }
-    else {
-      std::cerr << "ERROR: '" << pipelineType << "' is not a valid pipeline type\n";
-      return 2;
-    }
-
-    Consumer consumer(security::getAcceptAllValidator());
-    BOOST_ASSERT(discover != nullptr);
-    BOOST_ASSERT(pipeline != nullptr);
-    consumer.run(std::move(discover), std::move(pipeline));
-    face.processEvents();
-  }
-  catch (const Consumer::ApplicationNackError& e) {
-    std::cerr << "ERROR: " << e.what() << "\n";
-    return 3;
-  }
-  catch (const Consumer::DataValidationError& e) {
-    std::cerr << "ERROR: " << e.what() << "\n";
-    return 5;
-  }
-  catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << "\n";
-    return 1;
-  }
-
-  return 0;
-}
-
-} // namespace ndn::chunks
-
-int
-main(int argc, char* argv[])
-{
-  return ndn::chunks::main(argc, argv);
-}
diff --git a/tools/chunks/catchunks/options.hpp b/tools/chunks/catchunks/options.hpp
deleted file mode 100644
index d21481a..0000000
--- a/tools/chunks/catchunks/options.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Andrea Tosatto
- * @author Davide Pesavento
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_OPTIONS_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_OPTIONS_HPP
-
-#include <ndn-cxx/interest.hpp>
-#include <ndn-cxx/util/time.hpp>
-
-#include <limits>
-
-namespace ndn::chunks {
-
-struct Options
-{
-  // Common options
-  time::milliseconds interestLifetime = DEFAULT_INTEREST_LIFETIME;
-  int maxRetriesOnTimeoutOrNack = 15;
-  bool disableVersionDiscovery = false;
-  bool mustBeFresh = false;
-  bool isQuiet = false;
-  bool isVerbose = false;
-
-  // Fixed pipeline options
-  size_t maxPipelineSize = 1;
-
-  // Adaptive pipeline common options
-  double initCwnd = 2.0;        ///< initial congestion window size
-  double initSsthresh = std::numeric_limits<double>::max(); ///< initial slow start threshold
-  time::milliseconds rtoCheckInterval{10}; ///< interval for checking retransmission timer
-  bool ignoreCongMarks = false; ///< disable window decrease after receiving congestion mark
-  bool disableCwa = false;      ///< disable conservative window adaptation
-
-  // AIMD pipeline options
-  double aiStep = 1.0;          ///< AIMD additive increase step (in segments)
-  double mdCoef = 0.5;          ///< AIMD multiplicative decrease factor
-  bool resetCwndToInit = false; ///< reduce cwnd to initCwnd when loss event occurs
-
-  // Cubic pipeline options
-  double cubicBeta = 0.7;       ///< cubic multiplicative decrease factor
-  bool enableFastConv = false;  ///< use cubic fast convergence
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_OPTIONS_HPP
diff --git a/tools/chunks/catchunks/pipeline-interests-adaptive.cpp b/tools/chunks/catchunks/pipeline-interests-adaptive.cpp
deleted file mode 100644
index 492229f..0000000
--- a/tools/chunks/catchunks/pipeline-interests-adaptive.cpp
+++ /dev/null
@@ -1,461 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Shuo Yang
- * @author Weiwei Liu
- * @author Chavoosh Ghasemi
- * @author Klaus Schneider
- */
-
-#include "pipeline-interests-adaptive.hpp"
-#include "data-fetcher.hpp"
-
-#include <boost/lexical_cast.hpp>
-#include <iomanip>
-#include <iostream>
-
-namespace ndn::chunks {
-
-PipelineInterestsAdaptive::PipelineInterestsAdaptive(Face& face,
-                                                     RttEstimatorWithStats& rttEstimator,
-                                                     const Options& opts)
-  : PipelineInterests(face, opts)
-  , m_cwnd(m_options.initCwnd)
-  , m_ssthresh(m_options.initSsthresh)
-  , m_rttEstimator(rttEstimator)
-  , m_scheduler(m_face.getIoContext())
-{
-}
-
-PipelineInterestsAdaptive::~PipelineInterestsAdaptive()
-{
-  cancel();
-}
-
-void
-PipelineInterestsAdaptive::doRun()
-{
-  if (allSegmentsReceived()) {
-    cancel();
-    if (!m_options.isQuiet) {
-      printSummary();
-    }
-    return;
-  }
-
-  // schedule the event to check retransmission timer
-  m_checkRtoEvent = m_scheduler.schedule(m_options.rtoCheckInterval, [this] { checkRto(); });
-
-  schedulePackets();
-}
-
-void
-PipelineInterestsAdaptive::doCancel()
-{
-  m_checkRtoEvent.cancel();
-  m_segmentInfo.clear();
-}
-
-void
-PipelineInterestsAdaptive::checkRto()
-{
-  if (isStopping())
-    return;
-
-  bool hasTimeout = false;
-  uint64_t highTimeoutSeg = 0;
-
-  for (auto& entry : m_segmentInfo) {
-    SegmentInfo& segInfo = entry.second;
-    if (segInfo.state != SegmentState::InRetxQueue) { // skip segments already in the retx queue
-      auto timeElapsed = time::steady_clock::now() - segInfo.timeSent;
-      if (timeElapsed > segInfo.rto) { // timer expired?
-        m_nTimeouts++;
-        hasTimeout = true;
-        highTimeoutSeg = std::max(highTimeoutSeg, entry.first);
-        enqueueForRetransmission(entry.first);
-      }
-    }
-  }
-
-  if (hasTimeout) {
-    recordTimeout(highTimeoutSeg);
-    schedulePackets();
-  }
-
-  // schedule the next check after predefined interval
-  m_checkRtoEvent = m_scheduler.schedule(m_options.rtoCheckInterval, [this] { checkRto(); });
-}
-
-void
-PipelineInterestsAdaptive::sendInterest(uint64_t segNo, bool isRetransmission)
-{
-  if (isStopping())
-    return;
-
-  if (m_hasFinalBlockId && segNo > m_lastSegmentNo)
-    return;
-
-  if (!isRetransmission && m_hasFailure)
-    return;
-
-  if (m_options.isVerbose) {
-    std::cerr << (isRetransmission ? "Retransmitting" : "Requesting")
-              << " segment #" << segNo << "\n";
-  }
-
-  if (isRetransmission) {
-    // keep track of retx count for this segment
-    auto ret = m_retxCount.emplace(segNo, 1);
-    if (!ret.second) { // not the first retransmission
-      m_retxCount[segNo] += 1;
-      if (m_options.maxRetriesOnTimeoutOrNack != DataFetcher::MAX_RETRIES_INFINITE &&
-          m_retxCount[segNo] > m_options.maxRetriesOnTimeoutOrNack) {
-        return handleFail(segNo, "Reached the maximum number of retries (" +
-                          std::to_string(m_options.maxRetriesOnTimeoutOrNack) +
-                          ") while retrieving segment #" + std::to_string(segNo));
-      }
-
-      if (m_options.isVerbose) {
-        std::cerr << "# of retries for segment #" << segNo
-                  << " is " << m_retxCount[segNo] << "\n";
-      }
-    }
-  }
-
-  auto interest = Interest()
-                  .setName(Name(m_prefix).appendSegment(segNo))
-                  .setMustBeFresh(m_options.mustBeFresh)
-                  .setInterestLifetime(m_options.interestLifetime);
-
-  SegmentInfo& segInfo = m_segmentInfo[segNo];
-  segInfo.interestHdl = m_face.expressInterest(interest,
-                                               FORWARD_TO_MEM_FN(handleData),
-                                               FORWARD_TO_MEM_FN(handleNack),
-                                               FORWARD_TO_MEM_FN(handleLifetimeExpiration));
-  segInfo.timeSent = time::steady_clock::now();
-  segInfo.rto = m_rttEstimator.getEstimatedRto();
-
-  m_nInFlight++;
-  m_nSent++;
-
-  if (isRetransmission) {
-    segInfo.state = SegmentState::Retransmitted;
-    m_nRetransmitted++;
-  }
-  else {
-    m_highInterest = segNo;
-    segInfo.state = SegmentState::FirstTimeSent;
-  }
-}
-
-void
-PipelineInterestsAdaptive::schedulePackets()
-{
-  BOOST_ASSERT(m_nInFlight >= 0);
-  auto availableWindowSize = static_cast<int64_t>(m_cwnd) - m_nInFlight;
-
-  while (availableWindowSize > 0) {
-    if (!m_retxQueue.empty()) { // do retransmission first
-      uint64_t retxSegNo = m_retxQueue.front();
-      m_retxQueue.pop();
-      if (m_segmentInfo.count(retxSegNo) == 0) {
-        m_nSkippedRetx++;
-        continue;
-      }
-      // the segment is still in the map, that means it needs to be retransmitted
-      sendInterest(retxSegNo, true);
-    }
-    else { // send next segment
-      sendInterest(getNextSegmentNo(), false);
-    }
-    availableWindowSize--;
-  }
-}
-
-void
-PipelineInterestsAdaptive::handleData(const Interest& interest, const Data& data)
-{
-  if (isStopping())
-    return;
-
-  // Interest was expressed with CanBePrefix=false
-  BOOST_ASSERT(data.getName().equals(interest.getName()));
-
-  if (!m_hasFinalBlockId && data.getFinalBlock()) {
-    m_lastSegmentNo = data.getFinalBlock()->toSegment();
-    m_hasFinalBlockId = true;
-    cancelInFlightSegmentsGreaterThan(m_lastSegmentNo);
-    if (m_hasFailure && m_lastSegmentNo >= m_failedSegNo) {
-      // previously failed segment is part of the content
-      return onFailure(m_failureReason);
-    }
-    else {
-      m_hasFailure = false;
-    }
-  }
-
-  uint64_t recvSegNo = getSegmentFromPacket(data);
-  auto segIt = m_segmentInfo.find(recvSegNo);
-  if (segIt == m_segmentInfo.end()) {
-    return; // ignore already-received segment
-  }
-
-  SegmentInfo& segInfo = segIt->second;
-  time::nanoseconds rtt = time::steady_clock::now() - segInfo.timeSent;
-  if (m_options.isVerbose) {
-    std::cerr << "Received segment #" << recvSegNo
-              << ", rtt=" << rtt.count() / 1e6 << "ms"
-              << ", rto=" << segInfo.rto.count() / 1e6 << "ms\n";
-  }
-
-  m_highData = std::max(m_highData, recvSegNo);
-
-  // for segments in retx queue, we must not decrement m_nInFlight
-  // because it was already decremented when the segment timed out
-  if (segInfo.state != SegmentState::InRetxQueue) {
-    m_nInFlight--;
-  }
-
-  // upon finding congestion mark, decrease the window size
-  // without retransmitting any packet
-  if (data.getCongestionMark() > 0) {
-    m_nCongMarks++;
-    if (!m_options.ignoreCongMarks) {
-      if (m_options.disableCwa || m_highData > m_recPoint) {
-        m_recPoint = m_highInterest;  // react to only one congestion event (timeout or congestion mark)
-                                      // per RTT (conservative window adaptation)
-        m_nMarkDecr++;
-        decreaseWindow();
-
-        if (m_options.isVerbose) {
-          std::cerr << "Received congestion mark, value = " << data.getCongestionMark()
-                    << ", new cwnd = " << m_cwnd << "\n";
-        }
-      }
-    }
-    else {
-      increaseWindow();
-    }
-  }
-  else {
-    increaseWindow();
-  }
-
-  onData(data);
-
-  // do not sample RTT for retransmitted segments
-  if ((segInfo.state == SegmentState::FirstTimeSent ||
-       segInfo.state == SegmentState::InRetxQueue) &&
-      m_retxCount.count(recvSegNo) == 0) {
-    auto nExpectedSamples = std::max<int64_t>((m_nInFlight + 1) >> 1, 1);
-    BOOST_ASSERT(nExpectedSamples > 0);
-    m_rttEstimator.addMeasurement(rtt, static_cast<size_t>(nExpectedSamples));
-    afterRttMeasurement({recvSegNo, rtt,
-                         m_rttEstimator.getSmoothedRtt(),
-                         m_rttEstimator.getRttVariation(),
-                         m_rttEstimator.getEstimatedRto()});
-  }
-
-  // remove the entry associated with the received segment
-  m_segmentInfo.erase(segIt);
-
-  if (allSegmentsReceived()) {
-    cancel();
-    if (!m_options.isQuiet) {
-      printSummary();
-    }
-  }
-  else {
-    schedulePackets();
-  }
-}
-
-void
-PipelineInterestsAdaptive::handleNack(const Interest& interest, const lp::Nack& nack)
-{
-  if (isStopping())
-    return;
-
-  if (m_options.isVerbose)
-    std::cerr << "Received Nack with reason " << nack.getReason()
-              << " for Interest " << interest << "\n";
-
-  uint64_t segNo = getSegmentFromPacket(interest);
-
-  switch (nack.getReason()) {
-    case lp::NackReason::DUPLICATE:
-      // ignore duplicates
-      break;
-    case lp::NackReason::CONGESTION:
-      // treated the same as timeout for now
-      enqueueForRetransmission(segNo);
-      recordTimeout(segNo);
-      schedulePackets();
-      break;
-    default:
-      handleFail(segNo, "Could not retrieve data for " + interest.getName().toUri() +
-                 ", reason: " + boost::lexical_cast<std::string>(nack.getReason()));
-      break;
-  }
-}
-
-void
-PipelineInterestsAdaptive::handleLifetimeExpiration(const Interest& interest)
-{
-  if (isStopping())
-    return;
-
-  m_nTimeouts++;
-
-  uint64_t segNo = getSegmentFromPacket(interest);
-  enqueueForRetransmission(segNo);
-  recordTimeout(segNo);
-  schedulePackets();
-}
-
-void
-PipelineInterestsAdaptive::recordTimeout(uint64_t segNo)
-{
-  if (m_options.disableCwa || segNo > m_recPoint) {
-    // interests that are still outstanding during a timeout event
-    // should not trigger another window decrease later (bug #5202)
-    m_recPoint = m_highInterest;
-
-    decreaseWindow();
-    m_rttEstimator.backoffRto();
-    m_nLossDecr++;
-
-    if (m_options.isVerbose) {
-      std::cerr << "Packet loss event, new cwnd = " << m_cwnd
-                << ", ssthresh = " << m_ssthresh << "\n";
-    }
-  }
-}
-
-void
-PipelineInterestsAdaptive::enqueueForRetransmission(uint64_t segNo)
-{
-  BOOST_ASSERT(m_nInFlight > 0);
-  m_nInFlight--;
-  m_retxQueue.push(segNo);
-  m_segmentInfo.at(segNo).state = SegmentState::InRetxQueue;
-}
-
-void
-PipelineInterestsAdaptive::handleFail(uint64_t segNo, const std::string& reason)
-{
-  if (isStopping())
-    return;
-
-  // if the failed segment is definitely part of the content, raise a fatal error
-  if (m_hasFinalBlockId && segNo <= m_lastSegmentNo)
-    return onFailure(reason);
-
-  if (!m_hasFinalBlockId) {
-    m_segmentInfo.erase(segNo);
-    m_nInFlight--;
-
-    if (m_segmentInfo.empty()) {
-      onFailure("Fetching terminated but no final segment number has been found");
-    }
-    else {
-      cancelInFlightSegmentsGreaterThan(segNo);
-      m_hasFailure = true;
-      m_failedSegNo = segNo;
-      m_failureReason = reason;
-    }
-  }
-}
-
-void
-PipelineInterestsAdaptive::cancelInFlightSegmentsGreaterThan(uint64_t segNo)
-{
-  for (auto it = m_segmentInfo.begin(); it != m_segmentInfo.end();) {
-    // cancel fetching all segments that follow
-    if (it->first > segNo) {
-      it = m_segmentInfo.erase(it);
-      m_nInFlight--;
-    }
-    else {
-      ++it;
-    }
-  }
-}
-
-void
-PipelineInterestsAdaptive::printOptions() const
-{
-  PipelineInterests::printOptions();
-  std::cerr
-      << "\tInitial congestion window size = " << m_options.initCwnd << "\n"
-      << "\tInitial slow start threshold = " << m_options.initSsthresh << "\n"
-      << "\tAdditive increase step = " << m_options.aiStep << "\n"
-      << "\tMultiplicative decrease factor = " << m_options.mdCoef << "\n"
-      << "\tRTO check interval = " << m_options.rtoCheckInterval << "\n"
-      << "\tReact to congestion marks = " << (m_options.ignoreCongMarks ? "no" : "yes") << "\n"
-      << "\tConservative window adaptation = " << (m_options.disableCwa ? "no" : "yes") << "\n"
-      << "\tResetting window to " << (m_options.resetCwndToInit ?
-                                        "initial value" : "ssthresh") << " upon loss event\n";
-}
-
-void
-PipelineInterestsAdaptive::printSummary() const
-{
-  PipelineInterests::printSummary();
-  std::cerr << "Congestion marks: " << m_nCongMarks << " (caused " << m_nMarkDecr << " window decreases)\n"
-            << "Timeouts: " << m_nTimeouts << " (caused " << m_nLossDecr << " window decreases)\n"
-            << "Retransmitted segments: " << m_nRetransmitted
-            << " (" << (m_nSent == 0 ? 0 : (m_nRetransmitted * 100.0 / m_nSent)) << "%)"
-            << ", skipped: " << m_nSkippedRetx << "\n"
-            << "RTT ";
-
-  if (m_rttEstimator.getMinRtt() == time::nanoseconds::max() ||
-      m_rttEstimator.getMaxRtt() == time::nanoseconds::min()) {
-    std::cerr << "stats unavailable\n";
-  }
-  else {
-    std::cerr << "min/avg/max = " << std::fixed << std::setprecision(3)
-              << m_rttEstimator.getMinRtt().count() / 1e6 << "/"
-              << m_rttEstimator.getAvgRtt().count() / 1e6 << "/"
-              << m_rttEstimator.getMaxRtt().count() / 1e6 << " ms\n";
-  }
-}
-
-std::ostream&
-operator<<(std::ostream& os, SegmentState state)
-{
-  switch (state) {
-  case SegmentState::FirstTimeSent:
-    os << "FirstTimeSent";
-    break;
-  case SegmentState::InRetxQueue:
-    os << "InRetxQueue";
-    break;
-  case SegmentState::Retransmitted:
-    os << "Retransmitted";
-    break;
-  }
-  return os;
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/pipeline-interests-adaptive.hpp b/tools/chunks/catchunks/pipeline-interests-adaptive.hpp
deleted file mode 100644
index 572418f..0000000
--- a/tools/chunks/catchunks/pipeline-interests-adaptive.hpp
+++ /dev/null
@@ -1,231 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Shuo Yang
- * @author Weiwei Liu
- * @author Chavoosh Ghasemi
- * @author Klaus Schneider
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_ADAPTIVE_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_ADAPTIVE_HPP
-
-#include "pipeline-interests.hpp"
-
-#include <ndn-cxx/util/rtt-estimator.hpp>
-#include <ndn-cxx/util/scheduler.hpp>
-#include <ndn-cxx/util/signal.hpp>
-
-#include <queue>
-#include <unordered_map>
-
-namespace ndn::chunks {
-
-using util::RttEstimatorWithStats;
-
-/**
- * @brief indicates the state of the segment
- */
-enum class SegmentState {
-  FirstTimeSent, ///< segment has been sent for the first time
-  InRetxQueue,   ///< segment is in retransmission queue
-  Retransmitted, ///< segment has been retransmitted
-};
-
-std::ostream&
-operator<<(std::ostream& os, SegmentState state);
-
-/**
- * @brief Wraps up information that's necessary for segment transmission
- */
-struct SegmentInfo
-{
-  ScopedPendingInterestHandle interestHdl;
-  time::steady_clock::time_point timeSent;
-  time::nanoseconds rto;
-  SegmentState state;
-};
-
-/**
- * @brief Service for retrieving Data via an Interest pipeline
- *
- * Retrieves all segmented Data under the specified prefix by maintaining a dynamic
- * congestion window combined with a Conservative Loss Adaptation algorithm. For details,
- * please refer to the description in section "Interest pipeline types in ndncatchunks" of
- * tools/chunks/README.md
- *
- * Provides retrieved Data on arrival with no ordering guarantees. Data is delivered to the
- * PipelineInterests' user via callback immediately upon arrival.
- */
-class PipelineInterestsAdaptive : public PipelineInterests
-{
-public:
-  /**
-   * @brief Constructor.
-   *
-   * Configures the pipelining service without specifying the retrieval namespace. After this
-   * configuration the method run must be called to start the Pipeline.
-   */
-  PipelineInterestsAdaptive(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
-
-  ~PipelineInterestsAdaptive() override;
-
-  /**
-   * @brief Signals when the congestion window changes.
-   *
-   * The callback function should be: `void(nanoseconds age, double cwnd)`, where `age` is the
-   * time since the pipeline started and `cwnd` is the new congestion window size (in segments).
-   */
-  signal::Signal<PipelineInterestsAdaptive, time::nanoseconds, double> afterCwndChange;
-
-  struct RttSample
-  {
-    uint64_t segNum;          ///< segment number on which this sample was taken
-    time::nanoseconds rtt;    ///< measured RTT
-    time::nanoseconds sRtt;   ///< smoothed RTT
-    time::nanoseconds rttVar; ///< RTT variation
-    time::nanoseconds rto;    ///< retransmission timeout
-  };
-
-  /**
-   * @brief Signals when a new RTT sample has been taken.
-   */
-  signal::Signal<PipelineInterestsAdaptive, RttSample> afterRttMeasurement;
-
-protected:
-  DECLARE_SIGNAL_EMIT(afterCwndChange)
-
-  void
-  printOptions() const;
-
-private:
-  /**
-   * @brief Increase congestion window.
-   */
-  virtual void
-  increaseWindow() = 0;
-
-  /**
-   * @brief Decrease congestion window.
-   */
-  virtual void
-  decreaseWindow() = 0;
-
-private:
-  /**
-   * @brief Fetch all the segments between 0 and lastSegment of the specified prefix.
-   *
-   * Starts the pipeline with an adaptive window algorithm to control the window size.
-   * The pipeline will fetch every segment until the last segment is successfully received
-   * or an error occurs.
-   */
-  void
-  doRun() final;
-
-  /**
-   * @brief Stop all fetch operations.
-   */
-  void
-  doCancel() final;
-
-  /**
-   * @brief Check RTO for all sent-but-not-acked segments.
-   */
-  void
-  checkRto();
-
-  /**
-   * @param segNo the segment # of the to-be-sent Interest
-   * @param isRetransmission true if this is a retransmission
-   */
-  void
-  sendInterest(uint64_t segNo, bool isRetransmission);
-
-  void
-  schedulePackets();
-
-  void
-  handleData(const Interest& interest, const Data& data);
-
-  void
-  handleNack(const Interest& interest, const lp::Nack& nack);
-
-  void
-  handleLifetimeExpiration(const Interest& interest);
-
-  void
-  recordTimeout(uint64_t segNo);
-
-  void
-  enqueueForRetransmission(uint64_t segNo);
-
-  void
-  handleFail(uint64_t segNo, const std::string& reason);
-
-  void
-  cancelInFlightSegmentsGreaterThan(uint64_t segNo);
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  printSummary() const final;
-
-PUBLIC_WITH_TESTS_ELSE_PROTECTED:
-  static constexpr double MIN_SSTHRESH = 2.0;
-
-  double m_cwnd; ///< current congestion window size (in segments)
-  double m_ssthresh; ///< current slow start threshold
-  RttEstimatorWithStats& m_rttEstimator;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  Scheduler m_scheduler;
-  scheduler::ScopedEventId m_checkRtoEvent;
-
-  uint64_t m_highData = 0; ///< the highest segment number of the Data packet the consumer has received so far
-  uint64_t m_highInterest = 0; ///< the highest segment number of the Interests the consumer has sent so far
-  uint64_t m_recPoint = 0; ///< the value of m_highInterest when a packet loss event occurred,
-                           ///< it remains fixed until the next packet loss event happens
-
-  int64_t m_nInFlight = 0; ///< # of segments in flight
-  int64_t m_nLossDecr = 0; ///< # of window decreases caused by packet loss
-  int64_t m_nMarkDecr = 0; ///< # of window decreases caused by congestion marks
-  int64_t m_nTimeouts = 0; ///< # of timed out segments
-  int64_t m_nSkippedRetx = 0; ///< # of segments queued for retransmission but received before the
-                              ///< retransmission occurred
-  int64_t m_nRetransmitted = 0; ///< # of retransmitted segments
-  int64_t m_nCongMarks = 0; ///< # of data packets with congestion mark
-  int64_t m_nSent = 0; ///< # of interest packets sent out (including retransmissions)
-
-  std::unordered_map<uint64_t, SegmentInfo> m_segmentInfo; ///< keeps all the internal information
-                                                           ///< on sent but not acked segments
-  std::unordered_map<uint64_t, int> m_retxCount; ///< maps segment number to its retransmission count;
-                                                 ///< if the count reaches to the maximum number of
-                                                 ///< timeout/nack retries, the pipeline will be aborted
-  std::queue<uint64_t> m_retxQueue;
-
-  bool m_hasFailure = false;
-  uint64_t m_failedSegNo = 0;
-  std::string m_failureReason;
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_ADAPTIVE_HPP
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.cpp b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
deleted file mode 100644
index 4d84fdd..0000000
--- a/tools/chunks/catchunks/pipeline-interests-aimd.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2022, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Shuo Yang
- * @author Weiwei Liu
- * @author Chavoosh Ghasemi
- * @author Klaus Schneider
- */
-
-#include "pipeline-interests-aimd.hpp"
-
-#include <cmath>
-
-namespace ndn::chunks {
-
-PipelineInterestsAimd::PipelineInterestsAimd(Face& face, RttEstimatorWithStats& rttEstimator,
-                                             const Options& opts)
-  : PipelineInterestsAdaptive(face, rttEstimator, opts)
-{
-  if (m_options.isVerbose) {
-    printOptions();
-  }
-}
-
-void
-PipelineInterestsAimd::increaseWindow()
-{
-  if (m_cwnd < m_ssthresh) {
-    m_cwnd += m_options.aiStep; // additive increase
-  }
-  else {
-    m_cwnd += m_options.aiStep / std::floor(m_cwnd); // congestion avoidance
-  }
-
-  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
-}
-
-void
-PipelineInterestsAimd::decreaseWindow()
-{
-  // please refer to RFC 5681, Section 3.1 for the rationale behind it
-  m_ssthresh = std::max(MIN_SSTHRESH, m_cwnd * m_options.mdCoef); // multiplicative decrease
-  m_cwnd = m_options.resetCwndToInit ? m_options.initCwnd : m_ssthresh;
-
-  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.hpp b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
deleted file mode 100644
index 1792f95..0000000
--- a/tools/chunks/catchunks/pipeline-interests-aimd.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2022, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Shuo Yang
- * @author Weiwei Liu
- * @author Chavoosh Ghasemi
- * @author Klaus Schneider
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_AIMD_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_AIMD_HPP
-
-#include "pipeline-interests-adaptive.hpp"
-
-namespace ndn::chunks {
-
-/**
- * @brief Implements AIMD window increase and decrease.
- */
-class PipelineInterestsAimd final : public PipelineInterestsAdaptive
-{
-public:
-  PipelineInterestsAimd(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
-
-private:
-  void
-  increaseWindow() final;
-
-  void
-  decreaseWindow() final;
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_AIMD_HPP
diff --git a/tools/chunks/catchunks/pipeline-interests-cubic.cpp b/tools/chunks/catchunks/pipeline-interests-cubic.cpp
deleted file mode 100644
index 7fa57a5..0000000
--- a/tools/chunks/catchunks/pipeline-interests-cubic.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Klaus Schneider
- */
-
-#include "pipeline-interests-cubic.hpp"
-
-#include <cmath>
-#include <iostream>
-
-namespace ndn::chunks {
-
-constexpr double CUBIC_C = 0.4;
-
-PipelineInterestsCubic::PipelineInterestsCubic(Face& face, RttEstimatorWithStats& rttEstimator,
-                                               const Options& opts)
-  : PipelineInterestsAdaptive(face, rttEstimator, opts)
-  , m_lastDecrease(time::steady_clock::now())
-{
-  if (m_options.isVerbose) {
-    printOptions();
-    std::cerr << "\tCubic beta = " << m_options.cubicBeta << "\n"
-              << "\tFast convergence = " << (m_options.enableFastConv ? "yes" : "no") << "\n";
-  }
-}
-
-void
-PipelineInterestsCubic::increaseWindow()
-{
-  // Slow start phase
-  if (m_cwnd < m_ssthresh) {
-    m_cwnd += 1.0;
-  }
-  // Congestion avoidance phase
-  else {
-    // If wmax is still 0, set it to the current cwnd. Usually unnecessary,
-    // if m_ssthresh is large enough.
-    if (m_wmax < m_options.initCwnd) {
-      m_wmax = m_cwnd;
-    }
-
-    // 1. Time since last congestion event in seconds
-    const double t = (time::steady_clock::now() - m_lastDecrease).count() / 1e9;
-
-    // 2. Time it takes to increase the window to m_wmax = the cwnd right before the last
-    // window decrease.
-    // K = cubic_root(wmax*(1-beta_cubic)/C) (Eq. 2)
-    const double k = std::cbrt(m_wmax * (1 - m_options.cubicBeta) / CUBIC_C);
-
-    // 3. Target: W_cubic(t) = C*(t-K)^3 + wmax (Eq. 1)
-    const double wCubic = CUBIC_C * std::pow(t - k, 3) + m_wmax;
-
-    // 4. Estimate of Reno Increase (Eq. 4)
-    const double rtt = m_rttEstimator.getSmoothedRtt().count() / 1e9;
-    const double wEst = m_wmax * m_options.cubicBeta +
-                        (3 * (1 - m_options.cubicBeta) / (1 + m_options.cubicBeta)) * (t / rtt);
-
-    // Actual adaptation
-    double cubicIncrement = std::max(wCubic, wEst) - m_cwnd;
-    // Cubic increment must be positive
-    // Note: This change is not part of the RFC, but I added it to improve performance.
-    cubicIncrement = std::max(0.0, cubicIncrement);
-
-    m_cwnd += cubicIncrement / m_cwnd;
-  }
-
-  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
-}
-
-void
-PipelineInterestsCubic::decreaseWindow()
-{
-  // A flow remembers the last value of wmax,
-  // before it updates wmax for the current congestion event.
-
-  // Current wmax < last_wmax
-  if (m_options.enableFastConv && m_cwnd < m_lastWmax) {
-    m_lastWmax = m_cwnd;
-    m_wmax = m_cwnd * (1.0 + m_options.cubicBeta) / 2.0;
-  }
-  else {
-    // Save old cwnd as wmax
-    m_lastWmax = m_cwnd;
-    m_wmax = m_cwnd;
-  }
-
-  m_ssthresh = std::max(m_options.initCwnd, m_cwnd * m_options.cubicBeta);
-  m_cwnd = m_ssthresh;
-  m_lastDecrease = time::steady_clock::now();
-
-  emitSignal(afterCwndChange, time::steady_clock::now() - getStartTime(), m_cwnd);
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/pipeline-interests-cubic.hpp b/tools/chunks/catchunks/pipeline-interests-cubic.hpp
deleted file mode 100644
index 87b4824..0000000
--- a/tools/chunks/catchunks/pipeline-interests-cubic.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2022, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Klaus Schneider
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_CUBIC_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_CUBIC_HPP
-
-#include "pipeline-interests-adaptive.hpp"
-
-namespace ndn::chunks {
-
-/**
- * @brief Implements Cubic window increase and decrease.
- *
- * This implementation follows the RFC8312 https://tools.ietf.org/html/rfc8312
- * and the Linux kernel implementation https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_cubic.c
- */
-class PipelineInterestsCubic final : public PipelineInterestsAdaptive
-{
-public:
-  PipelineInterestsCubic(Face& face, RttEstimatorWithStats& rttEstimator, const Options& opts);
-
-private:
-  void
-  increaseWindow() final;
-
-  void
-  decreaseWindow() final;
-
-private:
-  double m_wmax = 0.0; ///< window size before last window decrease
-  double m_lastWmax = 0.0; ///< last wmax
-  time::steady_clock::time_point m_lastDecrease; ///< time of last window decrease
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_CUBIC_HPP
diff --git a/tools/chunks/catchunks/pipeline-interests-fixed.cpp b/tools/chunks/catchunks/pipeline-interests-fixed.cpp
deleted file mode 100644
index 9e8ffa1..0000000
--- a/tools/chunks/catchunks/pipeline-interests-fixed.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- * @author Davide Pesavento
- * @author Chavoosh Ghasemi
- */
-
-#include "pipeline-interests-fixed.hpp"
-#include "data-fetcher.hpp"
-
-#include <iostream>
-
-namespace ndn::chunks {
-
-PipelineInterestsFixed::PipelineInterestsFixed(Face& face, const Options& opts)
-  : PipelineInterests(face, opts)
-{
-  m_segmentFetchers.resize(m_options.maxPipelineSize);
-
-  if (m_options.isVerbose) {
-    printOptions();
-    std::cerr << "\tPipeline size = " << m_options.maxPipelineSize << "\n";
-  }
-}
-
-PipelineInterestsFixed::~PipelineInterestsFixed()
-{
-  cancel();
-}
-
-void
-PipelineInterestsFixed::doRun()
-{
-  // if the FinalBlockId is unknown, this could potentially request non-existent segments
-  for (size_t nRequestedSegments = 0;
-       nRequestedSegments < m_options.maxPipelineSize;
-       ++nRequestedSegments) {
-    if (!fetchNextSegment(nRequestedSegments))
-      // all segments have been requested
-      break;
-  }
-}
-
-bool
-PipelineInterestsFixed::fetchNextSegment(std::size_t pipeNo)
-{
-  if (isStopping())
-    return false;
-
-  if (m_hasFailure) {
-    onFailure("Fetching terminated but no final segment number has been found");
-    return false;
-  }
-
-  uint64_t nextSegmentNo = getNextSegmentNo();
-  if (m_hasFinalBlockId && nextSegmentNo > m_lastSegmentNo)
-    return false;
-
-  // send interest for next segment
-  if (m_options.isVerbose)
-    std::cerr << "Requesting segment #" << nextSegmentNo << "\n";
-
-  auto interest = Interest()
-                  .setName(Name(m_prefix).appendSegment(nextSegmentNo))
-                  .setMustBeFresh(m_options.mustBeFresh)
-                  .setInterestLifetime(m_options.interestLifetime);
-
-  auto fetcher = DataFetcher::fetch(m_face, interest,
-                                    m_options.maxRetriesOnTimeoutOrNack,
-                                    m_options.maxRetriesOnTimeoutOrNack,
-                                    [this, pipeNo] (const auto& interest, const auto& data) {
-                                      handleData(interest, data, pipeNo);
-                                    },
-                                    [this, pipeNo] (const auto&, const auto& reason) {
-                                      handleFail(reason, pipeNo);
-                                    },
-                                    [this, pipeNo] (const auto&, const auto& reason) {
-                                      handleFail(reason, pipeNo);
-                                    },
-                                    m_options.isVerbose);
-
-  BOOST_ASSERT(!m_segmentFetchers[pipeNo].first || !m_segmentFetchers[pipeNo].first->isRunning());
-  m_segmentFetchers[pipeNo] = make_pair(fetcher, nextSegmentNo);
-
-  return true;
-}
-
-void
-PipelineInterestsFixed::doCancel()
-{
-  for (auto& fetcher : m_segmentFetchers) {
-    if (fetcher.first)
-      fetcher.first->cancel();
-  }
-
-  m_segmentFetchers.clear();
-}
-
-void
-PipelineInterestsFixed::handleData(const Interest& interest, const Data& data, size_t pipeNo)
-{
-  if (isStopping())
-    return;
-
-  // Interest was expressed with CanBePrefix=false
-  BOOST_ASSERT(data.getName().equals(interest.getName()));
-
-  if (m_options.isVerbose)
-    std::cerr << "Received segment #" << getSegmentFromPacket(data) << "\n";
-
-  onData(data);
-
-  if (!m_hasFinalBlockId && data.getFinalBlock()) {
-    m_lastSegmentNo = data.getFinalBlock()->toSegment();
-    m_hasFinalBlockId = true;
-
-    for (auto& fetcher : m_segmentFetchers) {
-      if (fetcher.first == nullptr)
-        continue;
-
-      if (fetcher.second > m_lastSegmentNo) {
-        // stop trying to fetch segments that are beyond m_lastSegmentNo
-        fetcher.first->cancel();
-      }
-      else if (fetcher.first->hasError()) { // fetcher.second <= m_lastSegmentNo
-        // there was an error while fetching a segment that is part of the content
-        return onFailure("Failure retrieving segment #" + std::to_string(fetcher.second));
-      }
-    }
-  }
-
-  if (allSegmentsReceived()) {
-    if (!m_options.isQuiet) {
-      printSummary();
-    }
-  }
-  else {
-    fetchNextSegment(pipeNo);
-  }
-}
-
-void PipelineInterestsFixed::handleFail(const std::string& reason, std::size_t pipeNo)
-{
-  if (isStopping())
-    return;
-
-  // if the failed segment is definitely part of the content, raise a fatal error
-  if (m_hasFinalBlockId && m_segmentFetchers[pipeNo].second <= m_lastSegmentNo)
-    return onFailure(reason);
-
-  if (!m_hasFinalBlockId) {
-    bool areAllFetchersStopped = true;
-    for (auto& fetcher : m_segmentFetchers) {
-      if (fetcher.first == nullptr)
-        continue;
-
-      // cancel fetching all segments that follow
-      if (fetcher.second > m_segmentFetchers[pipeNo].second) {
-        fetcher.first->cancel();
-      }
-      else if (fetcher.first->isRunning()) { // fetcher.second <= m_segmentFetchers[pipeNo].second
-        areAllFetchersStopped = false;
-      }
-    }
-
-    if (areAllFetchersStopped) {
-      onFailure("Fetching terminated but no final segment number has been found");
-    }
-    else {
-      m_hasFailure = true;
-    }
-  }
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/pipeline-interests-fixed.hpp b/tools/chunks/catchunks/pipeline-interests-fixed.hpp
deleted file mode 100644
index 8e9e3ce..0000000
--- a/tools/chunks/catchunks/pipeline-interests-fixed.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024,  Regents of the University of California,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- * @author Davide Pesavento
- * @author Chavoosh Ghasemi
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_FIXED_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_FIXED_HPP
-
-#include "pipeline-interests.hpp"
-
-#include <vector>
-
-namespace ndn::chunks {
-
-class DataFetcher;
-
-/**
- * @brief Service for retrieving Data via an Interest pipeline
- *
- * Retrieves all segments of Data under a given prefix by maintaining a fixed-size window of
- * N Interests in flight. A user-specified callback function is used to notify the arrival of
- * each segment of Data.
- *
- * No guarantees are made as to the order in which segments are fetched or callbacks are invoked,
- * i.e. out-of-order delivery is possible.
- */
-class PipelineInterestsFixed final : public PipelineInterests
-{
-public:
-  PipelineInterestsFixed(Face& face, const Options& opts);
-
-  ~PipelineInterestsFixed() final;
-
-private:
-  /**
-   * @brief fetch all the segments between 0 and m_lastSegmentNo
-   *
-   * Starts a fixed-window pipeline with size equal to m_options.maxPipelineSize. The pipeline
-   * will fetch every segment until the last segment is successfully received or an error occurs.
-   */
-  void
-  doRun() final;
-
-  void
-  doCancel() final;
-
-  /**
-   * @brief fetch the next segment that has not been requested yet
-   *
-   * @return false if there is an error or all the segments have been fetched, true otherwise
-   */
-  bool
-  fetchNextSegment(size_t pipeNo);
-
-  void
-  handleData(const Interest& interest, const Data& data, size_t pipeNo);
-
-  void
-  handleFail(const std::string& reason, size_t pipeNo);
-
-private:
-  std::vector<std::pair<std::shared_ptr<DataFetcher>, uint64_t>> m_segmentFetchers;
-
-  /**
-   * true if one or more segment fetchers encountered an error; if m_hasFinalBlockId
-   * is false, this is usually not a fatal error for the pipeline
-   */
-  bool m_hasFailure = false;
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_FIXED_HPP
diff --git a/tools/chunks/catchunks/pipeline-interests.cpp b/tools/chunks/catchunks/pipeline-interests.cpp
deleted file mode 100644
index 2e29487..0000000
--- a/tools/chunks/catchunks/pipeline-interests.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- * @author Davide Pesavento
- * @author Weiwei Liu
- * @author Chavoosh Ghasemi
- */
-
-#include "pipeline-interests.hpp"
-#include "data-fetcher.hpp"
-
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/post.hpp>
-
-#include <iostream>
-
-namespace ndn::chunks {
-
-PipelineInterests::PipelineInterests(Face& face, const Options& opts)
-  : m_options(opts)
-  , m_face(face)
-{
-}
-
-PipelineInterests::~PipelineInterests() = default;
-
-void
-PipelineInterests::run(const Name& versionedName, DataCallback dataCb, FailureCallback failureCb)
-{
-  BOOST_ASSERT(m_options.disableVersionDiscovery ||
-               (!versionedName.empty() && versionedName[-1].isVersion()));
-  BOOST_ASSERT(dataCb != nullptr);
-
-  m_prefix = versionedName;
-  m_onData = std::move(dataCb);
-  m_onFailure = std::move(failureCb);
-
-  // record the start time of the pipeline
-  m_startTime = time::steady_clock::now();
-
-  doRun();
-}
-
-void
-PipelineInterests::cancel()
-{
-  if (m_isStopping)
-    return;
-
-  m_isStopping = true;
-  doCancel();
-}
-
-bool
-PipelineInterests::allSegmentsReceived() const
-{
-  return m_nReceived > 0 &&
-         m_hasFinalBlockId &&
-         static_cast<uint64_t>(m_nReceived - 1) >= m_lastSegmentNo;
-}
-
-uint64_t
-PipelineInterests::getNextSegmentNo()
-{
-  return m_nextSegmentNo++;
-}
-
-void
-PipelineInterests::onData(const Data& data)
-{
-  m_nReceived++;
-  m_receivedSize += data.getContent().value_size();
-
-  m_onData(data);
-}
-
-void
-PipelineInterests::onFailure(const std::string& reason)
-{
-  if (m_isStopping)
-    return;
-
-  cancel();
-
-  if (m_onFailure) {
-    boost::asio::post(m_face.getIoContext(), [this, reason] { m_onFailure(reason); });
-  }
-}
-
-void
-PipelineInterests::printOptions() const
-{
-  std::cerr << "Pipeline parameters:\n"
-            << "\tRequest fresh content = " << (m_options.mustBeFresh ? "yes" : "no") << "\n"
-            << "\tInterest lifetime = " << m_options.interestLifetime << "\n"
-            << "\tMax retries on timeout or Nack = " <<
-               (m_options.maxRetriesOnTimeoutOrNack == DataFetcher::MAX_RETRIES_INFINITE ?
-                  "infinite" : std::to_string(m_options.maxRetriesOnTimeoutOrNack)) << "\n";
-}
-
-void
-PipelineInterests::printSummary() const
-{
-  using namespace ndn::time;
-  duration<double, seconds::period> timeElapsed = steady_clock::now() - getStartTime();
-  double throughput = 8 * m_receivedSize / timeElapsed.count();
-
-  std::cerr << "\n\nAll segments have been received.\n"
-            << "Time elapsed: " << timeElapsed << "\n"
-            << "Segments received: " << m_nReceived << "\n"
-            << "Transferred size: " << m_receivedSize / 1e3 << " kB" << "\n"
-            << "Goodput: " << formatThroughput(throughput) << "\n";
-}
-
-std::string
-PipelineInterests::formatThroughput(double throughput)
-{
-  int pow = 0;
-  while (throughput >= 1000.0 && pow < 4) {
-    throughput /= 1000.0;
-    pow++;
-  }
-  switch (pow) {
-    case 0:
-      return std::to_string(throughput) + " bit/s";
-    case 1:
-      return std::to_string(throughput) + " kbit/s";
-    case 2:
-      return std::to_string(throughput) + " Mbit/s";
-    case 3:
-      return std::to_string(throughput) + " Gbit/s";
-    case 4:
-      return std::to_string(throughput) + " Tbit/s";
-  }
-  return "";
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/pipeline-interests.hpp b/tools/chunks/catchunks/pipeline-interests.hpp
deleted file mode 100644
index 2757b21..0000000
--- a/tools/chunks/catchunks/pipeline-interests.hpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2016-2024, Regents of the University of California,
- *                          Colorado State University,
- *                          University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Wentao Shang
- * @author Steve DiBenedetto
- * @author Andrea Tosatto
- * @author Davide Pesavento
- * @author Weiwei Liu
- * @author Chavoosh Ghasemi
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_HPP
-
-#include "core/common.hpp"
-#include "options.hpp"
-
-#include <ndn-cxx/face.hpp>
-
-#include <functional>
-
-namespace ndn::chunks {
-
-/**
- * @brief Service for retrieving Data via an Interest pipeline
- *
- * Retrieves all segments of Data under a given prefix by maintaining a (variable or fixed-size)
- * window of N Interests in flight. A user-specified callback function is used to notify
- * the arrival of each segment of Data.
- *
- * No guarantees are made as to the order in which segments are fetched or callbacks are invoked,
- * i.e. out-of-order delivery is possible.
- */
-class PipelineInterests : noncopyable
-{
-public:
-  /**
-   * @brief Constructor.
-   *
-   * Configures the pipelining service without specifying the retrieval namespace.
-   * After construction, the method run() must be called in order to start the pipeline.
-   */
-  PipelineInterests(Face& face, const Options& opts);
-
-  virtual
-  ~PipelineInterests();
-
-  using DataCallback = std::function<void(const Data&)>;
-  using FailureCallback = std::function<void(const std::string& reason)>;
-
-  /**
-   * @brief start fetching all the segments of the specified prefix
-   *
-   * @param versionedName the name of the segmented Data ending with a version number
-   * @param onData callback for every segment correctly received, must not be empty
-   * @param onFailure callback if an error occurs, may be empty
-   */
-  void
-  run(const Name& versionedName, DataCallback onData, FailureCallback onFailure);
-
-  /**
-   * @brief stop all fetch operations
-   */
-  void
-  cancel();
-
-protected:
-  time::steady_clock::time_point
-  getStartTime() const
-  {
-    return m_startTime;
-  }
-
-  bool
-  isStopping() const
-  {
-    return m_isStopping;
-  }
-
-  /**
-   * @brief check if the transfer is complete
-   * @return true if all segments have been received, false otherwise
-   */
-  [[nodiscard]] bool
-  allSegmentsReceived() const;
-
-  /**
-   * @return next segment number to retrieve
-   * @post m_nextSegmentNo == return-value + 1
-   */
-  uint64_t
-  getNextSegmentNo();
-
-  /**
-   * @brief subclasses must call this method to notify successful retrieval of a segment
-   */
-  void
-  onData(const Data& data);
-
-  /**
-   * @brief subclasses can call this method to signal an unrecoverable failure
-   */
-  void
-  onFailure(const std::string& reason);
-
-  void
-  printOptions() const;
-
-  /**
-   * @brief print statistics about this fetching session
-   *
-   * Subclasses can override this method to print additional stats or change the summary format
-   */
-  virtual void
-  printSummary() const;
-
-  /**
-   * @param throughput The throughput in bits/s
-   */
-  static std::string
-  formatThroughput(double throughput);
-
-private:
-  /**
-   * @brief perform subclass-specific operations to fetch all the segments
-   *
-   * When overriding this function, at a minimum, the subclass should implement the retrieving
-   * of all the segments. Subclass must guarantee that `onData` is called once for every
-   * segment that is fetched successfully.
-   *
-   * @note m_lastSegmentNo contains a valid value only if m_hasFinalBlockId is true.
-   */
-  virtual void
-  doRun() = 0;
-
-  virtual void
-  doCancel() = 0;
-
-protected:
-  const Options& m_options;
-  Face& m_face;
-  Name m_prefix;
-
-PUBLIC_WITH_TESTS_ELSE_PROTECTED:
-  bool m_hasFinalBlockId = false; ///< true if the last segment number is known
-  uint64_t m_lastSegmentNo = 0;   ///< valid only if m_hasFinalBlockId == true
-  int64_t m_nReceived = 0;        ///< number of segments received
-  size_t m_receivedSize = 0;      ///< size of received data in bytes
-
-private:
-  DataCallback m_onData;
-  FailureCallback m_onFailure;
-  uint64_t m_nextSegmentNo = 0;
-  time::steady_clock::time_point m_startTime;
-  bool m_isStopping = false;
-};
-
-template<typename Packet>
-uint64_t
-getSegmentFromPacket(const Packet& packet)
-{
-  return packet.getName().at(-1).toSegment();
-}
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_HPP
diff --git a/tools/chunks/catchunks/statistics-collector.cpp b/tools/chunks/catchunks/statistics-collector.cpp
deleted file mode 100644
index 2e303c9..0000000
--- a/tools/chunks/catchunks/statistics-collector.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2016-2022,  Regents of the University of California,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Weiwei Liu
- */
-
-#include "statistics-collector.hpp"
-
-namespace ndn::chunks {
-
-StatisticsCollector::StatisticsCollector(PipelineInterestsAdaptive& pipeline,
-                                         std::ostream& osCwnd, std::ostream& osRtt)
-  : m_osCwnd(osCwnd)
-  , m_osRtt(osRtt)
-{
-  m_osCwnd << "time\tcwndsize\n";
-  m_osRtt  << "segment\trtt\trttvar\tsrtt\trto\n";
-
-  pipeline.afterCwndChange.connect([this] (time::nanoseconds timeElapsed, double cwnd) {
-    m_osCwnd << timeElapsed.count() / 1e9 << '\t' << cwnd << '\n';
-  });
-
-  pipeline.afterRttMeasurement.connect([this] (const auto& sample) {
-    m_osRtt << sample.segNum << '\t'
-            << sample.rtt.count() / 1e6 << '\t'
-            << sample.rttVar.count() / 1e6 << '\t'
-            << sample.sRtt.count() / 1e6 << '\t'
-            << sample.rto.count() / 1e6 << '\n';
-  });
-}
-
-} // namespace ndn::chunks
diff --git a/tools/chunks/catchunks/statistics-collector.hpp b/tools/chunks/catchunks/statistics-collector.hpp
deleted file mode 100644
index 95abbae..0000000
--- a/tools/chunks/catchunks/statistics-collector.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016-2022,  Regents of the University of California,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University.
- *
- * This file is part of ndn-tools (Named Data Networking Essential Tools).
- * See AUTHORS.md for complete list of ndn-tools authors and contributors.
- *
- * ndn-tools 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-tools 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
- * ndn-tools, 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.
- *
- * @author Weiwei Liu
- */
-
-#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_STATISTICS_COLLECTOR_HPP
-#define NDN_TOOLS_CHUNKS_CATCHUNKS_STATISTICS_COLLECTOR_HPP
-
-#include "pipeline-interests-adaptive.hpp"
-
-namespace ndn::chunks {
-
-/**
- * @brief Statistics collector for Adaptive pipelines
- */
-class StatisticsCollector : noncopyable
-{
-public:
-  StatisticsCollector(PipelineInterestsAdaptive& pipeline,
-                      std::ostream& osCwnd, std::ostream& osRtt);
-
-private:
-  std::ostream& m_osCwnd;
-  std::ostream& m_osRtt;
-};
-
-} // namespace ndn::chunks
-
-#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_STATISTICS_COLLECTOR_HPP
diff --git a/tools/chunks/wscript b/tools/chunks/wscript
index 417bbf6..31fddd1 100644
--- a/tools/chunks/wscript
+++ b/tools/chunks/wscript
@@ -2,30 +2,13 @@
 top = '../..'
 
 def build(bld):
-
     bld.objects(
-        target='ndncatchunks-objects',
-        source=bld.path.ant_glob('catchunks/*.cpp', excl='catchunks/main.cpp'),
-        use='core-objects')
-
-    bld.program(
-        target='../../bin/ndncatchunks',
-        name='ndncatchunks',
-        source='catchunks/main.cpp',
-        use='ndncatchunks-objects')
-
-    bld.objects(
-        target='ndnputchunks-objects',
+        target='chunks-objects',
         source=bld.path.ant_glob('putchunks/*.cpp', excl='putchunks/main.cpp'),
         use='core-objects')
 
     bld.program(
-        target='../../bin/ndnputchunks',
+        target=f'{top}/bin/ndnputchunks',
         name='ndnputchunks',
         source='putchunks/main.cpp',
-        use='ndnputchunks-objects')
-
-    ## (for unit tests)
-
-    bld(target='chunks-objects',
-        use='ndncatchunks-objects ndnputchunks-objects')
+        use='chunks-objects')