diff --git a/src/mgmt/nfd/controller.cpp b/src/mgmt/nfd/controller.cpp
index 945c16d..7ed8005 100644
--- a/src/mgmt/nfd/controller.cpp
+++ b/src/mgmt/nfd/controller.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -133,15 +133,19 @@
 
 void
 Controller::fetchDataset(const Name& prefix,
-                         const std::function<void(const ConstBufferPtr&)>& processResponse,
+                         const std::function<void(ConstBufferPtr)>& processResponse,
                          const DatasetFailCallback& onFailure,
                          const CommandOptions& options)
 {
   Interest baseInterest(prefix);
-  baseInterest.setInterestLifetime(options.getTimeout());
 
-  SegmentFetcher::fetch(m_face, baseInterest, m_validator, processResponse,
-                        bind(&Controller::processDatasetFetchError, this, onFailure, _1, _2));
+  SegmentFetcher::Options fetcherOptions;
+  fetcherOptions.maxTimeout = options.getTimeout();
+  auto fetcher = SegmentFetcher::start(m_face, baseInterest, m_validator, fetcherOptions);
+  fetcher->onComplete.connect(processResponse);
+  fetcher->onError.connect([=] (uint32_t code, const std::string& msg) {
+      processDatasetFetchError(onFailure, code, msg);
+    });
 }
 
 void
@@ -156,6 +160,7 @@
       onFailure(ERROR_TIMEOUT, msg);
       break;
     case SegmentFetcher::ErrorCode::DATA_HAS_NO_SEGMENT:
+    case SegmentFetcher::ErrorCode::FINALBLOCKID_NOT_SEGMENT:
       onFailure(ERROR_SERVER, msg);
       break;
     case SegmentFetcher::ErrorCode::SEGMENT_VALIDATION_FAIL:
diff --git a/src/mgmt/nfd/controller.hpp b/src/mgmt/nfd/controller.hpp
index e98b606..8797b39 100644
--- a/src/mgmt/nfd/controller.hpp
+++ b/src/mgmt/nfd/controller.hpp
@@ -132,7 +132,7 @@
 
   void
   fetchDataset(const Name& prefix,
-               const std::function<void(const ConstBufferPtr&)>& processResponse,
+               const std::function<void(ConstBufferPtr)>& processResponse,
                const DatasetFailCallback& onFailure,
                const CommandOptions& options);
 
diff --git a/src/util/rtt-estimator.cpp b/src/util/rtt-estimator.cpp
new file mode 100644
index 0000000..f79b6e4
--- /dev/null
+++ b/src/util/rtt-estimator.cpp
@@ -0,0 +1,80 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (C) 2016-2018, Arizona Board of Regents.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ */
+
+#include "rtt-estimator.hpp"
+
+#include <cmath>
+#include <limits>
+
+namespace ndn {
+namespace util {
+
+RttEstimator::RttEstimator(const Options& options)
+  : m_options(options)
+  , m_sRtt(std::numeric_limits<double>::quiet_NaN())
+  , m_rttVar(std::numeric_limits<double>::quiet_NaN())
+  , m_rto(m_options.initialRto.count())
+  , m_rttMin(std::numeric_limits<double>::max())
+  , m_rttMax(std::numeric_limits<double>::min())
+  , m_rttAvg(0.0)
+  , m_nRttSamples(0)
+{
+}
+
+void
+RttEstimator::addMeasurement(MillisecondsDouble rtt, size_t nExpectedSamples)
+{
+  BOOST_ASSERT(nExpectedSamples > 0);
+
+  if (m_nRttSamples == 0) { // first measurement
+    m_sRtt = rtt;
+    m_rttVar = m_sRtt / 2;
+    m_rto = m_sRtt + m_options.k * m_rttVar;
+  }
+  else {
+    double alpha = m_options.alpha / nExpectedSamples;
+    double beta = m_options.beta / nExpectedSamples;
+    m_rttVar = (1 - beta) * m_rttVar + beta * time::abs(m_sRtt - rtt);
+    m_sRtt = (1 - alpha) * m_sRtt + alpha * rtt;
+    m_rto = m_sRtt + m_options.k * m_rttVar;
+  }
+
+  m_rto = clamp(m_rto, m_options.minRto, m_options.maxRto);
+
+  m_rttAvg = MillisecondsDouble((m_nRttSamples * m_rttAvg.count() + rtt.count()) / (m_nRttSamples + 1));
+  m_rttMax = std::max<MillisecondsDouble>(rtt, m_rttMax);
+  m_rttMin = std::min<MillisecondsDouble>(rtt, m_rttMin);
+  m_nRttSamples++;
+}
+
+void
+RttEstimator::backoffRto()
+{
+  m_rto = clamp(m_rto * m_options.rtoBackoffMultiplier,
+                m_options.minRto, m_options.maxRto);
+}
+
+} // namespace util
+} // namespace ndn
diff --git a/src/util/rtt-estimator.hpp b/src/util/rtt-estimator.hpp
new file mode 100644
index 0000000..4cf5586
--- /dev/null
+++ b/src/util/rtt-estimator.hpp
@@ -0,0 +1,143 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (C) 2016-2018, Arizona Board of Regents.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
+ */
+
+#ifndef NDN_CXX_UTIL_RTT_ESTIMATOR_HPP
+#define NDN_CXX_UTIL_RTT_ESTIMATOR_HPP
+
+#include "../common.hpp"
+#include "signal.hpp"
+#include "time.hpp"
+
+namespace ndn {
+namespace util {
+
+/**
+ * @brief RTT Estimator.
+ *
+ * This class implements the "Mean-Deviation" RTT estimator, as discussed in RFC 6298,
+ * with the modifications to RTO calculation described in RFC 7323 Appendix G.
+ */
+class RttEstimator
+{
+public:
+  using MillisecondsDouble = time::duration<double, time::milliseconds::period>;
+
+public:
+  class Options
+  {
+  public:
+    constexpr
+    Options() noexcept
+    {
+    }
+
+  public:
+    double alpha = 0.125; ///< weight of exponential moving average for meanRtt
+    double beta = 0.25; ///< weight of exponential moving average for varRtt
+    int k = 4; ///< factor of RTT variation when calculating RTO
+    MillisecondsDouble initialRto = MillisecondsDouble(1000.0); ///< initial RTO value
+    MillisecondsDouble minRto = MillisecondsDouble(200.0); ///< lower bound of RTO
+    MillisecondsDouble maxRto = MillisecondsDouble(20000.0); ///< upper bound of RTO
+    int rtoBackoffMultiplier = 2;
+  };
+
+  /**
+   * @brief Create a RTT Estimator
+   *
+   * Configures the RTT Estimator with the default parameters if an instance of Options
+   * is not passed to the constructor.
+   */
+  explicit
+  RttEstimator(const Options& options = Options());
+
+  /**
+   * @brief Add a new RTT measurement to the estimator.
+   *
+   * @param rtt the sampled rtt
+   * @param nExpectedSamples number of expected samples, must be greater than 0.
+   *        It should be set to current number of in-flight Interests. Please
+   *        refer to Appendix G of RFC 7323 for details.
+   * @note Don't add RTT measurements for retransmissions
+   */
+  void
+  addMeasurement(MillisecondsDouble rtt, size_t nExpectedSamples);
+
+  /**
+   * @brief Returns the estimated RTO value
+   */
+  MillisecondsDouble
+  getEstimatedRto() const
+  {
+    return m_rto;
+  }
+
+  /**
+   * @brief Returns the minimum RTT observed
+   */
+  MillisecondsDouble
+  getMinRtt() const
+  {
+    return m_rttMin;
+  }
+
+  /**
+   * @brief Returns the maximum RTT observed
+   */
+  MillisecondsDouble
+  getMaxRtt() const
+  {
+    return m_rttMax;
+  }
+
+  /**
+   * @brief Returns the average RTT
+   */
+  MillisecondsDouble
+  getAvgRtt() const
+  {
+    return m_rttAvg;
+  }
+
+  /**
+   * @brief Backoff RTO by a factor of Options::rtoBackoffMultiplier
+   */
+  void
+  backoffRto();
+
+private:
+  const Options m_options;
+  MillisecondsDouble m_sRtt; ///< smoothed round-trip time
+  MillisecondsDouble m_rttVar; ///< round-trip time variation
+  MillisecondsDouble m_rto; ///< retransmission timeout
+  MillisecondsDouble m_rttMin;
+  MillisecondsDouble m_rttMax;
+  MillisecondsDouble m_rttAvg;
+  int64_t m_nRttSamples; ///< number of RTT samples
+};
+
+} // namespace util
+} // namespace ndn
+
+#endif // NDN_CXX_UTIL_RTT_ESTIMATOR_HPP
diff --git a/src/util/segment-fetcher.cpp b/src/util/segment-fetcher.cpp
index 0d53aaf..de177fd 100644
--- a/src/util/segment-fetcher.cpp
+++ b/src/util/segment-fetcher.cpp
@@ -1,6 +1,8 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2018, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -17,10 +19,15 @@
  * <http://www.gnu.org/licenses/>.
  *
  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
  */
 
 #include "segment-fetcher.hpp"
 #include "../name-component.hpp"
+#include "../encoding/buffer-stream.hpp"
 #include "../lp/nack.hpp"
 #include "../lp/nack-header.hpp"
 
