diff --git a/src/common.hpp b/src/common.hpp
new file mode 100644
index 0000000..70d959f
--- /dev/null
+++ b/src/common.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_COMMON_HPP
+#define REPO_COMMON_HPP
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/interest.hpp>
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/data.hpp>
+#include <ndn-cxx/selectors.hpp>
+#include <ndn-cxx/key-locator.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/util/command-interest-validator.hpp>
+#include <ndn-cxx/util/time.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+
+#include <boost/utility.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+
+#include <map>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+namespace repo {
+
+using ndn::Face;
+using ndn::Block;
+using ndn::Name;
+using ndn::Interest;
+using ndn::Selectors;
+using ndn::Exclude;
+using ndn::Data;
+using ndn::KeyLocator;
+using ndn::KeyChain;
+using ndn::CommandInterestValidator;
+using ndn::Scheduler;
+
+using ndn::bind;
+using ndn::shared_ptr;
+using ndn::make_shared;
+using ndn::enable_shared_from_this;
+
+using std::vector;
+using std::string;
+
+using boost::noncopyable;
+
+typedef uint64_t ProcessId;
+typedef uint64_t SegmentNo;
+
+} // namespace repo
+
+#endif // REPO_COMMON_HPP
diff --git a/src/handles/base-handle.cpp b/src/handles/base-handle.cpp
new file mode 100644
index 0000000..76fa36c
--- /dev/null
+++ b/src/handles/base-handle.cpp
@@ -0,0 +1,32 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "base-handle.hpp"
+
+namespace repo {
+
+uint64_t
+BaseHandle::generateProcessId()
+{
+  static boost::random::mt19937_64 gen;
+  static boost::random::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFFLL);
+  return dist(gen);
+}
+
+}
diff --git a/src/handles/base-handle.hpp b/src/handles/base-handle.hpp
new file mode 100644
index 0000000..3223940
--- /dev/null
+++ b/src/handles/base-handle.hpp
@@ -0,0 +1,120 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_HANDLES_BASE_HANDLE_HPP
+#define REPO_HANDLES_BASE_HANDLE_HPP
+
+#include "common.hpp"
+
+#include "storage/storage-handle.hpp"
+#include "repo-command-response.hpp"
+#include "repo-command-parameter.hpp"
+
+namespace repo {
+
+class BaseHandle : noncopyable
+{
+
+public:
+  class Error : std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  BaseHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain, Scheduler& scheduler)
+    : m_face(face)
+    , m_storageHandle(storageHandle)
+    , m_keyChain(keyChain)
+    , m_scheduler(scheduler)
+  {
+  }
+
+  virtual void
+  listen(const Name& prefix) = 0;
+
+protected:
+
+  inline Face&
+  getFace()
+  {
+    return m_face;
+  }
+
+  inline StorageHandle&
+  getStorageHandle()
+  {
+    return m_storageHandle;
+  }
+
+  inline Scheduler&
+  getScheduler()
+  {
+    return m_scheduler;
+  }
+
+  uint64_t
+  generateProcessId();
+
+  void
+  reply(const Interest& commandInterest, const RepoCommandResponse& response);
+
+
+  /**
+   * @brief extract RepoCommandParameter from a command Interest.
+   * @param interest command Interest
+   * @param prefix Name prefix up to command-verb
+   * @param[out] parameter parsed parameter
+   * @throw RepoCommandParameter::Error parse error
+   */
+  void
+  extractParameter(const Interest& interest, const Name& prefix, RepoCommandParameter& parameter);
+
+private:
+
+  Face& m_face;
+  StorageHandle& m_storageHandle;
+  KeyChain& m_keyChain;
+  Scheduler& m_scheduler;
+};
+
+inline void
+BaseHandle::reply(const Interest& commandInterest, const RepoCommandResponse& response)
+{
+  Data rdata(commandInterest.getName());
+  rdata.setContent(response.wireEncode());
+  m_keyChain.sign(rdata);
+  m_face.put(rdata);
+}
+
+inline void
+BaseHandle::extractParameter(const Interest& interest, const Name& prefix,
+                             RepoCommandParameter& parameter)
+{
+  parameter.wireDecode(interest.getName().get(prefix.size()).blockFromValue());
+}
+
+} // namespace repo
+
+#endif // REPO_HANDLES_BASE_HANDLE_HPP
diff --git a/src/handles/delete-handle.cpp b/src/handles/delete-handle.cpp
new file mode 100644
index 0000000..49e4d98
--- /dev/null
+++ b/src/handles/delete-handle.cpp
@@ -0,0 +1,197 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "delete-handle.hpp"
+
+namespace repo {
+
+DeleteHandle::DeleteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
+                           Scheduler& scheduler, CommandInterestValidator& validator)
+  : BaseHandle(face, storageHandle, keyChain, scheduler)
+  , m_validator(validator)
+{
+}
+
+void
+DeleteHandle::onInterest(const Name& prefix, const Interest& interest)
+{
+  //std::cout << "call DeleteHandle" << std::endl;
+  m_validator.validate(interest, bind(&DeleteHandle::onValidated, this, _1, prefix),
+                       bind(&DeleteHandle::onValidationFailed, this, _1, prefix));
+}
+
+
+void
+DeleteHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  throw Error("Delete prefix registration failed");
+}
+
+
+void
+DeleteHandle::onCheckInterest(const Name& prefix, const Interest& interest)
+{
+  BOOST_ASSERT(false); // Deletion progress check, not implemented
+}
+
+
+void
+DeleteHandle::onCheckRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  throw Error("Delete check prefix registration failed");
+}
+
+
+void
+DeleteHandle::onValidated(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  RepoCommandParameter parameter;
+
+  try {
+    extractParameter(*interest, prefix, parameter);
+  }
+  catch (RepoCommandParameter::Error) {
+    negativeReply(*interest, 403);
+    return;
+  }
+
+  if (parameter.hasSelectors()) {
+
+    if (parameter.hasStartBlockId() || parameter.hasEndBlockId()) {
+      negativeReply(*interest, 402);
+      return;
+    }
+
+    //choose data with selector and delete it
+    processSelectorDeleteCommand(*interest, parameter);
+    return;
+  }
+
+  if (!parameter.hasStartBlockId() && !parameter.hasEndBlockId()) {
+    processSingleDeleteCommand(*interest, parameter);
+    return;
+  }
+
+  processSegmentDeleteCommand(*interest, parameter);
+}
+
+void
+DeleteHandle::onValidationFailed(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  std::cout << "invalidated" << std::endl;
+  negativeReply(*interest, 401);
+}
+
+void
+DeleteHandle::listen(const Name& prefix)
+{
+  getFace().setInterestFilter(Name(prefix).append("delete"),
+                              bind(&DeleteHandle::onInterest, this, _1, _2),
+                              bind(&DeleteHandle::onRegisterFailed, this, _1, _2));
+}
+
+void
+DeleteHandle::positiveReply(const Interest& interest, const RepoCommandParameter& parameter,
+                            uint64_t statusCode, uint64_t nDeletedDatas)
+{
+  RepoCommandResponse response;
+  if (parameter.hasProcessId()) {
+    response.setProcessId(parameter.getProcessId());
+    response.setStatusCode(statusCode);
+    response.setDeleteNum(nDeletedDatas);
+  }
+  else {
+    response.setStatusCode(403);
+  }
+  reply(interest, response);
+}
+
+void
+DeleteHandle::negativeReply(const Interest& interest, uint64_t statusCode)
+{
+  RepoCommandResponse response;
+  response.setStatusCode(statusCode);
+  reply(interest, response);
+}
+
+void
+DeleteHandle::processSingleDeleteCommand(const Interest& interest,
+                                         RepoCommandParameter& parameter)
+{
+  uint64_t nDeletedDatas = 0;
+  if (getStorageHandle().deleteData(parameter.getName())) {
+    nDeletedDatas++;
+  }
+  positiveReply(interest, parameter, 200, nDeletedDatas);
+}
+
+void
+DeleteHandle::processSelectorDeleteCommand(const Interest& interest,
+                                           RepoCommandParameter& parameter)
+{
+  uint64_t nDeletedDatas = 0;
+  Name name = parameter.getName();
+  Selectors selectors = parameter.getSelectors();
+  vector<Name> names;
+  getStorageHandle().readNameAny(name, selectors, names);
+
+  for (vector<Name>::iterator it = names.begin(); it != names.end(); ++it) {
+    if (getStorageHandle().deleteData(*it)) {
+      nDeletedDatas++;
+    }
+  }
+
+  //All data has been deleted, return 200
+  positiveReply(interest, parameter, 200, nDeletedDatas);
+}
+
+void
+DeleteHandle::processSegmentDeleteCommand(const Interest& interest,
+                                          RepoCommandParameter& parameter)
+{
+  if (!parameter.hasStartBlockId())
+    parameter.setStartBlockId(0);
+
+  if (parameter.hasEndBlockId()) {
+    SegmentNo startBlockId = parameter.getStartBlockId();
+    SegmentNo endBlockId = parameter.getEndBlockId();
+
+    if (startBlockId > endBlockId) {
+      negativeReply(interest, 403);
+      return;
+    }
+
+    Name prefix = parameter.getName();
+    uint64_t nDeletedDatas = 0;
+    for (SegmentNo i = startBlockId; i <= endBlockId; i++) {
+      Name name = prefix;
+      name.appendSegment(i);
+      if (getStorageHandle().deleteData(name)) {
+        nDeletedDatas++;
+      }
+    }
+    //All the data deleted, return 200
+    positiveReply(interest, parameter, 200, nDeletedDatas);
+  }
+  else {
+    BOOST_ASSERT(false); // segmented deletion without EndBlockId, not implemented
+  }
+}
+
+} //namespace repo
diff --git a/src/handles/delete-handle.hpp b/src/handles/delete-handle.hpp
new file mode 100644
index 0000000..680e8dc
--- /dev/null
+++ b/src/handles/delete-handle.hpp
@@ -0,0 +1,95 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_HANDLES_DELETE_HANDLE_HPP
+#define REPO_HANDLES_DELETE_HANDLE_HPP
+
+#include "base-handle.hpp"
+
+namespace repo {
+
+using std::vector;
+
+class DeleteHandle : public BaseHandle
+{
+
+public:
+  class Error : public BaseHandle::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : BaseHandle::Error(what)
+    {
+    }
+  };
+
+public:
+  DeleteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
+               Scheduler& scheduler, CommandInterestValidator& validator);
+
+  virtual void
+  listen(const Name& prefix);
+
+private:
+  void
+  onInterest(const Name& prefix, const Interest& interest);
+
+  void
+  onRegisterFailed(const Name& prefix, const std::string& reason);
+
+  void
+  onValidated(const shared_ptr<const Interest>& interest, const Name& prefix);
+
+  void
+  onValidationFailed(const shared_ptr<const Interest>& interest, const Name& prefix);
+
+  /**
+  * @todo delete check has not been realized due to the while loop of segmented data deletion.
+  */
+  void
+  onCheckInterest(const Name& prefix, const Interest& interest);
+
+  void
+  onCheckRegisterFailed(const Name& prefix, const std::string& reason);
+
+  void
+  positiveReply(const Interest& interest, const RepoCommandParameter& parameter,
+                uint64_t statusCode, uint64_t nDeletedDatas);
+
+  void
+  negativeReply(const Interest& interest, uint64_t statusCode);
+
+  void
+  processSingleDeleteCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+  void
+  processSelectorDeleteCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+  void
+  processSegmentDeleteCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+private:
+  CommandInterestValidator& m_validator;
+
+};
+
+} // namespace repo
+
+#endif // REPO_HANDLES_DELETE_HANDLE_HPP
diff --git a/src/handles/read-handle.cpp b/src/handles/read-handle.cpp
new file mode 100644
index 0000000..d0e80b3
--- /dev/null
+++ b/src/handles/read-handle.cpp
@@ -0,0 +1,48 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "read-handle.hpp"
+
+namespace repo {
+
+void
+ReadHandle::onInterest(const Name& prefix, const Interest& interest)
+{
+  Data data;
+  if (getStorageHandle().readData(interest, data)) {
+    getFace().put(data);
+  }
+}
+
+void
+ReadHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  std::cerr << "ERROR: Failed to register prefix in local hub's daemon" << std::endl;
+  getFace().shutdown();
+}
+
+void
+ReadHandle::listen(const Name& prefix)
+{
+  getFace().setInterestFilter(prefix,
+                              bind(&ReadHandle::onInterest, this, _1, _2),
+                              bind(&ReadHandle::onRegisterFailed, this, _1, _2));
+}
+
+} //namespace repo
diff --git a/src/handles/read-handle.hpp b/src/handles/read-handle.hpp
new file mode 100644
index 0000000..93468c0
--- /dev/null
+++ b/src/handles/read-handle.hpp
@@ -0,0 +1,52 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_HANDLES_READ_HANDLE_HPP
+#define REPO_HANDLES_READ_HANDLE_HPP
+
+#include "base-handle.hpp"
+
+namespace repo {
+
+class ReadHandle : public BaseHandle
+{
+
+public:
+  ReadHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain, Scheduler& scheduler)
+    : BaseHandle(face, storageHandle, keyChain, scheduler)
+  {
+  }
+
+  virtual void
+  listen(const Name& prefix);
+
+private:
+  /**
+   * @brief Read data from backend storage
+   */
+  void
+  onInterest(const Name& prefix, const Interest& interest);
+
+  void
+  onRegisterFailed(const Name& prefix, const std::string& reason);
+};
+
+} // namespace repo
+
+#endif // REPO_HANDLES_READ_HANDLE_HPP
diff --git a/src/handles/tcp-bulk-insert-handle.cpp b/src/handles/tcp-bulk-insert-handle.cpp
new file mode 100644
index 0000000..a69dfe2
--- /dev/null
+++ b/src/handles/tcp-bulk-insert-handle.cpp
@@ -0,0 +1,218 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tcp-bulk-insert-handle.hpp"
+
+namespace repo {
+
+const size_t MAX_NDN_PACKET_SIZE = 8800;
+
+namespace detail {
+
+class TcpBulkInsertClient : noncopyable
+{
+public:
+  TcpBulkInsertClient(TcpBulkInsertHandle& writer,
+                      const shared_ptr<boost::asio::ip::tcp::socket>& socket)
+    : m_writer(writer)
+    , m_socket(socket)
+    , m_hasStarted(false)
+    , m_inputBufferSize(0)
+  {
+  }
+
+  static void
+  startReceive(const shared_ptr<TcpBulkInsertClient>& client)
+  {
+    BOOST_ASSERT(!client->m_hasStarted);
+
+    client->m_socket->async_receive(
+      boost::asio::buffer(client->m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
+      bind(&TcpBulkInsertClient::handleReceive, client, _1, _2, client));
+
+    client->m_hasStarted = true;
+  }
+
+private:
+  void
+  handleReceive(const boost::system::error_code& error,
+                std::size_t nBytesReceived,
+                const shared_ptr<TcpBulkInsertClient>& client);
+
+private:
+  TcpBulkInsertHandle& m_writer;
+  shared_ptr<boost::asio::ip::tcp::socket> m_socket;
+  bool m_hasStarted;
+  uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
+  std::size_t m_inputBufferSize;
+};
+
+} // namespace detail
+
+TcpBulkInsertHandle::TcpBulkInsertHandle(boost::asio::io_service& ioService,
+                                         StorageHandle& storageHandle)
+  : m_acceptor(ioService)
+  , m_storageHandle(storageHandle)
+{
+}
+
+void
+TcpBulkInsertHandle::listen(const std::string& host, const std::string& port)
+{
+  using namespace boost::asio;
+
+  ip::tcp::resolver resolver(m_acceptor.get_io_service());
+  ip::tcp::resolver::query query(host, port);
+
+  ip::tcp::resolver::iterator endpoint = resolver.resolve(query);
+  ip::tcp::resolver::iterator end;
+
+  if (endpoint == end)
+    throw Error("Cannot listen on [" + host + ":" + port + "]");
+
+  m_localEndpoint = *endpoint;
+  std::cerr << "Start listening on " << m_localEndpoint  << std::endl;
+
+  m_acceptor.open(m_localEndpoint .protocol());
+  m_acceptor.set_option(ip::tcp::acceptor::reuse_address(true));
+  if (m_localEndpoint.address().is_v6())
+    {
+      m_acceptor.set_option(ip::v6_only(true));
+    }
+  m_acceptor.bind(m_localEndpoint);
+  m_acceptor.listen(255);
+
+  shared_ptr<ip::tcp::socket> clientSocket =
+    make_shared<ip::tcp::socket>(boost::ref(m_acceptor.get_io_service()));
+  m_acceptor.async_accept(*clientSocket,
+                          bind(&TcpBulkInsertHandle::handleAccept, this, _1,
+                               clientSocket));
+}
+
+void
+TcpBulkInsertHandle::stop()
+{
+  m_acceptor.cancel();
+  m_acceptor.close();
+}
+
+void
+TcpBulkInsertHandle::handleAccept(const boost::system::error_code& error,
+                                  const shared_ptr<boost::asio::ip::tcp::socket>& socket)
+{
+  using namespace boost::asio;
+
+  if (error) {
+    // if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
+    //   return;
+    return;
+  }
+
+  std::cerr << "New connection from " << socket->remote_endpoint() << std::endl;
+
+  shared_ptr<detail::TcpBulkInsertClient> client =
+    make_shared<detail::TcpBulkInsertClient>(boost::ref(*this), socket);
+  detail::TcpBulkInsertClient::startReceive(client);
+
+  // prepare accepting the next connection
+  shared_ptr<ip::tcp::socket> clientSocket =
+    make_shared<ip::tcp::socket>(boost::ref(m_acceptor.get_io_service()));
+  m_acceptor.async_accept(*clientSocket,
+                          bind(&TcpBulkInsertHandle::handleAccept, this, _1,
+                               clientSocket));
+}
+
+void
+detail::TcpBulkInsertClient::handleReceive(const boost::system::error_code& error,
+                                           std::size_t nBytesReceived,
+                                           const shared_ptr<detail::TcpBulkInsertClient>& client)
+{
+  if (error)
+    {
+      if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
+        return;
+
+      boost::system::error_code error;
+      m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
+      m_socket->close(error);
+      return;
+    }
+
+  m_inputBufferSize += nBytesReceived;
+
+  // do magic
+
+  std::size_t offset = 0;
+
+  bool isOk = true;
+  Block element;
+  while (m_inputBufferSize - offset > 0)
+    {
+      isOk = Block::fromBuffer(m_inputBuffer + offset, m_inputBufferSize - offset, element);
+      if (!isOk)
+        break;
+
+      offset += element.size();
+      BOOST_ASSERT(offset <= m_inputBufferSize);
+
+      if (element.type() == ndn::Tlv::Data)
+        {
+          try {
+            Data data(element);
+            bool isOk = m_writer.getStorageHandle().insertData(data);
+            if (isOk)
+              std::cerr << "Successfully injected " << data.getName() << std::endl;
+            else
+              std::cerr << "FAILED to inject " << data.getName() << std::endl;
+          }
+          catch (std::runtime_error& error) {
+            /// \todo Catch specific error after determining what wireDecode() can throw
+            std::cerr << "Error decoding received Data packet" << std::endl;
+          }
+        }
+    }
+  if (!isOk && m_inputBufferSize == MAX_NDN_PACKET_SIZE && offset == 0)
+    {
+      boost::system::error_code error;
+      m_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, error);
+      m_socket->close(error);
+      return;
+    }
+
+  if (offset > 0)
+    {
+      if (offset != m_inputBufferSize)
+        {
+          std::copy(m_inputBuffer + offset, m_inputBuffer + m_inputBufferSize,
+                    m_inputBuffer);
+          m_inputBufferSize -= offset;
+        }
+      else
+        {
+          m_inputBufferSize = 0;
+        }
+    }
+
+  m_socket->async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
+                                              MAX_NDN_PACKET_SIZE - m_inputBufferSize), 0,
+                          bind(&TcpBulkInsertClient::handleReceive, this, _1, _2, client));
+}
+
+
+} // namespace repo
diff --git a/src/handles/tcp-bulk-insert-handle.hpp b/src/handles/tcp-bulk-insert-handle.hpp
new file mode 100644
index 0000000..17233f4
--- /dev/null
+++ b/src/handles/tcp-bulk-insert-handle.hpp
@@ -0,0 +1,72 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_HANDLES_TCP_BULK_INSERT_HANDLE_HPP
+#define REPO_HANDLES_TCP_BULK_INSERT_HANDLE_HPP
+
+#include "common.hpp"
+#include "storage/storage-handle.hpp"
+
+#include <boost/asio.hpp>
+
+namespace repo {
+
+class TcpBulkInsertHandle : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  TcpBulkInsertHandle(boost::asio::io_service& ioService,
+                      StorageHandle& storageHandle);
+
+  void
+  listen(const std::string& host, const std::string& port);
+
+  void
+  stop();
+
+  StorageHandle&
+  getStorageHandle()
+  {
+    return m_storageHandle;
+  }
+
+private:
+  void
+  handleAccept(const boost::system::error_code& error,
+               const shared_ptr<boost::asio::ip::tcp::socket>& socket);
+
+private:
+  boost::asio::ip::tcp::acceptor m_acceptor;
+  boost::asio::ip::tcp::endpoint m_localEndpoint;
+  StorageHandle& m_storageHandle;
+};
+
+} // namespace repo
+
+#endif // REPO_HANDLES_TCP_BULK_INSERT_HANDLE_HPP
diff --git a/src/handles/write-handle.cpp b/src/handles/write-handle.cpp
new file mode 100644
index 0000000..0ea17ae
--- /dev/null
+++ b/src/handles/write-handle.cpp
@@ -0,0 +1,546 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "write-handle.hpp"
+
+namespace repo {
+
+static const int RETRY_TIMEOUT = 3;
+static const int DEFAULT_CREDIT = 12;
+static const ndn::time::milliseconds NOEND_TIMEOUT(10000);
+static const ndn::time::milliseconds PROCESS_DELETE_TIME(10000);
+
+WriteHandle::WriteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
+                         Scheduler& scheduler, CommandInterestValidator& validator)
+  : BaseHandle(face, storageHandle, keyChain, scheduler)
+  , m_validator(validator)
+  , m_retryTime(RETRY_TIMEOUT)
+  , m_credit(DEFAULT_CREDIT)
+  , m_noEndTimeout(NOEND_TIMEOUT)
+{
+}
+
+void
+WriteHandle::deleteProcess(ProcessId processId)
+{
+  m_processes.erase(processId);
+}
+
+// Interest.
+void
+WriteHandle::onInterest(const Name& prefix, const Interest& interest)
+{
+  m_validator.validate(interest,
+                          bind(&WriteHandle::onValidated, this, _1, prefix),
+                          bind(&WriteHandle::onValidationFailed, this, _1));
+}
+
+// onRegisterFailed.
+void
+WriteHandle::onRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  throw Error("Insert prefix registration failed");
+}
+
+// onRegisterFailed for insert.
+void
+WriteHandle::onCheckRegisterFailed(const Name& prefix, const std::string& reason)
+{
+  throw Error("Insert check prefix registration failed");
+}
+
+void
+WriteHandle::onValidated(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  //m_validResult = 1;
+  RepoCommandParameter parameter;
+  try {
+    extractParameter(*interest, prefix, parameter);
+  }
+  catch (RepoCommandParameter::Error) {
+    negativeReply(*interest, 403);
+    return;
+  }
+
+  if (parameter.hasStartBlockId() || parameter.hasEndBlockId()) {
+    if (parameter.hasSelectors()) {
+      negativeReply(*interest, 402);
+      return;
+    }
+    processSegmentedInsertCommand(*interest, parameter);
+  }
+  else {
+    processSingleInsertCommand(*interest, parameter);
+  }
+
+}
+
+void
+WriteHandle::onValidationFailed(const shared_ptr<const Interest>& interest)
+{
+  std::cout << "invalidated" << std::endl;
+  negativeReply(*interest, 401);
+}
+
+void
+WriteHandle::onData(const Interest& interest, ndn::Data& data, ProcessId processId)
+{
+  //std::cout << "onData" << std::endl;
+  //std::cout << "I: " << interest.toUri() << std::endl;
+  //std::cout << "D: " << data.getName().toUri() << std::endl;
+  if (m_processes.count(processId) == 0) {
+    return;
+  }
+
+  ProcessInfo& process = m_processes[processId];
+  RepoCommandResponse& response = process.response;
+
+  if (response.getInsertNum() == 0) {
+    getStorageHandle().insertData(data);
+    response.setInsertNum(1);
+  }
+
+  deferredDeleteProcess(processId);
+}
+
+void
+WriteHandle::onSegmentData(const Interest& interest, Data& data, ProcessId processId)
+{
+  //std::cout << "I: " << interest.toUri() << std::endl;
+  //std::cout << "D: " << data.getName().toUri() << std::endl;
+  //retrieve the process from the responsemap
+
+  if (m_processes.count(processId) == 0) {
+    return;
+  }
+  RepoCommandResponse& response = m_processes[processId].response;
+
+  //refresh endBlockId
+  Name::Component finalBlockId = data.getFinalBlockId();
+
+  if (!finalBlockId.empty()) {
+    SegmentNo final = finalBlockId.toSegment();
+    if (response.hasEndBlockId()) {
+      if (final < response.getEndBlockId()) {
+        response.setEndBlockId(final);
+      }
+    }
+    else {
+      response.setEndBlockId(final);
+    }
+  }
+
+  //insert data
+  //std::cout << "start to insert" << std::endl;
+  if (getStorageHandle().insertData(data)) {
+    response.setInsertNum(response.getInsertNum() + 1);
+  }
+  //std::cout << "end of insert" << std::endl;
+
+  //it->second = response;
+
+  onSegmentDataControl(processId, interest);
+}
+
+void
+WriteHandle::onTimeout(const ndn::Interest& interest, ProcessId processId)
+{
+  std::cout << "Timeout" << std::endl;
+  m_processes.erase(processId);
+}
+
+void
+WriteHandle::onSegmentTimeout(const Interest& interest, ProcessId processId)
+{
+  std::cout << "SegTimeout" << std::endl;
+
+  onSegmentTimeoutControl(processId, interest);
+}
+
+void
+WriteHandle::listen(const Name& prefix)
+{
+  Name insertPrefix;
+  insertPrefix.append(prefix).append("insert");
+  getFace().setInterestFilter(insertPrefix,
+                              bind(&WriteHandle::onInterest, this, _1, _2),
+                              bind(&WriteHandle::onRegisterFailed, this, _1, _2));
+  Name insertCheckPrefix;
+  insertCheckPrefix.append(prefix).append("insert check");
+  getFace().setInterestFilter(insertCheckPrefix,
+                              bind(&WriteHandle::onCheckInterest, this, _1, _2),
+                              bind(&WriteHandle::onRegisterFailed, this, _1, _2));
+}
+
+void
+WriteHandle::segInit(ProcessId processId, const RepoCommandParameter& parameter)
+{
+  ProcessInfo& process = m_processes[processId];
+  process.credit = 0;
+
+  map<SegmentNo, int>& processRetry = process.retryCounts;
+
+  Name name = parameter.getName();
+  SegmentNo startBlockId = parameter.getStartBlockId();
+
+  uint64_t initialCredit = m_credit;
+
+  if (parameter.hasEndBlockId()) {
+    initialCredit =
+      std::min(initialCredit, parameter.getEndBlockId() - parameter.getStartBlockId() + 1);
+  }
+  else {
+    // set noEndTimeout timer
+    process.noEndTime = ndn::time::steady_clock::now() +
+                        m_noEndTimeout;
+  }
+  process.credit = initialCredit;
+  SegmentNo segment = startBlockId;
+  for (; segment < startBlockId + initialCredit; ++segment) {
+    Name fetchName = name;
+    fetchName.appendSegment(segment);
+    Interest interest(fetchName);
+    //std::cout << "seg:" << j<<std::endl;
+    getFace().expressInterest(interest,
+                              bind(&WriteHandle::onSegmentData, this, _1, _2, processId),
+                              bind(&WriteHandle::onSegmentTimeout, this, _1, processId));
+    process.credit--;
+    processRetry[segment] = 0;
+  }
+
+  queue<SegmentNo>& nextSegmentQueue = process.nextSegmentQueue;
+
+  process.nextSegment = segment;
+  nextSegmentQueue.push(segment);
+}
+
+void
+WriteHandle::onSegmentDataControl(ProcessId processId, const Interest& interest)
+{
+  //std::cout << "onSegmentDataControl: " << processId << std::endl;
+
+  if (m_processes.count(processId) == 0) {
+    return;
+  }
+  ProcessInfo& process = m_processes[processId];
+  RepoCommandResponse& response = process.response;
+  int& processCredit = process.credit;
+  //onSegmentDataControl is called when a data returns.
+  //When data returns, processCredit++
+  processCredit++;
+  SegmentNo& nextSegment = process.nextSegment;
+  queue<SegmentNo>& nextSegmentQueue = process.nextSegmentQueue;
+  map<SegmentNo, int>& retryCounts = process.retryCounts;
+
+  //read whether notime timeout
+  if (!response.hasEndBlockId()) {
+
+    ndn::time::steady_clock::TimePoint& noEndTime = process.noEndTime;
+    ndn::time::steady_clock::TimePoint now = ndn::time::steady_clock::now();
+
+    if (now > noEndTime) {
+      std::cout << "noEndtimeout: " << processId << std::endl;
+      //m_processes.erase(processId);
+      //StatusCode should be refreshed as 405
+      response.setStatusCode(405);
+      //schedule a delete event
+      deferredDeleteProcess(processId);
+      return;
+    }
+  }
+
+  //read whether this process has total ends, if ends, remove control info from the maps
+  if (response.hasEndBlockId()) {
+    uint64_t nSegments =
+      response.getEndBlockId() - response.getStartBlockId() + 1;
+    if (response.getInsertNum() >= nSegments) {
+      //m_processes.erase(processId);
+      //All the data has been inserted, StatusCode is refreshed as 200
+      response.setStatusCode(200);
+      deferredDeleteProcess(processId);
+      return;
+    }
+  }
+
+  //check whether there is any credit
+  if (processCredit == 0)
+    return;
+
+
+  //check whether sent queue empty
+  if (nextSegmentQueue.empty()) {
+    //do not do anything
+    return;
+  }
+
+  //pop the queue
+  SegmentNo sendingSegment = nextSegmentQueue.front();
+  nextSegmentQueue.pop();
+
+  //check whether sendingSegment exceeds
+  if (response.hasEndBlockId() && sendingSegment > response.getEndBlockId()) {
+    //do not do anything
+    return;
+  }
+
+  //read whether this is retransmitted data;
+  SegmentNo fetchedSegment =
+    interest.getName().get(interest.getName().size() - 1).toSegment();
+
+  BOOST_ASSERT(retryCounts.count(fetchedSegment) != 0);
+
+  //find this fetched data, remove it from this map
+  //rit->second.erase(oit);
+  retryCounts.erase(fetchedSegment);
+  //express the interest of the top of the queue
+  Name fetchName(interest.getName().getPrefix(-1));
+  fetchName.appendSegment(sendingSegment);
+  Interest fetchInterest(fetchName);
+  getFace().expressInterest(fetchInterest,
+                            bind(&WriteHandle::onSegmentData, this, _1, _2, processId),
+                            bind(&WriteHandle::onSegmentTimeout, this, _1, processId));
+  //When an interest is expressed, processCredit--
+  processCredit--;
+  //std::cout << "sent seg: " << sendingSegment << std::endl;
+  if (retryCounts.count(sendingSegment) == 0) {
+    //not found
+    retryCounts[sendingSegment] = 0;
+  }
+  else {
+    //found
+    retryCounts[sendingSegment] = retryCounts[sendingSegment] + 1;
+  }
+  //increase the next seg and put it into the queue
+  if (!response.hasEndBlockId() || (nextSegment + 1) <= response.getEndBlockId()) {
+    nextSegment++;
+    nextSegmentQueue.push(nextSegment);
+  }
+}
+
+void
+WriteHandle::onSegmentTimeoutControl(ProcessId processId, const Interest& interest)
+{
+  if (m_processes.count(processId) == 0) {
+    return;
+  }
+  ProcessInfo& process = m_processes[processId];
+  // RepoCommandResponse& response = process.response;
+  // SegmentNo& nextSegment = process.nextSegment;
+  // queue<SegmentNo>& nextSegmentQueue = process.nextSegmentQueue;
+  map<SegmentNo, int>& retryCounts = process.retryCounts;
+
+  SegmentNo timeoutSegment = interest.getName().get(-1).toSegment();
+
+  std::cout << "timeoutSegment: " << timeoutSegment << std::endl;
+
+  BOOST_ASSERT(retryCounts.count(timeoutSegment) != 0);
+
+  //read the retry time. If retry out of time, fail the process. if not, plus
+  int& retryTime = retryCounts[timeoutSegment];
+  if (retryTime >= m_retryTime) {
+    //fail this process
+    std::cout << "Retry timeout: " << processId << std::endl;
+    m_processes.erase(processId);
+    return;
+  }
+  else {
+    //Reput it in the queue, retryTime++
+    retryTime++;
+    Interest retryInterest(interest.getName());
+    getFace().expressInterest(retryInterest,
+                              bind(&WriteHandle::onSegmentData, this, _1, _2, processId),
+                              bind(&WriteHandle::onSegmentTimeout, this, _1, processId));
+  }
+
+}
+
+void
+WriteHandle::onCheckInterest(const Name& prefix, const Interest& interest)
+{
+  m_validator.validate(interest,
+                          bind(&WriteHandle::onCheckValidated, this, _1, prefix),
+                          bind(&WriteHandle::onCheckValidationFailed, this, _1));
+
+}
+
+void
+WriteHandle::onCheckValidated(const shared_ptr<const Interest>& interest, const Name& prefix)
+{
+  RepoCommandParameter parameter;
+  try {
+    extractParameter(*interest, prefix, parameter);
+  }
+  catch (RepoCommandParameter::Error) {
+    negativeReply(*interest, 403);
+    return;
+  }
+
+  if (!parameter.hasProcessId()) {
+    negativeReply(*interest, 403);
+    return;
+  }
+  //check whether this process exists
+  ProcessId processId = parameter.getProcessId();
+  if (m_processes.count(processId) == 0) {
+    std::cout << "no such processId: " << processId << std::endl;
+    negativeReply(*interest, 404);
+    return;
+  }
+
+  ProcessInfo& process = m_processes[processId];
+
+  RepoCommandResponse& response = process.response;
+
+  //Check whether it is single data fetching
+  if (!response.hasStartBlockId() &&
+      !response.hasEndBlockId()) {
+    reply(*interest, response);
+    return;
+  }
+
+  //read if noEndtimeout
+  if (!response.hasEndBlockId()) {
+    extendNoEndTime(process);
+    reply(*interest, response);
+    return;
+  }
+  else {
+    reply(*interest, response);
+  }
+}
+
+void
+WriteHandle::onCheckValidationFailed(const shared_ptr<const Interest>& interest)
+{
+  negativeReply(*interest, 401);
+}
+
+void
+WriteHandle::deferredDeleteProcess(ProcessId processId)
+{
+  getScheduler().scheduleEvent(PROCESS_DELETE_TIME,
+                               ndn::bind(&WriteHandle::deleteProcess, this, processId));
+}
+
+void
+WriteHandle::processSingleInsertCommand(const Interest& interest,
+                                        RepoCommandParameter& parameter)
+{
+  ProcessId processId = generateProcessId();
+
+  ProcessInfo& process = m_processes[processId];
+
+  RepoCommandResponse& response = process.response;
+  response.setStatusCode(100);
+  response.setProcessId(processId);
+  response.setInsertNum(0);
+
+  reply(interest, response);
+
+  response.setStatusCode(300);
+
+  Interest fetchInterest(parameter.getName());
+  if (parameter.hasSelectors()) {
+    fetchInterest.setSelectors(parameter.getSelectors());
+  }
+  getFace().expressInterest(fetchInterest,
+                            bind(&WriteHandle::onData, this, _1, _2, processId),
+                            bind(&WriteHandle::onTimeout, this, _1, processId));
+}
+
+void
+WriteHandle::processSegmentedInsertCommand(const Interest& interest,
+                                           RepoCommandParameter& parameter)
+{
+  if (parameter.hasEndBlockId()) {
+    //normal fetch segment
+    if (!parameter.hasStartBlockId()) {
+      parameter.setStartBlockId(0);
+    }
+
+    SegmentNo startBlockId = parameter.getStartBlockId();
+    SegmentNo endBlockId = parameter.getEndBlockId();
+    //std::cout << "startBlockId: " << startBlockId << std::endl;
+    //std::cout << "endBlockId: " << endBlockId << std::endl;
+    if (startBlockId > endBlockId) {
+      negativeReply(interest, 403);
+      return;
+    }
+
+    ProcessId processId = generateProcessId();
+    ProcessInfo& process = m_processes[processId];
+    //std::cout << "processId: " << processId << std::endl;
+    RepoCommandResponse& response = process.response;
+    response.setStatusCode(100);
+    response.setProcessId(processId);
+    response.setInsertNum(0);
+    response.setStartBlockId(startBlockId);
+    response.setEndBlockId(endBlockId);
+
+    reply(interest, response);
+
+    //300 means data fetching is in progress
+    response.setStatusCode(300);
+
+    segInit(processId, parameter);
+  }
+  else {
+    //no EndBlockId, so fetch FinalBlockId in data, if timeout, stop
+    ProcessId processId = generateProcessId();
+    ProcessInfo& process = m_processes[processId];
+    //std::cout << "processId: " << processId << std::endl;
+    RepoCommandResponse& response = process.response;
+    response.setStatusCode(100);
+    response.setProcessId(processId);
+    response.setInsertNum(0);
+    response.setStartBlockId(parameter.getStartBlockId());
+    reply(interest, response);
+
+    //300 means data fetching is in progress
+    response.setStatusCode(300);
+
+    segInit(processId, parameter);
+  }
+}
+
+void
+WriteHandle::extendNoEndTime(ProcessInfo& process)
+{
+  ndn::time::steady_clock::TimePoint& noEndTime = process.noEndTime;
+  ndn::time::steady_clock::TimePoint now = ndn::time::steady_clock::now();
+  RepoCommandResponse& response = process.response;
+  if (now > noEndTime) {
+    response.setStatusCode(405);
+    return;
+  }
+  //extends noEndTime
+  process.noEndTime =
+    ndn::time::steady_clock::now() + m_noEndTimeout;
+
+}
+
+void
+WriteHandle::negativeReply(const Interest& interest, int statusCode)
+{
+  RepoCommandResponse response;
+  response.setStatusCode(statusCode);
+  reply(interest, response);
+}
+
+} //namespace repo
diff --git a/src/handles/write-handle.hpp b/src/handles/write-handle.hpp
new file mode 100644
index 0000000..075e78c
--- /dev/null
+++ b/src/handles/write-handle.hpp
@@ -0,0 +1,225 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_HANDLES_WRITE_HANDLE_HPP
+#define REPO_HANDLES_WRITE_HANDLE_HPP
+
+#include "base-handle.hpp"
+
+#include <queue>
+
+namespace repo {
+
+using std::map;
+using std::pair;
+using std::queue;
+
+/**
+ * @brief WriteHandle provides basic credit based congestion control.
+ *
+ * First repo sends interests of credit number and then credit will be 0.
+ *
+ * If a data comes, credit++ and sends a interest then credit--.
+ *
+ * If the interest timeout, repo will retry and send interest in retrytimes.
+ *
+ * If one interest timeout beyond retrytimes, the fetching process will terminate.
+ *
+ * Another case is that if command will insert segmented data without EndBlockId.
+ *
+ * The repo will keep fetching data in noendTimeout time.
+ *
+ * If data returns with FinalBlockId, this detecting timeout process will terminate.
+ *
+ * If client sends a insert check command, the noendTimeout timer will be set to 0.
+ *
+ * If repo cannot get FinalBlockId in noendTimeout time, the fetching process will terminate.
+ */
+class WriteHandle : public BaseHandle
+{
+
+public:
+  class Error : public BaseHandle::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : BaseHandle::Error(what)
+    {
+    }
+  };
+
+
+public:
+  WriteHandle(Face& face, StorageHandle& storageHandle, KeyChain& keyChain,
+              Scheduler& scheduler, CommandInterestValidator& validator);
+
+  virtual void
+  listen(const Name& prefix);
+
+private:
+  /**
+  * @brief Information of insert process including variables for response
+  *        and credit based flow control
+  */
+  struct ProcessInfo
+  {
+    //ProcessId id;
+    RepoCommandResponse response;
+    queue<SegmentNo> nextSegmentQueue;  ///< queue of waiting segment
+                                        ///  to be sent when having credits
+    SegmentNo nextSegment;  ///< last segment put into the nextSegmentQueue
+    map<SegmentNo, int> retryCounts;  ///< to store retrying times of timeout segment
+    int credit;  ///< congestion control credits of process
+
+    /**
+     * @brief the latest time point at which EndBlockId must be determined
+     *
+     * Segmented fetch process will terminate if EndBlockId cannot be
+     * determined before this time point.
+     * It is initialized to now()+noEndTimeout when segmented fetch process begins,
+     * and reset to now()+noEndTimeout each time an insert status check command is processed.
+     */
+    ndn::time::steady_clock::TimePoint noEndTime;
+  };
+
+private: // insert command
+  /**
+   * @brief handle insert commands
+   */
+  void
+  onInterest(const Name& prefix, const Interest& interest);
+
+  void
+  onValidated(const shared_ptr<const Interest>& interest, const Name& prefix);
+
+  void
+  onValidationFailed(const shared_ptr<const Interest>& interest);
+
+  /**
+   * @brief insert command prefix register failed
+   */
+  void
+  onRegisterFailed(const Name& prefix, const std::string& reason);
+
+private: // single data fetching
+  /**
+   * @brief fetch one data
+   */
+  void
+  onData(const Interest& interest, Data& data, ProcessId processId);
+
+  /**
+   * @brief handle when fetching one data timeout
+   */
+  void
+  onTimeout(const Interest& interest, ProcessId processId);
+
+  void
+  processSingleInsertCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+private:  // segmented data fetching
+  /**
+   * @brief fetch segmented data
+   */
+  void
+  onSegmentData(const Interest& interest, Data& data, ProcessId processId);
+
+  /**
+   * @brief Timeout when fetching segmented data. Data can be fetched RETRY_TIMEOUT times.
+   */
+  void
+  onSegmentTimeout(const Interest& interest, ProcessId processId);
+
+  /**
+   * @brief initiate fetching segmented data
+   */
+  void
+  segInit(ProcessId processId, const RepoCommandParameter& parameter);
+
+  /**
+   * @brief control for sending interests in function onSegmentData()
+   */
+  void
+  onSegmentDataControl(ProcessId processId, const Interest& interest);
+
+  /**
+   * @brief control for sending interest in function onSegmentTimeout
+   */
+  void
+  onSegmentTimeoutControl(ProcessId processId, const Interest& interest);
+
+  void
+  processSegmentedInsertCommand(const Interest& interest, RepoCommandParameter& parameter);
+
+  /**
+   * @brief extends noEndTime of process if not noEndTimeout, set StatusCode 405
+   *
+   * called by onCheckValidated() if there is no EndBlockId. If not noEndTimeout,
+   * extends noEndTime of process. If noEndTimeout, set status code 405 as noEndTimeout.
+   */
+  void
+  extendNoEndTime(ProcessInfo& process);
+
+private: // insert state check command
+  /**
+   * @brief handle insert check command
+   */
+  void
+  onCheckInterest(const Name& prefix, const Interest& interest);
+
+  /**
+   * @brief insert check command prefix register failed
+   */
+  void
+  onCheckRegisterFailed(const Name& prefix, const std::string& reason);
+
+  void
+  onCheckValidated(const shared_ptr<const Interest>& interest, const Name& prefix);
+
+  void
+  onCheckValidationFailed(const shared_ptr<const Interest>& interest);
+
+private:
+  void
+  deleteProcess(ProcessId processId);
+
+  /**
+   * @brief schedule a event to delete the process
+   */
+  void
+  deferredDeleteProcess(ProcessId processId);
+
+  void
+  negativeReply(const Interest& interest, int statusCode);
+
+private:
+
+  CommandInterestValidator& m_validator;
+
+  map<ProcessId, ProcessInfo> m_processes;
+
+  int m_retryTime;
+  int m_credit;
+  ndn::time::milliseconds m_noEndTimeout;
+};
+
+} // namespace repo
+
+#endif // REPO_HANDLES_WRITE_HANDLE_HPP
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..e69c32d
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,95 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.hpp"
+#include "repo.hpp"
+
+using namespace repo;
+
+static const string ndnRepoUsageMessage =
+  /* argv[0] */ " - Next generation of NDN repository\n"
+  "-h: show help message\n"
+  "-c: set config file path\n"
+  ;
+
+void
+terminate(boost::asio::io_service& ioService,
+          const boost::system::error_code& error,
+          int signalNo,
+          boost::asio::signal_set& signalSet)
+{
+  if (error)
+    return;
+
+  if (signalNo == SIGINT ||
+      signalNo == SIGTERM)
+    {
+      ioService.stop();
+      std::cout << "Caught signal '" << strsignal(signalNo) << "', exiting..." << std::endl;
+    }
+  else
+    {
+      /// \todo May be try to reload config file
+      signalSet.async_wait(bind(&terminate, boost::ref(ioService), _1, _2,
+                                boost::ref(signalSet)));
+    }
+}
+
+int
+main(int argc, char** argv)
+{
+  string configPath = DEFAULT_CONFIG_FILE;
+  int opt;
+  while ((opt = getopt(argc, argv, "hc:")) != -1) {
+    switch (opt) {
+    case 'h':
+      std::cout << argv[0] << ndnRepoUsageMessage << std::endl;
+      return 1;
+    case 'c':
+      configPath = string(optarg);
+      break;
+    default:
+      break;
+    }
+  }
+
+  try {
+    boost::asio::io_service ioService;
+    Repo repoInstance(ioService, parseConfig(configPath));
+
+    boost::asio::signal_set signalSet(ioService);
+    signalSet.add(SIGINT);
+    signalSet.add(SIGTERM);
+    signalSet.add(SIGHUP);
+    signalSet.add(SIGUSR1);
+    signalSet.add(SIGUSR2);
+    signalSet.async_wait(bind(&terminate, boost::ref(ioService), _1, _2,
+                              boost::ref(signalSet)));
+
+    repoInstance.enableListening();
+
+    ioService.run();
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    return 2;
+  }
+
+  return 0;
+}
diff --git a/src/repo-command-parameter.hpp b/src/repo-command-parameter.hpp
new file mode 100644
index 0000000..8a8c4bb
--- /dev/null
+++ b/src/repo-command-parameter.hpp
@@ -0,0 +1,344 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_REPO_COMMAND_PARAMETER_HPP
+#define REPO_REPO_COMMAND_PARAMETER_HPP
+
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/selectors.hpp>
+#include "repo-tlv.hpp"
+
+namespace repo {
+
+using ndn::Name;
+using ndn::Block;
+using ndn::EncodingImpl;
+using ndn::Selectors;
+using ndn::EncodingEstimator;
+using ndn::EncodingBuffer;
+
+/**
+* @brief Class defining abstraction of parameter of command for NDN Repo Protocol
+* @sa link http://redmine.named-data.net/projects/repo-ng/wiki/Repo_Protocol_Specification#RepoCommandParameter
+**/
+
+class RepoCommandParameter
+{
+public:
+  class Error : public ndn::Tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : ndn::Tlv::Error(what)
+    {
+    }
+  };
+
+  RepoCommandParameter()
+    : m_hasName(false)
+    , m_hasStartBlockId(false)
+    , m_hasEndBlockId(false)
+    , m_hasProcessId(false)
+  {
+  }
+
+  explicit
+  RepoCommandParameter(const Block& block)
+  {
+    wireDecode(block);
+  }
+
+  const Name&
+  getName() const
+  {
+    return m_name;
+  }
+
+  RepoCommandParameter&
+  setName(const Name& name)
+  {
+    m_name = name;
+    m_hasName = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasName() const
+  {
+    return m_hasName;
+  }
+
+  const Selectors&
+  getSelectors() const
+  {
+    return m_selectors;
+  }
+
+  RepoCommandParameter&
+  setSelectors(const Selectors& selectors)
+  {
+    m_selectors = selectors;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasSelectors() const
+  {
+    return !m_selectors.empty();
+  }
+
+  uint64_t
+  getStartBlockId() const
+  {
+    assert(hasStartBlockId());
+    return m_startBlockId;
+  }
+
+  RepoCommandParameter&
+  setStartBlockId(uint64_t startBlockId)
+  {
+    m_startBlockId  = startBlockId;
+    m_hasStartBlockId = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasStartBlockId() const
+  {
+    return m_hasStartBlockId;
+  }
+
+  uint64_t
+  getEndBlockId() const
+  {
+    assert(hasEndBlockId());
+    return m_endBlockId;
+  }
+
+  RepoCommandParameter&
+  setEndBlockId(uint64_t endBlockId)
+  {
+    m_endBlockId  = endBlockId;
+    m_hasEndBlockId = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasEndBlockId() const
+  {
+    return m_hasEndBlockId;
+  }
+
+  uint64_t
+  getProcessId() const
+  {
+    assert(hasProcessId());
+    return m_processId;
+  }
+
+  bool
+  hasProcessId() const
+  {
+    return m_hasProcessId;
+  }
+
+  RepoCommandParameter&
+  setProcessId(uint64_t processId)
+  {
+    m_processId = processId;
+    m_hasProcessId = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& wire);
+
+private:
+
+  Name m_name;
+  Selectors m_selectors;
+  uint64_t m_startBlockId;
+  uint64_t m_endBlockId;
+  uint64_t m_processId;
+
+  bool m_hasName;
+  bool m_hasStartBlockId;
+  bool m_hasEndBlockId;
+  bool m_hasProcessId;
+
+  mutable Block m_wire;
+};
+
+template<bool T>
+inline size_t
+RepoCommandParameter::wireEncode(EncodingImpl<T>& encoder) const
+{
+  size_t totalLength = 0;
+  size_t variableLength = 0;
+
+  if (m_hasProcessId) {
+    variableLength = encoder.prependNonNegativeInteger(m_processId);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::ProcessId);
+  }
+
+  if (m_hasEndBlockId) {
+    variableLength = encoder.prependNonNegativeInteger(m_endBlockId);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::EndBlockId);
+  }
+
+  if (m_hasStartBlockId) {
+    variableLength = encoder.prependNonNegativeInteger(m_startBlockId);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::StartBlockId);
+  }
+
+  if (!getSelectors().empty()) {
+    totalLength += getSelectors().wireEncode(encoder);
+  }
+
+  if (m_hasName) {
+    totalLength += getName().wireEncode(encoder);
+  }
+
+  totalLength += encoder.prependVarNumber(totalLength);
+  totalLength += encoder.prependVarNumber(tlv::RepoCommandParameter);
+  return totalLength;
+}
+
+inline const Block&
+RepoCommandParameter::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+inline void
+RepoCommandParameter::wireDecode(const Block& wire)
+{
+  m_hasName = false;
+  m_hasStartBlockId = false;
+  m_hasEndBlockId = false;
+  m_hasProcessId = false;
+
+  m_wire = wire;
+
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::RepoCommandParameter)
+    throw Error("Requested decoding of RepoCommandParameter, but Block is of different type");
+
+  // Name
+  Block::element_const_iterator val = m_wire.find(tlv::Name);
+  if (val != m_wire.elements_end())
+  {
+    m_hasName = true;
+    m_name.wireDecode(m_wire.get(tlv::Name));
+  }
+
+  // Selectors
+  val = m_wire.find(tlv::Selectors);
+  if (val != m_wire.elements_end())
+  {
+    m_selectors.wireDecode(*val);
+  }
+  else
+    m_selectors = Selectors();
+
+  // StartBlockId
+  val = m_wire.find(tlv::StartBlockId);
+  if (val != m_wire.elements_end())
+  {
+    m_hasStartBlockId = true;
+    m_startBlockId = readNonNegativeInteger(*val);
+  }
+
+  // EndBlockId
+  val = m_wire.find(tlv::EndBlockId);
+  if (val != m_wire.elements_end())
+  {
+    m_hasEndBlockId = true;
+    m_endBlockId = readNonNegativeInteger(*val);
+  }
+
+  // ProcessId
+  val = m_wire.find(tlv::ProcessId);
+  if (val != m_wire.elements_end())
+  {
+    m_hasProcessId = true;
+    m_processId = readNonNegativeInteger(*val);
+  }
+
+}
+
+inline std::ostream&
+operator<<(std::ostream& os, const RepoCommandParameter& repoCommandParameter)
+{
+  os << "RepoCommandParameter(";
+
+  // Name
+  if (repoCommandParameter.hasName()) {
+    os << " Name: " << repoCommandParameter.getName();
+  }
+  if (repoCommandParameter.hasStartBlockId()) {
+  // StartBlockId
+    os << " StartBlockId: " << repoCommandParameter.getStartBlockId();
+  }
+  // EndBlockId
+  if (repoCommandParameter.hasEndBlockId()) {
+    os << " EndBlockId: " << repoCommandParameter.getEndBlockId();
+  }
+  //ProcessId
+  if (repoCommandParameter.hasProcessId()) {
+    os << " ProcessId: " << repoCommandParameter.getProcessId();
+  }
+  os << " )";
+  return os;
+}
+
+} // namespace repo
+
+#endif // REPO_REPO_COMMAND_PARAMETER_HPP
diff --git a/src/repo-command-response.hpp b/src/repo-command-response.hpp
new file mode 100644
index 0000000..0eb4f1d
--- /dev/null
+++ b/src/repo-command-response.hpp
@@ -0,0 +1,397 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_REPO_COMMAND_RESPONSE_HPP
+#define REPO_REPO_COMMAND_RESPONSE_HPP
+
+#include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <ndn-cxx/encoding/tlv-nfd.hpp>
+#include "repo-tlv.hpp"
+
+namespace repo {
+
+using ndn::Block;
+using ndn::EncodingImpl;
+using ndn::EncodingEstimator;
+using ndn::EncodingBuffer;
+
+/**
+* @brief Class defining abstraction of Response for NDN Repo Protocol
+* @sa link http://redmine.named-data.net/projects/repo-ng/wiki/Repo_Protocol_Specification#Repo-Command-Response
+*/
+class RepoCommandResponse
+{
+public:
+  class Error : public ndn::Tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : ndn::Tlv::Error(what)
+    {
+    }
+  };
+
+  RepoCommandResponse()
+    : m_hasStartBlockId(false)
+    , m_hasEndBlockId(false)
+    , m_hasProcessId(false)
+    , m_hasInsertNum(false)
+    , m_hasDeleteNum(false)
+    , m_hasStatusCode(false)
+  {
+  }
+
+  explicit
+  RepoCommandResponse(const Block& block)
+  {
+    wireDecode(block);
+  }
+
+  uint64_t
+  getStartBlockId() const
+  {
+    return m_startBlockId;
+  }
+
+  RepoCommandResponse&
+  setStartBlockId(uint64_t startBlockId)
+  {
+    m_startBlockId  = startBlockId;
+    m_hasStartBlockId = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasStartBlockId() const
+  {
+    return m_hasStartBlockId;
+  }
+
+  uint64_t
+  getEndBlockId() const
+  {
+    assert(hasEndBlockId());
+    return m_endBlockId;
+  }
+
+  RepoCommandResponse&
+  setEndBlockId(uint64_t endBlockId)
+  {
+    m_endBlockId  = endBlockId;
+    m_hasEndBlockId = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasEndBlockId() const
+  {
+    return m_hasEndBlockId;
+  }
+
+
+  uint64_t
+  getProcessId() const
+  {
+    return m_processId;
+  }
+
+  RepoCommandResponse&
+  setProcessId(uint64_t processId)
+  {
+    m_processId  = processId;
+    m_hasProcessId = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasProcessId() const
+  {
+    return m_hasProcessId;
+  }
+
+  uint64_t
+  getStatusCode() const
+  {
+    return m_statusCode;
+  }
+
+  RepoCommandResponse&
+  setStatusCode(uint64_t statusCode)
+  {
+    m_statusCode  = statusCode;
+    m_hasStatusCode = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasStatusCode() const
+  {
+    return m_hasStatusCode;
+  }
+
+  uint64_t
+  getInsertNum() const
+  {
+    return m_insertNum;
+  }
+
+  RepoCommandResponse&
+  setInsertNum(uint64_t insertNum)
+  {
+    m_insertNum = insertNum;
+    m_hasInsertNum = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasInsertNum() const
+  {
+    return m_hasInsertNum;
+  }
+
+  uint64_t
+  getDeleteNum() const
+  {
+    return m_deleteNum;
+  }
+
+  RepoCommandResponse&
+  setDeleteNum(uint64_t deleteNum)
+  {
+    m_deleteNum = deleteNum;
+    m_hasDeleteNum = true;
+    m_wire.reset();
+    return *this;
+  }
+
+  bool
+  hasDeleteNum() const
+  {
+    return m_hasDeleteNum;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const Block& wire);
+
+private:
+  uint64_t m_statusCode;
+  uint64_t m_startBlockId;
+  uint64_t m_endBlockId;
+  uint64_t m_processId;
+  uint64_t m_insertNum;
+  uint64_t m_deleteNum;
+
+  bool m_hasStartBlockId;
+  bool m_hasEndBlockId;
+  bool m_hasProcessId;
+  bool m_hasInsertNum;
+  bool m_hasDeleteNum;
+  bool m_hasStatusCode;
+
+  mutable Block m_wire;
+};
+
+template<bool T>
+inline size_t
+RepoCommandResponse::wireEncode(EncodingImpl<T>& encoder) const
+{
+  size_t totalLength = 0;
+  size_t variableLength = 0;
+
+  if (m_hasDeleteNum) {
+    variableLength = encoder.prependNonNegativeInteger(m_deleteNum);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::DeleteNum);
+  }
+
+  if (m_hasInsertNum) {
+    variableLength = encoder.prependNonNegativeInteger(m_insertNum);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::InsertNum);
+  }
+
+  if (m_hasEndBlockId) {
+    variableLength = encoder.prependNonNegativeInteger(m_endBlockId);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::EndBlockId);
+  }
+
+  if (m_hasStartBlockId) {
+    variableLength = encoder.prependNonNegativeInteger(m_startBlockId);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(repo::tlv::StartBlockId);
+  }
+
+  if (m_hasStatusCode) {
+    variableLength = encoder.prependNonNegativeInteger(m_statusCode);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::StatusCode);
+  } else {
+    throw Error("required field StatusCode is missing");
+  }
+
+  if (m_hasProcessId) {
+    variableLength = encoder.prependNonNegativeInteger(m_processId);
+    totalLength += variableLength;
+    totalLength += encoder.prependVarNumber(variableLength);
+    totalLength += encoder.prependVarNumber(tlv::ProcessId);
+  }
+
+  totalLength += encoder.prependVarNumber(totalLength);
+  totalLength += encoder.prependVarNumber(tlv::RepoCommandResponse);
+  return totalLength;
+}
+
+inline const Block&
+RepoCommandResponse::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+inline void
+RepoCommandResponse::wireDecode(const Block& wire)
+{
+  m_hasStartBlockId = false;
+  m_hasEndBlockId = false;
+  m_hasProcessId = false;
+  m_hasStatusCode = false;
+  m_hasInsertNum = false;
+  m_hasDeleteNum = false;
+
+  m_wire = wire;
+
+  m_wire.parse();
+
+  Block::element_const_iterator val;
+
+  if (m_wire.type() != tlv::RepoCommandResponse)
+    throw Error("RepoCommandResponse malformed");
+
+  // StartBlockId
+  val = m_wire.find(tlv::StartBlockId);
+  if (val != m_wire.elements_end())
+  {
+    m_hasStartBlockId = true;
+    m_startBlockId = readNonNegativeInteger(*val);
+  }
+
+  // EndBlockId
+  val = m_wire.find(tlv::EndBlockId);
+  if (val != m_wire.elements_end())
+  {
+    m_hasEndBlockId = true;
+    m_endBlockId = readNonNegativeInteger(*val);
+  }
+
+  // ProcessId
+  val = m_wire.find(tlv::ProcessId);
+  if (val != m_wire.elements_end())
+  {
+    m_hasProcessId = true;
+    m_processId = readNonNegativeInteger(*val);
+  }
+
+  // StatusCode
+  val = m_wire.find(tlv::StatusCode);
+  if (val != m_wire.elements_end())
+  {
+    m_hasStatusCode = true;
+    m_statusCode = readNonNegativeInteger(*val);
+
+  } else {
+    throw Error("required field StatusCode is missing");
+  }
+
+  // InsertNum
+  val = m_wire.find(tlv::InsertNum);
+  if (val != m_wire.elements_end())
+  {
+    m_hasInsertNum = true;
+    m_insertNum = readNonNegativeInteger(*val);
+  }
+
+  // DeleteNum
+  val = m_wire.find(tlv::DeleteNum);
+  if (val != m_wire.elements_end())
+  {
+    m_hasDeleteNum = true;
+    m_deleteNum = readNonNegativeInteger(*val);
+  }
+}
+
+inline std::ostream&
+operator<<(std::ostream& os, const RepoCommandResponse& repoCommandResponse)
+{
+  os << "RepoCommandResponse(";
+
+  if (repoCommandResponse.hasProcessId()) {
+    os << " ProcessId: " << repoCommandResponse.getProcessId();
+  }
+  if (repoCommandResponse.hasStatusCode()) {
+    os << " StatusCode: " << repoCommandResponse.getStatusCode();
+  }
+  if (repoCommandResponse.hasStartBlockId()) {
+    os << " StartBlockId: " << repoCommandResponse.getStartBlockId();
+  }
+  if (repoCommandResponse.hasEndBlockId()) {
+    os << " EndBlockId: " << repoCommandResponse.getEndBlockId();
+  }
+  if (repoCommandResponse.hasInsertNum()) {
+    os << " InsertNum: " << repoCommandResponse.getInsertNum();
+  }
+  if (repoCommandResponse.hasDeleteNum()) {
+    os << " DeleteNum: " << repoCommandResponse.getDeleteNum();
+
+  }
+  os << " )";
+  return os;
+}
+
+} // namespace repo
+
+#endif // REPO_REPO_COMMAND_RESPONSE_HPP
diff --git a/src/repo-tlv.hpp b/src/repo-tlv.hpp
new file mode 100644
index 0000000..7d917e1
--- /dev/null
+++ b/src/repo-tlv.hpp
@@ -0,0 +1,44 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_REPO_TLV_HPP
+#define REPO_REPO_TLV_HPP
+
+#include <ndn-cxx/encoding/tlv.hpp>
+
+namespace repo {
+namespace tlv {
+
+using namespace ndn::Tlv;
+
+enum {
+  RepoCommandParameter = 201,
+  StartBlockId         = 204,
+  EndBlockId           = 205,
+  ProcessId            = 206,
+  RepoCommandResponse  = 207,
+  StatusCode           = 208,
+  InsertNum            = 209,
+  DeleteNum            = 210
+};
+
+} // tlv
+} // repo
+
+#endif // REPO_REPO_TLV_HPP
diff --git a/src/repo.cpp b/src/repo.cpp
new file mode 100644
index 0000000..3502763
--- /dev/null
+++ b/src/repo.cpp
@@ -0,0 +1,170 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "repo.hpp"
+
+namespace repo {
+
+RepoConfig
+parseConfig(const std::string& configPath)
+{
+  if (configPath.empty()) {
+    std::cerr << "configuration file path is empty" << std::endl;
+  }
+
+  std::ifstream fin(configPath.c_str());
+  if (!fin.is_open())
+    throw Repo::Error("failed to open configuration file '"+ configPath +"'");
+
+  using namespace boost::property_tree;
+  ptree propertyTree;
+  try {
+    read_info(fin, propertyTree);
+  }
+  catch (ptree_error& e) {
+    throw Repo::Error("failed to read configuration file '"+ configPath +"'");
+  }
+
+  ptree repoConf = propertyTree.get_child("repo");
+
+  RepoConfig repoConfig;
+
+  ptree dataConf = repoConf.get_child("data");
+
+  for (ptree::const_iterator it = dataConf.begin();
+       it != dataConf.end();
+       ++it)
+  {
+    if (it->first == "prefix")
+      repoConfig.dataPrefixes.push_back(Name(it->second.get_value<std::string>()));
+    else
+      throw Repo::Error("Unrecognized '" + it->first + "' option in 'data' section in "
+                        "configuration file '"+ configPath +"'");
+  }
+
+  ptree commandConf = repoConf.get_child("command");
+  for (ptree::const_iterator it = commandConf.begin();
+       it != commandConf.end();
+       ++it)
+  {
+    if (it->first == "prefix")
+      repoConfig.repoPrefixes.push_back(Name(it->second.get_value<std::string>()));
+    else
+      throw Repo::Error("Unrecognized '" + it->first + "' option in 'command' section in "
+                        "configuration file '"+ configPath +"'");
+  }
+
+  ptree tcpBulkInsert = repoConf.get_child("tcp_bulk_insert");
+  bool isTcpBulkEnabled = false;
+  std::string host = "localhost";
+  std::string port = "7376";
+  for (ptree::const_iterator it = tcpBulkInsert.begin();
+       it != tcpBulkInsert.end();
+       ++it)
+  {
+    isTcpBulkEnabled = true;
+
+    // tcp_bulk_insert {
+    //   host "localhost"  ; IP address or hostname to listen on
+    //   port 7635  ; Port number to listen on
+    // }
+    if (it->first == "host") {
+      host = it->second.get_value<std::string>();
+    }
+    else if (it->first == "port") {
+      port = it->second.get_value<std::string>();
+    }
+    else
+      throw Repo::Error("Unrecognized '" + it->first + "' option in 'tcp_bulk_insert' section in "
+                        "configuration file '"+ configPath +"'");
+  }
+  if (isTcpBulkEnabled) {
+    repoConfig.tcpBulkInsertEndpoints.push_back(std::make_pair(host, port));
+  }
+
+  if (repoConf.get<std::string>("storage.method") != "sqlite")
+    throw Repo::Error("Only 'sqlite' storage method is supported");
+
+  repoConfig.dbPath = repoConf.get<std::string>("storage.path");
+
+  repoConfig.validatorNode = repoConf.get_child("validator");
+  return repoConfig;
+}
+
+inline static void
+NullDeleter(boost::asio::io_service* variable)
+{
+  // do nothing
+}
+
+Repo::Repo(boost::asio::io_service& ioService, const RepoConfig& config)
+  : m_config(config)
+  , m_scheduler(ioService)
+  , m_face(shared_ptr<boost::asio::io_service>(&ioService, &NullDeleter))
+  , m_storageHandle(openStorage(config))
+  , m_readHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler)
+  , m_writeHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
+  , m_deleteHandle(m_face, *m_storageHandle, m_keyChain, m_scheduler, m_validator)
+  , m_tcpBulkInsertHandle(ioService, *m_storageHandle)
+
+{
+  //Trust model not implemented, this is just an empty validator
+  //@todo add a function to parse RepoConfig.validatorNode and define the trust model
+  m_validator.addInterestRule("^<>",
+                              *m_keyChain.
+                              getCertificate(m_keyChain.getDefaultCertificateName()));
+}
+
+shared_ptr<StorageHandle>
+Repo::openStorage(const RepoConfig& config)
+{
+  shared_ptr<StorageHandle> storageHandle = ndn::make_shared<SqliteHandle>(config.dbPath);
+  return storageHandle;
+}
+
+void
+Repo::enableListening()
+{
+  // Enable "listening" on Data prefixes
+  for (vector<ndn::Name>::iterator it = m_config.dataPrefixes.begin();
+       it != m_config.dataPrefixes.end();
+       ++it)
+    {
+      m_readHandle.listen(*it);
+    }
+
+  // Enable "listening" on control prefixes
+  for (vector<ndn::Name>::iterator it = m_config.repoPrefixes.begin();
+       it != m_config.repoPrefixes.end();
+       ++it)
+    {
+      m_writeHandle.listen(*it);
+      m_deleteHandle.listen(*it);
+    }
+
+  // Enable listening on TCP bulk insert addresses
+  for (vector<pair<string, string> >::iterator it = m_config.tcpBulkInsertEndpoints.begin();
+       it != m_config.tcpBulkInsertEndpoints.end();
+       ++it)
+    {
+      m_tcpBulkInsertHandle.listen(it->first, it->second);
+    }
+}
+
+} // namespace repo
diff --git a/src/repo.hpp b/src/repo.hpp
new file mode 100644
index 0000000..a92eb7d
--- /dev/null
+++ b/src/repo.hpp
@@ -0,0 +1,97 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_REPO_HPP
+#define REPO_REPO_HPP
+
+#include "storage/storage-handle.hpp"
+#include "storage/sqlite-handle.hpp"
+
+#include "handles/read-handle.hpp"
+#include "handles/write-handle.hpp"
+#include "handles/delete-handle.hpp"
+#include "handles/tcp-bulk-insert-handle.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/util/command-interest-validator.hpp>
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/info_parser.hpp>
+
+namespace repo {
+
+using std::string;
+using std::vector;
+using std::pair;
+
+struct RepoConfig
+{
+  //StorageMethod storageMethod; This will be implemtented if there is other method.
+  std::string dbPath;
+  vector<ndn::Name> dataPrefixes;
+  vector<ndn::Name> repoPrefixes;
+  vector<pair<string, string> > tcpBulkInsertEndpoints;
+
+  //@todo validator should be configured in config file
+  boost::property_tree::ptree validatorNode;
+};
+
+RepoConfig
+parseConfig(const std::string& confPath);
+
+class Repo : noncopyable
+{
+
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  Repo(boost::asio::io_service& ioService, const RepoConfig& config);
+
+  void
+  enableListening();
+
+private:
+  static shared_ptr<StorageHandle>
+  openStorage(const RepoConfig& config);
+
+private:
+  RepoConfig m_config;
+  ndn::Scheduler m_scheduler;
+  ndn::Face m_face;
+  shared_ptr<StorageHandle> m_storageHandle;
+  KeyChain m_keyChain;
+  CommandInterestValidator m_validator;
+  ReadHandle m_readHandle;
+  WriteHandle m_writeHandle;
+  DeleteHandle m_deleteHandle;
+  TcpBulkInsertHandle m_tcpBulkInsertHandle;
+};
+
+} // namespace repo
+
+#endif // REPO_REPO_HPP
diff --git a/src/storage/sqlite-handle.cpp b/src/storage/sqlite-handle.cpp
new file mode 100644
index 0000000..02598a9
--- /dev/null
+++ b/src/storage/sqlite-handle.cpp
@@ -0,0 +1,841 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.hpp"
+#include "sqlite-handle.hpp"
+#include <boost/filesystem.hpp>
+
+namespace repo {
+
+SqliteHandle::SqliteHandle(const string& dbPath)
+  : StorageHandle(STORAGE_METHOD_SQLITE)
+{
+  if (dbPath.empty()) {
+    std::cerr << "Create db file in local location [" << dbPath << "]. " << std::endl
+              << "You can assign the path using -d option" << std::endl;
+    m_dbPath = string("ndn_repo.db");
+  }
+  else {
+    boost::filesystem::path fsPath(dbPath);
+    boost::filesystem::file_status fsPathStatus = boost::filesystem::status(fsPath);
+    if (!boost::filesystem::is_directory(fsPathStatus)) {
+      if (!boost::filesystem::create_directory(boost::filesystem::path(fsPath))) {
+        throw Error("Folder '" + dbPath + "' does not exists and cannot be created");
+      }
+    }
+
+    m_dbPath = dbPath + "/ndn_repo.db";
+  }
+  initializeRepo();
+}
+
+void
+SqliteHandle::initializeRepo()
+{
+  char* errMsg = 0;
+
+  int rc = sqlite3_open_v2(m_dbPath.c_str(), &m_db,
+                           SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+#ifdef DISABLE_SQLITE3_FS_LOCKING
+                           "unix-dotfile"
+#else
+                           0
+#endif
+                           );
+
+  if (rc == SQLITE_OK) {
+    sqlite3_exec(m_db, "CREATE TABLE NDN_REPO ("
+                      "name BLOB PRIMARY KEY, "
+                      "data BLOB, "
+                      "parentName BLOB, "
+                      "nChildren INTEGER);\n"
+                      "CREATE INDEX NdnRepoParentName ON NDN_REPO (parentName);\n"
+                      "CREATE INDEX NdnRepoData ON NDN_REPO (data);\n"
+                 , 0, 0, &errMsg);
+    // Ignore errors (when database already exists, errors are expected)
+  }
+  else {
+    std::cerr << "Database file open failure rc:" << rc << std::endl;
+    throw Error("Database file open failure");
+  }
+
+  Name rootName;
+  string sql = string("SELECT * FROM NDN_REPO WHERE name = ?;");
+
+  sqlite3_stmt* queryStmt = 0;
+
+  rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &queryStmt, 0);
+  if (rc == SQLITE_OK) {
+    if (sqlite3_bind_blob(queryStmt, 1, rootName.wireEncode().wire(),
+                          rootName.wireEncode().size(), 0) == SQLITE_OK) {
+      rc = sqlite3_step(queryStmt);
+      if (rc == SQLITE_ROW) {
+        std::cerr << "root has been created" << std::endl;
+      }
+      else if (rc == SQLITE_DONE) {
+        sqlite3_stmt* p2Stmt = 0;
+        sql = string("INSERT INTO NDN_REPO (name, data, parentName, nChildren) "
+                     " VALUES (?,    ?,    ?,     ?);");
+        rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &p2Stmt, 0);
+        if (rc == SQLITE_OK) {
+          if (sqlite3_bind_blob(p2Stmt, 1, rootName.wireEncode().wire(),
+                                rootName.wireEncode().size(), 0) == SQLITE_OK &&
+              sqlite3_bind_null(p2Stmt, 2) == SQLITE_OK &&
+              sqlite3_bind_null(p2Stmt, 3) == SQLITE_OK &&
+              sqlite3_bind_int(p2Stmt, 4, 0) == SQLITE_OK) {
+            rc = sqlite3_step(p2Stmt);;
+            if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
+              std::cerr << "Root name insert failure rc:" << rc << std::endl;
+              sqlite3_finalize(p2Stmt);
+              throw Error("Root name insert failure");
+            }
+          }
+          else {
+            std::cerr << "bind blob failure rc:" << rc << std::endl;
+            sqlite3_finalize(p2Stmt);
+            throw Error("bind blob failure");
+          }
+        }
+        else {
+          std::cerr << "p2Stmt prepared rc:" << rc << std::endl;
+          sqlite3_finalize(p2Stmt);
+          throw Error("p2Stmt prepared");
+        }
+        sqlite3_finalize(p2Stmt);
+      }
+      else {
+        std::cerr << "Database query failure rc:" << rc << std::endl;
+        sqlite3_finalize(queryStmt);
+        throw Error("Database query failure");
+      }
+    }
+    sqlite3_finalize(queryStmt);
+  }
+  sqlite3_exec(m_db, "PRAGMA synchronous = OFF", 0, 0, &errMsg);
+  sqlite3_exec(m_db, "PRAGMA journal_mode = WAL", 0, 0, &errMsg);
+}
+
+SqliteHandle::~SqliteHandle()
+{
+  sqlite3_close(m_db);
+}
+
+
+//Temporarily assigned the datatype of every component. needs to be further discussed
+
+bool
+SqliteHandle::insertData(const Data& data)
+{
+  Name name = data.getName();
+
+  if (name.empty()) {
+    std::cerr << "name is empty" << std::endl;
+    return false;
+  }
+
+  int rc = 0;
+
+  string updateSql2 = string("UPDATE NDN_REPO SET data = ? WHERE name = ?;");
+  //std::cerr << "update" << std::endl;
+  sqlite3_stmt* update2Stmt = 0;
+  if (sqlite3_prepare_v2(m_db, updateSql2.c_str(), -1, &update2Stmt, 0) != SQLITE_OK) {
+    sqlite3_finalize(update2Stmt);
+    std::cerr << "update sql2 not prepared" << std::endl;
+    throw Error("update sql2 not prepared");
+  }
+  if (sqlite3_bind_blob(update2Stmt, 1,
+                        data.wireEncode().wire(),
+                        data.wireEncode().size(), 0) == SQLITE_OK &&
+      sqlite3_bind_blob(update2Stmt, 2,
+                        name.wireEncode().wire(),
+                        name.wireEncode().size(), 0) == SQLITE_OK) {
+    rc = sqlite3_step(update2Stmt);
+    sqlite3_finalize(update2Stmt);
+    if (rc != SQLITE_DONE) {
+      return false;
+    }
+    //what error??
+    //std::cerr << "update rc:" << rc << std::endl;
+    /// \todo Do something with rc
+  }
+  int changeCount = sqlite3_changes(m_db);
+  //std::cerr << "changeCount: " << changeCount << std::endl;
+  if (changeCount > 0) {
+    return true;
+  }
+
+  sqlite3_stmt* insertStmt = 0;
+  sqlite3_stmt* updateStmt = 0;
+  string insertSql = string("INSERT INTO NDN_REPO (name, data, parentName, nChildren) "
+                            "VALUES (?, ?, ?, ?)");
+  string updateSql = string("UPDATE NDN_REPO SET nChildren = nChildren + 1 WHERE name = ?");
+
+  Name rootName;
+
+
+  if (sqlite3_prepare_v2(m_db, insertSql.c_str(), -1, &insertStmt, 0) != SQLITE_OK) {
+    sqlite3_finalize(insertStmt);
+    std::cerr << "insert sql not prepared" << std::endl;
+  }
+  if (sqlite3_prepare_v2(m_db, updateSql.c_str(), -1, &updateStmt, 0) != SQLITE_OK) {
+    sqlite3_finalize(updateStmt);
+    std::cerr << "update sql not prepared" << std::endl;
+    throw Error("update sql not prepared");
+  }
+
+  //Insert and read the prefix
+  Name parentName = name;
+  Name grandName;
+  do {
+    parentName = parentName.getPrefix(-1);
+    if (!hasName(parentName)) {
+      grandName = parentName.getPrefix(-1);
+      if (sqlite3_bind_blob(insertStmt, 1,
+                            parentName.wireEncode().wire(),
+                            parentName.wireEncode().size(), 0) == SQLITE_OK &&
+          sqlite3_bind_null(insertStmt, 2) == SQLITE_OK &&
+          sqlite3_bind_blob(insertStmt, 3,
+                            grandName.wireEncode().wire(),
+                            grandName.wireEncode().size(), 0) == SQLITE_OK &&
+          sqlite3_bind_int(insertStmt, 4, 1) == SQLITE_OK) {
+        rc = sqlite3_step(insertStmt);
+        if (rc == SQLITE_CONSTRAINT) {
+          std::cerr << "Insert parent prefix failed" << std::endl;
+          sqlite3_finalize(insertStmt);
+          throw Error("Insert parent prefix failed");
+        }
+        sqlite3_reset(insertStmt);
+      }
+    }
+    else {
+      break;
+    }
+  } while (!parentName.empty());
+
+  //The existed parent nChildren + 1
+
+  if (sqlite3_bind_blob(updateStmt, 1, parentName.wireEncode().wire(),
+                        parentName.wireEncode().size(), 0) == SQLITE_OK) {
+    rc = sqlite3_step(updateStmt);
+    if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
+      std::cerr << "update error rc:" << rc << std::endl;
+      sqlite3_finalize(updateStmt);
+      sqlite3_finalize(insertStmt);
+      throw Error("update error");
+    }
+    sqlite3_reset(updateStmt);
+  }
+
+  //Insert the name and the data, if this data name exists update, else insert data
+
+  parentName = name.getPrefix(-1);
+  sqlite3_reset(insertStmt);
+  if (sqlite3_bind_blob(insertStmt, 1,
+                        name.wireEncode().wire(),
+                        name.wireEncode().size(), 0) == SQLITE_OK &&
+      sqlite3_bind_blob(insertStmt, 2,
+                        data.wireEncode().wire(),
+                        data.wireEncode().size(), 0) == SQLITE_OK &&
+      sqlite3_bind_blob(insertStmt, 3,
+                        parentName.wireEncode().wire(),
+                        parentName.wireEncode().size(), 0) == SQLITE_OK &&
+      sqlite3_bind_int(insertStmt, 4, 0) == SQLITE_OK) {
+    rc = sqlite3_step(insertStmt);
+    //std::cerr << "insert rc:" << rc << std::endl;
+    //std::cerr << "insert the data: " << data.wireEncode().wire() << std::endl;
+    if (rc == SQLITE_CONSTRAINT) {
+      std::cerr << "The name of the data has existed!" << std::endl;
+      sqlite3_finalize(insertStmt);
+      return false;
+    }
+  }
+
+  sqlite3_finalize(updateStmt);
+  sqlite3_finalize(insertStmt);
+  return true;
+}
+
+bool
+SqliteHandle::deleteData(const Name& name)
+{
+  sqlite3_stmt* queryStmt = 0;
+  sqlite3_stmt* deleteStmt = 0;
+  sqlite3_stmt* updateStmt = 0;
+  sqlite3_stmt* update2Stmt = 0;
+
+  string querySql = string("SELECT * from NDN_REPO where name = ?;");
+  string deleteSql = string("DELETE from NDN_REPO where name = ?;");
+
+  string updateSql = string("UPDATE NDN_REPO SET nChildren = nChildren - 1 WHERE name = ?;");
+  string updateSql2 = string("UPDATE NDN_REPO SET data = NULL WHERE name = ?;");
+
+  int rc = sqlite3_prepare_v2(m_db, querySql.c_str(), -1, &queryStmt, 0);
+  Name tmpName = name;
+  int nChildren = -1;
+  if (sqlite3_prepare_v2(m_db, deleteSql.c_str(), -1, &deleteStmt, 0) != SQLITE_OK) {
+    sqlite3_finalize(deleteStmt);
+    std::cerr << "delete statement prepared failed" << std::endl;
+    throw Error("delete statement prepared failed");
+  }
+  if (sqlite3_prepare_v2(m_db, updateSql.c_str(), -1, &updateStmt, 0) != SQLITE_OK) {
+    sqlite3_finalize(updateStmt);
+    std::cerr << "delete update prepared failed" << std::endl;
+    throw Error("delete update prepared failed");
+  }
+  if (rc == SQLITE_OK) {
+    if (sqlite3_bind_blob(queryStmt, 1,
+                          tmpName.wireEncode().wire(),
+                          tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+      rc = sqlite3_step(queryStmt);
+      if (rc == SQLITE_ROW) {
+        nChildren = sqlite3_column_int(queryStmt, 3);
+      }
+      else {
+        std::cerr << "Database query no such name or failure rc:" << rc << std::endl;
+        sqlite3_finalize(queryStmt);
+        return false;
+      }
+    }
+    if (nChildren > 0) {
+      //update internal node, so just update and return
+      if (sqlite3_prepare_v2(m_db, updateSql2.c_str(), -1, &update2Stmt, 0) != SQLITE_OK) {
+        sqlite3_finalize(update2Stmt);
+        std::cerr << "delete update prepared failed" << std::endl;
+        throw Error("delete update prepared failed");
+      }
+      if (sqlite3_bind_blob(update2Stmt, 1,
+                            tmpName.wireEncode().wire(),
+                            tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+        rc = sqlite3_step(update2Stmt);
+        std::cerr << "deleteData update" << std::endl;
+      }
+      else {
+        std::cerr << "delete bind error" << std::endl;
+        sqlite3_finalize(update2Stmt);
+        throw Error("delete bind error");
+      }
+      return true;
+    }
+    else {
+      //Delete the leaf node
+      if (sqlite3_bind_blob(deleteStmt, 1,
+                            tmpName.wireEncode().wire(),
+                            tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+        rc = sqlite3_step(deleteStmt);
+        if (rc != SQLITE_DONE && rc !=SQLITE_ROW) {
+          std::cerr << "leaf node delete error rc:" << rc << std::endl;
+          sqlite3_finalize(deleteStmt);
+          throw Error("leaf node delete error");
+        }
+      }
+      else {
+        std::cerr << "delete bind error" << std::endl;
+        sqlite3_finalize(deleteStmt);
+        throw Error("delete bind error");
+      }
+      sqlite3_reset(deleteStmt);
+    }
+    queryStmt = 0;
+    rc = sqlite3_prepare_v2(m_db, querySql.c_str(), -1, &queryStmt, 0);
+    if (rc != SQLITE_OK) {
+      std::cerr << "prepare error" << std::endl;
+      sqlite3_finalize(queryStmt);
+      throw Error("prepare error");
+    }
+    //read prefix if nChildren is 0 and data is 0
+    int dataSize = 0;
+    do {
+      tmpName = tmpName.getPrefix(-1);
+      if (sqlite3_bind_blob(queryStmt, 1,
+                            tmpName.wireEncode().wire(),
+                            tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+        rc = sqlite3_step(queryStmt);
+        if (rc == SQLITE_ROW) {
+          nChildren = sqlite3_column_int(queryStmt, 3);
+          dataSize = sqlite3_column_bytes(queryStmt, 1);
+        }
+        else {
+          std::cerr << "Database query no such name or failure rc:" << rc << std::endl;
+          sqlite3_finalize(queryStmt);
+          return false;
+        }
+        if (nChildren == 1 && !tmpName.empty() && dataSize == 0) {
+          //Delete this internal node
+          if (sqlite3_bind_blob(deleteStmt, 1,
+                                tmpName.wireEncode().wire(),
+                                tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+            rc = sqlite3_step(deleteStmt);
+            if (rc != SQLITE_DONE && rc !=SQLITE_ROW) {
+              std::cerr << "internal node delete error rc:" << rc << std::endl;
+              sqlite3_finalize(deleteStmt);
+              throw Error("internal node delete error");
+            }
+          }
+          else {
+            std::cerr << "delete bind error" << std::endl;
+            sqlite3_finalize(deleteStmt);
+            throw Error("delete bind error");
+          }
+          sqlite3_reset(deleteStmt);
+        }
+        else {
+          //nChildren - 1
+          if (sqlite3_bind_blob(updateStmt, 1,
+                                tmpName.wireEncode().wire(),
+                                tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+            rc = sqlite3_step(updateStmt);
+            if (rc != SQLITE_DONE && rc !=SQLITE_ROW) {
+              std::cerr << "internal node nChildren update error rc:" << rc << std::endl;
+              sqlite3_finalize(updateStmt);
+              throw Error("internal node nChildren update error");
+            }
+          }
+          else {
+            std::cerr << "update bind error" << std::endl;
+            sqlite3_finalize(updateStmt);
+            throw Error("update bind error");
+          }
+          sqlite3_reset(updateStmt);
+          break;
+        }
+      }
+      else {
+        std::cerr << "query bind error" << std::endl;
+        sqlite3_finalize(queryStmt);
+        throw Error("query bind error");
+      }
+      sqlite3_reset(queryStmt);
+    } while (!tmpName.empty());
+
+  }
+  else {
+    std::cerr << "query prepared failure rc:" << rc << std::endl;
+    sqlite3_finalize(queryStmt);
+    throw Error("query prepared failure");
+  }
+  return true;
+}
+
+bool
+SqliteHandle::readData(const Interest& interest, Data& data)
+{
+  vector<Name> names;
+  Name resultName;
+  if (!interest.hasSelectors()) {
+    return readDataPlain(interest.getName(), data);
+  }
+  else {
+    if (readNameSelector(interest, names)) {
+      if (!filterNameChild(interest.getName(), interest.getChildSelector(), names, resultName)) {
+        return false;
+      }
+    }
+    return readData(resultName, data);
+  }
+}
+
+// This function is the first version of data read following longest prefix match.
+// It will return the leftmost data
+bool
+SqliteHandle::readDataPlain(const Name& name, Data& data)
+{
+  vector<Name> names;
+  Name resultName;
+  readDataName(name, names);
+  filterNameChild(name, 0, names, resultName);
+  if (!resultName.empty()) {
+    return readData(resultName, data);
+  }
+  else
+  {
+    return false;
+  }
+}
+
+// retrieve all the leaf nodes of a subtree
+bool
+SqliteHandle::readDataName(const Name& name, vector<Name>& names) const
+{
+  if (name.empty()) {
+    std::cerr << "The name is empty" << std::endl;
+    return false;
+  }
+  Name tmpName = name;
+  //This queue is for internal node;
+  queue<Name> internalNames;
+
+  // Step 1. Check if the requested name corresponds to a leaf (data is not NULL)
+  string sql = string("SELECT * FROM NDN_REPO WHERE name = ? AND data IS NOT NULL;");
+  sqlite3_stmt* queryStmt = 0;
+  int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &queryStmt, 0);
+  if (rc != SQLITE_OK)
+    throw Error("prepare error");
+
+  if (sqlite3_bind_blob(queryStmt, 1,
+                        tmpName.wireEncode().wire(),
+                        tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+    rc = sqlite3_step(queryStmt);
+    if (rc == SQLITE_ROW) {
+      int nChildren = sqlite3_column_int(queryStmt, 3);
+      Name elementName;
+      elementName.wireDecode(Block(sqlite3_column_blob(queryStmt, 0),
+                                   sqlite3_column_bytes(queryStmt, 0)));
+      names.push_back(elementName);
+      if (nChildren == 0) {
+        sqlite3_finalize(queryStmt);
+        return true;
+      }
+    }
+    else if (rc == SQLITE_DONE) {
+      // ignore
+    }
+    else {
+      std::cerr << "read error rc:" << rc << std::endl;
+      sqlite3_finalize(queryStmt);
+      throw Error("read error");
+    }
+  }
+  sqlite3_finalize(queryStmt);
+
+
+  // Step 2. Recursively find all data packets with the specified prefix
+  string psql = string("SELECT * FROM NDN_REPO WHERE parentName = ?;");
+  sqlite3_stmt* queryParentStmt = 0;
+  rc = sqlite3_prepare_v2(m_db, psql.c_str(), -1, &queryParentStmt, 0);
+  if (rc != SQLITE_OK)
+    throw Error("prepare error");
+
+  internalNames.push(tmpName);
+  while (!internalNames.empty()) {
+    tmpName = internalNames.front();
+    internalNames.pop();
+    if (sqlite3_bind_blob(queryParentStmt, 1,
+                          tmpName.wireEncode().wire(),
+                          tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+      while (true) {
+        rc = sqlite3_step(queryParentStmt);
+        if (rc == SQLITE_ROW) {
+          Name elementName;
+          elementName.wireDecode(Block(sqlite3_column_blob(queryParentStmt, 0),
+                                       sqlite3_column_bytes(queryParentStmt, 0)));
+          int nChildren = sqlite3_column_int(queryParentStmt, 3);
+          if (nChildren > 0) {
+            internalNames.push(elementName);
+          }
+          if (sqlite3_column_type(queryParentStmt, 1) != SQLITE_NULL) {
+            names.push_back(elementName);
+          }
+        }
+        else if (rc == SQLITE_DONE) {
+          break;
+        }
+        else {
+          std::cerr << "read error rc:" << rc << std::endl;
+          sqlite3_finalize(queryParentStmt);
+          throw Error("read error");
+        }
+      }
+      sqlite3_reset(queryParentStmt);
+    }
+    else {
+      std::cerr << "bind error" << std::endl;
+      sqlite3_finalize(queryParentStmt);
+      throw Error("bind error");
+    }
+  }
+  sqlite3_finalize(queryParentStmt);
+  return true;
+}
+
+bool
+SqliteHandle::readNameSelector(const Interest& interest, vector<Name>& names) const
+{
+  if (interest.getName().empty()) {
+    std::cerr << "The name of interest is empty" << std::endl;
+    return false;
+  }
+  Name tmpName = interest.getName();
+  //This queue is for internal node;
+  queue<Name> internalNames;
+
+  // Step 1. Check if the requested Data corresponds to a leaf (data is not NULL)
+  sqlite3_stmt* queryStmt = 0;
+  string sql = string("SELECT * FROM NDN_REPO WHERE name = ? AND data IS NOT NULL;");
+  int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &queryStmt, 0);
+  if (rc != SQLITE_OK)
+    throw Error("prepare error");
+
+  if (sqlite3_bind_blob(queryStmt, 1,
+                        tmpName.wireEncode().wire(),
+                        tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+    rc = sqlite3_step(queryStmt);
+    if (rc == SQLITE_ROW) {
+      Data elementData;
+      elementData.wireDecode(Block(sqlite3_column_blob(queryStmt, 1),
+                                   sqlite3_column_bytes(queryStmt, 1)));
+      if (interest.matchesData(elementData)) {
+        names.push_back(elementData.getName());
+      }
+
+      int nChildren = sqlite3_column_int(queryStmt, 3);
+      if (nChildren == 0) {
+        sqlite3_finalize(queryStmt);
+        return true;
+      }
+    }
+    else if (rc == SQLITE_DONE) {
+      // ignore
+    }
+    else {
+      std::cerr << "read error rc:" << rc << std::endl;
+      sqlite3_finalize(queryStmt);
+      throw Error("read error");
+    }
+  }
+  sqlite3_finalize(queryStmt);
+
+  // Step 2. Recursively find all data packets that match the Interest
+  internalNames.push(tmpName);
+  sqlite3_stmt* queryParentStmt = 0;
+  string psql = string("SELECT * FROM NDN_REPO WHERE parentName = ?;");
+  rc = sqlite3_prepare_v2(m_db, psql.c_str(), -1, &queryParentStmt, 0);
+  if (rc != SQLITE_OK)
+    throw Error("prepare error");
+
+  while (!internalNames.empty()) {
+    tmpName = internalNames.front();
+    internalNames.pop();
+    if (sqlite3_bind_blob(queryParentStmt, 1,
+                          tmpName.wireEncode().wire(),
+                          tmpName.wireEncode().size(), 0) == SQLITE_OK) {
+      while (true) {
+        rc = sqlite3_step(queryParentStmt);
+        if (rc == SQLITE_ROW) {
+          if (sqlite3_column_type(queryParentStmt, 1) != SQLITE_NULL) {
+            Data elementData;
+            elementData.wireDecode(Block(sqlite3_column_blob(queryParentStmt, 1),
+                                         sqlite3_column_bytes(queryParentStmt, 1)));
+            if (interest.matchesData(elementData)) {
+              names.push_back(elementData.getName());
+            }
+          }
+
+          Name elementName;
+          elementName.wireDecode(Block(sqlite3_column_blob(queryParentStmt, 0),
+                                       sqlite3_column_bytes(queryParentStmt, 0)));
+
+          int nChildren = sqlite3_column_int(queryParentStmt, 3);
+          if (nChildren > 0) {
+            internalNames.push(elementName);
+          }
+        }
+        else if (rc == SQLITE_DONE) {
+          break;
+        }
+        else {
+          std::cerr << "read error rc:" << rc << std::endl;
+          sqlite3_finalize(queryParentStmt);
+          throw Error("read error");
+        }
+      }
+      sqlite3_reset(queryParentStmt);
+    }
+    else {
+      std::cerr << "bind error" << std::endl;
+      sqlite3_finalize(queryParentStmt);
+      throw Error("bind error");
+    }
+  }
+  sqlite3_finalize(queryParentStmt);
+  return true;
+}
+
+bool
+SqliteHandle::filterNameChild(const Name& name, int childSelector,
+                              const vector<Name>& names, Name& resultName)
+{
+  if (childSelector == 0) {
+    if (!names.empty()) {
+      resultName = *std::min_element(names.begin(), names.end());
+    }
+    else {
+      return false;
+    }
+  }
+  else if (childSelector == 1) {
+    if (!names.empty()) {
+      resultName = *std::max_element(names.begin(), names.end());
+    }
+    else {
+      return false;
+    }
+  }
+  else {
+    return false;
+  }
+  return true;
+}
+
+bool
+SqliteHandle::readNameAny(const Name& name, const Selectors& selectors, vector<Name>& names)
+{
+  if (selectors.empty()) {
+    if (hasName(name)) {
+      names.push_back(name);
+    }
+    return true;
+  }
+  else {
+    Interest interest(name);
+    interest.setSelectors(selectors);
+    readNameSelector(interest, names);
+    if (selectors.getChildSelector() >= 0) {
+      Name resultName;
+      if (!filterNameChild(name, selectors.getChildSelector(), names, resultName))
+        return false;
+      names.clear();
+      names.push_back(resultName);
+      return true;
+    }
+    else {
+      return true;
+    }
+  }
+}
+
+bool
+SqliteHandle::readData(const Name& name, Data& data)
+{
+  sqlite3_stmt* queryStmt = 0;
+  string sql = string("SELECT * FROM NDN_REPO WHERE name = ? AND data IS NOT NULL;");
+  int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &queryStmt, 0);
+  if (rc == SQLITE_OK) {
+    if (sqlite3_bind_blob(queryStmt, 1,
+                          name.wireEncode().wire(),
+                          name.wireEncode().size(), 0) == SQLITE_OK) {
+      rc = sqlite3_step(queryStmt);
+      if (rc == SQLITE_ROW) {
+        data.wireDecode(Block(sqlite3_column_blob(queryStmt, 1),
+                              sqlite3_column_bytes(queryStmt, 1)));
+        sqlite3_finalize(queryStmt);
+        return true;
+      }
+      else if (rc == SQLITE_DONE) {
+        return false;
+      }
+      else {
+        std::cerr << "Database query failure rc:" << rc << std::endl;
+        sqlite3_finalize(queryStmt);
+        throw Error("Database query failure");
+      }
+    }
+    sqlite3_finalize(queryStmt);
+  }
+  return true;
+}
+
+
+//This is the exact name query in database.
+bool
+SqliteHandle::hasName(const Name& name)
+{
+  sqlite3_stmt* queryStmt = 0;
+  string sql = string("select * from NDN_REPO where name = ?;");
+  int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &queryStmt, 0);
+  if (rc == SQLITE_OK) {
+    if (sqlite3_bind_blob(queryStmt, 1,
+                          name.wireEncode().wire(),
+                          name.wireEncode().size(), 0) == SQLITE_OK) {
+      rc = sqlite3_step(queryStmt);
+      if (rc == SQLITE_ROW) {
+        sqlite3_finalize(queryStmt);
+        return true;
+      }
+      else if (rc == SQLITE_DONE) {
+        sqlite3_finalize(queryStmt);
+        return false;
+      }
+      else {
+        std::cerr << "Database query failure rc:" << rc << std::endl;
+        sqlite3_finalize(queryStmt);
+        return false;
+      }
+    }
+    sqlite3_finalize(queryStmt);
+  }
+  return true;
+}
+
+//This is the exact parent name query in database.
+bool
+SqliteHandle::hasParentName(const Name& parentName) const
+{
+  sqlite3_stmt* queryStmt = 0;
+  string sql = string("SELECT * FROM NDN_REPO WHERE parentName = ?;");
+  int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &queryStmt, 0);
+  if (rc == SQLITE_OK) {
+    if (sqlite3_bind_blob(queryStmt, 1,
+                          parentName.wireEncode().wire(),
+                          parentName.wireEncode().size(), 0) == SQLITE_OK) {
+      rc = sqlite3_step(queryStmt);
+      if (rc == SQLITE_ROW) {
+        sqlite3_finalize(queryStmt);
+        return true;
+      }
+      else if (rc == SQLITE_DONE) {
+        sqlite3_finalize(queryStmt);
+        return false;
+      }
+      else {
+        std::cerr << "Database query failure rc:" << rc << std::endl;
+        sqlite3_finalize(queryStmt);
+        return false;
+      }
+    }
+    sqlite3_finalize(queryStmt);
+  }
+  return true;
+}
+
+size_t
+SqliteHandle::size()
+{
+  sqlite3_stmt* queryStmt = 0;
+  string sql("SELECT count(*) FROM NDN_REPO WHERE data IS NOT NULL");
+  int rc = sqlite3_prepare_v2(m_db, sql.c_str(), -1, &queryStmt, 0);
+  if (rc != SQLITE_OK)
+    {
+      std::cerr << "Database query failure rc:" << rc << std::endl;
+      sqlite3_finalize(queryStmt);
+      throw Error("Database query failure");
+    }
+
+  rc = sqlite3_step(queryStmt);
+  if (rc != SQLITE_ROW)
+    {
+      std::cerr << "Database query failure rc:" << rc << std::endl;
+      sqlite3_finalize(queryStmt);
+      throw Error("Database query failure");
+    }
+
+  size_t nDatas = static_cast<size_t>(sqlite3_column_int64(queryStmt, 0));
+  return nDatas;
+}
+
+} //namespace repo
diff --git a/src/storage/sqlite-handle.hpp b/src/storage/sqlite-handle.hpp
new file mode 100644
index 0000000..a0fbb1c
--- /dev/null
+++ b/src/storage/sqlite-handle.hpp
@@ -0,0 +1,144 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_STORAGE_SQLITE_HANDLE_HPP
+#define REPO_STORAGE_SQLITE_HANDLE_HPP
+
+#include "storage-handle.hpp"
+
+#include <string>
+#include <iostream>
+#include <sqlite3.h>
+#include <stdlib.h>
+#include <vector>
+#include <queue>
+#include <algorithm>
+
+namespace repo {
+
+using std::queue;
+
+class SqliteHandle : public StorageHandle
+{
+public:
+  class Error : public StorageHandle::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : StorageHandle::Error(what)
+    {
+    }
+  };
+
+  SqliteHandle();
+
+  explicit
+  SqliteHandle(const string& dbPath);
+
+  virtual
+  ~SqliteHandle();
+
+
+  // from StorageHandle
+
+  virtual bool
+  insertData(const Data& data);
+
+  virtual bool
+  deleteData(const Name& name);
+
+  virtual bool
+  readData(const Interest& interest, Data& data);
+
+  virtual bool
+  hasName(const Name& name);
+
+  virtual bool
+  readNameAny(const Name& name, const Selectors& selectors, vector<Name>& names);
+
+  virtual size_t
+  size();
+
+private:
+  void
+  initializeRepo();
+
+  /**
+  * @brief find data with the exact name matched
+  * @param[out] data Data matching Interest.
+  * @return if no data or something is wrong, return false
+  */
+  bool
+  readData(const Name& name, Data& data);
+
+  /**
+  * @brief check whether there is one row with this parentName = parentName in database
+  * @return if no data or something is wrong, return false.
+  */
+  bool
+  hasParentName(const Name& parentName) const;
+
+  /**
+  * @brief This function is for no selector, it will reply the leftmost data
+  * @param[out] data Data matching Interest.
+  * @return if no data or something is wrong, return false.
+  */
+  bool
+  readDataPlain(const Name& name, Data& data);
+
+  /**
+  * @brief  read data with this prefix or name
+  * @param name indicates name or prefix of interest
+  * @param[out] names is vector to contain the result of this function.
+  * @return success return true, error return false
+  */
+  bool
+  readDataName(const Name& name, vector<Name>& names) const;
+
+  /**
+  * @brief  read data with this prefix or name and selectors including  MinSuffixComponents,
+  * MaxSuffixComponents, PublisherPublicKeyLocator, and Exclude.
+  * This method does not consider ChildSelector and MustBeFresh.
+  *
+  * @param name indicates name or prefix of interest
+  * @param[out] names is vector to contain the result of this function.
+  * @return success return true, error return false
+  */
+  bool
+  readNameSelector(const Interest& interest, vector<Name>& names) const;
+
+  /**
+  * @brief ChildSelector filter
+  * @param names list of candidate names for ChildSelector filter
+  * @param[out] resultName is the result of selected name
+  * @return success return true, error return false
+  */
+  bool
+  filterNameChild(const Name& name, int childSelector,
+                  const vector<Name>& names, Name& resultName);
+
+private:
+  sqlite3* m_db;
+  string m_dbPath;
+};
+
+} // namespace repo
+
+#endif // REPO_STORAGE_SQLITE_HANDLE_HPP
diff --git a/src/storage/storage-handle.hpp b/src/storage/storage-handle.hpp
new file mode 100644
index 0000000..b75de2c
--- /dev/null
+++ b/src/storage/storage-handle.hpp
@@ -0,0 +1,126 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_STORAGE_STORAGE_HANDLE_HPP
+#define REPO_STORAGE_STORAGE_HANDLE_HPP
+
+#include "common.hpp"
+#include "storage-method.hpp"
+
+namespace repo {
+
+/**
+ * @brief this class defines handles to read, insert and delete data packets in storage media
+ */
+
+class StorageHandle : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+  /**
+   * @brief Create a basic class object the specified storage type
+   */
+  explicit
+  StorageHandle(StorageMethod storageMethod);
+
+  virtual
+  ~StorageHandle();
+
+  /**
+   * @return storage method defined in storage-define.hpp
+   */
+  StorageMethod
+  getStorageMethod() const;
+
+  /**
+   * @brief insert data
+   * @return true on success, false otherwise
+   */
+  virtual bool
+  insertData(const Data& data) = 0;
+
+  /**
+   * @brief delete the data that exactly matches the name
+   * @return true on success, false otherwise
+   * @note It's considered successful if Data doesn't exist.
+   */
+  virtual bool
+  deleteData(const Name& name) = 0;
+
+  /**
+  * @brief find data according to the interest. This interest may contain selectors.
+  * @param[out] data Data matching Interest.
+  * @return true if Data is found, false otherwise
+  */
+  virtual bool
+  readData(const Interest& interest, Data& data) = 0;
+
+  /**
+   * @return if storage media has data packets with this name, return true, else return false
+   */
+  virtual bool
+  hasName(const Name& name) = 0;
+
+  /**
+   * @brief select any data conforms to the selector
+   * @param[out] names Data names matching @p name and @p selectors.
+   * @return true if at least one Data is found, false otherwise
+   */
+  virtual bool
+  readNameAny(const Name& name, const Selectors& selectors, vector<Name>& names) = 0;
+
+  /**
+   * @brief Get the number of Data packets stored
+   */
+  virtual size_t
+  size() = 0;
+
+private:
+  StorageMethod m_storageMethod;
+};
+
+inline
+StorageHandle::StorageHandle(StorageMethod storageMethod)
+  : m_storageMethod(storageMethod)
+{
+}
+
+inline
+StorageHandle::~StorageHandle()
+{
+}
+
+inline StorageMethod
+StorageHandle::getStorageMethod() const
+{
+  return m_storageMethod;
+}
+
+} // namespace repo
+
+#endif // REPO_STORAGE_STORAGE_HANDLE_HPP
diff --git a/src/storage/storage-method.hpp b/src/storage/storage-method.hpp
new file mode 100644
index 0000000..219be7e
--- /dev/null
+++ b/src/storage/storage-method.hpp
@@ -0,0 +1,31 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REPO_STORAGE_STORAGE_METHOD_HPP
+#define REPO_STORAGE_STORAGE_METHOD_HPP
+
+namespace repo {
+
+enum StorageMethod {
+  STORAGE_METHOD_SQLITE = 1
+};
+
+} // namespace repo
+
+#endif // REPO_STORAGE_STORAGE_METHOD_HPP
