diff --git a/src/torrent-manager.cpp b/src/torrent-manager.cpp
index c06db40..4a0eaff 100644
--- a/src/torrent-manager.cpp
+++ b/src/torrent-manager.cpp
@@ -436,18 +436,44 @@
 
 void
 TorrentManager::downloadTorrentFile(const std::string& path,
-                                    DataReceivedCallback onSuccess,
+                                    TorrentFileReceivedCallback onSuccess,
                                     FailedCallback onFailed)
 {
+  shared_ptr<Name> searchRes = this->findTorrentFileSegmentToDownload();
   auto manifestNames = make_shared<std::vector<Name>>();
-  this->downloadTorrentFileSegment(m_torrentFileName, path, manifestNames,
+  if (searchRes == nullptr) {
+    this->findFileManifestsToDownload(*manifestNames);
+    if (manifestNames->empty()) {
+      auto packetNames = make_shared<std::vector<Name>>();
+      this->findAllMissingDataPackets(*packetNames);
+      onSuccess(*packetNames);
+      return;
+    }
+    else {
+      onSuccess(*manifestNames);
+      return;
+    }
+  }
+  this->downloadTorrentFileSegment(*searchRes, path, manifestNames,
                                    true, onSuccess, onFailed);
 }
 
 std::vector<Name>
 TorrentManager::downloadTorrentFile(const std::string& path)
 {
+  shared_ptr<Name> searchRes = this->findTorrentFileSegmentToDownload();
   auto manifestNames = make_shared<std::vector<Name>>();
+  if (searchRes == nullptr) {
+    this->findFileManifestsToDownload(*manifestNames);
+    if (manifestNames->empty()) {
+      auto packetNames = make_shared<std::vector<Name>>();
+      this->findAllMissingDataPackets(*packetNames);
+      return *packetNames;
+    }
+    else {
+      return *manifestNames;
+    }
+  }
   this->downloadTorrentFileSegment(m_torrentFileName, path, manifestNames,
                                   false, {}, {});
   return *manifestNames;
@@ -458,7 +484,7 @@
                                            const std::string& path,
                                            std::shared_ptr<std::vector<Name>> manifestNames,
                                            bool async,
-                                           DataReceivedCallback onSuccess,
+                                           TorrentFileReceivedCallback onSuccess,
                                            FailedCallback onFailed)
 {
   shared_ptr<Interest> interest = createInterest(name);
@@ -469,6 +495,10 @@
       m_stats_table_iter->incrementReceivedData();
       m_retries = 0;
 
+      if (async) {
+        manifestNames->clear();
+      }
+
       TorrentFile file(data.wireEncode());
 
       // Write the torrent file segment to disk...
@@ -480,7 +510,7 @@
       shared_ptr<Name> nextSegmentPtr = file.getTorrentFilePtr();
 
       if (async) {
-        onSuccess(file.getName());
+        onSuccess(*manifestNames);
       }
       if (nextSegmentPtr != nullptr) {
         this->downloadTorrentFileSegment(*nextSegmentPtr, path, manifestNames,
@@ -517,8 +547,14 @@
                                        TorrentManager::ManifestReceivedCallback onSuccess,
                                        TorrentManager::FailedCallback           onFailed)
 {
+  shared_ptr<Name> searchRes = findManifestSegmentToDownload(manifestName);
   auto packetNames = make_shared<std::vector<Name>>();
-  this->downloadFileManifestSegment(manifestName, path, packetNames, onSuccess, onFailed);
+  if (searchRes == nullptr) {
+    this->findDataPacketsToDownload(manifestName, *packetNames);
+    onSuccess(*packetNames);
+    return;
+  }
+  this->downloadFileManifestSegment(*searchRes, path, packetNames, onSuccess, onFailed);
 }
 
 void
@@ -570,6 +606,11 @@
                                      DataReceivedCallback onSuccess,
                                      FailedCallback onFailed)
 {
+  if (this->dataAlreadyDownloaded(packetName)) {
+    onSuccess(packetName);
+    return;
+  }
+
   shared_ptr<Interest> interest = this->createInterest(packetName);
 
   auto dataReceived = [onSuccess, onFailed, this]
@@ -624,5 +665,121 @@
   return interest;
 }
 
+shared_ptr<Name>
+TorrentManager::findTorrentFileSegmentToDownload()
+{
+  // if we have no segments
+  if (m_torrentSegments.empty()) {
+    return make_shared<Name>(m_torrentFileName);
+  }
+  // otherwise just return the next segment ptr of the last segment we have
+  return m_torrentSegments.back().getTorrentFilePtr();
+}
+
+shared_ptr<Name>
+TorrentManager::findManifestSegmentToDownload(const Name& manifestName)
+{
+  //sequentially find whether we have downloaded any segments of this manifest file
+  Name manifestPrefix = manifestName.getSubName(0, manifestName.size() - 2);
+  auto it = std::find_if(m_fileManifests.rbegin(), m_fileManifests.rend(),
+                      [&manifestPrefix] (const FileManifest& f) {
+                        return manifestPrefix.isPrefixOf(f.getName());
+                      });
+
+  // if we do not have any segments of the file manifest
+  if (it == m_fileManifests.rend()) {
+    return make_shared<Name>(manifestName);
+  }
+
+  // if we already have the requested segment of the file manifest
+  if (it->submanifest_number() >= manifestName.get(manifestName.size() - 2).toSequenceNumber()) {
+    return it->submanifest_ptr();
+  }
+  // if we do not have the requested segment
+  else {
+    return make_shared<Name>(manifestName);
+  }
+}
+
+bool
+TorrentManager::dataAlreadyDownloaded(const Name& dataName)
+{
+
+  auto manifest_it = std::find_if(m_fileManifests.begin(), m_fileManifests.end(),
+                                 [&dataName](const FileManifest& m) {
+                                   return m.getName().isPrefixOf(dataName);
+                                 });
+
+  // if we do not have the file manifest, just return false
+  if (manifest_it == m_fileManifests.end()) {
+    return false;
+  }
+
+  // find the pair of (std::shared_ptr<fs::fstream>, std::vector<bool>)
+  // that corresponds to the specific submanifest
+  auto& fileState = m_fileStates[manifest_it->getFullName()];
+
+  auto dataNum = dataName.get(dataName.size() - 2).toSequenceNumber();
+
+  // find whether we have the requested packet from the bitmap
+  return fileState.second[dataNum];
+}
+
+void
+TorrentManager::findFileManifestsToDownload(std::vector<Name>& manifestNames)
+{
+  std::vector<Name> manifests;
+  // insert the first segment name of all the file manifests to the vector
+  for (auto i = m_torrentSegments.begin(); i != m_torrentSegments.end(); i++) {
+    manifests.insert(manifests.end(), i->getCatalog().begin(), i->getCatalog().end());
+  }
+  // for each file
+  for (const auto& manifestName : manifests) {
+    // find the first (if any) segment we are missing
+    shared_ptr<Name> manifestSegmentName = findManifestSegmentToDownload(manifestName);
+    if (nullptr != manifestSegmentName) {
+      manifestNames.push_back(*manifestSegmentName);
+    }
+  }
+}
+
+void
+TorrentManager::findDataPacketsToDownload(const Name& manifestName, std::vector<Name>& packetNames)
+{
+  auto manifest_it = std::find_if(m_fileManifests.begin(), m_fileManifests.end(),
+                                 [&manifestName](const FileManifest& m) {
+                                   return m.name().getSubName(0, m.name().size()
+                                                              - 1).isPrefixOf(manifestName);
+                                 });
+
+  for (auto j = manifest_it; j != m_fileManifests.end(); j++) {
+    auto& fileState = m_fileStates[j->getFullName()];
+    for (size_t dataNum = 0; dataNum < j->catalog().size(); ++dataNum) {
+      if (!fileState.second[dataNum]) {
+        packetNames.push_back(j->catalog()[dataNum]);
+      }
+    }
+
+    // check that the next manifest in the vector refers to the next segment of the same file
+    if ((j + 1) != m_fileManifests.end() && (j+1)->file_name() != manifest_it->file_name()) {
+      break;
+    }
+  }
+}
+
+void
+TorrentManager::findAllMissingDataPackets(std::vector<Name>& packetNames)
+{
+  for (auto j = m_fileManifests.begin(); j != m_fileManifests.end(); j++) {
+    auto& fileState = m_fileStates[j->getFullName()];
+    for (auto i = j->catalog().begin(); i != j->catalog().end(); i++) {
+      auto dataNum = i->get(i->size() - 2).toSequenceNumber();
+      if (!fileState.second[dataNum]) {
+        packetNames.push_back(*i);
+      }
+    }
+  }
+}
+
 }  // end ntorrent
 }  // end ndn