@@ -30,22 +37,59 @@
 namespace ndn {
 namespace util {
 
-const uint32_t SegmentFetcher::MAX_INTEREST_REEXPRESS = 3;
+constexpr double SegmentFetcher::MIN_SSTHRESH;
 
-SegmentFetcher::SegmentFetcher(Face& face, security::v2::Validator& validator)
-  : m_face(face)
+void
+SegmentFetcher::Options::validate()
+{
+  if (maxTimeout < 1_ms) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("maxTimeout must be greater than or equal to 1 millisecond"));
+  }
+
+  if (initCwnd < 1.0) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("initCwnd must be greater than or equal to 1"));
+  }
+
+  if (aiStep < 0.0) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("aiStep must be greater than or equal to 0"));
+  }
+
+  if (mdCoef < 0.0 || mdCoef > 1.0) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("mdCoef must be in range [0, 1]"));
+  }
+}
+
+SegmentFetcher::SegmentFetcher(Face& face,
+                               security::v2::Validator& validator,
+                               const SegmentFetcher::Options& options)
+  : m_options(options)
+  , m_face(face)
   , m_scheduler(m_face.getIoService())
   , m_validator(validator)
+  , m_rttEstimator(options.rttOptions)
+  , m_timeLastSegmentReceived(time::steady_clock::now())
+  , m_nextSegmentNum(0)
+  , m_cwnd(options.initCwnd)
+  , m_ssthresh(options.initSsthresh)
+  , m_nSegmentsInFlight(0)
+  , m_nSegments(0)
+  , m_highInterest(0)
+  , m_highData(0)
+  , m_recPoint(0)
+  , m_nReceived(0)
+  , m_nBytesReceived(0)
 {
+  m_options.validate();
 }
 
 shared_ptr<SegmentFetcher>
 SegmentFetcher::start(Face& face,
                       const Interest& baseInterest,
-                      security::v2::Validator& validator)
+                      security::v2::Validator& validator,
+                      const SegmentFetcher::Options& options)
 {
-  shared_ptr<SegmentFetcher> fetcher(new SegmentFetcher(face, validator));
-  fetcher->fetchFirstSegment(baseInterest, fetcher);
+  shared_ptr<SegmentFetcher> fetcher(new SegmentFetcher(face, validator, options));
+  fetcher->fetchFirstSegment(baseInterest, false, fetcher);
   return fetcher;
 }
 
@@ -56,7 +100,12 @@
                       const CompleteCallback& completeCallback,
                       const ErrorCallback& errorCallback)
 {
-  shared_ptr<SegmentFetcher> fetcher = start(face, baseInterest, validator);
+  Options options;
+  options.useConstantCwnd = true;
+  options.useConstantInterestTimeout = true;
+  options.maxTimeout = baseInterest.getInterestLifetime();
+  options.interestLifetime = baseInterest.getInterestLifetime();
+  shared_ptr<SegmentFetcher> fetcher = start(face, baseInterest, validator, options);
   fetcher->onComplete.connect(completeCallback);
   fetcher->onError.connect(errorCallback);
   return fetcher;
@@ -70,135 +119,412 @@
                       const ErrorCallback& errorCallback)
 {
   auto fetcher = fetch(face, baseInterest, *validator, completeCallback, errorCallback);
+  // Ensure lifetime of validator shared_ptr
   fetcher->onComplete.connect([validator] (ConstBufferPtr) {});
   return fetcher;
 }
 
 void
 SegmentFetcher::fetchFirstSegment(const Interest& baseInterest,
+                                  bool isRetransmission,
                                   shared_ptr<SegmentFetcher> self)
 {
   Interest interest(baseInterest);
   interest.setChildSelector(1);
   interest.setMustBeFresh(true);
+  interest.setInterestLifetime(m_options.interestLifetime);
+  if (isRetransmission) {
+    interest.refreshNonce();
+  }
 
-  m_face.expressInterest(interest,
-                         bind(&SegmentFetcher::afterSegmentReceivedCb, this, _1, _2, true, self),
-                         bind(&SegmentFetcher::afterNackReceivedCb, this, _1, _2, 0, self),
-                         bind([this] { onError(INTEREST_TIMEOUT, "Timeout"); }));
+  m_nSegmentsInFlight++;
+  auto pendingInterest = m_face.expressInterest(interest,
+                                                bind(&SegmentFetcher::afterSegmentReceivedCb,
+                                                     this, _1, _2, self),
+                                                bind(&SegmentFetcher::afterNackReceivedCb,
+                                                     this, _1, _2, self),
+                                                nullptr);
+  auto timeoutEvent =
+    m_scheduler.scheduleEvent(m_options.useConstantInterestTimeout ? m_options.maxTimeout : getEstimatedRto(),
+                              bind(&SegmentFetcher::afterTimeoutCb, this, interest, self));
+  if (isRetransmission) {
+    updateRetransmittedSegment(0, pendingInterest, timeoutEvent);
+  }
+  else {
+    BOOST_ASSERT(m_pendingSegments.count(0) == 0);
+    m_pendingSegments.emplace(0, PendingSegment{SegmentState::FirstInterest, time::steady_clock::now(),
+                                                pendingInterest, timeoutEvent});
+  }
 }
 
 void
