diff --git a/src/torrent-manager.cpp b/src/torrent-manager.cpp
new file mode 100644
index 0000000..305fa3b
--- /dev/null
+++ b/src/torrent-manager.cpp
@@ -0,0 +1,307 @@
+#include "torrent-manager.hpp"
+
+#include "file-manifest.hpp"
+#include "torrent-file.hpp"
+
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+#include <ndn-cxx/data.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+#include <ndn-cxx/util/io.hpp>
+
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace fs = boost::filesystem;
+
+using std::string;
+using std::vector;
+
+namespace {
+// TODO(msweatt) Move this to a utility
+template<typename T>
+static vector<T>
+load_directory(const string& dirPath,
+               ndn::io::IoEncoding encoding = ndn::io::IoEncoding::BASE_64) {
+  vector<T> structures;
+
+  if (fs::exists(dirPath)) {
+    for(fs::directory_iterator it(dirPath);
+      it !=  fs::directory_iterator();
+      ++it)
+    {
+      auto data_ptr = ndn::io::load<T>(it->path().string(), encoding);
+      if (nullptr != data_ptr) {
+        structures.push_back(*data_ptr);
+      }
+    }
+  }
+  structures.shrink_to_fit();
+  return structures;
+}
+
+} // end anonymous
+
+namespace ndn {
+namespace ntorrent {
+
+// TODO(msweatt) Move this to a utility
+static vector<ndn::Data>
+packetize_file(const fs::path& filePath,
+               const ndn::Name& commonPrefix,
+               size_t dataPacketSize,
+               size_t subManifestSize,
+               size_t subManifestNum)
+{
+  BOOST_ASSERT(0 < dataPacketSize);
+  size_t APPROX_BUFFER_SIZE = std::numeric_limits<int>::max(); // 2 * 1024 * 1024 *1024
+  auto file_size = fs::file_size(filePath);
+  auto start_offset = subManifestNum * subManifestSize * dataPacketSize;
+  // determine the number of bytes in this submanifest
+  auto subManifestLength = subManifestSize * dataPacketSize;
+  auto remainingFileLength = file_size - start_offset;
+  subManifestLength = remainingFileLength < subManifestLength
+                    ? remainingFileLength
+                    : subManifestLength;
+  vector<ndn::Data> packets;
+  packets.reserve(subManifestLength/dataPacketSize + 1);
+  fs::ifstream fs(filePath, fs::ifstream::binary);
+  if (!fs) {
+    BOOST_THROW_EXCEPTION(FileManifest::Error("IO Error when opening" + filePath.string()));
+  }
+  // ensure that buffer is large enough to contain whole packets
+  // buffer size is either the entire file or the smallest number of data packets >= 2 GB
+  auto buffer_size =
+    subManifestLength < APPROX_BUFFER_SIZE   ?
+    subManifestLength                        :
+    APPROX_BUFFER_SIZE % dataPacketSize == 0 ?
+    APPROX_BUFFER_SIZE :
+    APPROX_BUFFER_SIZE + dataPacketSize - (APPROX_BUFFER_SIZE % dataPacketSize);
+  vector<char> file_bytes;
+  file_bytes.reserve(buffer_size);
+  size_t bytes_read = 0;
+  fs.seekg(start_offset);
+  while(fs && bytes_read < subManifestLength && !fs.eof()) {
+    // read the file into the buffer
+    fs.read(&file_bytes.front(), buffer_size);
+    auto read_size = fs.gcount();
+    if (fs.bad() || read_size < 0) {
+      BOOST_THROW_EXCEPTION(FileManifest::Error("IO Error when reading" + filePath.string()));
+    }
+    bytes_read += read_size;
+    char *curr_start = &file_bytes.front();
+    for (size_t i = 0u; i < buffer_size; i += dataPacketSize) {
+      // Build a packet from the data
+      Name packetName = commonPrefix;
+      packetName.appendSequenceNumber(packets.size());
+      Data d(packetName);
+      auto content_length = i + dataPacketSize > buffer_size ? buffer_size - i : dataPacketSize;
+      d.setContent(encoding::makeBinaryBlock(tlv::Content, curr_start, content_length));
+      curr_start += content_length;
+      // append to the collection
+      packets.push_back(d);
+    }
+    file_bytes.clear();
+    // recompute the buffer_size
+    buffer_size =
+      subManifestLength - bytes_read < APPROX_BUFFER_SIZE ?
+      subManifestLength - bytes_read                      :
+      APPROX_BUFFER_SIZE % dataPacketSize == 0            ?
+      APPROX_BUFFER_SIZE                                  :
+      APPROX_BUFFER_SIZE + dataPacketSize - (APPROX_BUFFER_SIZE % dataPacketSize);
+  }
+  fs.close();
+  packets.shrink_to_fit();
+  ndn::security::KeyChain key_chain;
+  // sign all the packets
+  for (auto& p : packets) {
+    key_chain.sign(p, signingWithSha256());
+  }
+  return packets;
+}
+
+static vector<TorrentFile>
+intializeTorrentSegments(const string& torrentFilePath, const Name& initialSegmentName)
+{
+  security::KeyChain key_chain;
+  Name currSegmentFullName = initialSegmentName;
+  vector<TorrentFile> torrentSegments = load_directory<TorrentFile>(torrentFilePath);
+  // Starting with the initial segment name, verify the names, loading next name from torrentSegment
+  for (auto it = torrentSegments.begin(); it != torrentSegments.end(); ++it) {
+    TorrentFile& segment = *it;
+    key_chain.sign(segment, signingWithSha256());
+    if (segment.getFullName() != currSegmentFullName) {
+      vector<TorrentFile> correctSegments(torrentSegments.begin(), it);
+      torrentSegments.swap(correctSegments);
+      break;
+    }
+    // load the next full name
+    if (nullptr == segment.getTorrentFilePtr()) {
+      break;
+    }
+    currSegmentFullName = *segment.getTorrentFilePtr();
+  }
+  return torrentSegments;
+}
+
+static vector<FileManifest>
+intializeFileManifests(const string& manifestPath, vector<TorrentFile> torrentSegments)
+{
+  security::KeyChain key_chain;
+
+  vector<FileManifest> manifests = load_directory<FileManifest>(manifestPath);
+
+  // sign the manifests
+  std::for_each(manifests.begin(), manifests.end(),
+                [&key_chain](FileManifest& m){
+                  key_chain.sign(m,signingWithSha256());
+                });
+
+  // put all names of manifests from the valid torrent files into a set
+  std::set<ndn::Name> validManifestNames;
+  for (const auto& segment : torrentSegments) {
+    const auto& catalog = segment.getCatalog();
+    validManifestNames.insert(catalog.begin(), catalog.end());
+  }
+
+  // put all names of file manifests from disk into a set
+  std::set<ndn::Name> loadedManifestNames;
+  std::for_each(manifests.begin(), manifests.end(),
+                [&loadedManifestNames](const FileManifest& m){
+                  loadedManifestNames.insert(m.getFullName());
+                });
+
+  // the set of fileManifests that we have is simply the intersection
+  std::set<Name> output;
+  std::set_intersection(validManifestNames.begin() , validManifestNames.end(),
+                        loadedManifestNames.begin(), loadedManifestNames.end(),
+                        std::inserter(output, output.begin()));
+
+  // filter out those manifests that are not in this set
+  std::remove_if(manifests.begin(),
+                 manifests.end(),
+                 [&output](const FileManifest& m) {
+                   return (output.end() == output.find(m.name()));
+                 });
+
+  // order the manifests in the same order they are in the torrent
+  std::vector<Name> catalogNames;
+  for (const auto& segment : torrentSegments) {
+    const auto& catalog = segment.getCatalog();
+    catalogNames.insert(catalogNames.end(), catalog.begin(), catalog.end());
+  }
+  size_t curr_index = 0;
+  for (auto name : catalogNames) {
+    auto it = std::find_if(manifests.begin(), manifests.end(),
+                          [&name](const FileManifest& m) {
+                            return m.getFullName() == name;
+                           });
+    if (it != manifests.end()) {
+      // not already in the correct position
+      if (it != manifests.begin() + curr_index) {
+        std::swap(manifests[curr_index], *it);
+      }
+      ++curr_index;
+    }
+  }
+
+  return manifests;
+}
+
+static vector<Data>
+intializeDataPackets(const string&      filePath,
+                     const FileManifest manifest,
+                     const TorrentFile& torrentFile)
+{
+  vector<Data> packets;
+  auto subManifestNum = manifest.name().get(manifest.name().size() - 1).toSequenceNumber();
+
+  packets =  packetize_file(filePath,
+                             manifest.name(),
+                             manifest.data_packet_size(),
+                             manifest.catalog().size(),
+                             subManifestNum);
+
+  auto catalog = manifest.catalog();
+
+  // Filter out invalid packet names
+  std::remove_if(packets.begin(), packets.end(),
+                [&packets, &catalog](const Data& p) {
+                  return catalog.end() == std::find(catalog.begin(),
+                                                     catalog.end(),
+                                                     p.getFullName());
+                });
+  return packets;
+}
+
+void TorrentManager::Initialize()
+{
+  // .../<torrent_name>/torrent-file/<implicit_digest>
+  string dataPath = ".appdata/" + m_torrentFileName.get(-3).toUri();
+  string manifestPath = dataPath +"/manifests";
+  string torrentFilePath = dataPath +"/torrent_files";
+
+  // get the torrent file segments and manifests that we have.
+  if (!fs::exists(torrentFilePath)) {
+    return;
+  }
+  m_torrentSegments = intializeTorrentSegments(torrentFilePath, m_torrentFileName);
+  if (m_torrentSegments.empty()) {
+    return;
+  }
+  m_fileManifests   = intializeFileManifests(manifestPath, m_torrentSegments);
+  auto currTorrentFile_it = m_torrentSegments.begin();
+  for (const auto& m : m_fileManifests) {
+    // find the appropriate torrent file
+    auto currCatalog = currTorrentFile_it->getCatalog();
+    while (currCatalog.end() == std::find(currCatalog.begin(), currCatalog.end(), m.getFullName()))
+    {
+      ++currTorrentFile_it;
+      currCatalog = currTorrentFile_it->getCatalog();
+    }
+    // construct the file name
+    auto fileName = m.name().getSubName(1, m.name().size() - 2).toUri();
+    auto filePath = m_dataPath + fileName;
+    // If there are any valid packets, add corresponding state to manager
+    auto packets = intializeDataPackets(filePath, m, *currTorrentFile_it);
+    if (!packets.empty()) {
+      // build the bit map
+      auto catalog =  m.catalog();
+      vector<bool> fileBitMap(catalog.size());
+      auto read_it = packets.begin();
+      size_t i = 0;
+      for (auto name : catalog) {
+        if (name == read_it->getFullName()) {
+          ++read_it;
+          fileBitMap[i]= true;
+        }
+        ++i;
+      }
+      for (const auto& d : packets) {
+        seed(d);
+      }
+      auto s = std::make_shared<fs::fstream>(filePath, fs::fstream::binary
+                                                     | fs::fstream::in
+                                                     | fs::fstream::out);
+      m_fileStates[m.getFullName()] = std::make_pair(s, fileBitMap);
+    }
+  }
+  for (const auto& t : m_torrentSegments) {
+    seed(t);
+  }
+  for (const auto& m : m_fileManifests) {
+    seed(m);
+  }
+
+}
+
+void TorrentManager::seed(const Data& data) const {
+  // TODO(msweatt) IMPLEMENT ME
+}
+
+}  // end ntorrent
+}  // end ndn
\ No newline at end of file
diff --git a/src/torrent-manager.hpp b/src/torrent-manager.hpp
new file mode 100644
index 0000000..3c4b923
--- /dev/null
+++ b/src/torrent-manager.hpp
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+* Copyright (c) 2016 Regents of the University of California.
+*
+* This file is part of the nTorrent codebase.
+*
+* nTorrent 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.
+*
+* nTorrent 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 nTorrent, e.g., in COPYING.md file. If not, see
+* <http://www.gnu.org/licenses/>.
+*
+* See AUTHORS for complete list of nTorrent authors and contributors.
+*/
+#ifndef INCLUDED_TORRENT_FILE_MANAGER_H
+#define INCLUDED_TORRENT_FILE_MANAGER_H
+
+#include "torrent-file.hpp"
+#include "file-manifest.hpp"
+
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/data.hpp>
+
+#include <boost/filesystem/fstream.hpp>
+#include <boost/utility.hpp>
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace fs = boost::filesystem;
+
+namespace ndn {
+namespace ntorrent {
+
+class TorrentManager : boost::noncopyable {
+  /**
+   * \class TorrentManager
+   *
+   * \brief A class to manage the interaction with the system in seeding/leaching a torrent
+   */
+ public:
+  typedef std::function<void(const ndn::Name&)>                     DataReceivedCallback;
+  typedef std::function<void(const std::vector<ndn::Name>&)>        ManifestReceivedCallback;
+  typedef std::function<void(const ndn::Name&, const std::string&)> FailedCallback;
+
+  TorrentManager(const ndn::Name&   torrentFileName,
+                 const std::string& dataPath);
+  /*
+   * \brief Create a new Torrent manager with the specified parameters.
+   * @param torrentFileName The full name of the initial segment of the torrent file
+   * @param filePath The path to the location on disk to use for the torrent data
+   *
+   * The behavior is undefined unless Initialize() is called before calling any other method on a
+   * TorrentManger object.
+   */
+
+  void Initialize();
+  /*
+   * \brief Initialize the state of this object.
+   * Read and validate from disk all torrent file segments, file manifests, and data packets for
+   * the torrent file managed by this object initializing all state in this manager respectively.
+   * Also seeds all validated data.
+   */
+
+  std::vector<Name> downloadTorrentFile(const std::string& path = "");
+  // Request from the network the all segments of the 'torrentFileName' and write onto local disk at
+  // the specified 'path'.
+
+  void download_file_manifest(const Name&              manifestName,
+                              const std::string&       path,
+                              ManifestReceivedCallback onSuccess,
+                              FailedCallback           onFailed) const;
+  // Request from the network the all segments of the 'manifestName' and write onto local disk at
+  // the specified 'path'.
+
+  void download_data_packet(const Name&          packetName,
+                            DataReceivedCallback onSuccess,
+                            FailedCallback       onFailed) const;
+  // Request from the network the Data with the specified 'packetName' and write onto local disk at
+  // 'm_dataPath'.
+
+  void seed(const Data& data) const;
+  // Seed the specified 'data' to the network.
+
+ protected:
+  void onDataReceived(const Data& data);
+
+  void onInterestReceived(const Name& name);
+
+  // A map from each fileManifest to corresponding file stream on disk and a bitmap of which Data
+  // packets this manager currently has
+  mutable std::unordered_map<Name,
+                             std::pair<std::shared_ptr<fs::fstream>,
+                                       std::vector<bool>>>            m_fileStates;
+  // The segments of the TorrentFile this manager has
+  std::vector<TorrentFile>                                            m_torrentSegments;
+  // The FileManifests this manager has
+  std::vector<FileManifest>                                           m_fileManifests;
+  // The name of the initial segment of the torrent file for this manager
+  Name                                                                m_torrentFileName;
+  // The path to the location on disk of the Data packet for this manager
+  std::string                                                         m_dataPath;
+};
+
+inline
+TorrentManager::TorrentManager(const ndn::Name&   torrentFileName,
+                               const std::string& dataPath)
+: m_fileStates()
+, m_torrentSegments()
+, m_fileManifests()
+, m_torrentFileName(torrentFileName)
+, m_dataPath(dataPath)
+{
+}
+
+}  // end ntorrent
+}  // end ndn
+
+#endif // INCLUDED_TORRENT_FILE_MANAGER_H
\ No newline at end of file