diff --git a/src/torrent-manager.hpp b/src/torrent-manager.hpp
index a96f21b..28053f2 100644
--- a/src/torrent-manager.hpp
+++ b/src/torrent-manager.hpp
@@ -54,6 +54,7 @@
  public:
    typedef std::function<void(const ndn::Name&)>                     DataReceivedCallback;
    typedef std::function<void(const std::vector<ndn::Name>&)>        ManifestReceivedCallback;
+   typedef std::function<void(const std::vector<ndn::Name>&)>        TorrentFileReceivedCallback;
    typedef std::function<void(const ndn::Name&, const std::string&)> FailedCallback;
 
    /*
@@ -114,7 +115,7 @@
    */
   void
   downloadTorrentFile(const std::string& path,
-                      DataReceivedCallback onSuccess,
+                      TorrentFileReceivedCallback onSuccess,
                       FailedCallback onFailed);
 
   /*
@@ -131,10 +132,11 @@
    * This method provides non-blocking downloading of all the file manifest segments
    *
    */
-  void download_file_manifest(const Name&              manifestName,
-                              const std::string&       path,
-                              ManifestReceivedCallback onSuccess,
-                              FailedCallback           onFailed);
+  void
+  download_file_manifest(const Name&              manifestName,
+                         const std::string&       path,
+                         ManifestReceivedCallback onSuccess,
+                         FailedCallback           onFailed);
 
   /*
    * @brief Download a data packet
@@ -147,12 +149,14 @@
    * This method writes the downloaded data packet to m_dataPath on disk
    *
    */