-SegmentFetcher::fetchNextSegment(const Interest& origInterest, const Name& dataName,
-                                 uint64_t segmentNo,
-                                 shared_ptr<SegmentFetcher> self)
+SegmentFetcher::fetchSegmentsInWindow(const Interest& origInterest, shared_ptr<SegmentFetcher> self)
 {
-  Interest interest(origInterest); // to preserve any selectors
-  interest.refreshNonce();
-  interest.setChildSelector(0);
-  interest.setMustBeFresh(false);
-  interest.setName(dataName.getPrefix(-1).appendSegment(segmentNo));
-  m_face.expressInterest(interest,
-                         bind(&SegmentFetcher::afterSegmentReceivedCb, this, _1, _2, false, self),
-                         bind(&SegmentFetcher::afterNackReceivedCb, this, _1, _2, 0, self),
-                         bind([this] { onError(INTEREST_TIMEOUT, "Timeout"); }));
+  if (checkAllSegmentsReceived()) {
+    // All segments have been retrieved
+    finalizeFetch(self);
+  }
+
+  int64_t availableWindowSize = static_cast<int64_t>(m_cwnd) - m_nSegmentsInFlight;
+
+  std::vector<std::pair<uint64_t, bool>> segmentsToRequest; // The boolean indicates whether a retx or not
+
+  while (availableWindowSize > 0) {
+    if (!m_retxQueue.empty()) {
+      auto pendingSegmentIt = m_pendingSegments.find(m_retxQueue.front());
+      m_retxQueue.pop();
+      if (pendingSegmentIt == m_pendingSegments.end()) {
+        // Skip re-requesting this segment, since it was received after RTO timeout
+        continue;
+      }
+      BOOST_ASSERT(pendingSegmentIt->second.state == SegmentState::InRetxQueue);
+      segmentsToRequest.emplace_back(pendingSegmentIt->first, true);
+    }
+    else if (m_nSegments == 0 || m_nextSegmentNum < static_cast<uint64_t>(m_nSegments)) {
+      if (m_receivedSegments.count(m_nextSegmentNum) > 0) {
+        // Don't request a segment a second time if received in response to first "discovery" Interest
+        m_nextSegmentNum++;
+        continue;
+      }
+      segmentsToRequest.emplace_back(m_nextSegmentNum++, false);
+    }
+    else {
+      break;
+    }
+    availableWindowSize--;
+  }
+
+  for (const auto& segment : segmentsToRequest) {
+    Interest interest(origInterest); // to preserve Interest elements
+    interest.refreshNonce();
+    interest.setChildSelector(0);
+    interest.setMustBeFresh(false);
+
+    Name interestName(m_versionedDataName);
+    interestName.appendSegment(segment.first);
+    interest.setName(interestName);
+    interest.setInterestLifetime(m_options.interestLifetime);
+    m_nSegmentsInFlight++;
+    auto pendingInterest = m_face.expressInterest(interest,
+                                                  bind(&SegmentFetcher::afterSegmentReceivedCb,
+                                                       this, _1, _2, self),
+                                                  bind(&SegmentFetcher::afterNackReceivedCb,
+                                                       this, _1, _2, self),
+                                                  nullptr);
+    auto timeoutEvent =
+      m_scheduler.scheduleEvent(m_options.useConstantInterestTimeout ? m_options.maxTimeout : getEstimatedRto(),
+                                bind(&SegmentFetcher::afterTimeoutCb, this, interest, self));
+    if (segment.second) { // Retransmission
+      updateRetransmittedSegment(segment.first, pendingInterest, timeoutEvent);
+    }
+    else { // First request for segment
+      BOOST_ASSERT(m_pendingSegments.count(segment.first) == 0);
+      m_pendingSegments.emplace(segment.first, PendingSegment{SegmentState::FirstInterest,
+                                                              time::steady_clock::now(),
+                                                              pendingInterest, timeoutEvent});
+      m_highInterest = segment.first;
+    }
+  }
 }
 
 void
 SegmentFetcher::afterSegmentReceivedCb(const Interest& origInterest,
-                                       const Data& data, bool isSegmentZeroExpected,
+                                       const Data& data,
                                        shared_ptr<SegmentFetcher> self)
 {
   afterSegmentReceived(data);
-  m_validator.validate(data,
-                       bind(&SegmentFetcher::afterValidationSuccess, this, _1,
-                            isSegmentZeroExpected, origInterest, self),
-                       bind(&SegmentFetcher::afterValidationFailure, this, _1, _2));
+  BOOST_ASSERT(m_nSegmentsInFlight > 0);
+  m_nSegmentsInFlight--;
 
+  name::Component currentSegmentComponent = data.getName().get(-1);
+  if (!currentSegmentComponent.isSegment()) {
+    return signalError(DATA_HAS_NO_SEGMENT, "Data Name has no segment number");
+  }
+
+  uint64_t currentSegment = currentSegmentComponent.toSegment();
+
+  // The first received Interest could have any segment ID
+  std::map<uint64_t, PendingSegment>::iterator pendingSegmentIt;
+  if (m_receivedSegments.size() > 0) {
+    pendingSegmentIt = m_pendingSegments.find(currentSegment);
+  }
+  else {
+    pendingSegmentIt = m_pendingSegments.begin();
+  }
+
+  // Cancel timeout event
+  m_scheduler.cancelEvent(pendingSegmentIt->second.timeoutEvent);
+  pendingSegmentIt->second.timeoutEvent = nullptr;
+
+  m_validator.validate(data,
+                       bind(&SegmentFetcher::afterValidationSuccess, this, _1, origInterest,
+                            pendingSegmentIt, self),
+                       bind(&SegmentFetcher::afterValidationFailure, this, _1, _2, self));
 }
 
 void
 SegmentFetcher::afterValidationSuccess(const Data& data,
-                                       bool isSegmentZeroExpected,
                                        const Interest& origInterest,
+                                       std::map<uint64_t, PendingSegment>::iterator pendingSegmentIt,
                                        shared_ptr<SegmentFetcher> self)
 {
-  name::Component currentSegment = data.getName().get(-1);
+  // We update the last receive time here instead of in the segment received callback so that the
+  // transfer will not fail to terminate if we only received invalid Data packets.
+  m_timeLastSegmentReceived = time::steady_clock::now();
 
-  if (currentSegment.isSegment()) {
-    if (isSegmentZeroExpected && currentSegment.toSegment() != 0) {
-      fetchNextSegment(origInterest, data.getName(), 0, self);
+  m_nReceived++;
+
+  // It was verified in afterSegmentReceivedCb that the last Data name component is a segment number
+  uint64_t currentSegment = data.getName().get(-1).toSegment();
+  // Add measurement to RTO estimator (if not retransmission)
+  if (pendingSegmentIt->second.state == SegmentState::FirstInterest) {
+    m_rttEstimator.addMeasurement(m_timeLastSegmentReceived - pendingSegmentIt->second.sendTime,
+                                  std::max<int64_t>(m_nSegmentsInFlight + 1, 1));
+  }
+
+  // Remove from pending segments map
+  m_pendingSegments.erase(pendingSegmentIt);
+
+  // Copy data in segment to temporary buffer
+  auto receivedSegmentIt = m_receivedSegments.emplace(std::piecewise_construct,
+                                                      std::forward_as_tuple(currentSegment),
+                                                      std::forward_as_tuple(data.getContent().value_size()));
+  std::copy(data.getContent().value_begin(), data.getContent().value_end(),
+            receivedSegmentIt.first->second.begin());
+  m_nBytesReceived += data.getContent().value_size();
+  afterSegmentValidated(data);
+
+  if (data.getFinalBlock()) {
+    if (!data.getFinalBlock()->isSegment()) {
+      return signalError(FINALBLOCKID_NOT_SEGMENT,
+                         "Received FinalBlockId did not contain a segment component");
+    }
+
+    if (data.getFinalBlock()->toSegment() + 1 != static_cast<uint64_t>(m_nSegments)) {
+      m_nSegments = data.getFinalBlock()->toSegment() + 1;
+      cancelExcessInFlightSegments();
+    }
+  }
+
+  if (m_receivedSegments.size() == 1) {
+    m_versionedDataName = data.getName().getPrefix(-1);
+    if (currentSegment == 0) {
+      // We received the first segment in response, so we can increment the next segment number
+      m_nextSegmentNum++;
+    }
+  }
+
+  if (m_highData < currentSegment) {
+    m_highData = currentSegment;
+  }
+
+  if (data.getCongestionMark() > 0 && !m_options.ignoreCongMarks) {
+    windowDecrease();
+  }
+  else {
+    windowIncrease();
+  }
+
+  fetchSegmentsInWindow(origInterest, self);
+}
+
+void
+SegmentFetcher::afterValidationFailure(const Data& data,
+                                       const security::v2::ValidationError& error,
+                                       shared_ptr<SegmentFetcher> self)
+{
+  signalError(SEGMENT_VALIDATION_FAIL, "Segment validation failed: " +
+                                       boost::lexical_cast<std::string>(error));
+}
+
+
+void
+SegmentFetcher::afterNackReceivedCb(const Interest& origInterest,
+                                    const lp::Nack& nack,
+                                    shared_ptr<SegmentFetcher> self)
+{
+  afterSegmentNacked();
+  BOOST_ASSERT(m_nSegmentsInFlight > 0);
+  m_nSegmentsInFlight--;
+
+  switch (nack.getReason()) {
+    case lp::NackReason::DUPLICATE:
+    case lp::NackReason::CONGESTION:
+      afterNackOrTimeout(origInterest, self);
+      break;
+    default:
+      signalError(NACK_ERROR, "Nack Error");
+      break;
+  }
+}
+
+void
+SegmentFetcher::afterTimeoutCb(const Interest& origInterest,
+                               shared_ptr<SegmentFetcher> self)
+{
+  afterSegmentTimedOut();
+  BOOST_ASSERT(m_nSegmentsInFlight > 0);
+  m_nSegmentsInFlight--;
+  afterNackOrTimeout(origInterest, self);
+}
+
+void
+SegmentFetcher::afterNackOrTimeout(const Interest& origInterest, shared_ptr<SegmentFetcher> self)
+{
+  if (time::steady_clock::now() >= m_timeLastSegmentReceived + m_options.maxTimeout) {
+    // Fail transfer due to exceeding the maximum timeout between the succesful receipt of segments
+    return signalError(INTEREST_TIMEOUT, "Timeout exceeded");
+  }
+
+  name::Component lastNameComponent = origInterest.getName().get(-1);
+  std::map<uint64_t, PendingSegment>::iterator pendingSegmentIt;
+  BOOST_ASSERT(m_pendingSegments.size() > 0);
+  if (lastNameComponent.isSegment()) {
+    BOOST_ASSERT(m_pendingSegments.count(lastNameComponent.toSegment()) > 0);
+    pendingSegmentIt = m_pendingSegments.find(lastNameComponent.toSegment());
+  }
+  else { // First Interest
+    BOOST_ASSERT(m_pendingSegments.size() > 0);
+    pendingSegmentIt = m_pendingSegments.begin();
+  }
+
+  // Cancel timeout event and set status to InRetxQueue
+  m_scheduler.cancelEvent(pendingSegmentIt->second.timeoutEvent);
+  pendingSegmentIt->second.timeoutEvent = nullptr;
+  pendingSegmentIt->second.state = SegmentState::InRetxQueue;
+
+  m_rttEstimator.backoffRto();
+
+  if (m_receivedSegments.size() == 0) {
+    // Resend first Interest (until maximum receive timeout exceeded)
+    fetchFirstSegment(origInterest, true, self);
+  }
+  else {
+    windowDecrease();
+    m_retxQueue.push(pendingSegmentIt->first);
+    fetchSegmentsInWindow(origInterest, self);
+  }
+}
+
+void
+SegmentFetcher::finalizeFetch(shared_ptr<SegmentFetcher> self)
+{
+  // Combine segments into final buffer
+  OBufferStream buf;
+  // We may have received more segments than exist in the object.
+  BOOST_ASSERT(m_receivedSegments.size() >= static_cast<uint64_t>(m_nSegments));
+
+  for (int64_t i = 0; i < m_nSegments; i++) {
+    buf.write(m_receivedSegments[i].get<const char>(), m_receivedSegments[i].size());
+  }
+
+  onComplete(buf.buf());
+}
+
+void
+SegmentFetcher::windowIncrease()
+{
+  if (m_options.useConstantCwnd) {
+    BOOST_ASSERT(m_cwnd == m_options.initCwnd);
+    return;
+  }
+
+  if (m_cwnd < m_ssthresh) {
+    m_cwnd += m_options.aiStep; // additive increase
+  }
+  else {
+    m_cwnd += m_options.aiStep / std::floor(m_cwnd); // congestion avoidance
+  }
+}
+
+void
+SegmentFetcher::windowDecrease()
+{
+  if (m_options.disableCwa || m_highData > m_recPoint) {
+    m_recPoint = m_highInterest;
+
+    if (m_options.useConstantCwnd) {
+      BOOST_ASSERT(m_cwnd == m_options.initCwnd);
+      return;
+    }
+
+    // Refer to RFC 5681, Section 3.1 for the rationale behind the code below
+    m_ssthresh = std::max(MIN_SSTHRESH, m_cwnd * m_options.mdCoef); // multiplicative decrease
+    m_cwnd = m_options.resetCwndToInit ? m_options.initCwnd : m_ssthresh;
+  }
+}
+
+void
+SegmentFetcher::signalError(uint32_t code, const std::string& msg)
+{
+  // Cancel all pending Interests before signaling error
+  for (const auto& pendingSegment : m_pendingSegments) {
+    m_face.removePendingInterest(pendingSegment.second.id);
+    if (pendingSegment.second.timeoutEvent) {
+      m_scheduler.cancelEvent(pendingSegment.second.timeoutEvent);
+    }
+  }
+  onError(code, msg);
+}
+
+void
+SegmentFetcher::updateRetransmittedSegment(uint64_t segmentNum,
+                                           const PendingInterestId* pendingInterest,
+                                           scheduler::EventId timeoutEvent)
+{
+  auto pendingSegmentIt = m_pendingSegments.find(segmentNum);
+  BOOST_ASSERT(pendingSegmentIt != m_pendingSegments.end());
+  BOOST_ASSERT(pendingSegmentIt->second.state == SegmentState::InRetxQueue);
+  pendingSegmentIt->second.state = SegmentState::Retransmitted;
+  pendingSegmentIt->second.id = pendingInterest;
+  pendingSegmentIt->second.timeoutEvent = timeoutEvent;
+}
+
+void
+SegmentFetcher::cancelExcessInFlightSegments()
+{
+  for (auto it = m_pendingSegments.begin(); it != m_pendingSegments.end();) {
+    if (it->first >= static_cast<uint64_t>(m_nSegments)) {
+      m_face.removePendingInterest(it->second.id);
+      if (it->second.timeoutEvent) {
+        m_scheduler.cancelEvent(it->second.timeoutEvent);
+      }
+      it = m_pendingSegments.erase(it);
+      BOOST_ASSERT(m_nSegmentsInFlight > 0);
+      m_nSegmentsInFlight--;
     }
     else {
-      m_buffer.write(reinterpret_cast<const char*>(data.getContent().value()),
-                     data.getContent().value_size());
-      afterSegmentValidated(data);
-      const auto& finalBlockId = data.getFinalBlock();
-      if (!finalBlockId || (*finalBlockId > currentSegment)) {
-        fetchNextSegment(origInterest, data.getName(), currentSegment.toSegment() + 1, self);
-      }
-      else {
-        onComplete(m_buffer.buf());
-      }
-    }
-  }
-  else {
-    onError(DATA_HAS_NO_SEGMENT, "Data Name has no segment number.");
-  }
-}
-
-void
-SegmentFetcher::afterValidationFailure(const Data& data, const security::v2::ValidationError& error)
-{
-  onError(SEGMENT_VALIDATION_FAIL, "Segment validation fail " +
-                                   boost::lexical_cast<std::string>(error));
-}
-
-
-void
-SegmentFetcher::afterNackReceivedCb(const Interest& origInterest, const lp::Nack& nack,
-                                    uint32_t reExpressCount, shared_ptr<SegmentFetcher> self)
-{
-  if (reExpressCount >= MAX_INTEREST_REEXPRESS) {
-    onError(NACK_ERROR, "Nack Error");
-  }
-  else {
-    switch (nack.getReason()) {
-      case lp::NackReason::DUPLICATE:
-        reExpressInterest(origInterest, reExpressCount, self);
-        break;
-      case lp::NackReason::CONGESTION:
-        using ms = time::milliseconds;
-        m_scheduler.scheduleEvent(ms(static_cast<ms::rep>(std::pow(2, reExpressCount + 1))),
-                                  bind(&SegmentFetcher::reExpressInterest, this,
-                                       origInterest, reExpressCount, self));
-        break;
-      default:
-        onError(NACK_ERROR, "Nack Error");
-        break;
+      ++it;
     }
   }
 }
 
-void
-SegmentFetcher::reExpressInterest(Interest interest, uint32_t reExpressCount,
-                                  shared_ptr<SegmentFetcher> self)
+bool
+SegmentFetcher::checkAllSegmentsReceived()
 {
-  interest.refreshNonce();
-  BOOST_ASSERT(interest.hasNonce());
+  bool haveReceivedAllSegments = false;
 
-  bool isSegmentZeroExpected = true;
-  if (!interest.getName().empty()) {
-    name::Component lastComponent = interest.getName().get(-1);
-    isSegmentZeroExpected = !lastComponent.isSegment();
+  if (m_nSegments != 0 && m_nReceived >= m_nSegments) {
+    haveReceivedAllSegments = true;
+    // Verify that all segments in window have been received. If not, send Interests for missing segments.
+    for (uint64_t i = 0; i < static_cast<uint64_t>(m_nSegments); i++) {
+      if (m_receivedSegments.count(i) == 0) {
+        m_retxQueue.push(i);
+        haveReceivedAllSegments = false;
+      }
+    }
   }
 
-  m_face.expressInterest(interest,
-                         bind(&SegmentFetcher::afterSegmentReceivedCb, this, _1, _2,
-                              isSegmentZeroExpected, self),
-                         bind(&SegmentFetcher::afterNackReceivedCb, this, _1, _2,
-                              ++reExpressCount, self),
-                         bind([this] { onError(INTEREST_TIMEOUT, "Timeout"); }));
+  return haveReceivedAllSegments;
+}
+
+time::milliseconds
+SegmentFetcher::getEstimatedRto()
+{
+  // We don't want an Interest timeout greater than the maximum allowed timeout between the
+  // succesful receipt of segments
+  return std::min(m_options.maxTimeout,
+                  time::duration_cast<time::milliseconds>(m_rttEstimator.getEstimatedRto()));
 }
 
 } // namespace util
diff --git a/src/util/segment-fetcher.hpp b/src/util/segment-fetcher.hpp
index 3b81cb4..e3df0c5 100644
--- a/src/util/segment-fetcher.hpp
+++ b/src/util/segment-fetcher.hpp
@@ -1,6 +1,8 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2018, Regents of the University of California,
+ *                          Colorado State University,
+ *                          University Pierre & Marie Curie, Sorbonne University.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -17,6 +19,10 @@
  * <http://www.gnu.org/licenses/>.
  *
  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Shuo Yang
+ * @author Weiwei Liu
+ * @author Chavoosh Ghasemi
  */
 
 #ifndef NDN_UTIL_SEGMENT_FETCHER_HPP
@@ -24,16 +30,18 @@
 
 #include "../common.hpp"
 #include "../face.hpp"
-#include "../encoding/buffer-stream.hpp"
 #include "../security/v2/validator.hpp"
+#include "rtt-estimator.hpp"
 #include "scheduler.hpp"
 #include "signal.hpp"
 
+#include <queue>
+
 namespace ndn {
 namespace util {
 
 /**
- * @brief Utility class to fetch latest version of the segmented data
+ * @brief Utility class to fetch the latest version of segmented data
  *
  * SegmentFetcher assumes that the data is named `/<prefix>/<version>/<segment>`,
  * where:
@@ -61,25 +69,20 @@
  *
  *    >> Interest: `/<prefix>/<version>/<segment=(N+1))>`
  *
- * 6. Fire onCompletion callback with memory block that combines content part from all
- *    segmented objects.
+ * 6. Signal `onComplete` with a memory block that combines the content of all segments of the
+ *    object.
  *
- * If an error occurs during the fetching process, an error callback is fired
- * with a proper error code.  The following errors are possible:
+ * If an error occurs during the fetching process, `onError` is signaled with one of the error codes
+ * from `SegmentFetcher::ErrorCode`.
  *
- * - `INTEREST_TIMEOUT`: if any of the Interests times out
- * - `DATA_HAS_NO_SEGMENT`: if any of the retrieved Data packets don't have segment
- *   as a last component of the name (not counting implicit digest)
- * - `SEGMENT_VALIDATION_FAIL`: if any retrieved segment fails user-provided validation
- *
- * In order to validate individual segments, a Validator instance needs to be specified.
- * If the segment validation is successful, afterValidationSuccess callback is fired, otherwise
- * afterValidationFailure callback.
+ * A Validator instance must be specified to validate individual segments. Every time a segment has
+ * been successfully validated, `afterValidationSuccess` will be signaled. If a segment fails
+ * validation, `afterValidationFailure` will be signaled.
  *
  * Examples:
  *
  *     void
- *     afterFetchComplete(const ConstBufferPtr& data)
+ *     afterFetchComplete(ConstBufferPtr data)
  *     {
  *       ...
  *     }
@@ -91,80 +94,113 @@
  *     }
  *
  *     ...
- *     SegmentFetcher::fetch(face, Interest("/data/prefix", 30_s),
- *                           validator,
- *                           bind(&afterFetchComplete, this, _1),
- *                           bind(&afterFetchError, this, _1, _2));
+ *     auto fetcher = SegmentFetcher::start(face, Interest("/data/prefix"), validator);
+ *     fetcher->onComplete.connect(bind(&afterFetchComplete, this, _1));
+ *     fetcher->onError.connect(bind(&afterFetchError, this, _1, _2));
+ *
  *
  */
 class SegmentFetcher : noncopyable
 {
 public:
-  /**
-   * @brief Maximum number of times an interest will be reexpressed incase of NackCallback
-   */
-  static const uint32_t MAX_INTEREST_REEXPRESS;
-
+  // Deprecated: will be removed when deprecated fetch() API is removed - use start() instead
   typedef function<void (ConstBufferPtr data)> CompleteCallback;
   typedef function<void (uint32_t code, const std::string& msg)> ErrorCallback;
 
   /**
-   * @brief Error codes that can be passed to ErrorCallback
+   * @brief Error codes passed to `onError`
    */
   enum ErrorCode {
+    /// retrieval timed out because the maximum timeout between the successful receipt of segments was exceeded
     INTEREST_TIMEOUT = 1,
+    /// one of the retrieved Data packets lacked a segment number in the last Name component (excl. implicit digest)
     DATA_HAS_NO_SEGMENT = 2,
+    /// one of the retrieved segments failed user-provided validation
     SEGMENT_VALIDATION_FAIL = 3,
-    NACK_ERROR = 4
+    /// an unrecoverable Nack was received during retrieval
+    NACK_ERROR = 4,
+    /// a received FinalBlockId did not contain a segment component
+    FINALBLOCKID_NOT_SEGMENT = 5
+  };
+
+  class Options
+  {
+  public:
+    Options()
+    {
+    }
+
+    void
+    validate();
+
+  public:
+    bool useConstantCwnd = false; ///< if true, window size is kept at `initCwnd`
+    bool useConstantInterestTimeout = false; ///< if true, Interest timeout is kept at `maxTimeout`
+    time::milliseconds maxTimeout = 60_s; ///< maximum allowed time between successful receipt of segments
+    time::milliseconds interestLifetime = 4_s; ///< lifetime of sent Interests - independent of Interest timeout
+    double initCwnd = 1.0; ///< initial congestion window size
+    double initSsthresh = std::numeric_limits<double>::max(); ///< initial slow start threshold
+    double aiStep = 1.0; ///< additive increase step (in segments)
+    double mdCoef = 0.5; ///< multiplicative decrease coefficient
+    bool disableCwa = false; ///< disable Conservative Window Adaptation
+    bool resetCwndToInit = false; ///< reduce cwnd to initCwnd when loss event occurs
+    bool ignoreCongMarks = false; ///< disable window decrease after congestion mark received
+    RttEstimator::Options rttOptions; ///< options for RTT estimator
   };
 
   /**
    * @brief Initiates segment fetching
    *
    * @param face         Reference to the Face that should be used to fetch data
-   * @param baseInterest An Interest for the initial segment of requested data.
+   * @param baseInterest Interest for the initial segment of requested data.
    *                     This interest may include a custom InterestLifetime and selectors that will
    *                     propagate to all subsequent Interests. The only exception is that the
    *                     initial Interest will be forced to include the "ChildSelector=1" and
-   *                     "MustBeFresh=true" selectors, which will be turned off in subsequent
+   *                     "MustBeFresh=true" selectors, which will not be included in subsequent
    *                     Interests.
-   * @param validator    Reference to the Validator that should be used to validate data. Caller
-   *                     must ensure validator is valid until either onComplete or onError has been
-   *                     signaled.
+   * @param validator    Reference to the Validator the fetcher will use to validate data.
+   *                     The caller must ensure the validator is valid until either `onComplete` or
+   *                     `onError` has been signaled.
+   * @param options      Options controlling the transfer
    *
-   * @return A shared_ptr to the constructed SegmentFetcher
+   * @return             A shared_ptr to the constructed SegmentFetcher.
+   *                     This shared_ptr is kept internally for the lifetime of the transfer.
+   *                     Therefore, it does not need to be saved and is provided here so that the
+   *                     SegmentFetcher's signals can be connected to.
    *
    * Transfer completion, failure, and progress are indicated via signals.
    */
-  static
-  shared_ptr<SegmentFetcher>
+  static shared_ptr<SegmentFetcher>
   start(Face& face,
         const Interest& baseInterest,
-        security::v2::Validator& validator);
+        security::v2::Validator& validator,
+        const Options& options = Options());
 
   /**
    * @brief Initiates segment fetching
    *
    * @deprecated Use @c start
    *
-   * @param face          Reference to the Face that should be used to fetch data
-   * @param baseInterest  An Interest for the initial segment of requested data.
-   *                      This interest may include custom InterestLifetime and selectors that
-   *                      will propagate to all subsequent Interests.  The only exception is that
-   *                      the initial Interest will be forced to include "ChildSelector=rightmost" and
-   *                      "MustBeFresh=true" selectors, which will be turned off in subsequent
-   *                      Interests.
-   * @param validator     Reference to the Validator that should be used to validate data. Caller
-   *                      must ensure validator is valid until either completeCallback or errorCallback
-   *                      is invoked.
+   * @param face             Reference to the Face that should be used to fetch data
+   * @param baseInterest     An Interest for the initial segment of requested data.
+   *                         This interest may include custom InterestLifetime and selectors that
+   *                         will propagate to all subsequent Interests.  The only exception is that
+   *                         the initial Interest will be forced to include
+   *                         "ChildSelector=rightmost" and "MustBeFresh=true" selectors, which will
+   *                         be turned off in subsequent Interests.
+   * @param validator        Reference to the Validator that should be used to validate data. Caller
+   *                         must ensure validator is valid until either completeCallback or
+   *                         errorCallback is invoked.
+   * @param completeCallback Callback to be fired when all segments are fetched
+   * @param errorCallback    Callback to be fired when an error occurs (@see Errors)
    *
-   * @param completeCallback    Callback to be fired when all segments are fetched
-   * @param errorCallback       Callback to be fired when an error occurs (@see Errors)
-   * @return A shared_ptr to the constructed SegmentFetcher
+   * @return                 A shared_ptr to the constructed SegmentFetcher.
+   *                         This shared_ptr is kept internally for the lifetime of the transfer.
+   *                         Therefore, it does not need to be saved and is provided here so that
+   *                         the SegmentFetcher's signals can be connected to.
    */
   [[deprecated("use SegmentFetcher::start instead")]]
-  static
-  shared_ptr<SegmentFetcher>
+  static shared_ptr<SegmentFetcher>
   fetch(Face& face,
         const Interest& baseInterest,
         security::v2::Validator& validator,
@@ -176,22 +212,25 @@
    *
    * @deprecated Use @c start
    *
-   * @param face          Reference to the Face that should be used to fetch data
-   * @param baseInterest  An Interest for the initial segment of requested data.
-   *                      This interest may include custom InterestLifetime and selectors that
-   *                      will propagate to all subsequent Interests.  The only exception is that
-   *                      the initial Interest will be forced to include "ChildSelector=1" and
-   *                      "MustBeFresh=true" selectors, which will be turned off in subsequent
-   *                      Interests.
-   * @param validator     A shared_ptr to the Validator that should be used to validate data.
+   * @param face             Reference to the Face that should be used to fetch data
+   * @param baseInterest     An Interest for the initial segment of requested data.
+   *                         This interest may include custom InterestLifetime and selectors that
+   *                         will propagate to all subsequent Interests.  The only exception is that
+   *                         the initial Interest will be forced to include "ChildSelector=1" and
+   *                         "MustBeFresh=true" selectors, which will be turned off in subsequent
+   *                         Interests.
+   * @param validator        A shared_ptr to the Validator that should be used to validate data.
    *
-   * @param completeCallback    Callback to be fired when all segments are fetched
-   * @param errorCallback       Callback to be fired when an error occurs (@see Errors)
-   * @return A shared_ptr to the constructed SegmentFetcher
+   * @param completeCallback Callback to be fired when all segments are fetched
+   * @param errorCallback    Callback to be fired when an error occurs (@see Errors)
+   *
+   * @return                 A shared_ptr to the constructed SegmentFetcher.
+   *                         This shared_ptr is kept internally for the lifetime of the transfer.
+   *                         Therefore, it does not need to be saved and is provided here so that
+   *                         the SegmentFetcher's signals can be connected to.
    */
   [[deprecated("use SegmentFetcher::start instead")]]
-  static
-  shared_ptr<SegmentFetcher>
+  static shared_ptr<SegmentFetcher>
   fetch(Face& face,
         const Interest& baseInterest,
         shared_ptr<security::v2::Validator> validator,
@@ -199,35 +238,71 @@
         const ErrorCallback& errorCallback);
 
 private:
-  SegmentFetcher(Face& face, security::v2::Validator& validator);
+  class PendingSegment;
+
+  SegmentFetcher(Face& face, security::v2::Validator& validator, const Options& options);
 
   void
-  fetchFirstSegment(const Interest& baseInterest, shared_ptr<SegmentFetcher> self);
+  fetchFirstSegment(const Interest& baseInterest,
+                    bool isRetransmission,
+                    shared_ptr<SegmentFetcher> self);
 
   void
-  fetchNextSegment(const Interest& origInterest, const Name& dataName, uint64_t segmentNo,
-                   shared_ptr<SegmentFetcher> self);
+  fetchSegmentsInWindow(const Interest& origInterest, shared_ptr<SegmentFetcher> self);
 
   void
   afterSegmentReceivedCb(const Interest& origInterest,
-                         const Data& data, bool isSegmentZeroExpected,
+                         const Data& data,
                          shared_ptr<SegmentFetcher> self);
   void
   afterValidationSuccess(const Data& data,
-                         bool isSegmentZeroExpected,
                          const Interest& origInterest,
+                         std::map<uint64_t, PendingSegment>::iterator pendingSegmentIt,
                          shared_ptr<SegmentFetcher> self);
 
   void
-  afterValidationFailure(const Data& data, const security::v2::ValidationError& error);
+  afterValidationFailure(const Data& data,
+                         const security::v2::ValidationError& error,
+                         shared_ptr<SegmentFetcher> self);
 
   void
-  afterNackReceivedCb(const Interest& origInterest, const lp::Nack& nack,
-                      uint32_t reExpressCount, shared_ptr<SegmentFetcher> self);
+  afterNackReceivedCb(const Interest& origInterest,
+                      const lp::Nack& nack,
+                      shared_ptr<SegmentFetcher> self);
 
   void
-  reExpressInterest(Interest interest, uint32_t reExpressCount,
-                    shared_ptr<SegmentFetcher> self);
+  afterTimeoutCb(const Interest& origInterest,
+                 shared_ptr<SegmentFetcher> self);
+
+  void
+  afterNackOrTimeout(const Interest& origInterest,
+                     shared_ptr<SegmentFetcher> self);
+
+  void
+  finalizeFetch(shared_ptr<SegmentFetcher> self);
+
+  void
+  windowIncrease();
+
+  void
+  windowDecrease();
+
+  void
+  signalError(uint32_t code, const std::string& msg);
+
+  void
+  updateRetransmittedSegment(uint64_t segmentNum,
+                             const PendingInterestId* pendingInterest,
+                             scheduler::EventId timeoutEvent);
+
+  void
+  cancelExcessInFlightSegments();
+
+  bool
+  checkAllSegmentsReceived();
+
+  time::milliseconds
+  getEstimatedRto();
 
 public:
   /**
@@ -252,12 +327,58 @@
    */
   Signal<SegmentFetcher, Data> afterSegmentValidated;
 
+  /**
+   * @brief Emits whenever an Interest for a data segment is nacked
+   */
+  Signal<SegmentFetcher> afterSegmentNacked;
+
+  /**
+   * @brief Emits whenever an Interest for a data segment times out
+   */
+  Signal<SegmentFetcher> afterSegmentTimedOut;
+
 private:
+  enum class SegmentState {
+    FirstInterest, ///< the first Interest for this segment has been sent
+    InRetxQueue,   ///< the segment is awaiting Interest retransmission
+    Retransmitted, ///< one or more retransmitted Interests have been sent for this segment
+  };
+
+  class PendingSegment
+  {
+  public:
+    SegmentState state;
+    time::steady_clock::TimePoint sendTime;
+    const PendingInterestId* id;
+    scheduler::EventId timeoutEvent;
+  };
+
+NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  static constexpr double MIN_SSTHRESH = 2.0;
+
+  Options m_options;
   Face& m_face;
   Scheduler m_scheduler;
   security::v2::Validator& m_validator;
+  RttEstimator m_rttEstimator;
+  time::milliseconds m_timeout;
 
-  OBufferStream m_buffer;
+  time::steady_clock::TimePoint m_timeLastSegmentReceived;
+  std::queue<uint64_t> m_retxQueue;
+  Name m_versionedDataName;
+  uint64_t m_nextSegmentNum;
+  double m_cwnd;
+  double m_ssthresh;
+  int64_t m_nSegmentsInFlight;
+  int64_t m_nSegments;
+  uint64_t m_highInterest;
+  uint64_t m_highData;
+  uint64_t m_recPoint;
+  int64_t m_nReceived;
+  int64_t m_nBytesReceived;
+
+  std::map<uint64_t, Buffer> m_receivedSegments;
+  std::map<uint64_t, PendingSegment> m_pendingSegments;
 };
 
 } // namespace util
diff --git a/tests/unit-tests/util/segment-fetcher.t.cpp b/tests/unit-tests/util/segment-fetcher.t.cpp
index d8f2bf5..c804f70 100644
--- a/tests/unit-tests/util/segment-fetcher.t.cpp
+++ b/tests/unit-tests/util/segment-fetcher.t.cpp
@@ -30,15 +30,14 @@
 #include "make-interest-data.hpp"
 #include "../identity-management-time-fixture.hpp"
 
+#include <set>
+
 namespace ndn {
 namespace util {
 namespace tests {
 
 using namespace ndn::tests;
 
-BOOST_AUTO_TEST_SUITE(Util)
-BOOST_AUTO_TEST_SUITE(TestSegmentFetcher)
-
 class Fixture : public IdentityManagementTimeFixture
 {
 public:
@@ -69,11 +68,11 @@
   }
 
   void
-  onComplete(const ConstBufferPtr& data)
+  onComplete(ConstBufferPtr data)
   {
     ++nCompletions;
     dataSize = data->size();
-    dataString = std::string(data->get<char>());
+    dataBuf = data;
   }
 
   void
@@ -92,22 +91,88 @@
     fetcher->onError.connect(bind(&Fixture::onError, this, _1));
   }
 
+  void
+  onInterest(const Interest& interest)
+  {
+    if (interest.getName().get(-1).isSegment()) {
+      if (segmentsToDropOrNack.size() > 0 &&
+          interest.getName().get(-1).toSegment() == segmentsToDropOrNack.front()) {
+        segmentsToDropOrNack.pop();
+        if (sendNackInsteadOfDropping) {
+          lp::Nack nack = makeNack(interest, nackReason);
+          face.receive(nack);
+        }
+        return;
+      }
+
+      auto data = makeDataSegment("/hello/world/version0",
+                                  interest.getName().get(-1).toSegment(),
+                                  interest.getName().get(-1).toSegment() == nSegments - 1);
+      face.receive(*data);
+
+      uniqSegmentsSent.insert(interest.getName().get(-1).toSegment());
+      if (uniqSegmentsSent.size() == nSegments) {
+        io.stop();
+      }
+    }
+    else {
+      if (segmentsToDropOrNack.size() > 0 &&
+          segmentsToDropOrNack.front() == 0) {
+        segmentsToDropOrNack.pop();
+        if (sendNackInsteadOfDropping) {
+          lp::Nack nack = makeNack(interest, nackReason);
+          face.receive(nack);
+        }
+        return;
+      }
+
+      auto data = makeDataSegment("/hello/world/version0", defaultSegmentToSend, nSegments == 1);
+      face.receive(*data);
+      uniqSegmentsSent.insert(defaultSegmentToSend);
+    }
+  }
+
 public:
   DummyClientFace face;
+  std::set<uint64_t> uniqSegmentsSent;
 
   int nErrors = 0;
   uint32_t lastError = 0;
   int nCompletions = 0;
   size_t dataSize = 0;
-  std::string dataString;
+  ConstBufferPtr dataBuf;
+
+  // number of segments in fetched object
+  uint64_t nSegments = 0;
+  std::queue<uint64_t> segmentsToDropOrNack;
+  bool sendNackInsteadOfDropping = false;
+  lp::NackReason nackReason = lp::NackReason::NONE;
+  // segment that is sent in response to an Interest w/o a segment component in its name
+  uint64_t defaultSegmentToSend = 0;
 };
 
-BOOST_FIXTURE_TEST_CASE(Timeout, Fixture)
+BOOST_AUTO_TEST_SUITE(Util)
+BOOST_FIXTURE_TEST_SUITE(TestSegmentFetcher, Fixture)
+
+BOOST_AUTO_TEST_CASE(InvalidOptions)
+{
+  SegmentFetcher::Options options;
+  options.mdCoef = 1.5;
+  DummyValidator acceptValidator;
+  BOOST_CHECK_THROW(SegmentFetcher::start(face, Interest("/hello/world"), acceptValidator, options),
+                    std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE(ExceedMaxTimeout)
 {
   DummyValidator acceptValidator;
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world", 100_ms),
-                                                             acceptValidator);
+  size_t nAfterSegmentTimedOut = 0;
+  SegmentFetcher::Options options;
+  options.maxTimeout = 100_ms;
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator, options);
   connectSignals(fetcher);
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
 
   advanceClocks(1_ms);
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
@@ -121,46 +186,338 @@
   BOOST_CHECK_EQUAL(nErrors, 0);
   BOOST_CHECK_EQUAL(nCompletions, 0);
   BOOST_CHECK_EQUAL(face.sentData.size(), 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
 
   advanceClocks(1_ms, 2);
   BOOST_CHECK_EQUAL(nErrors, 1);
   BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::INTEREST_TIMEOUT));
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
   BOOST_CHECK_EQUAL(face.sentData.size(), 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 1);
 }
 
-BOOST_FIXTURE_TEST_CASE(Basic, Fixture)
+BOOST_AUTO_TEST_CASE(BasicSingleSegment)
 {
   DummyValidator acceptValidator;
   size_t nAfterSegmentReceived = 0;
   size_t nAfterSegmentValidated = 0;
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world", 1000_s),
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
                                                              acceptValidator);
   connectSignals(fetcher);
   fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
   fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
 
   advanceClocks(10_ms);
 
-  for (uint64_t i = 0; i < 400; i++) {
-    advanceClocks(10_ms);
-    face.receive(*makeDataSegment("/hello/world/version0", i, false));
-  }
-  advanceClocks(10_ms);
-  face.receive(*makeDataSegment("/hello/world/version0", 400, true));
+  face.receive(*makeDataSegment("/hello/world/version0", 0, true));
 
   advanceClocks(10_ms);
 
   BOOST_CHECK_EQUAL(nErrors, 0);
   BOOST_CHECK_EQUAL(nCompletions, 1);
-  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
-  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 1);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 1);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
 }
 
