diff --git a/AUTHORS.md b/AUTHORS.md
index a4e6eec..93c29e2 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -16,3 +16,6 @@
 * Qi Zhao               <https://www.linkedin.com/pub/qi-zhao/73/835/9a3>
 * Seunghyun Yoo         <http://relue2718.com/>
 * Seungbae Kim          <https://sites.google.com/site/sbkimcv/>
+* Wentao Shang          <http://irl.cs.ucla.edu/~wentao/>
+* Steve DiBenedetto     <https://dibenede.github.io>
+* Andrea Tosatto        <https://linkedin.com/in/tosattoandrea>
diff --git a/README.md b/README.md
index eda9d2b..24de965 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,7 @@
 Tools in this collection include:
 
 * [peek](tools/peek): transmit a single packet between a consumer and a producer
+* [chunks](tools/chunks): segmented file transfer between a consumer and producer
 * [ping](tools/ping): test reachability between two nodes
 * [dump](tools/dump): analyze traffic on wire
 * [dissect](tools/dissect): inspect TLV structure of NDN packet format
diff --git a/core/common.hpp b/core/common.hpp
index 09d378c..01a30c4 100644
--- a/core/common.hpp
+++ b/core/common.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -63,6 +63,7 @@
 #include <ndn-cxx/security/key-chain.hpp>
 #include <ndn-cxx/security/signing-helpers.hpp>
 #include <ndn-cxx/security/signing-info.hpp>
+#include <ndn-cxx/util/backports.hpp>
 #include <ndn-cxx/util/scheduler.hpp>
 #include <ndn-cxx/util/scheduler-scoped-event-id.hpp>
 #include <ndn-cxx/util/signal.hpp>