-  void download_data_packet(const Name&          packetName,
-                            DataReceivedCallback onSuccess,
-                            FailedCallback       onFailed);
+  void
+  download_data_packet(const Name&          packetName,
+                       DataReceivedCallback onSuccess,
+                       FailedCallback       onFailed);
 
   // Seed the specified 'data' to the network.
-  void seed(const Data& data) const;
+  void
+  seed(const Data& data) const;
 
  protected:
   /*
@@ -162,7 +166,8 @@
    * otherwise. Behavior is undefined unless the corresponding file manifest has already been
    * downloaded.
    */
-  bool writeData(const Data& packet);
+  bool
+  writeData(const Data& packet);
 
   /*
    * \brief Write the @p segment torrent segment to disk at the specified path.
@@ -172,7 +177,8 @@
    * otherwise. Behavior is undefined unless @segment is a correct segment for the torrent file of
    * this manager and @p path is the directory used for all segments of this torrent file.
    */
-  bool writeTorrentSegment(const TorrentFile& segment, const std::string& path);
+  bool
+  writeTorrentSegment(const TorrentFile& segment, const std::string& path);
 
   /*
    * \brief Write the @p manifest file manifest to disk at the specified @p path.
@@ -183,7 +189,8 @@
    * torrent file of this manager and @p path is the directory used for all file manifests of this
    * torrent file.
    */
-  bool writeFileManifest(const FileManifest& manifest, const std::string& path);
+  bool
+  writeFileManifest(const FileManifest& manifest, const std::string& path);
 
   /*
    * \brief Download the segments of the torrent file
@@ -201,12 +208,13 @@
    *                 specified when async is false
    *
    */
-  void downloadTorrentFileSegment(const ndn::Name& name,
-                                  const std::string& path,
-                                  std::shared_ptr<std::vector<Name>> manifestNames,
-                                  bool async,
-                                  DataReceivedCallback onSuccess,
-                                  FailedCallback onFailed);
+  void
+  downloadTorrentFileSegment(const ndn::Name& name,
+                             const std::string& path,
+                             std::shared_ptr<std::vector<Name>> manifestNames,
+                             bool async,
+                             TorrentFileReceivedCallback onSuccess,
+                             FailedCallback onFailed);
 
   /*
    * \brief Download the segments of a file manifest
@@ -218,11 +226,12 @@
    * @param onFailed Callback to be called when we fail to download a file manifest segment
    *
    */