-BOOST_FIXTURE_TEST_CASE(MissingSegmentNum, Fixture)
+BOOST_AUTO_TEST_CASE(ConstantCwnd)
+{
+  SegmentFetcher::Options options;
+  options.useConstantCwnd = true;
+  DummyValidator acceptValidator;
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator, options);
+  connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
+
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
+
+  face.receive(*makeDataSegment("/hello/world/version0", 0, false));
+
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2);
+  BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 1);
+  face.receive(*makeDataSegment("/hello/world/version0", 1, false));
+
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 3);
+  BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 2);
+  face.receive(*makeDataSegment("/hello/world/version0", 2, false));
+
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 4);
+  BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 3);
+  face.receive(*makeDataSegment("/hello/world/version0", 3, false));
+
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 5);
+  BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 4);
+  nackLastInterest(lp::NackReason::CONGESTION);
+
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 6);
+  BOOST_CHECK_EQUAL(face.sentInterests.back().getName().get(-1).toSegment(), 4);
+  face.receive(*makeDataSegment("/hello/world/version0", 4, true));
+
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 1);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 5);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 5);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 1);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+}
+
+BOOST_AUTO_TEST_CASE(BasicMultipleSegments)
 {
   DummyValidator acceptValidator;
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world", 1000_s),
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  nSegments = 401;
+  sendNackInsteadOfDropping = false;
+  face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
+
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator);
+  connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
+
+  face.processEvents(1_s);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 1);
+  BOOST_CHECK_EQUAL(dataSize, 14 * 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
+}
+
+BOOST_AUTO_TEST_CASE(FirstSegmentNotZero)
+{
+  DummyValidator acceptValidator;
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  nSegments = 401;
+  sendNackInsteadOfDropping = false;
+  defaultSegmentToSend = 47;
+  face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
+
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator);
+  connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
+
+  face.processEvents(1_s);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 1);
+  BOOST_CHECK_EQUAL(dataSize, 14 * 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
+}
+
+BOOST_AUTO_TEST_CASE(WindowSize)
+{
+  DummyValidator acceptValidator;
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator);
+  connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+
+  advanceClocks(10_ms); // T+10ms
+
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
+  BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, 1.0);
+  BOOST_CHECK_EQUAL(fetcher->m_ssthresh, std::numeric_limits<double>::max());
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, 1);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_highInterest, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_highData, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nReceived, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 0);
+  BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), 1);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
+
+  double oldCwnd = fetcher->m_cwnd;
+  double oldSsthresh = fetcher->m_ssthresh;
+  uint64_t oldNextSegmentNum = fetcher->m_nextSegmentNum;
+
+  face.receive(*makeDataSegment("/hello/world/version0", 0, false));
+
+  advanceClocks(10_ms); //T+20ms
+
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
+  BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
+  BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
+  // +2 below because m_nextSegmentNum will be incremented in the receive callback if segment 0 is
+  // the first received
+  BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum + fetcher->m_options.aiStep + 2);
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd + fetcher->m_options.aiStep);
+  BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldSsthresh);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, oldCwnd + fetcher->m_options.aiStep);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 14);
+  BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_highData, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 1);
+  BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), fetcher->m_cwnd);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 1 + fetcher->m_cwnd);
+
+  oldCwnd = fetcher->m_cwnd;
+  oldNextSegmentNum = fetcher->m_nextSegmentNum;
+
+  face.receive(*makeDataSegment("/hello/world/version0", 2, false));
+
+  advanceClocks(10_ms); //T+30ms
+
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
+  BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
+  BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
+  BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum + fetcher->m_options.aiStep + 1);
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd + fetcher->m_options.aiStep);
+  BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldSsthresh);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, fetcher->m_cwnd);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 28);
+  BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
+  BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 2);
+  BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), fetcher->m_cwnd);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 2 + fetcher->m_cwnd);
+
+  oldCwnd = fetcher->m_cwnd;
+  oldNextSegmentNum = fetcher->m_nextSegmentNum;
+
+  face.receive(*makeDataSegment("/hello/world/version0", 1, false));
+
+  advanceClocks(10_ms); //T+40ms
+
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 10_ms);
+  BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 0);
+  BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
+  BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum + fetcher->m_options.aiStep + 1);
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd + fetcher->m_options.aiStep);
+  BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldSsthresh);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, fetcher->m_cwnd);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 42);
+  BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
+  BOOST_CHECK_EQUAL(fetcher->m_recPoint, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 3);
+  BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), fetcher->m_cwnd);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 3 + fetcher->m_cwnd);
+
+  oldCwnd = fetcher->m_cwnd;
+  oldSsthresh = fetcher->m_ssthresh;
+  oldNextSegmentNum = fetcher->m_nextSegmentNum;
+  size_t oldSentInterestsSize = face.sentInterests.size();
+
+  nackLastInterest(lp::NackReason::CONGESTION); //T+50ms
+
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 20_ms);
+  BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 1);
+  BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
+  BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum);
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd / 2.0);
+  BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldCwnd / 2.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, oldCwnd - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 42);
+  BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
+  BOOST_CHECK_EQUAL(fetcher->m_recPoint, fetcher->m_nextSegmentNum - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 3);
+  // The Nacked segment will remain in pendingSegments, so the size of the structure doesn't change
+  BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), oldCwnd);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), oldSentInterestsSize);
+
+  advanceClocks(10_ms); //T+60ms
+
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 30_ms);
+  BOOST_CHECK_EQUAL(fetcher->m_retxQueue.size(), 1);
+  BOOST_CHECK_EQUAL(fetcher->m_versionedDataName, "/hello/world/version0");
+  BOOST_CHECK_EQUAL(fetcher->m_nextSegmentNum, oldNextSegmentNum);
+  BOOST_CHECK_EQUAL(fetcher->m_cwnd, oldCwnd / 2.0);
+  BOOST_CHECK_EQUAL(fetcher->m_ssthresh, oldCwnd / 2.0);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegmentsInFlight, oldCwnd - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_nSegments, 0);
+  BOOST_CHECK_EQUAL(fetcher->m_nBytesReceived, 42);
+  BOOST_CHECK_EQUAL(fetcher->m_highInterest, fetcher->m_nextSegmentNum - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_highData, 2);
+  BOOST_CHECK_EQUAL(fetcher->m_recPoint, fetcher->m_nextSegmentNum - 1);
+  BOOST_CHECK_EQUAL(fetcher->m_receivedSegments.size(), 3);
+  BOOST_CHECK_EQUAL(fetcher->m_pendingSegments.size(), oldCwnd);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), oldSentInterestsSize);
+
+  // Properly end test case
+  lp::Nack nack = makeNack(face.sentInterests[face.sentInterests.size() - 2], lp::NackReason::NO_ROUTE);
+  face.receive(nack);
+  advanceClocks(10_ms); //T+70ms
+
+  BOOST_CHECK_EQUAL(nErrors, 1);
+  BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::NACK_ERROR));
+  BOOST_CHECK_EQUAL(nCompletions, 0);
+}
+
+BOOST_AUTO_TEST_CASE(MissingSegmentNum)
+{
+  DummyValidator acceptValidator;
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
                                                              acceptValidator);
   connectSignals(fetcher);
 