diff --git a/tests/chunks/consumer.t.cpp b/tests/chunks/consumer.t.cpp
new file mode 100644
index 0000000..0ce7290
--- /dev/null
+++ b/tests/chunks/consumer.t.cpp
@@ -0,0 +1,142 @@
+/* -*- 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 "tools/chunks/catchunks/consumer.hpp"
+
+#include "tests/test-common.hpp"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+#include <ndn-cxx/security/validator-null.hpp>
+
+#include <boost/test/output_test_stream.hpp>
+
+namespace ndn {
+namespace chunks {
+namespace tests {
+
+using namespace ndn::tests;
+using boost::test_tools::output_test_stream;
+
+BOOST_AUTO_TEST_SUITE(Chunks)
+BOOST_AUTO_TEST_SUITE(TestConsumer)
+
+BOOST_AUTO_TEST_CASE(OutputDataSequential)
+{
+  // Test sequential segments in the right order
+  // Segment order: 0 1 2
+
+  std::string name("/ndn/chunks/test");
+
+  std::vector<std::string> testStrings {
+      "",
+
+      "a1b2c3%^&(#$&%^$$/><",
+
+      "123456789123456789123456789123456789123456789123456789123456789"
+      "123456789123456789123456789123456789123456789123456789123456789",
+
+      "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. "
+      "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur "
+      "ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla "
+      "consequat massa Donec pede justo,"
+  };
+
+  util::DummyClientFace face;
+  ValidatorNull validator;
+  output_test_stream output("");
+  Consumer cons(face, validator, false, output);
+
+  auto interest = makeInterest(name);
+
+  for (size_t i = 0; i < testStrings.size(); ++i) {
+    output.flush();
+
+    auto data = makeData(Name(name).appendVersion(1).appendSegment(i));
+    data->setContent(reinterpret_cast<const uint8_t*>(testStrings[i].data()),
+                     testStrings[i].size());
+
+    cons.m_bufferedData[i] = data;
+    cons.writeInOrderData();
+
+    BOOST_CHECK(output.is_equal(testStrings[i]));
+  }
+}
+
+BOOST_AUTO_TEST_CASE(OutputDataUnordered)
+{
+  // Test unordered segments
+  // Segment order: 1 0 2
+
+  std::string name("/ndn/chunks/test");
+
+  std::vector<std::string> testStrings {
+      "a1b2c3%^&(#$&%^$$/><",
+
+      "123456789123456789123456789123456789123456789123456789123456789"
+      "123456789123456789123456789123456789123456789123456789123456789",
+
+      "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. "
+      "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur "
+      "ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla "
+      "consequat massa Donec pede justo,"
+  };;
+
+  util::DummyClientFace face;
+  ValidatorNull validator;
+  output_test_stream output("");
+  Consumer cons(face, validator, false, output);
+
+  auto interest = makeInterest(name);
+  std::vector<shared_ptr<Data>> dataStore;
+
+  for (size_t i = 0; i < testStrings.size(); ++i) {
+    auto data = makeData(Name(name).appendVersion(1).appendSegment(i));
+    data->setContent(reinterpret_cast<const uint8_t*>(testStrings[i].data()),
+                     testStrings[i].size());
+
+    dataStore.push_back(data);
+  }
+
+  output.flush();
+  cons.m_bufferedData[1] = dataStore[1];
+  cons.writeInOrderData();
+  BOOST_CHECK(output.is_equal(""));
+
+  output.flush();
+  cons.m_bufferedData[0] = dataStore[0];
+  cons.writeInOrderData();
+  BOOST_CHECK(output.is_equal(testStrings[0] + testStrings[1]));
+
+  output.flush();
+  cons.m_bufferedData[2] = dataStore[2];
+  cons.writeInOrderData();
+  BOOST_CHECK(output.is_equal(testStrings[2]));
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestConsumer
+BOOST_AUTO_TEST_SUITE_END() // Chunks
+
+} // namespace tests
+} // namespace chunks
+} // namespace ndn
diff --git a/tests/chunks/discover-version-fixed.t.cpp b/tests/chunks/discover-version-fixed.t.cpp
new file mode 100644
index 0000000..a57e5c8
--- /dev/null
+++ b/tests/chunks/discover-version-fixed.t.cpp
@@ -0,0 +1,147 @@
+/* -*- 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 "tools/chunks/catchunks/discover-version-fixed.hpp"
+
+#include "discover-version-fixture.hpp"
+
+namespace ndn {
+namespace chunks {
+namespace tests {
+
+using namespace ndn::tests;
+
+class DiscoverVersionFixedFixture : public DiscoverVersionFixture
+{
+public:
+  DiscoverVersionFixedFixture()
+    : DiscoverVersionFixture(makeOptions())
+    , version(1449227841747)
+  {
+    setDiscover(make_unique<DiscoverVersionFixed>(Name(name).appendVersion(version),
+                                                  face, makeOptions()));
+  }
+
+protected:
+  uint64_t version; //Version to find
+};
+
+BOOST_AUTO_TEST_SUITE(Chunks)
+BOOST_AUTO_TEST_SUITE(TestDiscoverVersionFixed)
+
+BOOST_FIXTURE_TEST_CASE(RequestedVersionAvailable, DiscoverVersionFixedFixture)
+{
+  discover->run();
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+
+  face.receive(*makeDataWithVersion(version));
+
+  advanceClocks(io, time::nanoseconds(1), 1);
+
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
+  BOOST_CHECK_EQUAL(discoveredVersion, version);
+
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+  auto lastInterest = face.sentInterests.back();
+  BOOST_CHECK_EQUAL(lastInterest.getExclude().size(), 0);
+  BOOST_CHECK_EQUAL(lastInterest.getMaxSuffixComponents(), 2);
+  BOOST_CHECK_EQUAL(lastInterest.getMinSuffixComponents(), 2);
+  BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+}
+
+BOOST_FIXTURE_TEST_CASE(NoVersionsAvailable, DiscoverVersionFixedFixture)
+{
+  discover->run();
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+
+  for (int retries = 0; retries < maxRetriesOnTimeoutOrNack; ++retries) {
+    advanceClocks(io, interestLifetime, 1);
+    BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2 + retries);
+  }
+
+  for (const auto& lastInterest : face.sentInterests) {
+    BOOST_CHECK_EQUAL(lastInterest.getExclude().size(), 0);
+    BOOST_CHECK_EQUAL(lastInterest.getMaxSuffixComponents(), 2);
+    BOOST_CHECK_EQUAL(lastInterest.getMinSuffixComponents(), 2);
+    BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+    BOOST_CHECK_EQUAL(lastInterest.getName().equals(Name(name).appendVersion(version)), true);
+  }
+
+  advanceClocks(io, interestLifetime, 1);
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
+  // check if discovered version is the default value
+  BOOST_CHECK_EQUAL(discoveredVersion, 0);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), maxRetriesOnTimeoutOrNack + 1);
+}
+
+BOOST_FIXTURE_TEST_CASE(DataNotSegment, DiscoverVersionFixedFixture)
+{
+  discover->run();
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+
+  std::vector<std::string> randomStrings {
+      "",
+      "abcdefg",
+      "12345",
+      "qr%67a3%4e"
+  };
+
+  Exclude expectedExclude;
+  for (size_t retries = 0; retries < randomStrings.size(); ++retries) {
+    auto data = make_shared<Data>(Name(name).appendVersion(version).append(randomStrings[retries]));
+    data->setFinalBlockId(name::Component::fromSegment(0));
+    data = signData(data);
+
+    face.receive(*data);
+    advanceClocks(io, time::nanoseconds(1), 1);
+
+    BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
+
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1 + retries);
+    auto lastInterest = face.sentInterests.back();
+    if (randomStrings[retries] != "")
+      expectedExclude.excludeOne(name::Component::fromEscapedString(randomStrings[retries]));
+    BOOST_CHECK_EQUAL(lastInterest.getExclude(), expectedExclude);
+    BOOST_CHECK_EQUAL(lastInterest.getMaxSuffixComponents(), 2);
+    BOOST_CHECK_EQUAL(lastInterest.getMinSuffixComponents(), 2);
+    BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+  }
+
+  advanceClocks(io, interestLifetime, maxRetriesOnTimeoutOrNack + 1);
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
+  // check if discovered version is the default value
+  BOOST_CHECK_EQUAL(discoveredVersion, 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestDiscoverVersionFixed
+BOOST_AUTO_TEST_SUITE_END() // Chunks
+
+} // namespace tests
+} // namespace chunks
+} // namespace ndn
diff --git a/tests/chunks/discover-version-fixture.hpp b/tests/chunks/discover-version-fixture.hpp
new file mode 100644
index 0000000..9009301
--- /dev/null
+++ b/tests/chunks/discover-version-fixture.hpp
@@ -0,0 +1,104 @@
+/* -*- 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_TESTS_CHUNKS_DISCOVER_VERSION_FIXTURE_HPP
+#define NDN_TOOLS_TESTS_CHUNKS_DISCOVER_VERSION_FIXTURE_HPP
+
+#include "tools/chunks/catchunks/discover-version.hpp"
+
+#include "tests/test-common.hpp"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace ndn {
+namespace chunks {
+namespace tests {
+
+class DiscoverVersionFixture : public ndn::tests::UnitTestTimeFixture, virtual protected Options
+{
+public:
+  DiscoverVersionFixture(const Options& options)
+    : Options(options)
+    , face(io)
+    , name("/ndn/chunks/test")
+    , isDiscoveryFinished(false)
+    , discoveredVersion(0)
+  {
+  }
+
+protected:
+  void setDiscover(unique_ptr<DiscoverVersion> disc)
+  {
+    discover = std::move(disc);
+    discover->onDiscoverySuccess.connect(bind(&DiscoverVersionFixture::onSuccess, this, _1));
+    discover->onDiscoveryFailure.connect(bind(&DiscoverVersionFixture::onFailure, this, _1));
+  }
+
+  shared_ptr<Data>
+  makeDataWithVersion(uint64_t version)
+  {
+    auto data = make_shared<Data>(Name(name).appendVersion(version).appendSegment(0));
+    data->setFinalBlockId(name::Component::fromSegment(0));
+    return ndn::tests::signData(data);
+  }
+
+  static Options
+  makeOptions()
+  {
+    Options options;
+    options.isVerbose = false;
+    options.interestLifetime = time::seconds(1);
+    options.maxRetriesOnTimeoutOrNack = 3;
+    return options;
+  }
+
+  virtual void
+  onSuccess(const Data& data)
+  {
+    isDiscoveryFinished = true;
+
+    if (data.getName()[name.size()].isVersion())
+      discoveredVersion = data.getName()[name.size()].toVersion();
+  }
+
+  virtual void
+  onFailure(const std::string& reason)
+  {
+    isDiscoveryFinished = true;
+  }
+
+protected:
+  boost::asio::io_service io;
+  util::DummyClientFace face;
+  Name name;
+  unique_ptr<DiscoverVersion> discover;
+  bool isDiscoveryFinished;
+  uint64_t discoveredVersion;
+};
+
+} // namespace tests
+} // namespace chunks
+} // namespace ndn
+
+#endif // NDN_TOOLS_TESTS_CHUNKS_DISCOVER_VERSION_FIXTURE_HPP
diff --git a/tests/chunks/discover-version-iterative.t.cpp b/tests/chunks/discover-version-iterative.t.cpp
new file mode 100644
index 0000000..233f36c
--- /dev/null
+++ b/tests/chunks/discover-version-iterative.t.cpp
@@ -0,0 +1,235 @@
+/* -*- 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 "tools/chunks/catchunks/discover-version-iterative.hpp"
+
+#include "discover-version-fixture.hpp"
+
+namespace ndn {
+namespace chunks {
+namespace tests {
+
+using namespace ndn::tests;
+
+class DiscoverVersionIterativeFixture : public DiscoverVersionFixture,
+                                        protected DiscoverVersionIterativeOptions
+{
+public:
+  typedef DiscoverVersionIterativeOptions Options;
+
+public:
+  explicit
+  DiscoverVersionIterativeFixture(const Options& opt = makeOptionsIterative())
+    : chunks::Options(opt)
+    , DiscoverVersionFixture(opt)
+    , Options(opt)
+  {
+    setDiscover(make_unique<DiscoverVersionIterative>(Name(name), face, opt));
+  }
+
+protected:
+  static Options
+  makeOptionsIterative()
+  {
+    Options options;
+    options.isVerbose = false;
+    options.maxRetriesOnTimeoutOrNack = 3;
+    options.maxRetriesAfterVersionFound = 1;
+    return options;
+  }
+};
+
+
+BOOST_AUTO_TEST_SUITE(Chunks)
+BOOST_AUTO_TEST_SUITE(TestDiscoverVersionIterative)
+
+BOOST_FIXTURE_TEST_CASE(SingleVersionAvailable, DiscoverVersionIterativeFixture)
+{
+  discover->run();
+  advanceClocks(io, time::nanoseconds(1), 1);
+
+  uint64_t version = 1449241767037;
+
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+  auto lastInterest = face.sentInterests.back();
+  BOOST_CHECK_EQUAL(lastInterest.getExclude().size(), 0);
+  BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+  BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+
+  // Send first segment for the right version
+  face.receive(*makeDataWithVersion(version));
+  advanceClocks(io, time::nanoseconds(1), 1);
+
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2);
+  lastInterest = face.sentInterests.back();
+  Exclude expectedExclude;
+  expectedExclude.excludeBefore(name::Component::fromVersion(version));
+  BOOST_CHECK_EQUAL(lastInterest.getExclude(), expectedExclude);
+  BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+  BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+
+  // Generate the timeout
+  for (int retries = 0; retries < maxRetriesAfterVersionFound; ++retries) {
+    advanceClocks(io, interestLifetime, 1);
+
+    BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
+
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), retries + 3);
+    lastInterest = face.sentInterests.back();
+    Exclude expectedExclude;
+    expectedExclude.excludeBefore(name::Component::fromVersion(version));
+    BOOST_CHECK_EQUAL(lastInterest.getExclude(), expectedExclude);
+    BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+    BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+    BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+  }
+
+  advanceClocks(io, interestLifetime, 1);
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
+  BOOST_CHECK_EQUAL(discoveredVersion, version);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), maxRetriesAfterVersionFound + 2);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(NoVersionsAvailable, DiscoverVersionIterativeFixture)
+{
+  discover->run();
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+
+  for (int retries = 0; retries < maxRetriesOnTimeoutOrNack; ++retries) {
+    advanceClocks(io, interestLifetime, 1);
+    BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2 + retries);
+  }
+
+  for (auto& lastInterest : face.sentInterests) {
+    BOOST_CHECK_EQUAL(lastInterest.getExclude().size(), 0);
+    BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+    BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+    BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+  }
+
+  advanceClocks(io, interestLifetime, 1);
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), maxRetriesOnTimeoutOrNack + 1);
+}
+
+BOOST_FIXTURE_TEST_CASE(MultipleVersionsAvailable, DiscoverVersionIterativeFixture)
+{
+  // nVersions must be positive
+  const uint64_t nVersions = 5;
+
+  discover->run();
+  advanceClocks(io, time::nanoseconds(1), 1);
+
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+  auto lastInterest = face.sentInterests.back();
+  BOOST_CHECK_EQUAL(lastInterest.getExclude().size(), 0);
+  BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+  BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+
+  for (uint64_t nSentVersions = 0; nSentVersions < nVersions; ++nSentVersions) {
+    face.receive(*makeDataWithVersion(nSentVersions));
+    advanceClocks(io, time::nanoseconds(1), 1);
+
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2 + nSentVersions);
+    lastInterest = face.sentInterests.back();
+    Exclude expectedExclude;
+    expectedExclude.excludeBefore(name::Component::fromVersion(nSentVersions));
+    BOOST_CHECK_EQUAL(lastInterest.getExclude(), expectedExclude);
+    BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+    BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+    BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+  }
+
+  for (int retries = 0; retries < maxRetriesAfterVersionFound; ++retries) {
+    advanceClocks(io, interestLifetime, 1);
+
+    BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
+
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2 + retries + nVersions);
+    lastInterest = face.sentInterests.back();
+    Exclude expectedExclude;
+    expectedExclude.excludeBefore(name::Component::fromVersion(nVersions - 1));
+    BOOST_CHECK_EQUAL(lastInterest.getExclude(), expectedExclude);
+    BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+    BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+    BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+  }
+
+  advanceClocks(io, interestLifetime, 1);
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
+  BOOST_CHECK_EQUAL(discoveredVersion, nVersions - 1);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), nVersions + maxRetriesAfterVersionFound + 1);
+}
+
+BOOST_FIXTURE_TEST_CASE(MultipleVersionsAvailableDescendent, DiscoverVersionIterativeFixture)
+{
+  // nVersions must be positive
+  const uint64_t nVersions = 5;
+
+  discover->run();
+  advanceClocks(io, time::nanoseconds(1), 1);
+
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
+  auto lastInterest = face.sentInterests.back();
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
+  BOOST_CHECK_EQUAL(lastInterest.getExclude().size(), 0);
+  BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+  BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+
+  for (uint64_t nVersionsToSend = nVersions; nVersionsToSend > 0; --nVersionsToSend) {
+    face.receive(*makeDataWithVersion(nVersionsToSend - 1));
+    advanceClocks(io, time::nanoseconds(1), 1);
+
+    BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
+
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2);
+    lastInterest = face.sentInterests.back();
+    Exclude expectedExclude;
+    expectedExclude.excludeBefore(name::Component::fromVersion(nVersions - 1));
+    BOOST_CHECK_EQUAL(lastInterest.getExclude(), expectedExclude);
+    BOOST_CHECK_EQUAL(lastInterest.getChildSelector(), 1);
+    BOOST_CHECK_EQUAL(lastInterest.getMustBeFresh(), mustBeFresh);
+    BOOST_CHECK_EQUAL(lastInterest.getName().equals(name), true);
+  }
+
+  advanceClocks(io, interestLifetime, maxRetriesAfterVersionFound + 1);
+  BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
+  BOOST_CHECK_EQUAL(discoveredVersion, nVersions - 1);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), maxRetriesAfterVersionFound + 2);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestDiscoverVersionIterative
+BOOST_AUTO_TEST_SUITE_END() // Chunks
+
+} // namespace tests
+} // namespace chunks
+} // namespace ndn
diff --git a/tests/chunks/pipeline-interests.t.cpp b/tests/chunks/pipeline-interests.t.cpp
new file mode 100644
index 0000000..98abfa4
--- /dev/null
+++ b/tests/chunks/pipeline-interests.t.cpp
@@ -0,0 +1,378 @@
+/* -*- 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 "tools/chunks/catchunks/pipeline-interests.hpp"
+#include "tools/chunks/catchunks/data-fetcher.hpp"
+
+#include "tests/test-common.hpp"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+namespace ndn {
+namespace chunks {
+namespace tests {
+
+using namespace ndn::tests;
+
+class PipelineInterestsFixture : public UnitTestTimeFixture
+{
+public:
+  typedef PipelineInterestsOptions Options;
+
+public:
+  PipelineInterestsFixture()
+    : face(io)
+    , opt(makeOptions())
+    , name("/ndn/chunks/test")
+    , pipeline(face, opt)
+    , nDataSegments(0)
+    , nReceivedSegments(0)
+    , hasFailed(false)
+  {
+  }
+
+protected:
+  shared_ptr<Data>
+  makeDataWithSegment(uint64_t segmentNo, bool setFinalBlockId = true)
+  {
+    auto data = make_shared<Data>(Name(name).appendVersion(0).appendSegment(segmentNo));
+    if (setFinalBlockId)
+      data->setFinalBlockId(name::Component::fromSegment(nDataSegments - 1));
+    return signData(data);
+  }
+
+  void
+  runWithData(const Data& data)
+  {
+    pipeline.runWithExcludedSegment(data,
+                                    bind(&PipelineInterestsFixture::onData, this, _1, _2),
+                                    bind(&PipelineInterestsFixture::onFailure, this, _1));
+  }
+
+private:
+  void
+  onData(const Interest& interest, const Data& data)
+  {
+    nReceivedSegments++;
+  }
+
+  void
+  onFailure(const std::string& reason)
+  {
+    hasFailed = true;
+  }
+
+  static Options
+  makeOptions()
+  {
+    Options options;
+    options.isVerbose = false;
+    options.interestLifetime = time::seconds(1);
+    options.maxRetriesOnTimeoutOrNack = 3;
+    options.maxPipelineSize = 5;
+    return options;
+  }
+
+protected:
+  boost::asio::io_service io;
+  util::DummyClientFace face;
+  Options opt;
+  Name name;
+  PipelineInterests pipeline;
+  uint64_t nDataSegments;
+  uint64_t nReceivedSegments;
+  bool hasFailed;
+};
+
+BOOST_AUTO_TEST_SUITE(Chunks)
+BOOST_AUTO_TEST_SUITE(TestPipelineInterests)
+
+BOOST_FIXTURE_TEST_CASE(FewerSegmentsThanPipelineCapacity, PipelineInterestsFixture)
+{
+  nDataSegments = 3;
+  BOOST_ASSERT(nDataSegments <= opt.maxPipelineSize);
+
+  runWithData(*makeDataWithSegment(0));
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), nDataSegments - 1);
+
+  for (uint64_t i = 0; i < nDataSegments - 1; ++i) {
+    face.receive(*makeDataWithSegment(i));
+    advanceClocks(io, time::nanoseconds(1), 1);
+
+    BOOST_CHECK_EQUAL(nReceivedSegments, i);
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), nDataSegments - 1);
+    // check if the interest for the segment i+1 is well formed
+    auto sentInterest = face.sentInterests[i];
+    BOOST_CHECK_EQUAL(sentInterest.getExclude().size(), 0);
+    BOOST_CHECK_EQUAL(sentInterest.getMaxSuffixComponents(), 1);
+    BOOST_CHECK_EQUAL(sentInterest.getMustBeFresh(), opt.mustBeFresh);
+    BOOST_CHECK_EQUAL(Name(name).isPrefixOf(sentInterest.getName()), true);
+    BOOST_CHECK_EQUAL(sentInterest.getName()[-1].toSegment(), i + 1);
+  }
+
+  BOOST_CHECK_EQUAL(hasFailed, false);
+
+  advanceClocks(io, ndn::DEFAULT_INTEREST_LIFETIME, opt.maxRetriesOnTimeoutOrNack + 1);
+  BOOST_CHECK_EQUAL(hasFailed, true);
+}
+
+BOOST_FIXTURE_TEST_CASE(FullPipeline, PipelineInterestsFixture)
+{
+  nDataSegments = 13;
+  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);
+
+  runWithData(*makeDataWithSegment(nDataSegments - 1));
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);
+
+  for (uint64_t i = 0; i < nDataSegments - 1; ++i) {
+    face.receive(*makeDataWithSegment(i));
+    advanceClocks(io, time::nanoseconds(1), 1);
+    BOOST_CHECK_EQUAL(nReceivedSegments, i + 1);
+
+    if (i < nDataSegments - opt.maxPipelineSize - 1) {
+      BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize + i + 1);
+      // check if the interest for the segment i+1 is well formed
+      auto sentInterest = face.sentInterests[i];
+      BOOST_CHECK_EQUAL(sentInterest.getExclude().size(), 0);
+      BOOST_CHECK_EQUAL(sentInterest.getMaxSuffixComponents(), 1);
+      BOOST_CHECK_EQUAL(sentInterest.getMustBeFresh(), opt.mustBeFresh);
+      BOOST_CHECK_EQUAL(Name(name).isPrefixOf(sentInterest.getName()), true);
+      BOOST_CHECK_EQUAL(sentInterest.getName()[-1].toSegment(), i);
+    }
+    else {
+      // all the interests have been sent for all the segments
+      BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments - 1);
+    }
+  }
+
+  BOOST_CHECK_EQUAL(hasFailed, false);
+}
+
+BOOST_FIXTURE_TEST_CASE(TimeoutAllSegments, PipelineInterestsFixture)
+{
+  nDataSegments = 13;
+  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);
+
+  runWithData(*makeDataWithSegment(nDataSegments - 1));
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);
+
+  for (int i = 0; i < opt.maxRetriesOnTimeoutOrNack; ++i) {
+    advanceClocks(io, opt.interestLifetime, 1);
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize * (i + 2));
+    BOOST_CHECK_EQUAL(nReceivedSegments, 0);
+
+    // A single retry for every pipeline element
+    for (size_t j = 0; j < opt.maxPipelineSize; ++j) {
+      auto interest = face.sentInterests[(opt.maxPipelineSize * (i + 1)) + j];
+      BOOST_CHECK_EQUAL(static_cast<size_t>(interest.getName()[-1].toSegment()), j);
+    }
+  }
+
+  advanceClocks(io, opt.interestLifetime, 1);
+  BOOST_CHECK_EQUAL(hasFailed, true);
+}
+
+BOOST_FIXTURE_TEST_CASE(TimeoutAfterFinalBlockIdReceived, PipelineInterestsFixture)
+{
+  // the FinalBlockId is sent with the first segment, after the first segment failure the pipeline
+  // should fail
+
+  nDataSegments = 18;
+  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);
+
+  runWithData(*makeDataWithSegment(nDataSegments - 1));
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);
+
+  // send a single segment for each pipeline element but not the first element
+  advanceClocks(io, opt.interestLifetime, 1);
+  for (uint64_t i = 1; i < opt.maxPipelineSize; ++i) {
+    face.receive(*makeDataWithSegment(i));
+    advanceClocks(io, time::nanoseconds(1), 1);
+  }
+
+  // send a single data packet for each pipeline element
+  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack - 1);
+  for (uint64_t i = 0; i < opt.maxPipelineSize - 1; ++i) {
+    face.receive(*makeDataWithSegment(opt.maxPipelineSize + i));
+    advanceClocks(io, time::nanoseconds(1), 1);
+  }
+  advanceClocks(io, opt.interestLifetime, 1);
+
+  size_t interestAfterFailure = face.sentInterests.size();
+
+  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
+  BOOST_CHECK_EQUAL(hasFailed, true);
+
+  // these new segments should not generate new interests
+  advanceClocks(io, opt.interestLifetime, 1);
+  for (uint64_t i = 0; i < opt.maxPipelineSize - 1; ++i) {
+    face.receive(*makeDataWithSegment(opt.maxPipelineSize * 2 + i - 1));
+    advanceClocks(io, time::nanoseconds(1), 1);
+  }
+
+  // no more interests after a failure
+  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack);
+  BOOST_CHECK_EQUAL(interestAfterFailure, face.sentInterests.size());
+  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
+}
+
+BOOST_FIXTURE_TEST_CASE(TimeoutBeforeFinalBlockIdReceived, PipelineInterestsFixture)
+{
+  // the FinalBlockId is sent only with the last segment, all segments are sent except for the
+  // second one (segment #1); all segments are received correctly until the FinalBlockId is received
+
+  nDataSegments = 22;
+  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);
+
+  runWithData(*makeDataWithSegment(nDataSegments - 1, false));
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);
+
+  advanceClocks(io, opt.interestLifetime, 1);
+  for (uint64_t i = 2; i < opt.maxPipelineSize; ++i) {
+    face.receive(*makeDataWithSegment(i, false));
+    advanceClocks(io, time::nanoseconds(1), 1);
+
+    auto lastInterest = face.sentInterests.back();
+    BOOST_CHECK_EQUAL(lastInterest.getName()[-1].toSegment(), opt.maxPipelineSize + i - 2);
+  }
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize * 3 - 2);
+
+  // nack for the first pipeline element (segment #0)
+  auto nack = make_shared<lp::Nack>(face.sentInterests[opt.maxPipelineSize]);
+  nack->setReason(lp::NackReason::DUPLICATE);
+  face.receive(*nack);
+
+  // all the pipeline elements are two retries near the timeout error, but not the
+  // second (segment #1) that is only one retry near the timeout
+  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack - 1);
+  BOOST_CHECK_EQUAL(hasFailed, false);
+
+  // data for the first pipeline element (segment #0)
+  face.receive(*makeDataWithSegment(0, false));
+  BOOST_CHECK_EQUAL(hasFailed, false);
+
+  // data for all the pipeline element, but not the second (segment #1)
+  for (uint64_t i = opt.maxPipelineSize; i < nDataSegments - 1; ++i) {
+    if (i == nDataSegments - 2) {
+      face.receive(*makeDataWithSegment(i, true));
+    }
+    else {
+      face.receive(*makeDataWithSegment(i, false));
+    }
+    advanceClocks(io, time::nanoseconds(1), 1);
+  }
+  // timeout for the second pipeline element (segment #1), this should trigger an error
+  advanceClocks(io, opt.interestLifetime, 1);
+
+  BOOST_CHECK_EQUAL(nReceivedSegments, nDataSegments - 2);
+  BOOST_CHECK_EQUAL(hasFailed, true);
+}
+
+BOOST_FIXTURE_TEST_CASE(SegmentReceivedAfterTimeout, PipelineInterestsFixture)
+{
+  // the FinalBlockId is never sent, all the pipeline elements with a segment number greater than
+  // segment #0 will fail, after this failure also segment #0 fail and this should trigger an error
+
+  nDataSegments = 22;
+  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);
+
+  runWithData(*makeDataWithSegment(nDataSegments - 1, false));
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);
+
+  advanceClocks(io, opt.interestLifetime, 1);
+
+  // nack for the first pipeline element (segment #0)
+  auto nack = make_shared<lp::Nack>(face.sentInterests[opt.maxPipelineSize]);
+  nack->setReason(lp::NackReason::DUPLICATE);
+  face.receive(*nack);
+  BOOST_CHECK_EQUAL(hasFailed, false);
+
+  // timeout for all the pipeline elements, but not the first (segment #0)
+  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack);
+  BOOST_CHECK_EQUAL(hasFailed, false);
+
+  // data for the first pipeline element (segment #0), this should trigger an error because the
+  // others pipeline elements failed
+  face.receive(*makeDataWithSegment(0, false));
+  advanceClocks(io, time::nanoseconds(1), 1);
+
+  BOOST_CHECK_EQUAL(nReceivedSegments, 1);
+  BOOST_CHECK_EQUAL(hasFailed, true);
+}
+
+BOOST_FIXTURE_TEST_CASE(CongestionAllSegments, PipelineInterestsFixture)
+{
+  nDataSegments = 13;
+  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);
+
+  runWithData(*makeDataWithSegment(nDataSegments - 1));
+  advanceClocks(io, time::nanoseconds(1), 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);
+
+  // send nack for all the pipeline elements first interest
+  for (size_t j = 0; j < opt.maxPipelineSize; j++) {
+    auto nack = make_shared<lp::Nack>(face.sentInterests[j]);
+    nack->setReason(lp::NackReason::CONGESTION);
+    face.receive(*nack);
+    advanceClocks(io, time::nanoseconds(1), 1);
+  }
+
+  // send nack for all the pipeline elements interests after the first
+  for (int i = 1; i <= opt.maxRetriesOnTimeoutOrNack; ++i) {
+    time::milliseconds backoffTime(static_cast<uint64_t>(std::pow(2, i)));
+    if (backoffTime > DataFetcher::MAX_CONGESTION_BACKOFF_TIME)
+      backoffTime = DataFetcher::MAX_CONGESTION_BACKOFF_TIME;
+
+    advanceClocks(io, backoffTime, 1);
+    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize * (i +1));
+
+    // A single retry for every pipeline element
+    for (size_t j = 0; j < opt.maxPipelineSize; ++j) {
+      auto interest = face.sentInterests[(opt.maxPipelineSize * i) + j];
+      BOOST_CHECK_LT(static_cast<size_t>(interest.getName()[-1].toSegment()), opt.maxPipelineSize);
+    }
+
+    for (size_t j = 0; j < opt.maxPipelineSize; j++) {
+      auto nack = make_shared<lp::Nack>(face.sentInterests[(opt.maxPipelineSize * i) + j]);
+      nack->setReason(lp::NackReason::CONGESTION);
+      face.receive(*nack);
+      advanceClocks(io, time::nanoseconds(1), 1);
+    }
+  }
+
+  BOOST_CHECK_EQUAL(hasFailed, true);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestPipelineInterests
+BOOST_AUTO_TEST_SUITE_END() // Chunks
+
+} // namespace tests
+} // namespace chunks
+} // namespace ndn
diff --git a/tests/chunks/producer.t.cpp b/tests/chunks/producer.t.cpp
new file mode 100644
index 0000000..dc5346f
--- /dev/null
+++ b/tests/chunks/producer.t.cpp
@@ -0,0 +1,233 @@
+/* -*- 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 "tools/chunks/putchunks/producer.hpp"
+
+#include "tests/test-common.hpp"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+#include <ndn-cxx/security/validator-null.hpp>
+
+#include <cmath>
+
+namespace ndn {
+namespace chunks {
+namespace tests {
+
+using namespace ndn::tests;
+
+BOOST_AUTO_TEST_SUITE(Chunks)
+BOOST_AUTO_TEST_SUITE(TestProducer)
+
+BOOST_AUTO_TEST_CASE(InputData)
+{
+  util::DummyClientFace face;
+  KeyChain keyChain;
+  security::SigningInfo signingInfo;
+  Name prefix("/ndn/chunks/test");
+  int maxSegmentSize = 40;
+  std::vector<std::string> testStrings {
+      "",
+
+      "a1b2c3%^&(#$&%^$$/><",
+
+      "123456789123456789123456789123456789123456789123456789123456789"
+      "123456789123456789123456789123456789123456789123456789123456789",
+
+      "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. "
+      "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur "
+      "ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla "
+      "consequat massa Donec pede justo,"
+  };
+
+  for (size_t i = 0; i <  testStrings.size(); ++i) {
+    std::istringstream str(testStrings[i]);
+    Producer prod(prefix, face, keyChain, signingInfo, time::seconds(4), maxSegmentSize, false,
+                  false, str);
+
+    size_t expectedSize = std::ceil(static_cast<double>(testStrings[i].size()) / maxSegmentSize);
+    if (testStrings[i].size() == 0)
+      expectedSize = 1;
+
+    BOOST_CHECK_EQUAL(prod.m_store.size(), expectedSize);
+  }
+}
+
+BOOST_AUTO_TEST_CASE(RequestSegmentUnspecifiedVersion)
+{
+  boost::asio::io_service io;
+  util::DummyClientFace face(io, {true, true});
+  KeyChain keyChain;
+  security::SigningInfo signingInfo;
+  Name prefix("/ndn/chunks/test");
+  time::milliseconds freshnessPeriod(time::seconds(10));
+  size_t maxSegmentSize(40);
+  std::istringstream testString(std::string(
+          "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget "
+          "dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, "
+          "nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, "
+          "sem. Nulla consequat massa Donec pede justo,"));
+
+  Name keyLocatorName = keyChain.getDefaultCertificateName().getPrefix(-1);
+
+  Producer producer(prefix, face, keyChain, signingInfo, freshnessPeriod, maxSegmentSize,
+                    false, false, testString);
+  io.poll();
+
+  size_t nSegments = std::ceil(static_cast<double>(testString.str().size()) / maxSegmentSize);
+
+  // version request
+  face.receive(*makeInterest(prefix));
+  face.processEvents();
+
+  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
+  auto lastData = face.sentData.back();
+  BOOST_REQUIRE_EQUAL(lastData.getName().size(), prefix.size() + 2);
+  BOOST_CHECK_EQUAL(lastData.getName()[-1].toSegment(), 0);
+  BOOST_REQUIRE(!lastData.getFinalBlockId().empty());
+  BOOST_CHECK_EQUAL(lastData.getFinalBlockId().toSegment(), nSegments - 1);
+  BOOST_CHECK_EQUAL(lastData.getSignature().getKeyLocator().getName(), keyLocatorName);
+
+  // segment request
+  Name nameWithVersion(prefix);
+  nameWithVersion.append(lastData.getName()[-2]);
+  size_t requestSegmentNo = 1;
+
+  face.receive(*makeInterest(nameWithVersion.appendSegment(requestSegmentNo)));
+  face.processEvents();
+
+  BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
+  lastData = face.sentData.back();
+  BOOST_REQUIRE_EQUAL(lastData.getName().size(), prefix.size() + 2);
+  BOOST_CHECK_EQUAL(lastData.getName()[-1].toSegment(), requestSegmentNo);
+  BOOST_REQUIRE(!lastData.getFinalBlockId().empty());
+  BOOST_CHECK_EQUAL(lastData.getFinalBlockId().toSegment(), nSegments - 1);
+  BOOST_CHECK_EQUAL(lastData.getSignature().getKeyLocator().getName(), keyLocatorName);
+}
+
+BOOST_AUTO_TEST_CASE(RequestSegmentSpecifiedVersion)
+{
+  boost::asio::io_service io;
+  util::DummyClientFace face(io, {true, true});
+  KeyChain keyChain;
+  security::SigningInfo signingInfo;
+  Name prefix("/ndn/chunks/test");
+  time::milliseconds freshnessPeriod(time::seconds(10));
+  size_t maxSegmentSize(40);
+  std::istringstream testString(std::string(
+          "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget "
+          "dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, "
+          "nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, "
+          "sem. Nulla consequat massa Donec pede justo,"));
+
+  uint64_t version = 1449227841747;
+  Name keyLocatorName = keyChain.getDefaultCertificateName().getPrefix(-1);
+
+  Producer producer(prefix.appendVersion(version), face, keyChain, signingInfo, freshnessPeriod,
+                    maxSegmentSize, false, false, testString);
+  io.poll();
+
+  size_t nSegments = std::ceil(static_cast<double>(testString.str().size()) / maxSegmentSize);
+
+  // version request
+  face.receive(*makeInterest(prefix));
+  face.processEvents();
+
+  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
+  auto lastData = face.sentData.back();
+  BOOST_REQUIRE_EQUAL(lastData.getName().size(), prefix.size() + 1);
+  BOOST_CHECK_EQUAL(lastData.getName()[-2].toVersion(), version);
+  BOOST_CHECK_EQUAL(lastData.getName()[-1].toSegment(), 0);
+  BOOST_REQUIRE(!lastData.getFinalBlockId().empty());
+  BOOST_CHECK_EQUAL(lastData.getFinalBlockId().toSegment(), nSegments - 1);
+  BOOST_CHECK_EQUAL(lastData.getSignature().getKeyLocator().getName(), keyLocatorName);
+
+  // segment request
+  Name nameWithVersion(prefix);
+  size_t requestSegmentNo = 1;
+
+  face.receive(*makeInterest(nameWithVersion.appendSegment(requestSegmentNo)));
+  face.processEvents();
+
+  BOOST_REQUIRE_EQUAL(face.sentData.size(), 2);
+  lastData = face.sentData.back();
+  BOOST_REQUIRE_EQUAL(lastData.getName().size(), prefix.size() + 1);
+  BOOST_CHECK_EQUAL(lastData.getName()[-2].toVersion(), version);
+  BOOST_CHECK_EQUAL(lastData.getName()[-1].toSegment(), requestSegmentNo);
+  BOOST_REQUIRE(!lastData.getFinalBlockId().empty());
+  BOOST_CHECK_EQUAL(lastData.getFinalBlockId().toSegment(), nSegments - 1);
+  BOOST_CHECK_EQUAL(lastData.getSignature().getKeyLocator().getName(), keyLocatorName);
+}
+
+BOOST_AUTO_TEST_CASE(RequestNotExistingSegment)
+{
+  boost::asio::io_service io;
+  util::DummyClientFace face(io, {true, true});
+  KeyChain keyChain;
+  security::SigningInfo signingInfo;
+  Name prefix("/ndn/chunks/test");
+  time::milliseconds freshnessPeriod(time::seconds(10));
+  size_t maxSegmentSize(40);
+  std::istringstream testString(std::string(
+          "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget "
+          "dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, "
+          "nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, "
+          "sem. Nulla consequat massa Donec pede justo,"));
+
+  Name keyLocatorName = keyChain.getDefaultCertificateName().getPrefix(-1);
+
+  Producer producer(prefix, face, keyChain, signingInfo, freshnessPeriod, maxSegmentSize,
+                    false, false, testString);
+  io.poll();
+
+  size_t nSegments = std::ceil(static_cast<double>(testString.str().size()) / maxSegmentSize);
+
+  // version request
+  face.receive(*makeInterest(prefix));
+  face.processEvents();
+
+  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
+  auto lastData = face.sentData.back();
+  BOOST_REQUIRE_EQUAL(lastData.getName().size(), prefix.size() + 2);
+  BOOST_CHECK_EQUAL(lastData.getName()[-1].toSegment(), 0);
+  BOOST_REQUIRE(!lastData.getFinalBlockId().empty());
+  BOOST_CHECK_EQUAL(lastData.getFinalBlockId().toSegment(), nSegments - 1);
+  BOOST_CHECK_EQUAL(lastData.getSignature().getKeyLocator().getName(), keyLocatorName);
+
+  // segment request
+  Name nameWithVersion(prefix);
+  nameWithVersion.append(lastData.getName()[-2]);
+  face.receive(*makeInterest(nameWithVersion.appendSegment(nSegments)));
+  face.processEvents();
+
+  // no new data
+  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestProducer
+BOOST_AUTO_TEST_SUITE_END() // Chunks
+
+} // namespace tests
+} // namespace chunks
+} // namespace ndn
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')
+