-  void downloadFileManifestSegment(const Name& manifestName,
-                                   const std::string& path,
-                                   std::shared_ptr<std::vector<Name>> packetNames,
-                                   TorrentManager::ManifestReceivedCallback onSuccess,
-                                   TorrentManager::FailedCallback onFailed);
+  void
+  downloadFileManifestSegment(const Name& manifestName,
+                              const std::string& path,
+                              std::shared_ptr<std::vector<Name>> packetNames,
+                              ManifestReceivedCallback onSuccess,
+                              FailedCallback onFailed);
 
   enum {
     // Number of times to retry if a routable prefix fails to retrieve data
@@ -245,6 +254,67 @@
   // The path to the location on disk of the Data packet for this manager
   std::string                                                         m_dataPath;
 
+protected:
+  /*
+   * \brief Find the torrent file segment that we should download
+   *        (either we have nothing or we have them all)
+   * @return A shared_ptr to the name of the segment to download or
+   *         nullptr if we have all the segments
+   *
+   */
+  shared_ptr<Name>
+  findTorrentFileSegmentToDownload();
+
+  /*
+   * \brief Given a file manifest segment name, find the next file manifest segment
+   *        that we should download
+   * @param manifestName The name of the file manifest segment that we want to download
+   * @return A shared_ptr to the name of the segment to download or
+   *         nullptr if we have all the segments
+   *
+   */
+  shared_ptr<Name>
+  findManifestSegmentToDownload(const Name& manifestName);
+
+  /*
+   * \brief Given a data packet name, find whether we have already downloaded this packet
+   * @param dataName The name of the data packet to download
+   * @return True if we have already downloaded this packet, false otherwise
+   *
+   */
+  bool
+  dataAlreadyDownloaded(const Name& dataName);
+
+  /*
+   * \brief Find the segments of all the file manifests that we are missing
+   * @param manifestNames The name of the manifest file segments to download (currently missing)
+   *                      This parameter is used as an output vector of names
+   */
+  void
+  findFileManifestsToDownload(std::vector<Name>& manifestNames);
+
+  /*
+   * \brief Find the names of the data packets of a file manifest that we are currently missing
+   * @param manifestName The name of the manifest
+   * @param packetNames The name of the data packets to be downloaded
+   *                    (used as an output vector of names)
+   *
+   * No matter what segment of a manifest file the manifestName parameter might refer to, the
+   * missing data packets starting from the first segment of this manifest file would be returned
+   *
+   */
+  void
+  findDataPacketsToDownload(const Name& manifestName, std::vector<Name>& packetNames);
+
+  /*
+   * \brief Find all the data packets that we are currently missing
+   * @param packetNames The name of the data packets to be downloaded
+   *                    (used as an output vector of names)
+   *
+   */
+  void
+  findAllMissingDataPackets(std::vector<Name>& packetNames);
+
 private:
   shared_ptr<Interest>
   createInterest(Name name);
diff --git a/tests/unit-tests/torrent-manager.t.cpp b/tests/unit-tests/torrent-manager.t.cpp
index bb16344..29938eb 100644
--- a/tests/unit-tests/torrent-manager.t.cpp
+++ b/tests/unit-tests/torrent-manager.t.cpp
@@ -65,6 +65,26 @@
     return m_fileManifests;
   }
 
+  void pushTorrentSegment(const TorrentFile& t) {
+    m_torrentSegments.push_back(t);
+  }
+
+  void pushFileManifestSegment(const FileManifest& m) {
+    m_fileManifests.push_back(m);
+  }
+
+  shared_ptr<Name> findTorrentFileSegmentToDownload() {
+    return TorrentManager::findTorrentFileSegmentToDownload();
+  }
+
+  shared_ptr<Name> findManifestSegmentToDownload(const Name& manifestName) {
+    return TorrentManager::findManifestSegmentToDownload(manifestName);
+  }
+
+  bool dataAlreadyDownloaded(const Name& name) {
+    return TorrentManager::dataAlreadyDownloaded(name);
+  }
+
   std::vector<bool> fileState(const ndn::Name& manifestName) {
     auto fout = m_fileStates[manifestName].first;
     if (nullptr != fout) {
@@ -73,6 +93,13 @@
     return m_fileStates[manifestName].second;
   }
 
+  void setFileState(const ndn::Name manifestName,
+                    std::shared_ptr<fs::fstream> f,
+                    const std::vector<bool>& stateVec) {
+
+    m_fileStates.insert({ manifestName, std::make_pair(f, stateVec) });
+  }
+
   bool writeData(const Data& data) {
     return TorrentManager::writeData(data);
   }
@@ -80,6 +107,7 @@
   bool writeTorrentSegment(const TorrentFile& segment, const std::string& path) {
     return TorrentManager::writeTorrentSegment(segment, path);
   }
+
   bool writeFileManifest(const FileManifest& manifest, const std::string& path) {
     return TorrentManager::writeFileManifest(manifest, path);
   }
@@ -293,13 +321,19 @@
 
   // Test download torrent file segments
   uint32_t counter = 0;
-  manager.downloadTorrentFile(filePath + "torrent_files", [&counter, &torrentSegments] (const ndn::Name& name) {
-                                          BOOST_CHECK_EQUAL(torrentSegments[counter].getName(), name);
-                                          counter++;
-                                        },
-                                        bind([] {
-                                          BOOST_FAIL("Unexpected failure");
-                                        }));
+  manager.downloadTorrentFile(filePath + "torrent_files", [&counter, &torrentSegments]
+                                (const std::vector<ndn::Name>& vec) {
+                                  uint32_t manifestNum = 0;
+                                  for (auto i = vec.begin(); i != vec.end(); i++) {
+                                    Name n = torrentSegments[counter].getCatalog()[manifestNum];
+                                    BOOST_CHECK_EQUAL(n, *i);
+                                    manifestNum++;
+                                  }
+                                  counter++;
+                                },
+                                bind([] {
+                                  BOOST_FAIL("Unexpected failure");
+                                }));
 
   for (auto i = torrentSegments.begin(); i != torrentSegments.end(); i++) {
     advanceClocks(time::milliseconds(1), 40);
@@ -307,6 +341,7 @@
   }
 
   fs::remove_all(filePath);
+  fs::remove_all(".appdata");
 }
 
 BOOST_AUTO_TEST_CASE(TestDownloadingFileManifests)