@@ -178,107 +535,165 @@
   BOOST_CHECK_EQUAL(nCompletions, 0);
 }
 
-BOOST_FIXTURE_TEST_CASE(DuplicateNack, Fixture)
+BOOST_AUTO_TEST_CASE(MoreSegmentsThanNSegments)
 {
   DummyValidator acceptValidator;
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world", 1000_s),
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
                                                              acceptValidator);
   connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
+
   advanceClocks(10_ms);
 
-  // receive nack for the original interest
-  nackLastInterest(lp::NackReason::DUPLICATE);
-
-  // receive nack due to Duplication for the reexpressed interests
-  for (uint32_t i = 1; i <= SegmentFetcher::MAX_INTEREST_REEXPRESS; ++i) {
-    nackLastInterest(lp::NackReason::DUPLICATE);
-  }
-
-  BOOST_CHECK_EQUAL(face.sentInterests.size(), (SegmentFetcher::MAX_INTEREST_REEXPRESS + 1));
-  BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::NACK_ERROR));
-}
-
-BOOST_FIXTURE_TEST_CASE(CongestionNack, Fixture)
-{
-  DummyValidator acceptValidator;
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world", 1000_s),
-                                                             acceptValidator);
-  connectSignals(fetcher);
+  face.receive(*makeDataSegment("/hello/world/version0", 0, false));
   advanceClocks(10_ms);
 
