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
