diff --git a/tools/chunks/catchunks/consumer.cpp b/tools/chunks/catchunks/consumer.cpp
new file mode 100644
index 0000000..8976f6a
--- /dev/null
+++ b/tools/chunks/catchunks/consumer.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 "discover-version.hpp"
+
+namespace ndn {
+namespace chunks {
+
+Consumer::Consumer(Face& face, Validator& validator, bool isVerbose, std::ostream& os)
+  : m_face(face)
+  , m_validator(validator)
+  , m_pipeline(nullptr)
+  , m_nextToPrint(0)
+  , m_outputStream(os)
+  , m_isVerbose(isVerbose)
+{
+}
+
+void Consumer::run(DiscoverVersion& discover, PipelineInterests& pipeline)
+{
+  m_pipeline = &pipeline;
+  m_nextToPrint = 0;
+
+  discover.onDiscoverySuccess.connect(bind(&Consumer::runWithData, this, _1));
+  discover.onDiscoveryFailure.connect(bind(&Consumer::onFailure, this, _1));
+
+  discover.run();
+  m_face.processEvents();
+}
+
+void Consumer::runWithData(const Data& data)
+{
+  m_validator.validate(data,
+                       bind(&Consumer::onDataValidated, this, _1),
+                       bind(&Consumer::onFailure, this, _2));
+
+  m_pipeline->runWithExcludedSegment(data,
+                                     bind(&Consumer::onData, this, _1, _2),
+                                     bind(&Consumer::onFailure, this, _1));
+
+}
+
+void
+Consumer::onData(const Interest& interest, const Data& data)
+{
+  m_validator.validate(data,
+                       bind(&Consumer::onDataValidated, this, _1),
+                       bind(&Consumer::onFailure, this, _2));
+}
+
+void
+Consumer::onDataValidated(shared_ptr<const Data> data)
+{
+  if (data->getContentType() == ndn::tlv::ContentType_Nack) {
+    if (m_isVerbose)
+      std::cerr << "Application level NACK: " << *data << std::endl;
+
+    m_pipeline->cancel();
+    throw ApplicationNackError(*data);
+  }
+
+  m_bufferedData[data->getName()[-1].toSegment()] = data;
+  writeInOrderData();
+}
+
+void
+Consumer::onFailure(const std::string& reason)
+{
+  throw std::runtime_error(reason);
+}
+
+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 chunks
+} // namespace ndn
diff --git a/tools/chunks/catchunks/consumer.hpp b/tools/chunks/catchunks/consumer.hpp
new file mode 100644
index 0000000..9428a06
--- /dev/null
+++ b/tools/chunks/catchunks/consumer.hpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 "pipeline-interests.hpp"
+#include "discover-version.hpp"
+
+#include <ndn-cxx/security/validator.hpp>
+
+namespace ndn {
+namespace 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))
+    {
+    }
+  };
+
+  /**
+   * @brief Create the consumer
+   */
+  Consumer(Face& face, Validator& validator, bool isVerbose, std::ostream& os = std::cout);
+
+  /**
+   * @brief Run the consumer
+   */
+  void
+  run(DiscoverVersion& discover, PipelineInterests& pipeline);
+
+private:
+  void
+  runWithData(const Data& data);
+
+  void
+  onData(const Interest& interest, const Data& data);
+
+  void
+  onDataValidated(shared_ptr<const Data> data);
+
+  void
+  onFailure(const std::string& reason);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  writeInOrderData();
+
+private:
+  Face& m_face;
+  Validator& m_validator;
+  PipelineInterests* m_pipeline;
+  uint64_t m_nextToPrint;
+  std::ostream& m_outputStream;
+  bool m_isVerbose;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  std::map<uint64_t, shared_ptr<const Data>> m_bufferedData;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_CONSUMER_HPP
diff --git a/tools/chunks/catchunks/data-fetcher.cpp b/tools/chunks/catchunks/data-fetcher.cpp
new file mode 100644
index 0000000..313334f
--- /dev/null
+++ b/tools/chunks/catchunks/data-fetcher.cpp
@@ -0,0 +1,181 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 <cmath>
+
+namespace ndn {
+namespace chunks {
+
+const int DataFetcher::MAX_RETRIES_INFINITE = -1;
+const time::milliseconds DataFetcher::MAX_CONGESTION_BACKOFF_TIME = time::seconds(10);
+
+shared_ptr<DataFetcher>
+DataFetcher::fetch(Face& face, const Interest& interest, int maxNackRetries, int maxTimeoutRetries,
+                   DataCallback onData, FailureCallback onNack, FailureCallback onTimeout,
+                   bool isVerbose)
+{
+  auto dataFetcher = 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.getIoService())
+  , m_onData(std::move(onData))
+  , m_onNack(std::move(onNack))
+  , m_onTimeout(std::move(onTimeout))
+  , m_maxNackRetries(maxNackRetries)
+  , m_maxTimeoutRetries(maxTimeoutRetries)
+  , m_nNacks(0)
+  , m_nTimeouts(0)
+  , m_nCongestionRetries(0)
+  , m_isVerbose(isVerbose)
+  , m_isStopped(false)
+  , m_hasError(false)
+{
+  BOOST_ASSERT(m_onData != nullptr);
+}
+
+void
+DataFetcher::cancel()
+{
+  if (isRunning()) {
+    m_isStopped = true;
+    m_face.removePendingInterest(m_interestId);
+    m_scheduler.cancelAllEvents();
+  }
+}
+
+void
+DataFetcher::expressInterest(const Interest& interest, const shared_ptr<DataFetcher>& self)
+{
+  m_nCongestionRetries = 0;
+  m_interestId = m_face.expressInterest(interest,
+                                        bind(&DataFetcher::handleData, this, _1, _2, self),
+                                        bind(&DataFetcher::handleNack, this, _1, _2, self),
+                                        bind(&DataFetcher::handleTimeout, this, _1, self));
+}
+
+void
+DataFetcher::handleData(const Interest& interest, const Data& data,
+                        const 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 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 << std::endl;
+
+  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.scheduleEvent(backoffTime, bind(&DataFetcher::expressInterest, this,
+                                                    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 (" + to_string(m_maxNackRetries) +
+                         ") while retrieving data for " + interest.getName().toUri());
+  }
+}
+
+void
+DataFetcher::handleTimeout(const Interest& interest, const shared_ptr<DataFetcher>& self)
+{
+  if (!isRunning())
+    return;
+
+  if (m_maxTimeoutRetries != MAX_RETRIES_INFINITE)
+    ++m_nTimeouts;
+
+  if (m_isVerbose)
+    std::cerr << "Timeout for Interest " << interest << std::endl;
+
+  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 (" + to_string(m_maxTimeoutRetries) +
+                            ") while retrieving data for " + interest.getName().toUri());
+  }
+}
+
+} // namespace chunks
+} // namespace ndn
diff --git a/tools/chunks/catchunks/data-fetcher.hpp b/tools/chunks/catchunks/data-fetcher.hpp
new file mode 100644
index 0000000..4335ab2
--- /dev/null
+++ b/tools/chunks/catchunks/data-fetcher.hpp
@@ -0,0 +1,132 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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"
+
+namespace ndn {
+namespace 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 const int MAX_RETRIES_INFINITE;
+
+  /**
+   * @brief ceiling value for backoff time used in congestion handling
+   */
+  static const time::milliseconds MAX_CONGESTION_BACKOFF_TIME;
+
+  typedef function<void(const Interest& interest, const std::string& reason)> FailureCallback;
+
+  /**
+   * @brief instantiate a DataFetcher object and start fetching data
+   *
+   * @param onData callback for segment correctly received, must not be empty
+   */
+  static 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 shared_ptr<DataFetcher>& self);
+
+  void
+  handleData(const Interest& interest, const Data& data, const shared_ptr<DataFetcher>& self);
+
+  void
+  handleNack(const Interest& interest, const lp::Nack& nack, const shared_ptr<DataFetcher>& self);
+
+  void
+  handleTimeout(const Interest& interest, const shared_ptr<DataFetcher>& self);
+
+private:
+  Face& m_face;
+  Scheduler m_scheduler;
+  const PendingInterestId* m_interestId;
+  DataCallback m_onData;
+  FailureCallback m_onNack;
+  FailureCallback m_onTimeout;
+
+  int m_maxNackRetries;
+  int m_maxTimeoutRetries;
+  int m_nNacks;
+  int m_nTimeouts;
+  uint32_t m_nCongestionRetries;
+
+  bool m_isVerbose;
+  bool m_isStopped;
+  bool m_hasError;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_DATA_FETCHER_HPP
diff --git a/tools/chunks/catchunks/discover-version-fixed.cpp b/tools/chunks/catchunks/discover-version-fixed.cpp
new file mode 100644
index 0000000..6b763de
--- /dev/null
+++ b/tools/chunks/catchunks/discover-version-fixed.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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
+ */
+
+#include "discover-version-fixed.hpp"
+
+#include <cmath>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace chunks {
+
+DiscoverVersionFixed::DiscoverVersionFixed(const Name& prefix, Face& face, const Options& options)
+  : Options(options)
+  , DiscoverVersion(prefix, face, options)
+  , m_strayExcludes()
+{
+}
+
+void
+DiscoverVersionFixed::run()
+{
+  Interest interest(m_prefix);
+  interest.setInterestLifetime(interestLifetime);
+  interest.setMustBeFresh(mustBeFresh);
+  interest.setMaxSuffixComponents(2);
+  interest.setMinSuffixComponents(2);
+
+  expressInterest(interest, maxRetriesOnTimeoutOrNack, maxRetriesOnTimeoutOrNack);
+}
+
+void
+DiscoverVersionFixed::handleData(const Interest& interest, const Data& data)
+{
+  if (isVerbose)
+    std::cerr << "Data: " << data << std::endl;
+
+  size_t segmentIndex = interest.getName().size();
+  if (data.getName()[segmentIndex].isSegment()) {
+    if (isVerbose)
+      std::cerr << "Found data with the requested version: " << m_prefix[-1] << std::endl;
+
+    this->emitSignal(onDiscoverySuccess, data);
+  }
+  else {
+    // data isn't a valid segment, add to the exclude list
+    m_strayExcludes.excludeOne(data.getName()[segmentIndex]);
+    Interest newInterest(interest);
+    newInterest.refreshNonce();
+    newInterest.setExclude(m_strayExcludes);
+
+    expressInterest(newInterest, maxRetriesOnTimeoutOrNack, maxRetriesOnTimeoutOrNack);
+  }
+}
+
+} // namespace chunks
+} // namespace ndn
diff --git a/tools/chunks/catchunks/discover-version-fixed.hpp b/tools/chunks/catchunks/discover-version-fixed.hpp
new file mode 100644
index 0000000..31c77db
--- /dev/null
+++ b/tools/chunks/catchunks/discover-version-fixed.hpp
@@ -0,0 +1,73 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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
+ */
+
+#ifndef NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_FIXED_HPP
+#define NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_FIXED_HPP
+
+#include "discover-version.hpp"
+
+namespace ndn {
+namespace chunks {
+
+/**
+ * @brief Service to retrieve a specific version segment. The version is specified in the prefix
+ *
+ * Send a request of a specific version and expect to be answered with one segment.
+ *
+ * The received name component after version can be an invalid segment number, this component will
+ * be excluded in the next interests. In the unlikely case that there are too many excluded
+ * components such that the Interest cannot fit in ndn::MAX_NDN_PACKET_SIZE, the discovery
+ * procedure will throw Face::Error.
+ *
+ * DiscoverVersionFixed's user is notified once after one segment with the user specified version
+ * is found or on failure to find any Data version.
+ */
+class DiscoverVersionFixed : public DiscoverVersion
+{
+
+public:
+  /**
+   * @brief create a DiscoverVersionSpecified service
+   */
+  DiscoverVersionFixed(const Name& prefix, Face& face, const Options& options);
+
+  /**
+   * @brief identify the latest Data version published.
+   */
+  void
+  run() NDN_CXX_DECL_FINAL;
+
+private:
+  void
+  handleData(const Interest& interest, const Data& data) NDN_CXX_DECL_FINAL;
+
+private:
+  Exclude m_strayExcludes;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_FIXED_HPP
diff --git a/tools/chunks/catchunks/discover-version-iterative.cpp b/tools/chunks/catchunks/discover-version-iterative.cpp
new file mode 100644
index 0000000..4f2f543
--- /dev/null
+++ b/tools/chunks/catchunks/discover-version-iterative.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 "discover-version-iterative.hpp"
+
+namespace ndn {
+namespace chunks {
+
+DiscoverVersionIterative::DiscoverVersionIterative(const Name& prefix, Face& face,
+                                                   const Options& options)
+  : chunks::Options(options)
+  , DiscoverVersion(prefix, face, options)
+  , Options(options)
+  , m_latestVersion(0)
+  , m_latestVersionData(nullptr)
+  , m_foundVersion(false)
+{
+}
+
+void
+DiscoverVersionIterative::run()
+{
+  m_latestVersion = 0;
+  m_foundVersion = false;
+
+  Interest interest(m_prefix);
+  interest.setInterestLifetime(interestLifetime);
+  interest.setMustBeFresh(mustBeFresh);
+  interest.setMinSuffixComponents(3);
+  interest.setMaxSuffixComponents(3);
+  interest.setChildSelector(1);
+
+  expressInterest(interest, maxRetriesOnTimeoutOrNack, maxRetriesOnTimeoutOrNack);
+}
+
+void
+DiscoverVersionIterative::handleData(const Interest& interest, const Data& data)
+{
+  size_t versionindex = m_prefix.size();
+
+  const Name& name = data.getName();
+  Exclude exclude;
+
+  if (isVerbose)
+    std::cerr << "Data: " << data << std::endl;
+
+  BOOST_ASSERT(name.size() > m_prefix.size());
+  if (name[versionindex].isVersion()) {
+    m_latestVersion = name[versionindex].toVersion();
+    m_latestVersionData = make_shared<Data>(data);
+    m_foundVersion = true;
+
+    exclude.excludeBefore(name[versionindex]);
+
+    if (isVerbose)
+      std::cerr << "Discovered version = " << m_latestVersion << std::endl;
+  }
+  else {
+    // didn't find a version number at expected index.
+    m_strayExcludes.excludeOne(name[versionindex]);
+  }
+
+  for (const auto& i : m_strayExcludes) {
+    exclude.excludeOne(i.first);
+  }
+
+  Interest newInterest(interest);
+  newInterest.refreshNonce();
+  newInterest.setExclude(exclude);
+
+  if (m_foundVersion)
+    expressInterest(newInterest, maxRetriesOnTimeoutOrNack, maxRetriesAfterVersionFound);
+  else
+    expressInterest(interest, maxRetriesOnTimeoutOrNack, maxRetriesOnTimeoutOrNack);
+}
+
+void
+DiscoverVersionIterative::handleTimeout(const Interest& interest, const std::string& reason)
+{
+  if (m_foundVersion) {
+    // a version has been found and after a timeout error this version can be used as the latest.
+    if (isVerbose)
+      std::cerr << "Found data with the latest version: " << m_latestVersion << std::endl;
+
+    // we discovered at least one version. assume what we have is the latest.
+    this->emitSignal(onDiscoverySuccess, *m_latestVersionData);
+  }
+  else {
+    DiscoverVersion::handleTimeout(interest, reason);
+  }
+}
+
+} // namespace chunks
+} // namespace ndn
diff --git a/tools/chunks/catchunks/discover-version-iterative.hpp b/tools/chunks/catchunks/discover-version-iterative.hpp
new file mode 100644
index 0000000..f772c8f
--- /dev/null
+++ b/tools/chunks/catchunks/discover-version-iterative.hpp
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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_DISCOVER_VERSION_ITERATIVE_HPP
+#define NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_ITERATIVE_HPP
+
+#include "discover-version.hpp"
+
+namespace ndn {
+namespace chunks {
+
+/**
+ * @brief Options for discover version iterative DiscoverVersionIterative
+ *
+ * The canonical name to use is DiscoverVersionIterative::Options
+ */
+class DiscoverVersionIterativeOptions : public virtual Options
+{
+public:
+  explicit
+  DiscoverVersionIterativeOptions(const Options& opt = Options())
+    : Options(opt)
+    , maxRetriesAfterVersionFound(1)
+  {
+  }
+
+public:
+  int maxRetriesAfterVersionFound;  // used only in timeout handling
+};
+
+/**
+ * @brief Service for discovering the latest Data version in the iterative way
+ *
+ * Identifies the latest retrievable version published under the specified namespace
+ * (as specified by the Version marker).
+ *
+ * DiscoverVersionIterative declares the largest discovered version to be the latest after some
+ * Interest timeouts (i.e. failed retrieval after exclusion and retransmission). The number of
+ * timeouts are specified by the value of maxRetriesAfterVersionFound inside the iterative options.
+ *
+ * The received name component after version can be an invalid segment number, this component will
+ * be excluded in the next interests. In the unlikely case that there are too many excluded
+ * components such that the Interest cannot fit in ndn::MAX_NDN_PACKET_SIZE, the discovery
+ * procedure will throw Face::Error.
+ *
+ * DiscoverVersionIterative's user is notified once after identifying the latest retrievable
+ * version or on failure to find any version Data.
+ */
+class DiscoverVersionIterative : public DiscoverVersion, protected DiscoverVersionIterativeOptions
+{
+public:
+  typedef DiscoverVersionIterativeOptions Options;
+
+public:
+  /**
+   * @brief create a DiscoverVersionIterative service
+   */
+  DiscoverVersionIterative(const Name& prefix, Face& face, const Options& options);
+
+  /**
+   * @brief identify the latest Data version published.
+   */
+  void
+  run() NDN_CXX_DECL_FINAL;
+
+private:
+  void
+  handleData(const Interest& interest, const Data& data) NDN_CXX_DECL_FINAL;
+
+  void
+  handleTimeout(const Interest& interest, const std::string& reason) NDN_CXX_DECL_FINAL;
+
+private:
+  uint64_t m_latestVersion;
+  shared_ptr<const Data> m_latestVersionData;
+  Exclude m_strayExcludes;
+  bool m_foundVersion;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_ITERATIVE_HPP
diff --git a/tools/chunks/catchunks/discover-version.cpp b/tools/chunks/catchunks/discover-version.cpp
new file mode 100644
index 0000000..1d3298e
--- /dev/null
+++ b/tools/chunks/catchunks/discover-version.cpp
@@ -0,0 +1,71 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 "discover-version.hpp"
+#include "data-fetcher.hpp"
+
+namespace ndn {
+namespace chunks {
+
+DiscoverVersion::DiscoverVersion(const Name& prefix, Face& face, const Options& options)
+  : Options(options)
+  , m_prefix(prefix)
+  , m_face(face)
+{
+}
+
+void
+DiscoverVersion::expressInterest(const Interest& interest, int maxRetriesNack,
+                                 int maxRetriesTimeout)
+{
+  fetcher = DataFetcher::fetch(m_face, interest, maxRetriesNack, maxRetriesTimeout,
+                               bind(&DiscoverVersion::handleData, this, _1, _2),
+                               bind(&DiscoverVersion::handleNack, this, _1, _2),
+                               bind(&DiscoverVersion::handleTimeout, this, _1, _2),
+                               isVerbose);
+}
+
+void
+DiscoverVersion::handleData(const Interest& interest, const Data& data)
+{
+  onDiscoverySuccess(data);
+}
+
+void
+DiscoverVersion::handleNack(const Interest& interest, const std::string& reason)
+{
+  onDiscoveryFailure(reason);
+}
+
+void
+DiscoverVersion::handleTimeout(const Interest& interest, const std::string& reason)
+{
+  onDiscoveryFailure(reason);
+}
+
+} // namespace chunks
+} // namespace ndn
diff --git a/tools/chunks/catchunks/discover-version.hpp b/tools/chunks/catchunks/discover-version.hpp
new file mode 100644
index 0000000..bb6a477
--- /dev/null
+++ b/tools/chunks/catchunks/discover-version.hpp
@@ -0,0 +1,95 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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_DISCOVER_VERSION_HPP
+#define NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_HPP
+
+#include "core/common.hpp"
+#include "options.hpp"
+
+namespace ndn {
+namespace chunks {
+
+class DataFetcher;
+
+/**
+ * @brief Base class of services 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 : virtual protected Options, noncopyable
+{
+public: // signals
+  /**
+   * @brief Signal emited when the first segment of a specific version is found.
+   */
+  signal::Signal<DiscoverVersion, const Data&> onDiscoverySuccess;
+
+  /**
+   * @brief Signal emitted when a failure occurs.
+   */
+  signal::Signal<DiscoverVersion, const std::string&> onDiscoveryFailure;
+
+  DECLARE_SIGNAL_EMIT(onDiscoverySuccess)
+  DECLARE_SIGNAL_EMIT(onDiscoveryFailure)
+
+public:
+  /**
+   * @brief create a DiscoverVersion service
+   */
+  DiscoverVersion(const Name& prefix, Face& face, const Options& options);
+
+  /**
+   * @brief identify the latest Data version published.
+   */
+  virtual void
+  run() = 0;
+
+protected:
+  void
+  expressInterest(const Interest& interest, int maxRetriesNack, int maxRetriesTimeout);
+
+  virtual void
+  handleData(const Interest& interest, const Data& data);
+
+  virtual void
+  handleNack(const Interest& interest, const std::string& reason);
+
+  virtual void
+  handleTimeout(const Interest& interest, const std::string& reason);
+
+protected:
+  const Name m_prefix;
+  Face& m_face;
+  shared_ptr<DataFetcher> fetcher;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_DISCOVER_VERSION_HPP
diff --git a/tools/chunks/catchunks/ndncatchunks.cpp b/tools/chunks/catchunks/ndncatchunks.cpp
new file mode 100644
index 0000000..d2b679f
--- /dev/null
+++ b/tools/chunks/catchunks/ndncatchunks.cpp
@@ -0,0 +1,180 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 "core/version.hpp"
+#include "options.hpp"
+#include "consumer.hpp"
+#include "discover-version-fixed.hpp"
+#include "discover-version-iterative.hpp"
+
+#include <ndn-cxx/security/validator-null.hpp>
+
+namespace ndn {
+namespace chunks {
+
+static int
+main(int argc, char** argv)
+{
+  std::string programName(argv[0]);
+  Options options;
+  std::string discoverType("fixed");
+  size_t maxPipelineSize(1);
+  int maxRetriesAfterVersionFound(1);
+  std::string uri;
+
+  namespace po = boost::program_options;
+  po::options_description visibleDesc("Options");
+  visibleDesc.add_options()
+    ("help,h",      "print this help message and exit")
+    ("discover-version,d",  po::value<std::string>(&discoverType)->default_value(discoverType),
+                            "version discovery algorithm to use; valid values are: 'fixed', 'iterative'")
+    ("fresh,f",     po::bool_switch(&options.mustBeFresh), "only return fresh content")
+    ("lifetime,l",  po::value<uint64_t>()->default_value(options.interestLifetime.count()),
+                    "lifetime of expressed Interests, in milliseconds")
+    ("pipeline,p",  po::value<size_t>(&maxPipelineSize)->default_value(maxPipelineSize),
+                    "maximum size of the Interest pipeline")
+    ("retries,r",   po::value<int>(&options.maxRetriesOnTimeoutOrNack)->default_value(options.maxRetriesOnTimeoutOrNack),
+                    "maximum number of retries in case of Nack or timeout (-1 = no limit)")
+    ("retries-iterative,i", po::value<int>(&maxRetriesAfterVersionFound)->default_value(maxRetriesAfterVersionFound),
+                            "number of timeouts that have to occur in order to confirm a discovered Data "
+                            "version as the latest one (only applicable to 'iterative' version discovery)")
+    ("verbose,v",   po::bool_switch(&options.isVerbose), "turn on verbose output")
+    ("version,V",   "print program version and exit")
+    ;
+
+  po::options_description hiddenDesc("Hidden options");
+  hiddenDesc.add_options()
+    ("ndn-name,n", po::value<std::string>(&uri), "NDN name of the requested content");
+
+  po::positional_options_description p;
+  p.add("ndn-name", -1);
+
+  po::options_description optDesc("Allowed options");
+  optDesc.add(visibleDesc).add(hiddenDesc);
+
+  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() << std::endl;
+    return 2;
+  }
+  catch (const boost::bad_any_cast& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 2;
+  }
+
+  if (vm.count("help") > 0) {
+    std::cout << "Usage: " << programName << " [options] ndn:/name" << std::endl;
+    std::cout << visibleDesc;
+    return 0;
+  }
+
+  if (vm.count("version") > 0) {
+    std::cout << "ndncatchunks " << tools::VERSION << std::endl;
+    return 0;
+  }
+
+  if (vm.count("ndn-name") == 0) {
+    std::cerr << "Usage: " << programName << " [options] ndn:/name" << std::endl;
+    std::cerr << visibleDesc;
+    return 2;
+  }
+
+  Name prefix(uri);
+  if (discoverType == "fixed" && (prefix.empty() || !prefix[-1].isVersion())) {
+    std::cerr << "ERROR: The specified name must contain a version component when using "
+                 "fixed version discovery" << std::endl;
+    return 2;
+  }
+
+  if (maxPipelineSize < 1 || maxPipelineSize > 1024) {
+    std::cerr << "ERROR: pipeline size must be between 1 and 1024" << std::endl;
+    return 2;
+  }
+
+  if (options.maxRetriesOnTimeoutOrNack < -1 || options.maxRetriesOnTimeoutOrNack > 1024) {
+    std::cerr << "ERROR: retries value must be between -1 and 1024" << std::endl;
+    return 2;
+  }
+
+  if (maxRetriesAfterVersionFound < 0 || maxRetriesAfterVersionFound > 1024) {
+    std::cerr << "ERROR: retries iterative value must be between 0 and 1024" << std::endl;
+    return 2;
+  }
+
+  options.interestLifetime = time::milliseconds(vm["lifetime"].as<uint64_t>());
+
+  try {
+    Face face;
+
+    unique_ptr<DiscoverVersion> discover;
+    if (discoverType == "fixed") {
+      discover = make_unique<DiscoverVersionFixed>(prefix, face, options);
+    }
+    else if (discoverType == "iterative") {
+      DiscoverVersionIterative::Options optionsIterative(options);
+      optionsIterative.maxRetriesAfterVersionFound = maxRetriesAfterVersionFound;
+      discover = make_unique<DiscoverVersionIterative>(prefix, face, optionsIterative);
+    }
+    else {
+      std::cerr << "ERROR: discover version type not valid" << std::endl;
+      return 2;
+    }
+
+    ValidatorNull validator;
+    Consumer consumer(face, validator, options.isVerbose);
+
+    PipelineInterests::Options optionsPipeline(options);
+    optionsPipeline.maxPipelineSize = maxPipelineSize;
+    PipelineInterests pipeline(face, optionsPipeline);
+
+    BOOST_ASSERT(discover != nullptr);
+    consumer.run(*discover, pipeline);
+  }
+  catch (const Consumer::ApplicationNackError& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 3;
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 1;
+  }
+
+  return 0;
+}
+
+} // namespace chunks
+} // namespace ndn
+
+int
+main(int argc, char** argv)
+{
+  return ndn::chunks::main(argc, argv);
+}
diff --git a/tools/chunks/catchunks/options.cpp b/tools/chunks/catchunks/options.cpp
new file mode 100644
index 0000000..4f5f586
--- /dev/null
+++ b/tools/chunks/catchunks/options.cpp
@@ -0,0 +1,43 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 "options.hpp"
+
+#include <ndn-cxx/interest.hpp>
+
+namespace ndn {
+namespace chunks {
+
+Options::Options()
+  : interestLifetime(ndn::DEFAULT_INTEREST_LIFETIME)
+  , maxRetriesOnTimeoutOrNack(3)
+  , mustBeFresh(false)
+  , isVerbose(false)
+{
+}
+
+} // namespace chunks
+} // namespace ndn
diff --git a/tools/chunks/catchunks/options.hpp b/tools/chunks/catchunks/options.hpp
new file mode 100644
index 0000000..09a914b
--- /dev/null
+++ b/tools/chunks/catchunks/options.hpp
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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/util/time.hpp>
+
+namespace ndn {
+namespace chunks {
+
+class Options
+{
+public:
+  Options();
+
+public:
+  time::milliseconds interestLifetime;
+  int maxRetriesOnTimeoutOrNack;
+  bool mustBeFresh;
+  bool isVerbose;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_OPTIONS_HPP
diff --git a/tools/chunks/catchunks/pipeline-interests.cpp b/tools/chunks/catchunks/pipeline-interests.cpp
new file mode 100644
index 0000000..b07c959
--- /dev/null
+++ b/tools/chunks/catchunks/pipeline-interests.cpp
@@ -0,0 +1,202 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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 "pipeline-interests.hpp"
+#include "data-fetcher.hpp"
+
+namespace ndn {
+namespace chunks {
+
+PipelineInterests::PipelineInterests(Face& face, const Options& options)
+  : m_face(face)
+  , m_nextSegmentNo(0)
+  , m_lastSegmentNo(0)
+  , m_excludeSegmentNo(0)
+  , m_options(options)
+  , m_hasFinalBlockId(false)
+  , m_hasError(false)
+  , m_hasFailure(false)
+{
+  m_segmentFetchers.resize(m_options.maxPipelineSize);
+}
+
+PipelineInterests::~PipelineInterests()
+{
+  cancel();
+}
+
+void
+PipelineInterests::runWithExcludedSegment(const Data& data, DataCallback onData,
+                                          FailureCallback onFailure)
+{
+  BOOST_ASSERT(onData != nullptr);
+  m_onData = std::move(onData);
+  m_onFailure = std::move(onFailure);
+
+  Name dataName = data.getName();
+  m_prefix = dataName.getPrefix(-1);
+  m_excludeSegmentNo = dataName[-1].toSegment();
+
+  if (!data.getFinalBlockId().empty()) {
+    m_hasFinalBlockId = true;
+    m_lastSegmentNo = data.getFinalBlockId().toSegment();
+  }
+
+  // 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
+PipelineInterests::fetchNextSegment(std::size_t pipeNo)
+{
+  if (m_hasFailure) {
+    fail("Fetching terminated but no final segment number has been found");
+    return false;
+  }
+
+  if (m_nextSegmentNo == m_excludeSegmentNo)
+    m_nextSegmentNo++;
+
+  if (m_hasFinalBlockId && m_nextSegmentNo > m_lastSegmentNo)
+   return false;
+
+  // Send interest for next segment
+  if (m_options.isVerbose)
+    std::cerr << "Requesting segment #" << m_nextSegmentNo << std::endl;
+
+  Interest interest(Name(m_prefix).appendSegment(m_nextSegmentNo));
+  interest.setInterestLifetime(m_options.interestLifetime);
+  interest.setMustBeFresh(m_options.mustBeFresh);
+  interest.setMaxSuffixComponents(1);
+
+  BOOST_ASSERT(!m_segmentFetchers[pipeNo].first || !m_segmentFetchers[pipeNo].first->isRunning());
+
+  auto fetcher = DataFetcher::fetch(m_face, interest,
+                                    m_options.maxRetriesOnTimeoutOrNack,
+                                    m_options.maxRetriesOnTimeoutOrNack,
+                                    bind(&PipelineInterests::handleData, this, _1, _2, pipeNo),
+                                    bind(&PipelineInterests::handleFail, this, _2, pipeNo),
+                                    bind(&PipelineInterests::handleFail, this, _2, pipeNo),
+                                    m_options.isVerbose);
+
+  m_segmentFetchers[pipeNo] = make_pair(fetcher, m_nextSegmentNo);
+
+  m_nextSegmentNo++;
+  return true;
+}
+
+void
+PipelineInterests::cancel()
+{
+  for (auto& fetcher : m_segmentFetchers)
+    if (fetcher.first)
+      fetcher.first->cancel();
+
+  m_segmentFetchers.clear();
+}
+
+void
+PipelineInterests::fail(const std::string& reason)
+{
+  if (!m_hasError) {
+    cancel();
+    m_hasError = true;
+    m_hasFailure = true;
+    if (m_onFailure)
+      m_face.getIoService().post([this, reason] { m_onFailure(reason); });
+  }
+}
+
+void
+PipelineInterests::handleData(const Interest& interest, const Data& data, size_t pipeNo)
+{
+  if (m_hasError)
+    return;
+
+  BOOST_ASSERT(data.getName().equals(interest.getName()));
+
+  if (m_options.isVerbose)
+    std::cerr << "Received segment #" << data.getName()[-1].toSegment() << std::endl;
+
+  m_onData(interest, data);
+
+  if (!m_hasFinalBlockId && !data.getFinalBlockId().empty()) {
+    m_lastSegmentNo = data.getFinalBlockId().toSegment();
+    m_hasFinalBlockId = true;
+
+    for (auto& fetcher : m_segmentFetchers) {
+      if (fetcher.first && fetcher.second > m_lastSegmentNo) {
+        // Stop trying to fetch segments that are not part of the content
+        fetcher.first->cancel();
+      }
+      else if (fetcher.first && fetcher.first->hasError()) { // fetcher.second <= m_lastSegmentNo
+        // there was an error while fetching a segment that is part of the content
+        fail("Failure retriving segment #" + to_string(fetcher.second));
+        return;
+      }
+    }
+  }
+
+  fetchNextSegment(pipeNo);
+}
+
+void PipelineInterests::handleFail(const std::string& reason, std::size_t pipeNo)
+{
+  if (m_hasError)
+    return;
+
+  if (m_hasFinalBlockId && m_segmentFetchers[pipeNo].second <= m_lastSegmentNo) {
+    fail(reason);
+  }
+  else if (!m_hasFinalBlockId) {
+    // don't fetch the following segments
+    bool areAllFetchersStopped = true;
+    for (auto& fetcher : m_segmentFetchers) {
+      if (fetcher.first && fetcher.second > m_segmentFetchers[pipeNo].second) {
+        fetcher.first->cancel();
+      }
+      else if (fetcher.first && fetcher.first->isRunning()) {
+        // fetcher.second <= m_segmentFetchers[pipeNo].second
+        areAllFetchersStopped = false;
+      }
+    }
+    if (areAllFetchersStopped) {
+      if (m_onFailure)
+        fail("Fetching terminated but no final segment number has been found");
+    }
+    else {
+      m_hasFailure = true;
+    }
+  }
+}
+
+} // namespace chunks
+} // namespace ndn
diff --git a/tools/chunks/catchunks/pipeline-interests.hpp b/tools/chunks/catchunks/pipeline-interests.hpp
new file mode 100644
index 0000000..32d5b79
--- /dev/null
+++ b/tools/chunks/catchunks/pipeline-interests.hpp
@@ -0,0 +1,143 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2016,  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_PIPELINE_INTERESTS_HPP
+#define NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_HPP
+
+#include "core/common.hpp"
+#include "options.hpp"
+
+namespace ndn {
+namespace chunks {
+
+class DataFetcher;
+
+class PipelineInterestsOptions : public Options
+{
+public:
+  explicit
+  PipelineInterestsOptions(const Options& options = Options())
+    : Options(options)
+    , maxPipelineSize(1)
+  {
+  }
+
+public:
+  size_t maxPipelineSize;
+};
+
+/**
+ * @brief Service for retrieving Data via an Interest pipeline
+ *
+ * Retrieves all segmented Data under the specified prefix by maintaining a pipeline of N Interests
+ * in flight.
+ *
+ * Provides retrieved Data on arrival with no ordering guarantees. Data is delivered to the
+ * PipelineInterests' user via callback immediately upon arrival.
+ */
+class PipelineInterests
+{
+public:
+  typedef PipelineInterestsOptions Options;
+  typedef function<void(const std::string& reason)> FailureCallback;
+
+public:
+  /**
+   * @brief create a PipelineInterests service
+   *
+   * Configures the pipelining service without specifying the retrieval namespace. After this
+   * configuration the method runWithExcludedSegment must be called to run the Pipeline.
+   */
+  explicit
+  PipelineInterests(Face& face, const Options& options = Options());
+
+  ~PipelineInterests();
+
+  /**
+   * @brief fetch all the segments between 0 and lastSegment of the specified prefix
+   *
+   * Starts the pipeline of size defined inside the options. The pipeline retrieves all the segments
+   * until the last segment is received, @p data is excluded from the retrieving.
+   *
+   * @param data a segment of the segmented Data to retrive; data.getName() must end with a segment
+   *        number
+   * @param onData callback for every segment correctly received, must not be empty
+   * @param onfailure callback called if an error occurs
+   */
+  void
+  runWithExcludedSegment(const Data& data, DataCallback onData, FailureCallback onFailure);
+
+  /**
+   * @brief stop all fetch operations
+   */
+  void
+  cancel();
+
+private:
+  /**
+   * @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
+  fail(const std::string& reason);
+
+  void
+  handleData(const Interest& interest, const Data& data, size_t pipeNo);
+
+  void
+  handleFail(const std::string& reason, size_t pipeNo);
+
+private:
+  Name m_prefix;
+  Face& m_face;
+  uint64_t m_nextSegmentNo;
+  uint64_t m_lastSegmentNo;
+  uint64_t m_excludeSegmentNo;
+  DataCallback m_onData;
+  FailureCallback m_onFailure;
+  const Options m_options;
+  std::vector<std::pair<shared_ptr<DataFetcher>, uint64_t>> m_segmentFetchers;
+  bool m_hasFinalBlockId;
+  /**
+   * true if there's a critical error
+   */
+  bool m_hasError;
+  /**
+   * true if one or more segmentFetcher failed, if lastSegmentNo is not set this is usually not a
+   * fatal error for the pipeline
+   */
+  bool m_hasFailure;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_CATCHUNKS_PIPELINE_INTERESTS_HPP