-  // receive nack for the original interest
-  nackLastInterest(lp::NackReason::CONGESTION);
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 0);
 
-  // receive nack due to Congestion for the reexpressed interests
-  for (uint32_t i = 1; i <= SegmentFetcher::MAX_INTEREST_REEXPRESS; ++i) {
-    nackLastInterest(lp::NackReason::CONGESTION);
-  }
-
-  BOOST_CHECK_EQUAL(face.sentInterests.size(), (SegmentFetcher::MAX_INTEREST_REEXPRESS + 1));
-  BOOST_CHECK_EQUAL(lastError, static_cast<uint32_t>(SegmentFetcher::NACK_ERROR));
-}
-
-BOOST_FIXTURE_TEST_CASE(SegmentZero, Fixture)
-{
-  int nNacks = 2;
-
-  ndn::Name interestName("ndn:/A");
-  DummyValidator acceptValidator;
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest(interestName),
-                                                             acceptValidator);
-  connectSignals(fetcher);
-
-  advanceClocks(1000_ms);
-
-  for (uint64_t segmentNo = 0; segmentNo <= 3; segmentNo++) {
-    if (segmentNo == 1) {
-      while (nNacks--) {
-        nackLastInterest(lp::NackReason::CONGESTION);
-        advanceClocks(10_ms);
-      }
-    }
-
-    auto data = makeDataSegment(interestName, segmentNo, segmentNo == 3);
-    face.receive(*data);
-    advanceClocks(10_ms);
-  }
-
-  // Total number of sent interests should be 6: one interest for segment zero and segment one each,
-  // two re-expressed interests for segment one after getting nack twice, and two interests for
-  // segment two and three
-  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 6);
-
-  BOOST_CHECK_EQUAL(face.sentInterests[0].getName(), ndn::Name("ndn:/A"));
-  BOOST_CHECK_EQUAL(face.sentInterests[1].getName(), ndn::Name("ndn:/A/%00%01"));
-  BOOST_CHECK_EQUAL(face.sentInterests[2].getName(), ndn::Name("ndn:/A/%00%01"));
-  BOOST_CHECK_EQUAL(face.sentInterests[3].getName(), ndn::Name("ndn:/A/%00%01"));
-  BOOST_CHECK_EQUAL(face.sentInterests[4].getName(), ndn::Name("ndn:/A/%00%02"));
-  BOOST_CHECK_EQUAL(face.sentInterests[5].getName(), ndn::Name("ndn:/A/%00%03"));
-}
-
-BOOST_FIXTURE_TEST_CASE(SingleSegment, Fixture)
-{
-  DummyValidator acceptValidator;
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("ndn:/", 1000_s),
-                                                             acceptValidator);
-  connectSignals(fetcher);
+  face.receive(*makeDataSegment("/hello/world/version0", 1, false));
   advanceClocks(10_ms);