@@ -380,6 +415,7 @@
   }
 
   fs::remove_all(filePath);
+  fs::remove_all(".appdata");
 }
 
 BOOST_AUTO_TEST_CASE(TestDownloadingDataPackets)
@@ -411,7 +447,7 @@
 
   // Fail to download data
   manager.download_data_packet(dataName,
-                              [] (const ndn::Name& name) {
+                              [](const ndn::Name& name) {
                                 BOOST_FAIL("Unexpected failure");
                               },
                               [&dataName](const ndn::Name& name, const std::string& reason) {
@@ -421,6 +457,389 @@
   advanceClocks(time::milliseconds(1), 2100);
 
   fs::remove_all(filePath);
+  fs::remove_all(".appdata");
+}
+
+// we already have downloaded the torrent file
+BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload1)
+{
+  std::string filePath = ".appdata/foo/";
+  TestTorrentManager manager("NTORRENT/test/torrent-file/sha256digest",
+                             filePath, face);
+  manager.Initialize();
+
+  TorrentFile t1(Name("NTORRENT/test/torrent-file/sha256digest"),
+                 Name("NTORRENT/test/torrent-file/1/sha256digest"), Name("/test"),
+                 { Name("/manifest1") });
+  manager.pushTorrentSegment(t1);
+
+  TorrentFile t2(Name("NTORRENT/test/torrent-file/1/sha256digest"),
+                 Name("NTORRENT/test/torrent-file/2/sha256digest"), Name("/test"),
+                 { Name("/manifest2"), Name("/manifest3") });
+  manager.pushTorrentSegment(t2);
+
+  TorrentFile t3(Name("NTORRENT/test/torrent-file/3/sha256digest"),
+                 Name("NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"),
+                 { Name("/manifest4"), Name("/manifest5") });
+  manager.pushTorrentSegment(t3);
+
+  TorrentFile t4(Name("NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"), {});
+  manager.pushTorrentSegment(t4);
+
+  BOOST_CHECK(!(manager.findTorrentFileSegmentToDownload()));
+
+  std::vector<Name> manifests;
+  manifests = manager.downloadTorrentFile("/test");
+
+  BOOST_CHECK_EQUAL(manifests[0].toUri(), "/manifest1");
+  BOOST_CHECK_EQUAL(manifests[1].toUri(), "/manifest2");
+  BOOST_CHECK_EQUAL(manifests[2].toUri(), "/manifest3");
+  BOOST_CHECK_EQUAL(manifests[3].toUri(), "/manifest4");
+  BOOST_CHECK_EQUAL(manifests[4].toUri(), "/manifest5");
+
+  fs::remove_all(filePath);
+  fs::remove_all(".appdata");
+}
+
+// we do not have the torrent file
+BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload2)
+{
+  std::string filePath = ".appdata/foo/";
+  TestTorrentManager manager("/test/0/sha256digest",
+                             filePath, face);
+  manager.Initialize();
+
+  BOOST_CHECK_EQUAL(manager.findTorrentFileSegmentToDownload()->toUri(), "/test/0/sha256digest");
+
+  fs::remove_all(filePath);
+  fs::remove_all(".appdata");
+}
+
+// we have the torrent file and the manifests
+BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload3)
+{
+  vector<FileManifest> manifests;
+  vector<TorrentFile>  torrentSegments;
+  // for each file, the data packets
+  std::vector<vector<Data>> fileData;
+  std::string filePath = "tests/testdata/temp";
+  // get torrent files and manifests
+  {
+    auto temp = TorrentFile::generate("tests/testdata/foo",
+                                      1024,
+                                      2048,
+                                      8192,
+                                      true);
+    torrentSegments = temp.first;
+    auto temp1      = temp.second;
+    for (const auto& ms : temp1) {
+      manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
+      fileData.push_back(ms.second);
+    }
+  }
+  // write the torrent segments and manifests to disk
+  std::string dirPath = ".appdata/foo/";
+  boost::filesystem::create_directories(dirPath);
+  std::string torrentPath = dirPath + "torrent_files/";
+  boost::filesystem::create_directories(torrentPath);
+  auto fileNum = 0;
+  for (const auto& t : torrentSegments) {
+    fileNum++;
+    auto filename = torrentPath + to_string(fileNum);
+    io::save(t, filename);
+  }
+
+  auto manifestPath = dirPath + "manifests/";
+  boost::filesystem::create_directory(manifestPath);
+  for (const auto& m : manifests) {
+    fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
+    boost::filesystem::create_directory(filename.parent_path());
+    io::save(m, filename.string());
+  }
+  // Initialize manager
+  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
+                             filePath);
+  manager.Initialize();
+
+  // Set the file state
+  std::vector<bool> v1 = {true};
+  manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
+
+  std::vector<bool> v2 = {false, true, true, false, false, false};
+  manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
+
+  std::vector<bool> v3 = {true, false, false, false, false, false};
+  manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
+
+  manager.downloadTorrentFile(filePath + "torrent_files/",
+                                 [&manifests](const std::vector<ndn::Name>& vec) {
+                                   BOOST_CHECK_EQUAL(vec[0].toUri(),
+                                                     manifests[1].catalog()[0].toUri());
+                                   BOOST_CHECK_EQUAL(vec[1].toUri(),
+                                                     manifests[1].catalog()[3].toUri());
+                                   BOOST_CHECK_EQUAL(vec[2].toUri(),
+                                                     manifests[1].catalog()[4].toUri());
+                                   BOOST_CHECK_EQUAL(vec[3].toUri(),
+                                                     manifests[1].catalog()[5].toUri());
+                                   BOOST_CHECK_EQUAL(vec[4].toUri(),
+                                                     manifests[2].catalog()[1].toUri());
+                                   BOOST_CHECK_EQUAL(vec[5].toUri(),
+                                                     manifests[2].catalog()[2].toUri());
+                                   BOOST_CHECK_EQUAL(vec[6].toUri(),
+                                                     manifests[2].catalog()[3].toUri());
+                                   BOOST_CHECK_EQUAL(vec[7].toUri(),
+                                                     manifests[2].catalog()[4].toUri());
+                                   BOOST_CHECK_EQUAL(vec[8].toUri(),
+                                                     manifests[2].catalog()[5].toUri());
+                                 },
+                                 [](const ndn::Name& name, const std::string& reason) {
+                                   BOOST_FAIL("Unexpected failure");
+                                 });
+
+  fs::remove_all(filePath);
+  fs::remove_all(".appdata");
+}
+
+
+BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload1)
+{
+  std::string filePath = ".appdata/foo/";
+  TestTorrentManager manager("NTORRENT/test/sha256digest",
+                             filePath, face);
+  manager.Initialize();
+
+  Name n1(Name("NTORRENT/test/file0"));
+  n1.appendSequenceNumber(0);
+
+  Name n2(Name("NTORRENT/test/file0"));
+  n2.appendSequenceNumber(1);
+
+  Name n3(Name("NTORRENT/test/file0"));
+  n3.appendSequenceNumber(2);
+
+  Name n4(Name("NTORRENT/test/file0"));
+  n4.appendSequenceNumber(3);
+
+  Name n5(Name("NTORRENT/test/file0"));
+  n5.appendSequenceNumber(4);
+
+  Name n6(Name("NTORRENT/test1/file0"));
+  n6.appendSequenceNumber(0);
+
+  Name n7(Name("NTORRENT/test1/file0"));
+  n7.appendSequenceNumber(1);
+
+  // In theory, this may not be correct, but here let's suck it up for the sake
+  // of testing the function correctness
+  Name n8(Name("NTORRENT/test1/file2"));
+  n8.appendSequenceNumber(0);
+
+  Name n9(Name("NTORRENT/test1/file2"));
+  n9.appendSequenceNumber(1);
+
+  FileManifest f1(n1, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n2));
+  manager.pushFileManifestSegment(f1);
+
+  FileManifest f2(n2, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n3));
+  manager.pushFileManifestSegment(f2);
+
+  FileManifest f3(n3, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n4));
+  manager.pushFileManifestSegment(f3);
+
+  FileManifest f4(n4, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n5));
+  manager.pushFileManifestSegment(f4);
+
+  FileManifest f5(n6, 50, Name("NTORRENT/test2"), {}, make_shared<Name>(n7));
+  manager.pushFileManifestSegment(f5);
+
+  FileManifest f6(n7, 50, Name("NTORRENT/test2"), {}, {});
+  manager.pushFileManifestSegment(f6);
+
+  FileManifest f7(n8, 50, Name("NTORRENT/test3"), {}, make_shared<Name>(n9));
+  manager.pushFileManifestSegment(f7);
+
+  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n2.toUri() + "/sha256digest"))->toUri(), n5.toUri());
+  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n8.toUri() + "/sha256digest"))->toUri(), n9.toUri());
+  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n5.toUri() + "/sha256digest"))->toUri(),
+                                                               Name(n5.toUri() + "/sha256digest").toUri());
+  BOOST_CHECK(!(manager.findManifestSegmentToDownload(Name(n7.toUri() + "/sha256digest"))));
+
+  Name n10(Name("NTORRENT/test1/file1"));
+  n10.appendSequenceNumber(1);
+  n10 = Name(n10.toUri() + "/sha256digest");
+
+  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(n10)->toUri(), n10.toUri());
+
+  fs::remove_all(filePath);
+  fs::remove_all(".appdata");
+}
+
+BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload2)
+{
+  vector<FileManifest> manifests;
+  vector<TorrentFile>  torrentSegments;
+  // for each file, the data packets
+  std::vector<vector<Data>> fileData;
+  std::string filePath = "tests/testdata/temp";
+  // get torrent files and manifests
+  {
+    auto temp = TorrentFile::generate("tests/testdata/foo",
+                                      1024,
+                                      2048,
+                                      8192,
+                                      true);
+    torrentSegments = temp.first;
+    auto temp1      = temp.second;
+    for (const auto& ms : temp1) {
+      manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
+      fileData.push_back(ms.second);
+    }
+  }
+  // write the torrent segments and manifests to disk
+  std::string dirPath = ".appdata/foo/";
+  boost::filesystem::create_directories(dirPath);
+  std::string torrentPath = dirPath + "torrent_files/";
+  boost::filesystem::create_directories(torrentPath);
+  auto fileNum = 0;
+  for (const auto& t : torrentSegments) {
+    fileNum++;
+    auto filename = torrentPath + to_string(fileNum);
+    io::save(t, filename);
+  }
+
+  auto manifestPath = dirPath + "manifests/";
+  boost::filesystem::create_directory(manifestPath);
+  for (const auto& m : manifests) {
+    fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
+    boost::filesystem::create_directory(filename.parent_path());
+    io::save(m, filename.string());
+  }
+  // Initialize manager
+  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
+                             filePath);
+  manager.Initialize();
+
+  // Set the file state
+  std::vector<bool> v1 = {true};
+  manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
+
+  std::vector<bool> v2 = {false, true, true, false, false, false};
+  manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
+
+  std::vector<bool> v3 = {true, false, false, false, false, false};
+  manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
+
+  manager.download_file_manifest(manifests[0].getFullName(), filePath + "manifests",
+                                [&manifests](const std::vector<ndn::Name>& vec) {
+                                      BOOST_CHECK_EQUAL(vec.size(), 0);
+                                },
+                                [](const ndn::Name& name, const std::string& reason) {
+                                  BOOST_FAIL("Unexpected failure");
+                                });
+
+  manager.download_file_manifest(manifests[1].getFullName(), filePath + "manifests",
+                                 [&manifests](const std::vector<ndn::Name>& vec) {
+                                   BOOST_CHECK_EQUAL(vec[0].toUri(),
+                                                     manifests[1].catalog()[0].toUri());
+                                   BOOST_CHECK_EQUAL(vec[1].toUri(),
+                                                     manifests[1].catalog()[3].toUri());
+                                   BOOST_CHECK_EQUAL(vec[2].toUri(),
+                                                     manifests[1].catalog()[4].toUri());
+                                   BOOST_CHECK_EQUAL(vec[3].toUri(),
+                                                     manifests[1].catalog()[5].toUri());
+                                 },
+                                 [](const ndn::Name& name, const std::string& reason) {
+                                   BOOST_FAIL("Unexpected failure");
+                                 });
+
+  manager.download_file_manifest(manifests[2].getFullName(), filePath + "manifests",
+                                 [&manifests](const std::vector<ndn::Name>& vec) {
+                                   BOOST_CHECK_EQUAL(vec[0].toUri(),
+                                                     manifests[2].catalog()[1].toUri());
+                                   BOOST_CHECK_EQUAL(vec[1].toUri(),
+                                                     manifests[2].catalog()[2].toUri());
+                                   BOOST_CHECK_EQUAL(vec[2].toUri(),
+                                                     manifests[2].catalog()[3].toUri());
+                                   BOOST_CHECK_EQUAL(vec[3].toUri(),
+                                                     manifests[2].catalog()[4].toUri());
+                                   BOOST_CHECK_EQUAL(vec[4].toUri(),
+                                                     manifests[2].catalog()[5].toUri());
+                                 },
+                                 [](const ndn::Name& name, const std::string& reason) {
+                                   BOOST_FAIL("Unexpected failure");
+                                 });
+  fs::remove_all(filePath);
+  fs::remove_all(".appdata");
+}
+
+BOOST_AUTO_TEST_CASE(TestDataAlreadyDownloaded)
+{
+  vector<FileManifest> manifests;
+  vector<TorrentFile>  torrentSegments;
+  // for each file, the data packets
+  std::vector<vector<Data>> fileData;
+  std::string filePath = "tests/testdata/temp";
+  // get torrent files and manifests
+  {
+    auto temp = TorrentFile::generate("tests/testdata/foo",
+                                      1024,
+                                      2048,
+                                      8192,
+                                      true);
+    torrentSegments = temp.first;
+    auto temp1      = temp.second;
+    for (const auto& ms : temp1) {
+      manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
+      fileData.push_back(ms.second);
+    }
+  }
+  // write the torrent segments and manifests to disk
+  std::string dirPath = ".appdata/foo/";
+  boost::filesystem::create_directories(dirPath);
+  std::string torrentPath = dirPath + "torrent_files/";
+  boost::filesystem::create_directories(torrentPath);
+  auto fileNum = 0;
+  for (const auto& t : torrentSegments) {
+    fileNum++;
+    auto filename = torrentPath + to_string(fileNum);
+    io::save(t, filename);
+  }
+
+  auto manifestPath = dirPath + "manifests/";
+  boost::filesystem::create_directory(manifestPath);
+  for (const auto& m : manifests) {
+    fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
+    boost::filesystem::create_directory(filename.parent_path());
+    io::save(m, filename.string());
+  }
+  // Initialize manager
+  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
+                             filePath);
+  manager.Initialize();
+
+  // Set the file state
+  std::vector<bool> v1 = {true};
+  manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
+
+  std::vector<bool> v2 = {false, true, true, false, false, false};
+  manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
+
+  std::vector<bool> v3 = {true, false, false, false, false, false};
+  manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
+
+  Name p1("NTORRENT/foo/bar1.txt");
+  p1.appendSequenceNumber(0);
+  p1.appendSequenceNumber(0);
+  p1 = Name(p1.toUri() + "/sha256digest");
+
+  BOOST_CHECK(!(manager.dataAlreadyDownloaded(p1)));
+
+  Name p2("NTORRENT/foo/bar.txt");
+  p2.appendSequenceNumber(0);
+  p2.appendSequenceNumber(0);
+  p2 = Name(p2.toUri() + "/sha256digest");
+
+  BOOST_CHECK(manager.dataAlreadyDownloaded(p2));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
@@ -482,7 +901,7 @@
     for (auto& d : data) {
       BOOST_CHECK(manager.writeData(d));
     }
-    // check that the  state is updated appropriately
+    // check that the state is updated appropriately
     auto fileState = manager.fileState(manifest_it->getFullName());
     for (auto s : fileState) {
       BOOST_CHECK(s);
