diff --git a/tools/chunks/README.md b/tools/chunks/README.md
new file mode 100644
index 0000000..3f0ffd6
--- /dev/null
+++ b/tools/chunks/README.md
@@ -0,0 +1,73 @@
+# ndncatchunks and 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 NDN Data segments.  It appends version and segment number components
+  to the specified name, according to the
+  [NDN naming conventions](http://named-data.net/publications/techreports/ndn-tr-22-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 methods
+
+* `fixed`    : ndncatchunks will send an interest attempting to find a data packet with the
+               specified prefix and version number. A version component must be present at the
+               end of the user-specified NDN name.
+
+* `iterative`: ndncatchunks will send a series of interests with ChildSelector set to prefer the
+               rightmost child and Exclude selectors, attempting to find a data packet with the
+               specified prefix and the latest (the largest in the NDN canonical ordering)
+               version number.  The version is declared "latest" after a predefined number of
+               data retrieval timeouts (default: 1).
+
+The default discovery method is `fixed`. Other methods will be implemented in future versions
+of the tool.
+
+
+## Usage examples
+
+### Publishing
+
+The following command will publish the text of the GPL-3 license under the `/localhost/demo/gpl3`
+prefix:
+
+    ndnputchunks ndn:/localhost/demo/gpl3 < /usr/share/common-licenses/GPL-3
+
+To find the published version you have to start ndnputchunks with the `-p` command line option,
+for example:
+
+    ndnputchunks -p ndn:/localhost/demo/gpl3 < /usr/share/common-licenses/GPL-3
+
+This command will print the published version to the standard output.
+
+To publish data with a specific version, you must append a version component to the end of the
+prefix. The version component must follow the aforementioned NDN naming conventions.
+For example, the following command will publish the version `%FD%00%00%01Qc%CF%17v` of the
+`/localhost/demo/gpl3` prefix:
+
+    ndnputchunks ndn:/localhost/demo/gpl3/%FD%00%00%01Qc%CF%17v < /usr/share/common-licenses/GPL-3
+
+If the version component is not valid, a new well-formed version will be generated and appended
+to the supplied NDN name.
+
+
+### Retrieval
+
+To retrieve the latest version of a published file, the following command can be used:
+
+    ndncatchunks -d iterative ndn:/localhost/demo/gpl3
+
+This command will use the iterative method to discover the latest version of the file.
+
+To fetch a specific version of a published file, you can use the `fixed` version discovery method
+(the default). In this case the version needs to be supplied as part of the name.  For example,
+if the version is known to be `%FD%00%00%01Qc%CF%17v`, the following command will fetch that
+exact version of the file:
+
+    ndncatchunks ndn:/localhost/demo/gpl3/%FD%00%00%01Qc%CF%17v
+
+
+For more information, run the programs with `--help` as argument.
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
diff --git a/tools/chunks/putchunks/ndnputchunks.cpp b/tools/chunks/putchunks/ndnputchunks.cpp
new file mode 100644
index 0000000..202cd83
--- /dev/null
+++ b/tools/chunks/putchunks/ndnputchunks.cpp
@@ -0,0 +1,137 @@
+/* -*- 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 "producer.hpp"
+
+namespace ndn {
+namespace chunks {
+
+static int
+main(int argc, char** argv)
+{
+  std::string programName = argv[0];
+  uint64_t freshnessPeriod = 10000;
+  bool printVersion = false;
+  size_t maxChunkSize = MAX_NDN_PACKET_SIZE >> 1;
+  std::string signingStr;
+  bool isVerbose = false;
+  std::string prefix;
+
+  namespace po = boost::program_options;
+  po::options_description visibleDesc("Options");
+  visibleDesc.add_options()
+    ("help,h",          "print this help message and exit")
+    ("freshness,f",     po::value<uint64_t>(&freshnessPeriod)->default_value(freshnessPeriod),
+                        "specify FreshnessPeriod, in milliseconds")
+    ("print-data-version,p",  po::bool_switch(&printVersion), "print Data version to the standard output")
+    ("size,s",          po::value<size_t>(&maxChunkSize)->default_value(maxChunkSize),
+                        "maximum chunk size, in bytes")
+    ("signing-info,S",  po::value<std::string>(&signingStr)->default_value(signingStr),
+                        "set signing information")
+    ("verbose,v",       po::bool_switch(&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>(&prefix), "NDN name for the served 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 << "ndnputchunks " << tools::VERSION << std::endl;
+    return 0;
+  }
+
+  if (prefix.empty()) {
+    std::cerr << "Usage: " << programName << " [options] ndn:/name" << std::endl;
+    std::cerr << visibleDesc;
+    return 2;
+  }
+
+  if (maxChunkSize < 1 || maxChunkSize > MAX_NDN_PACKET_SIZE) {
+    std::cerr << "ERROR: Maximum chunk size must be between 1 and " << MAX_NDN_PACKET_SIZE << std::endl;
+    return 2;
+  }
+
+  security::SigningInfo signingInfo;
+  try {
+    signingInfo = security::SigningInfo(signingStr);
+  }
+  catch (const std::invalid_argument& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 2;
+  }
+
+  try {
+    Face face;
+    KeyChain keyChain;
+    Producer producer(prefix, face, keyChain, signingInfo, time::milliseconds(freshnessPeriod),
+                      maxChunkSize, isVerbose, printVersion, std::cin);
+    producer.run();
+  }
+  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/putchunks/producer.cpp b/tools/chunks/putchunks/producer.cpp
new file mode 100644
index 0000000..141be5b
--- /dev/null
+++ b/tools/chunks/putchunks/producer.cpp
@@ -0,0 +1,157 @@
+/* -*- 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 "producer.hpp"
+
+namespace ndn {
+namespace chunks {
+
+Producer::Producer(const Name& prefix,
+                   Face& face,
+                   KeyChain& keyChain,
+                   const security::SigningInfo& signingInfo,
+                   time::milliseconds freshnessPeriod,
+                   size_t maxSegmentSize,
+                   bool isVerbose,
+                   bool needToPrintVersion,
+                   std::istream& is)
+  : m_face(face)
+  , m_keyChain(keyChain)
+  , m_signingInfo(signingInfo)
+  , m_freshnessPeriod(freshnessPeriod)
+  , m_maxSegmentSize(maxSegmentSize)
+  , m_isVerbose(isVerbose)
+{
+  if (prefix.size() > 0 && prefix[-1].isVersion()) {
+    m_prefix = prefix.getPrefix(-1);
+    m_versionedPrefix = prefix;
+  }
+  else {
+    m_prefix = prefix;
+    m_versionedPrefix = Name(m_prefix).appendVersion();
+  }
+
+  populateStore(is);
+
+  if (needToPrintVersion)
+    std::cout << m_versionedPrefix[-1] << std::endl;
+
+  m_face.setInterestFilter(m_prefix,
+                           bind(&Producer::onInterest, this, _2),
+                           RegisterPrefixSuccessCallback(),
+                           bind(&Producer::onRegisterFailed, this, _1, _2));
+
+  if (m_isVerbose)
+    std::cerr << "Data published with name: " << m_versionedPrefix << std::endl;
+}
+
+void
+Producer::run()
+{
+  m_face.processEvents();
+}
+
+void
+Producer::onInterest(const Interest& interest)
+{
+  BOOST_ASSERT(m_store.size() > 0);
+
+  if (m_isVerbose)
+    std::cerr << "Interest: " << interest << std::endl;
+
+  const Name& name = interest.getName();
+  shared_ptr<Data> data;
+
+  // is this a discovery Interest or a sequence retrieval?
+  if (name.size() == m_versionedPrefix.size() + 1 && m_versionedPrefix.isPrefixOf(name) &&
+      name[-1].isSegment()) {
+    const auto segmentNo = static_cast<size_t>(interest.getName()[-1].toSegment());
+    // specific segment retrieval
+    if (segmentNo < m_store.size()) {
+      data = m_store[segmentNo];
+    }
+  }
+  else if (interest.matchesData(*m_store[0])) {
+    // Interest has version and is looking for the first segment or has no version
+    data = m_store[0];
+  }
+
+  if (data != nullptr) {
+    if (m_isVerbose)
+      std::cerr << "Data: " << *data << std::endl;
+
+    m_face.put(*data);
+  }
+}
+
+void
+Producer::populateStore(std::istream& is)
+{
+  BOOST_ASSERT(m_store.size() == 0);
+
+  if (m_isVerbose)
+    std::cerr << "Loading input ..." << std::endl;
+
+  std::vector<uint8_t> buffer(m_maxSegmentSize);
+  while (is.good()) {
+    is.read(reinterpret_cast<char*>(buffer.data()), buffer.size());
+    const auto nCharsRead = is.gcount();
+    if (nCharsRead > 0) {
+      auto data = make_shared<Data>(Name(m_versionedPrefix).appendSegment(m_store.size()));
+      data->setFreshnessPeriod(m_freshnessPeriod);
+      data->setContent(&buffer[0], nCharsRead);
+
+      m_store.push_back(data);
+    }
+  }
+
+  if (m_store.empty()) {
+    auto data = make_shared<Data>(Name(m_versionedPrefix).appendSegment(0));
+    data->setFreshnessPeriod(m_freshnessPeriod);
+    m_store.push_back(data);
+  }
+
+  auto finalBlockId = name::Component::fromSegment(m_store.size() - 1);
+  for (const auto& data : m_store) {
+    data->setFinalBlockId(finalBlockId);
+    m_keyChain.sign(*data, m_signingInfo);
+  }
+
+  if (m_isVerbose)
+    std::cerr << "Created " << m_store.size() << " chunks for prefix " << m_prefix << std::endl;
+}
+
+void
+Producer::onRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  std::cerr << "ERROR: Failed to register prefix '"
+            << prefix << "' (" << reason << ")" << std::endl;
+  m_face.shutdown();
+}
+
+} // namespace chunks
+} // namespace ndn
diff --git a/tools/chunks/putchunks/producer.hpp b/tools/chunks/putchunks/producer.hpp
new file mode 100644
index 0000000..061a2bf
--- /dev/null
+++ b/tools/chunks/putchunks/producer.hpp
@@ -0,0 +1,100 @@
+/* -*- 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_PUTCHUNKS_PRODUCER_HPP
+#define NDN_TOOLS_CHUNKS_PUTCHUNKS_PRODUCER_HPP
+
+#include "core/common.hpp"
+
+namespace ndn {
+namespace chunks {
+
+/**
+ * @brief Segmented version Producer
+ *
+ * Packetizes and publishes data from an input stream under /prefix/<version>/<segment number>.
+ * The current time is used as the version number. The store has always at least one element (also
+ * with empty input stream).
+ */
+class Producer : noncopyable
+{
+public:
+  /**
+   * @brief Create the Producer
+   *
+   * @prefix prefix used to publish data, if the last component of prefix is not a version number
+   *         the current time is used as version number.
+   */
+  Producer(const Name& prefix, Face& face, KeyChain& keyChain,
+           const security::SigningInfo& signingInfo, time::milliseconds freshnessPeriod,
+           size_t maxSegmentSize, bool isVerbose = false, bool needToPrintVersion = false,
+           std::istream& is = std::cin);
+
+  /**
+   * @brief Run the Producer
+   */
+  void
+  run();
+
+private:
+  void
+  onInterest(const Interest& interest);
+
+  /**
+   * @brief Split the input stream in data packets and save them to the store
+   *
+   * Create data packets reading all the characters from the input stream until EOF, or an
+   * error occurs. Each data packet has a maximum payload size of m_maxSegmentSize value and is
+   * stored inside the vector m_store. An empty data packet is created and stored if the input
+   * stream is empty.
+   *
+   * @return Number of data packets contained in the store after the operation
+   */
+  void
+  populateStore(std::istream& is);
+
+  void
+  onRegisterFailed(const Name& prefix, const std::string& reason);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  std::vector<shared_ptr<Data>> m_store;
+
+private:
+  Name m_prefix;
+  Name m_versionedPrefix;
+  Face& m_face;
+  KeyChain& m_keyChain;
+  security::SigningInfo m_signingInfo;
+  time::milliseconds m_freshnessPeriod;
+  size_t m_maxSegmentSize;
+  bool m_isVerbose;
+};
+
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_CHUNKS_PUTCHUNKS_PRODUCER_HPP
diff --git a/tools/chunks/wscript b/tools/chunks/wscript
new file mode 100644
index 0000000..56ff392
--- /dev/null
+++ b/tools/chunks/wscript
@@ -0,0 +1,30 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+top = '../..'
+
+def build(bld):
+
+    bld(features='cxx',
+        name='ndncatchunks-objects',
+        source=bld.path.ant_glob('catchunks/*.cpp', excl='catchunks/ndncatchunks.cpp'),
+        use='core-objects')
+
+    bld(features='cxx cxxprogram',
+        target='../../bin/ndncatchunks',
+        source='catchunks/ndncatchunks.cpp',
+        use='ndncatchunks-objects')
+
+    bld(features='cxx',
+        name='ndnputchunks-objects',
+        source=bld.path.ant_glob('putchunks/*.cpp', excl='putchunks/ndnputchunks.cpp'),
+        use='core-objects')
+
+    bld(features='cxx cxxprogram',
+        target='../../bin/ndnputchunks',
+        source='putchunks/ndnputchunks.cpp',
+        use='ndnputchunks-objects')
+
+    ## (for unit tests)
+
+    bld(name='chunks-objects',
+        use='ndncatchunks-objects ndnputchunks-objects')
+