-  nackLastInterest(lp::NackReason::DUPLICATE);
-  face.receive(*makeDataSegment("/hello/world", 0, true));
 
-  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 2);
-  BOOST_CHECK_EQUAL(face.sentInterests[0].getName(), ndn::Name("ndn:/"));
-  BOOST_CHECK_EQUAL(face.sentInterests[1].getName(), ndn::Name("ndn:/"));
-  BOOST_REQUIRE_EQUAL(nCompletions, 1);
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 0);
+
+  face.receive(*makeDataSegment("/hello/world/version0", 2, false));
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 0);
+
+  face.receive(*makeDataSegment("/hello/world/version0", 3, false));
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 0);
+
+  auto data4 = makeDataSegment("/hello/world/version0", 4, false);
+  data4->setFinalBlock(name::Component::fromSegment(2));
+  face.receive(*data4);
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 1);
+  BOOST_CHECK_EQUAL(dataSize, 14 * 3);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 5);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 5);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
 }
 
-BOOST_FIXTURE_TEST_CASE(ValidationFailure, Fixture)
+BOOST_AUTO_TEST_CASE(DuplicateNack)
+{
+  DummyValidator acceptValidator;
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  nSegments = 401;
+  segmentsToDropOrNack.push(0);
+  segmentsToDropOrNack.push(200);
+  sendNackInsteadOfDropping = true;
+  nackReason = lp::NackReason::DUPLICATE;
+  face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
+
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator);
+  connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
+
+  face.processEvents(1_s);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 1);
+  BOOST_CHECK_EQUAL(dataSize, 14 * 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 2);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
+}
+
+BOOST_AUTO_TEST_CASE(CongestionNack)
+{
+  DummyValidator acceptValidator;
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  nSegments = 401;
+  segmentsToDropOrNack.push(0);
+  segmentsToDropOrNack.push(200);
+  sendNackInsteadOfDropping = true;
+  nackReason = lp::NackReason::CONGESTION;
+  face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
+
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator);
+  connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
+
+  face.processEvents(1_s);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 1);
+  BOOST_CHECK_EQUAL(dataSize, 14 * 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 401);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 2);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
+}
+
+BOOST_AUTO_TEST_CASE(OtherNackReason)
+{
+  DummyValidator acceptValidator;
+  size_t nAfterSegmentReceived = 0;
+  size_t nAfterSegmentValidated = 0;
+  size_t nAfterSegmentNacked = 0;
+  size_t nAfterSegmentTimedOut = 0;
+  segmentsToDropOrNack.push(0);
+  sendNackInsteadOfDropping = true;
+  nackReason = lp::NackReason::NO_ROUTE;
+  face.onSendInterest.connect(bind(&Fixture::onInterest, this, _1));
+
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
+                                                             acceptValidator);
+  connectSignals(fetcher);
+  fetcher->afterSegmentReceived.connect(bind([&nAfterSegmentReceived] { ++nAfterSegmentReceived; }));
+  fetcher->afterSegmentValidated.connect(bind([&nAfterSegmentValidated] { ++nAfterSegmentValidated; }));
+  fetcher->afterSegmentNacked.connect(bind([&nAfterSegmentNacked] { ++nAfterSegmentNacked; }));
+  fetcher->afterSegmentTimedOut.connect(bind([&nAfterSegmentTimedOut] { ++nAfterSegmentTimedOut; }));
+
+  face.processEvents(1_s);
+
+  BOOST_CHECK_EQUAL(nErrors, 1);
+  BOOST_CHECK_EQUAL(nCompletions, 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentReceived, 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentValidated, 0);
+  BOOST_CHECK_EQUAL(nAfterSegmentNacked, 1);
+  BOOST_CHECK_EQUAL(nAfterSegmentTimedOut, 0);
+  BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(ValidationFailure)
 {
   DummyValidator validator;
   validator.getPolicy().setResultCallback([] (const Name& name) {
       return name.at(-1).toSegment() % 2 == 0;
     });
-  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world", 1000_s),
+  shared_ptr<SegmentFetcher> fetcher = SegmentFetcher::start(face, Interest("/hello/world"),
                                                              validator);
   connectSignals(fetcher);
 
@@ -297,14 +712,19 @@
 
   advanceClocks(10_ms, 10);
 
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 100_ms);
+
   face.receive(*data1);
 
   advanceClocks(10_ms, 10);
 
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 100_ms);
+
   face.receive(*data2);
 
   advanceClocks(10_ms, 10);
 
+  BOOST_CHECK_EQUAL(fetcher->m_timeLastSegmentReceived, time::steady_clock::now() - 200_ms);
   BOOST_CHECK_EQUAL(nRecvSegments, 2);
   BOOST_CHECK_EQUAL(nValidatedSegments, 1);
   BOOST_CHECK_EQUAL(nErrors, 1);
@@ -312,7 +732,7 @@
 
 // Tests deprecated `fetch` API that uses callbacks instead of signals. This test case will be
 // removed when this API is removed.
-BOOST_FIXTURE_TEST_CASE(DeprecatedFetch, Fixture)
+BOOST_AUTO_TEST_CASE(DeprecatedFetch)
 {
   DummyValidator acceptValidator;
   SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
@@ -330,11 +750,11 @@
 
   BOOST_CHECK_EQUAL(dataSize, 14);
 
-  const uint8_t buffer[] = "Hello, world!";
-  std::string bufferString(reinterpret_cast<const char*>(buffer));
+  const uint8_t buffer[] = "Hello, world!\0";
+  BOOST_REQUIRE_EQUAL(dataBuf->size(), 14);
+  BOOST_CHECK_EQUAL_COLLECTIONS(dataBuf->begin(), dataBuf->end(), buffer, buffer + 14);
 
-  BOOST_CHECK_EQUAL(dataString, bufferString);
-
+  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
   BOOST_CHECK_EQUAL(face.sentData.size(), 0);
 
@@ -342,11 +762,65 @@
   BOOST_CHECK_EQUAL(interest.getName(), "/hello/world");
   BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
   BOOST_CHECK_EQUAL(interest.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(interest.getInterestLifetime(), 1000_s);
+}
+
+// Tests deprecated `fetch` API that uses callbacks instead of signals. This test case will be
+// removed when this API is removed.
+BOOST_AUTO_TEST_CASE(DeprecatedFetchMultipleSegments)
+{
+  DummyValidator acceptValidator;
+  SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
+                        acceptValidator,
+                        bind(&Fixture::onComplete, this, _1),
+                        bind(&Fixture::onError, this, _1));
+
+  advanceClocks(10_ms);
+
+  face.receive(*makeDataSegment("/hello/world/version0", 0, false));
+  advanceClocks(10_ms);
+
+  face.receive(*makeDataSegment("/hello/world/version0", 1, false));
+  advanceClocks(10_ms);
+
+  face.receive(*makeDataSegment("/hello/world/version0", 2, true));
+  advanceClocks(10_ms);
+
+  BOOST_CHECK_EQUAL(nErrors, 0);
+  BOOST_CHECK_EQUAL(nCompletions, 1);
+
+  BOOST_CHECK_EQUAL(dataSize, 14 * 3);
+
+  const uint8_t buffer[] = "Hello, world!\0Hello, world!\0Hello, world!\0";
+  BOOST_REQUIRE_EQUAL(dataBuf->size(), 14 * 3);
+  BOOST_CHECK_EQUAL_COLLECTIONS(dataBuf->begin(), dataBuf->end(), buffer, buffer + (14 * 3));
+
+  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
+  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 3);
+  BOOST_CHECK_EQUAL(face.sentData.size(), 0);
+
+  const Interest& interest0 = face.sentInterests[0];
+  BOOST_CHECK_EQUAL(interest0.getName(), "/hello/world");
+  BOOST_CHECK_EQUAL(interest0.getMustBeFresh(), true);
+  BOOST_CHECK_EQUAL(interest0.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(interest0.getInterestLifetime(), 1000_s);
+
+  const Interest& interest1 = face.sentInterests[1];
+  BOOST_CHECK_EQUAL(interest1.getName(), "/hello/world/version0/%00%01");
+  BOOST_CHECK_EQUAL(interest1.getMustBeFresh(), false);
+  BOOST_CHECK_EQUAL(interest1.getChildSelector(), 0);
+  BOOST_CHECK_EQUAL(interest1.getInterestLifetime(), 1000_s);
+
+  const Interest& interest2 = face.sentInterests[2];
+  BOOST_CHECK_EQUAL(interest2.getName(), "/hello/world/version0/%00%02");
+  BOOST_CHECK_EQUAL(interest2.getMustBeFresh(), false);
+  BOOST_CHECK_EQUAL(interest2.getChildSelector(), 0);
+  BOOST_CHECK_EQUAL(interest2.getInterestLifetime(), 1000_s);
 }
 
 // Tests deprecated `fetch` API that uses callbacks instead of signals (with an accepting shared_ptr
 // Validator). This test case will be removed when this API is removed.
-BOOST_FIXTURE_TEST_CASE(DeprecatedFetchSharedPtrComplete, Fixture)
+BOOST_AUTO_TEST_CASE(DeprecatedFetchSharedPtrComplete)
 {
   auto acceptValidator = make_shared<DummyValidator>(true);
   SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
@@ -372,11 +846,11 @@
 
   BOOST_CHECK_EQUAL(dataSize, 14);
 
-  const uint8_t buffer[] = "Hello, world!";
-  std::string bufferString(reinterpret_cast<const char*>(buffer));
+  const uint8_t buffer[] = "Hello, world!\0";
+  BOOST_REQUIRE_EQUAL(dataBuf->size(), 14);
+  BOOST_CHECK_EQUAL_COLLECTIONS(dataBuf->begin(), dataBuf->end(), buffer, buffer + 14);
 
-  BOOST_CHECK_EQUAL(dataString, bufferString);
-
+  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
   BOOST_CHECK_EQUAL(face.sentData.size(), 0);
 
@@ -384,11 +858,12 @@
   BOOST_CHECK_EQUAL(interest.getName(), "/hello/world");
   BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
   BOOST_CHECK_EQUAL(interest.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(interest.getInterestLifetime(), 1000_s);
 }
 
 // Tests deprecated `fetch` API that uses callbacks instead of signals (with a rejecting shared_ptr
 // Validator). This test case will be removed when this API is removed.
-BOOST_FIXTURE_TEST_CASE(DeprecatedFetchSharedPtrError, Fixture)
+BOOST_AUTO_TEST_CASE(DeprecatedFetchSharedPtrError)
 {
   auto acceptValidator = make_shared<DummyValidator>(false);
   SegmentFetcher::fetch(face, Interest("/hello/world", 1000_s),
@@ -412,6 +887,7 @@
   BOOST_CHECK_EQUAL(nErrors, 1);
   BOOST_CHECK_EQUAL(nCompletions, 0);
 
+  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
   BOOST_CHECK_EQUAL(face.sentData.size(), 0);
 
@@ -419,6 +895,7 @@
   BOOST_CHECK_EQUAL(interest.getName(), "/hello/world");
   BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
   BOOST_CHECK_EQUAL(interest.getChildSelector(), 1);
+  BOOST_CHECK_EQUAL(interest.getInterestLifetime(), 1000_s);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestSegmentFetcher
