diff --git a/core/auditor.cpp b/core/auditor.cpp
index d0afa62..34f85d0 100644
--- a/core/auditor.cpp
+++ b/core/auditor.cpp
@@ -16,175 +16,225 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
+
 #include "auditor.hpp"
 
+#include <ndn-cxx/util/digest.hpp>
+
 namespace nsl {
 
-ndn::ConstBufferPtr
-Auditor::computeHash(ndn::ConstBufferPtr hash_l, ndn::ConstBufferPtr hash_r)
+bool
+Auditor::doesExist(const NonNegativeInteger& seqNo,
+                   ndn::ConstBufferPtr hash,
+                   const NonNegativeInteger& rootNextSeqNo,
+                   ndn::ConstBufferPtr rootHash,
+                   const std::vector<shared_ptr<Data>>& proofs,
+                   const Name& loggerName)
 {
-  ndn::Buffer tmp_buf = *hash_l;
-  for (int i = 0; i < hash_r->size(); i++)
-    {
-      tmp_buf.push_back((*hash_r)[i]);
+  BOOST_ASSERT(rootHash != nullptr);
+  BOOST_ASSERT(hash != nullptr);
+
+  std::map<Node::Index, ConstSubTreeBinaryPtr> trees;
+
+  if (!loadProof(trees, proofs, loggerName))
+    return false;
+
+  // std::cerr << "Loaded" << std::endl;
+
+  size_t rootLevel = 0;
+  NonNegativeInteger tmpSeqNo = rootNextSeqNo - 1;
+  while (tmpSeqNo != 0) {
+    rootLevel++;
+    tmpSeqNo = tmpSeqNo >> 1;
+  }
+
+  if (rootLevel == 0) { // only one node
+    // std::cerr << "one level" << std::endl;
+    if (seqNo != 0)
+      return false;
+
+    auto it = trees.find(Node::Index(0, SubTreeBinary::SUB_TREE_DEPTH - 1));
+    if (it != trees.end()) {
+      // std::cerr << "find subtree" << std::endl;
+      auto node = it->second->getNode(Node::Index(0, 0));
+      if (node != nullptr && *node->getHash() == *hash && *hash == *rootHash)
+        return true;
+      else
+        return false;
     }
-  ndn::ConstBufferPtr digest = ndn::crypto::sha256(tmp_buf.buf(), tmp_buf.size());
-  return digest;
+    else
+      return false;
+  }
+
+
+  NonNegativeInteger childSeqMask = 1;
+  NonNegativeInteger childSeqNo = seqNo;
+  size_t childLevel = 0;
+  ndn::ConstBufferPtr childHash = hash;
+
+  NonNegativeInteger parentSeqMask = (~0) << 1;
+  NonNegativeInteger parentSeqNo = childSeqNo & parentSeqMask;
+  size_t parentLevel = 1;
+
+  Node::Index treePeakIndex(0, 0);
+  ConstSubTreeBinaryPtr subTree;
+
+  do { // get parent hash
+    Node::Index tmpIndex =
+      SubTreeBinary::toSubTreePeakIndex(Node::Index(childSeqNo, childLevel));
+
+    // std::cerr << "peak: " << tmpIndex.level << ", " << tmpIndex.seqNo << std::endl;
+    if (tmpIndex != treePeakIndex) {
+      treePeakIndex = tmpIndex;
+      auto it = trees.find(treePeakIndex);
+      if (it != trees.end() && it->second != nullptr) {
+        subTree = it->second;
+      }
+      else
+        return false;
+    }
+
+    // std::cerr << "Hey" << std::endl;
+    // right child or left child
+    ndn::util::Sha256 sha256;
+    if (childSeqMask & seqNo) { // right child
+      // std::cerr << "right" << std::endl;
+      // std::cerr << parentSeqNo << ", " << childLevel << std::endl;
+      auto leftChild = subTree->getNode(Node::Index(parentSeqNo, childLevel));
+      if (leftChild == nullptr && leftChild->getHash() == nullptr)
+        return false;
+
+      // std::cerr << "found node" << std::endl;
+      sha256 << parentLevel << parentSeqNo;
+      sha256.update(leftChild->getHash()->buf(), leftChild->getHash()->size());
+      sha256.update(childHash->buf(), childHash->size());
+    }
+    else { // left child
+      // std::cerr << "left" << std::endl;
+      ndn::ConstBufferPtr rightChildHash = Node::getEmptyHash();
+      if (rootNextSeqNo > childSeqNo + (1 << childLevel)) {
+        // std::cerr << childSeqNo + (1 << childLevel) << ", " << childLevel << std::endl;
+        auto rightChild = subTree->getNode(Node::Index(childSeqNo + (1 << childLevel), childLevel));
+        if (rightChild == nullptr || rightChild->getHash() == nullptr)
+          return false;
+        rightChildHash = rightChild->getHash();
+        // std::cerr << "left done" << std::endl;
+      }
+
+      sha256 << parentLevel << parentSeqNo;
+      sha256.update(childHash->buf(), childHash->size());
+      sha256.update(rightChildHash->buf(), rightChildHash->size());
+    }
+
+    childSeqMask = childSeqMask << 1;
+    childSeqNo = parentSeqNo;
+    childLevel = parentLevel;
+    childHash = sha256.computeDigest();
+
+    parentSeqMask = parentSeqMask << 1;
+    parentSeqNo = childSeqNo & parentSeqMask;
+    parentLevel++;
+
+  } while (childLevel < rootLevel);
+
+  // std::cerr << "done" << std::endl;
+
+  return (*childHash == *rootHash);
 }
 
-
-
-
-
-ndn::ConstBufferPtr
-Auditor::computeHashOneSide(ndn::ConstBufferPtr hash_l)
-{
-  ndn::ConstBufferPtr digest = ndn::crypto::sha256(hash_l->buf(), hash_l->size());
-  return digest;
-}
-
-
-
-
-
-
 bool
-Auditor::verifyConsistency(uint64_t version1, uint64_t version2, ndn::ConstBufferPtr hash1,
-                           ndn::ConstBufferPtr hash2, std::vector<ConstNodePtr> proof)
+Auditor::isConsistent(const NonNegativeInteger& oldRootNextSeqNo,
+                      ndn::ConstBufferPtr oldRootHash,
+                      const NonNegativeInteger& newRootNextSeqNo,
+                      ndn::ConstBufferPtr newRootHash,
+                      const std::vector<shared_ptr<Data>>& proofs,
+                      const Name& loggerName)
 {
-  // find version2's level
-  uint64_t levelVer2 = 1;
-  uint64_t ver2 = version2;
-  while(ver2 >= 1)
-    {
-      ver2 = ver2 / 2;
-      levelVer2 += 1;
-    }
+  BOOST_ASSERT(oldRootHash != nullptr);
+  BOOST_ASSERT(newRootHash != nullptr);
 
-  // compare version2's hash
-  ndn::ConstBufferPtr hash_l;
-  ndn::ConstBufferPtr hash_r;
-  ndn::ConstBufferPtr tmp_hash;
-  Index tmp_idx = proof[0]->getIndex();
-  int isRight = tmp_idx.number % int(pow(2, tmp_idx.level + 1));
-  if (isRight != 0)
-    hash_r = proof[0]->getHash();
-  else
-    hash_l = proof[0]->getHash();
-  uint64_t i_ = 1;
-  for (; tmp_idx.level < levelVer2 - 1; )
-    {
-      if (isRight != 0)
-        {
-          hash_l = proof[i_]->getHash();
-          tmp_hash = computeHash(hash_l, hash_r);
-          i_++;
-        }
-      else
-        {
-          tmp_hash = computeHashOneSide(hash_l);
-        }
-      tmp_idx.level += 1;
-      tmp_idx.number -= tmp_idx.number % int(pow(2, tmp_idx.level));
-      isRight = tmp_idx.number % int(pow(2, tmp_idx.level + 1));
-      if (isRight != 0)
-        {
-          hash_r = tmp_hash;
-        }
-      else
-        {
-          hash_l = tmp_hash;
-        }
-    }
-  bool hash2_consis = true;
-  if (isRight != 0)
-    {
-      for (int i = 0; i < hash_r->size() ; i++)
-        {
-          if ((*hash2)[i] != (*hash_r)[i])
-            {
-              hash2_consis = false;
-              break;
-            }
-        }
-    }
-  else
-    {
-      for (int i = 0; i < hash_l->size() ; i++)
-        {
-          if ((*hash2)[i] != (*hash_l)[i])
-            {
-              hash2_consis = false;
-              break;
-            }
-        }
-    }
+  if (oldRootNextSeqNo > newRootNextSeqNo)
+    return false;
 
+  std::map<Node::Index, ConstSubTreeBinaryPtr> trees;
+  if (!loadProof(trees, proofs, loggerName))
+    return false;
 
+  // std::cerr << "1" << std::endl;
 
+  // get boundary leaf:
+  NonNegativeInteger leafSeqNo = oldRootNextSeqNo - 1;
+  NonNegativeInteger treeSeqNo = leafSeqNo & ((~0) << (SubTreeBinary::SUB_TREE_DEPTH - 1));
+  auto it = trees.find(Node::Index(treeSeqNo, SubTreeBinary::SUB_TREE_DEPTH - 1));
+  if (it == trees.end())
+    return false;
 
-  // compare hash1
-  tmp_idx = proof[i_]->getIndex();
-  isRight = tmp_idx.number % int(pow(2, tmp_idx.level + 1));
-  if (isRight != 0)
-    hash_r = proof[i_]->getHash();
-  else
-    hash_l = proof[i_]->getHash();
-  i_++;
-  for (; i_ < proof.size(); )
-    {
-      if (isRight != 0)
-        {
-          hash_l = proof[i_]->getHash();
-          tmp_hash = computeHash(hash_l, hash_r);
-          i_++;
-        }
-      else
-        {
-          tmp_hash = computeHashOneSide(hash_l);
-        }
-      tmp_idx.level += 1;
-      tmp_idx.number -= tmp_idx.number % int(pow(2, tmp_idx.level));
-      isRight = tmp_idx.number % int(pow(2, tmp_idx.level + 1));
-      if (isRight != 0)
-        {
-          hash_r = tmp_hash;
-        }
-      else
-        {
-          hash_l = tmp_hash;
-        }
-    }
+  auto leaf = it->second->getNode(Node::Index(leafSeqNo, 0));
+  if (leaf == nullptr || leaf->getHash() == nullptr)
+    return false;
 
-  bool hash1_consis = true;
-  if (isRight != 0)
-    {
-      for (int i = 0; i < hash_r->size() ; i++)
-        {
-          if ((*hash1)[i] != (*hash_r)[i])
-            {
-              hash1_consis = false;
-              break;
-            }
-        }
-    }
-  else
-    {
-      for (int i = 0; i < hash_l->size() ; i++)
-        {
-          if ((*hash1)[i] != (*hash_l)[i])
-            {
-              hash1_consis = false;
-              break;
-            }
-        }
-    }
+  if (!doesExist(leafSeqNo, leaf->getHash(), oldRootNextSeqNo, oldRootHash,
+                 proofs, loggerName))
+    return false;
 
-  return hash1_consis && hash2_consis;
+  // std::cerr << "2" << std::endl;
 
+  if (oldRootNextSeqNo == newRootNextSeqNo) {
+    if (*oldRootHash == *newRootHash)
+      return true;
+    else
+      return false;
+  }
+
+  // std::cerr << "3" << std::endl;
+
+  if (!doesExist(leafSeqNo, leaf->getHash(), newRootNextSeqNo, newRootHash,
+                 proofs, loggerName))
+    return false;
+
+  // std::cerr << "4" << std::endl;
+
+  return true;
 }
 
+bool
+Auditor::loadProof(std::map<Node::Index, ConstSubTreeBinaryPtr>& trees,
+                   const std::vector<shared_ptr<Data>>& proofs,
+                   const Name& loggerName)
+{
+  try {
+    for (auto proof : proofs) {
+      // std::cerr << proof->getName() << std::endl;
+      auto subtree =
+        make_shared<SubTreeBinary>(loggerName,
+                                   [] (const Node::Index& idx) {},
+                                   [] (const Node::Index&,
+                                       const NonNegativeInteger& seqNo,
+                                       ndn::ConstBufferPtr hash) {});
+      subtree->decode(*proof);
+
+      // std::cerr << subtree->getPeakIndex().level << ", " << subtree->getPeakIndex().seqNo << std::endl;
+      if (trees.find(subtree->getPeakIndex()) == trees.end())
+        trees[subtree->getPeakIndex()] = subtree;
+      else
+        return false;
+    }
+  }
+  catch (SubTreeBinary::Error& e) {
+    // std::cerr << e.what() << std::endl;
+    return false;
+  }
+  catch (Node::Error& e) {
+    // std::cerr << e.what() << std::endl;
+    return false;
+  }
+  catch (tlv::Error&) {
+    return false;
+  }
+
+  return true;
+}
 
 } // namespace nsl
diff --git a/core/auditor.hpp b/core/auditor.hpp
index 8f2919a..9117d5d 100644
--- a/core/auditor.hpp
+++ b/core/auditor.hpp
@@ -16,59 +16,47 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
-#ifndef NLS_CORE_AUDITOR_HPP
-#define NLS_CORE_AUDITOR_HPP
 
-#include <string>
+#ifndef NSL_CORE_AUDITOR_HPP
+#define NSL_CORE_AUDITOR_HPP
+
+#include "common.hpp"
+#include "node.hpp"
+#include "sub-tree-binary.hpp"
+#include "util/non-negative-integer.hpp"
+#include <ndn-cxx/encoding/buffer.hpp>
 #include <vector>
 
-#include <math.h>
-#include <stdint.h>
-
-#include <ndn-cxx/util/crypto.hpp>
-
-#include "node.hpp"
-
 namespace nsl {
 
-typedef ndn::shared_ptr<const Node> ConstNodePtr;
-typedef ndn::shared_ptr<Node> NodePtr;
-
 class Auditor
 {
 public:
-  Auditor()
-  {
-  }
+  static bool
+  doesExist(const NonNegativeInteger& seqNo,
+            ndn::ConstBufferPtr hash,
+            const NonNegativeInteger& rootNextSeqNo,
+            ndn::ConstBufferPtr rootHash,
+            const std::vector<shared_ptr<Data>>& proofs,
+            const Name& loggerName);
 
+  static bool
+  isConsistent(const NonNegativeInteger& seqNo,
+               ndn::ConstBufferPtr hash,
+               const NonNegativeInteger& rootNextSeqNo,
+               ndn::ConstBufferPtr rootHash,
+               const std::vector<shared_ptr<Data>>& proofs,
+               const Name& loggerName);
 
-  ~Auditor()
-  {
-  }
-
-
-  bool
-  verifyConsistency(uint64_t version1, uint64_t version2, ndn::ConstBufferPtr hash1,
-                    ndn::ConstBufferPtr hash2, std::vector<ConstNodePtr> proof);
-
-
-  std::vector<Node*>
-  queryByTime(time_t);
-
-  ndn::ConstBufferPtr
-  computeHash(ndn::ConstBufferPtr hash_l, ndn::ConstBufferPtr hash_r);
-
-
-  ndn::ConstBufferPtr
-  computeHashOneSide(ndn::ConstBufferPtr hash_l);
-
-
-private:
-
+NSL_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  static bool
+  loadProof(std::map<Node::Index, ConstSubTreeBinaryPtr>& trees,
+            const std::vector<shared_ptr<Data>>& proofs,
+            const Name& loggerName);
 };
 
 } // namespace nsl
 
-#endif // NLS_CORE_AUDITOR_HPP
+#endif // NSL_CORE_AUDITOR_HPP
diff --git a/core/db.cpp b/core/db.cpp
new file mode 100644
index 0000000..22361c5
--- /dev/null
+++ b/core/db.cpp
@@ -0,0 +1,309 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "db.hpp"
+
+#include <sqlite3.h>
+#include <string>
+#include <boost/filesystem.hpp>
+
+namespace nsl {
+
+static const std::string INITIALIZATION =
+  "CREATE TABLE IF NOT EXISTS                    \n"
+  "  cTrees(                                     \n"
+  "    id                    INTEGER PRIMARY KEY,\n"
+  "    level                 INTEGER NOT NULL,   \n"
+  "    seqNo                 INTEGER NOT NULL,   \n"
+  "    data                  BLOB NOT NULL       \n"
+  "  );                                          \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
+  "  cTreeIndex ON cTrees(level, seqNo);         \n"
+  "CREATE TRIGGER IF NOT EXISTS                  \n"
+  "  cTrees_after_insert_trigger                 \n"
+  "  AFTER INSERT ON cTrees                      \n"
+  "  FOR EACH ROW                                \n"
+  "  BEGIN                                       \n"
+  "    DELETE FROM pTrees                        \n"
+  "    WHERE level=NEW.level AND seqNo=NEW.seqNo;\n"
+  "  END;                                        \n"
+  "                                              \n"
+  "CREATE TABLE IF NOT EXISTS                    \n"
+  "  pTrees(                                     \n"
+  "    id                    INTEGER PRIMARY KEY,\n"
+  "    level                 INTEGER NOT NULL,   \n"
+  "    seqNo                 INTEGER NOT NULL,   \n"
+  "    nextLeafSeqNo         INTEGER NOT NULL,   \n"
+  "    data                  BLOB NOT NULL       \n"
+  "  );                                          \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
+  "  pTreeIndex ON pTrees(level, seqNo);         \n"
+  "                                              \n"
+  "CREATE TABLE IF NOT EXISTS                    \n"
+  "  leaves(                                     \n"
+  "    id                    INTEGER PRIMARY KEY,\n"
+  "    dataSeqNo             INTEGER NOT NULL,   \n"
+  "    dataName              BLOB NOT NULL,      \n"
+  "    signerSeqNo           INTEGER NOT NULL,   \n"
+  "    timestamp             INTEGER NOT NULL,   \n"
+  "    isCert                INTEGER DEFAULT 0,  \n"
+  "    cert                  BLOB                \n"
+  "  );                                          \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS             \n"
+  "  leavesIndex ON leaves(dataSeqNo);           \n";
+
+
+/**
+ * A utility function to call the normal sqlite3_bind_blob where the value and length are
+ * block.wire() and block.size().
+ */
+static int
+sqlite3_bind_block(sqlite3_stmt* statement,
+                   int index,
+                   const Block& block,
+                   void(*destructor)(void*))
+{
+  return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
+}
+
+/**
+ * A utility function to generate block by calling the normal sqlite3_column_text.
+ */
+static Block
+sqlite3_column_block(sqlite3_stmt* statement, int column)
+{
+  return Block(sqlite3_column_blob(statement, column), sqlite3_column_bytes(statement, column));
+}
+
+void
+Db::open(const std::string& dbDir)
+{
+  // Determine the path of logger database
+  if (dbDir == "")
+    throw Error("Db: empty db path");
+
+  boost::filesystem::path dir = boost::filesystem::path(dbDir);
+  boost::filesystem::create_directories(dir);
+
+  // Open database
+  int result = sqlite3_open_v2((dir / "sig-logger.db").c_str(), &m_db,
+                               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+#ifdef NSL_DISABLE_SQLITE3_FS_LOCKING
+                               "unix-dotfile"
+#else
+                               nullptr
+#endif
+                               );
+
+  if (result != SQLITE_OK)
+    throw Error("SigLogger DB cannot be opened/created: " + dbDir);
+
+  // initialize SigLogger specific tables
+  char* errorMessage = nullptr;
+  result = sqlite3_exec(m_db, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
+  if (result != SQLITE_OK && errorMessage != nullptr) {
+    sqlite3_free(errorMessage);
+    throw Error("SigLogger DB cannot be initialized");
+  }
+
+  getMaxLeafSeq();
+}
+
+bool
+Db::insertSubTreeData(size_t level, const NonNegativeInteger& seqNo,
+                      const Data& data,
+                      bool isFull, const NonNegativeInteger& nextLeafSeqNo)
+{
+  sqlite3_stmt* statement;
+  if (isFull) {
+    sqlite3_prepare_v2(m_db,
+                       "INSERT INTO cTrees (level, seqNo, data) VALUES (?, ?, ?)",
+                       -1, &statement, nullptr);
+  }
+  else {
+    sqlite3_prepare_v2(m_db,
+                       "INSERT OR REPLACE INTO pTrees (level, seqNo, data, nextLeafSeqNo)\
+                        VALUES (?, ?, ?, ?)",
+                       -1, &statement, nullptr);
+  }
+  sqlite3_bind_int(statement, 1, level);
+  sqlite3_bind_int(statement, 2, seqNo);
+  sqlite3_bind_block(statement, 3, data.wireEncode(), SQLITE_TRANSIENT);
+  if (!isFull)
+    sqlite3_bind_int(statement, 4, nextLeafSeqNo);
+
+  int result = sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  if (result == SQLITE_OK)
+    return true;
+  return false;
+}
+
+shared_ptr<Data>
+Db::getSubTreeData(size_t level, const NonNegativeInteger& seqNo)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_db,
+                     "SELECT data FROM cTrees WHERE level=? AND seqNo=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_int(statement, 1, level);
+  sqlite3_bind_int(statement, 2, seqNo);
+
+  if (sqlite3_step(statement) == SQLITE_ROW) {
+    auto result = make_shared<Data>(sqlite3_column_block(statement, 0));
+    sqlite3_finalize(statement);
+    return result;
+  }
+
+  sqlite3_prepare_v2(m_db,
+                     "SELECT data FROM pTrees WHERE level=? AND seqNo=?",
+                     -1, &statement, nullptr);
+  sqlite3_bind_int(statement, 1, level);
+  sqlite3_bind_int(statement, 2, seqNo);
+
+  shared_ptr<Data> result;
+  if (sqlite3_step(statement) == SQLITE_ROW)
+    result = make_shared<Data>(sqlite3_column_block(statement, 0));
+
+  sqlite3_finalize(statement);
+  return result;
+}
+
+std::vector<shared_ptr<Data>>
+Db::getPendingSubTrees()
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_db,
+                     "SELECT data FROM pTrees ORDER BY level DESC",
+                     -1, &statement, nullptr);
+
+  std::vector<shared_ptr<Data>> datas;
+  while (sqlite3_step(statement) == SQLITE_ROW)
+    datas.push_back(make_shared<Data>(sqlite3_column_block(statement, 0)));
+
+  sqlite3_finalize(statement);
+  return datas;
+}
+
+bool
+Db::insertLeafData(const Leaf& leaf)
+{
+  if (leaf.getDataSeqNo() != m_nextLeafSeqNo)
+    return false;
+
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_db,
+                     "INSERT INTO leaves (dataSeqNo, dataName, signerSeqNo, timestamp, isCert)\
+                      VALUES (?, ?, ?, ?, 0)",
+                     -1, &statement, nullptr);
+
+  sqlite3_bind_int(statement, 1, leaf.getDataSeqNo());
+  sqlite3_bind_block(statement, 2, leaf.getDataName().wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_bind_int(statement, 3, leaf.getSignerSeqNo());
+  sqlite3_bind_int(statement, 4, leaf.getTimestamp());
+
+  int result = sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  if (result == SQLITE_OK || result == SQLITE_DONE) {
+    m_nextLeafSeqNo++;
+    return true;
+  }
+
+  return false;
+}
+
+bool
+Db::insertLeafData(const Leaf& leaf, const Data& data)
+{
+  if (leaf.getDataSeqNo() != m_nextLeafSeqNo)
+    return false;
+
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_db,
+                     "INSERT INTO leaves (dataSeqNo, dataName, signerSeqNo, timestamp, isCert, cert)\
+                      VALUES (?, ?, ?, ?, 1, ?)",
+                     -1, &statement, nullptr);
+
+  sqlite3_bind_int(statement, 1, leaf.getDataSeqNo());
+  sqlite3_bind_block(statement, 2, leaf.getDataName().wireEncode(), SQLITE_TRANSIENT);
+  sqlite3_bind_int(statement, 3, leaf.getSignerSeqNo());
+  sqlite3_bind_int(statement, 4, leaf.getTimestamp());
+  sqlite3_bind_block(statement, 5, data.wireEncode(), SQLITE_TRANSIENT);
+
+  int result = sqlite3_step(statement);
+  sqlite3_finalize(statement);
+
+  if (result == SQLITE_OK || result == SQLITE_DONE) {
+    m_nextLeafSeqNo++;
+    return true;
+  }
+
+  return false;
+}
+
+std::pair<shared_ptr<Leaf>, shared_ptr<Data>>
+Db::getLeaf(const NonNegativeInteger& seqNo)
+{
+  sqlite3_stmt* statement;
+  sqlite3_prepare_v2(m_db,
+                     "SELECT dataName, signerSeqNo, timestamp, cert\
+                      FROM leaves WHERE dataSeqNo=?",
+                     -1, &statement, nullptr);
+
+  sqlite3_bind_int(statement, 1, seqNo);
+
+  if (sqlite3_step(statement) == SQLITE_ROW) {
+    auto leaf = make_shared<Leaf>(Name(sqlite3_column_block(statement, 0)),
+                                  sqlite3_column_int(statement, 2),
+                                  seqNo,
+                                  sqlite3_column_int(statement, 1));
+
+    shared_ptr<Data> data;
+    if (sqlite3_column_bytes(statement, 3) != 0) {
+      data = make_shared<Data>(sqlite3_column_block(statement, 3));
+    }
+    sqlite3_finalize(statement);
+    return std::make_pair(leaf, data);
+  }
+  else {
+    sqlite3_finalize(statement);
+    return std::make_pair(nullptr, nullptr);
+  }
+}
+
+const NonNegativeInteger&
+Db::getMaxLeafSeq()
+{
+  sqlite3_stmt* statement;
+
+  sqlite3_prepare_v2(m_db, "SELECT count(dataSeqNo) FROM leaves", -1, &statement, nullptr);
+  if (sqlite3_step(statement) == SQLITE_ROW)
+    m_nextLeafSeqNo = sqlite3_column_int(statement, 0);
+  else
+    throw Error("getMaxLeafSeq: db error");
+
+  sqlite3_finalize(statement);
+  return m_nextLeafSeqNo;
+}
+
+} // namespace nsl
diff --git a/core/db.hpp b/core/db.hpp
new file mode 100644
index 0000000..503b562
--- /dev/null
+++ b/core/db.hpp
@@ -0,0 +1,84 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#ifndef NSL_CORE_DB_HPP
+#define NSL_CORE_DB_HPP
+
+#include "common.hpp"
+#include "leaf.hpp"
+#include "util/non-negative-integer.hpp"
+#include <vector>
+
+struct sqlite3;
+
+namespace nsl {
+
+class Db : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  void
+  open(const std::string& dbDir);
+
+  bool
+  insertSubTreeData(size_t level, const NonNegativeInteger& seqNo,
+                    const Data& data,
+                    bool isFull = true,
+                    const NonNegativeInteger& nextLeafSeqNo = 0);
+
+  shared_ptr<Data>
+  getSubTreeData(size_t level, const NonNegativeInteger& seqNo);
+
+  std::vector<shared_ptr<Data>>
+  getPendingSubTrees();
+
+  bool
+  insertLeafData(const Leaf& leaf);
+
+  bool
+  insertLeafData(const Leaf& leaf, const Data& data);
+
+  std::pair<shared_ptr<Leaf>, shared_ptr<Data>>
+  getLeaf(const NonNegativeInteger& seqNo);
+
+NSL_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  const NonNegativeInteger&
+  getMaxLeafSeq();
+
+private:
+  sqlite3* m_db;
+
+  NonNegativeInteger m_nextLeafSeqNo;
+};
+
+} // namespace nsl
+
+#endif // NSL_CORE_DB_HPP
diff --git a/core/intermediate-node.cpp b/core/intermediate-node.cpp
deleted file mode 100644
index 11c37ff..0000000
--- a/core/intermediate-node.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-#include "intermediate-node.hpp"
-
-namespace nsl {
-
-bool
-IntermediateNode::isFull() const
-{
-  return m_isFull;
-}
-
-
-
-bool
-IntermediateNode::setIsFull(uint64_t number)
-{
-  Index info = this->getIndex();
-  uint64_t num = info.number;
-  uint64_t lev = info.level;
-  if (double(num) + pow(2, lev) <= number)
-    {
-      m_isFull = true;
-      return m_isFull;
-    }
-  else
-    {
-      m_isFull = false;
-      return m_isFull;
-    }
-
-}
-
-
-
-void
-IntermediateNode::computeHash(ndn::ConstBufferPtr hash_l, ndn::ConstBufferPtr hash_r)
-{
-  ndn::Buffer tmp_buf = *hash_l;
-  for (int i = 0; i < hash_r->size(); i++)
-    {
-      tmp_buf.push_back((*hash_r)[i]);
-    }
-  ndn::ConstBufferPtr digest = ndn::crypto::sha256(tmp_buf.buf(), tmp_buf.size());
-  this->setHash(digest);
-}
-
-void IntermediateNode::computeHashOneSide(ndn::ConstBufferPtr hash_l)
-{
-  ndn::ConstBufferPtr digest = ndn::crypto::sha256(hash_l->buf(), hash_l->size());
-  this->setHash(digest);
-}
-
-} // namespace nsl
diff --git a/core/intermediate-node.hpp b/core/intermediate-node.hpp
deleted file mode 100644
index c2c3c0b..0000000
--- a/core/intermediate-node.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-#ifndef NLS_CORE_INTERMEDIATE_NODE_HPP
-#define NLS_CORE_INTERMEDIATE_NODE_HPP
-
-#include <stddef.h>
-#include <math.h>
-#include <ndn-cxx/util/crypto.hpp>
-#include "node.hpp"
-
-
-namespace nsl {
-
-
-class IntermediateNode : public Node
-{
-public:
-
-  IntermediateNode()
-    : Node()
-  {
-  }
-
-  IntermediateNode(uint64_t sequenceNumber, uint64_t level, time_t timestamp)
-    : Node(sequenceNumber, level, timestamp), m_isFull(false)
-  {
-  }
-
-  IntermediateNode(const IntermediateNode& new_node)
-    :Node(new_node.getIndex().number, new_node.getIndex().level, 0)
-  {
-    m_isFull = new_node.isFull();
-    this->setHash(new_node.getHash());
-  }
-
-  ~IntermediateNode()
-  {
-  }
-
-  bool
-  setIsFull(uint64_t totalLeafNum);
-
-  bool
-  isFull() const;
-
-  void
-  computeHash(ndn::ConstBufferPtr hash_l, ndn::ConstBufferPtr hash_r);
-
-  void
-  computeHashOneSide(ndn::ConstBufferPtr hash_l);
-
-private:
-  bool m_isFull;
-};
-
-} // namespace nsl
-
-#endif // NLS_CORE_INTERMEDIATE_NODE_HPP
diff --git a/core/leaf.cpp b/core/leaf.cpp
index 33ee527..e862d37 100644
--- a/core/leaf.cpp
+++ b/core/leaf.cpp
@@ -16,25 +16,239 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
+
 #include "leaf.hpp"
+#include "tlv.hpp"
+#include <ndn-cxx/security/digest-sha256.hpp>
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <ndn-cxx/util/crypto.hpp>
 
-namespace nsl{
+namespace nsl {
 
-ndn::ConstBufferPtr
-Leaf::getData() const
+const Name Leaf::EMPTY_NAME;
+const size_t Leaf::N_LOGGER_LEAF_SUFFIX = 4;
+const ssize_t Leaf::OFFSET_LEAF_SEQNO = -2;
+const ssize_t Leaf::OFFSET_LEAF_HASH = -1;
+
+Leaf::Leaf()
 {
-  return m_data;
 }
 
-
+Leaf::Leaf(const Name& dataName,
+       const Timestamp& timestamp,
+       const NonNegativeInteger& dataSeqNo,
+       const NonNegativeInteger& signerSeqNo,
+       const Name& loggerName)
+  : m_dataName(dataName)
+  , m_timestamp(timestamp)
+  , m_dataSeqNo(dataSeqNo)
+  , m_signerSeqNo(signerSeqNo)
+  , m_loggerName(loggerName)
+{
+  if (m_dataSeqNo < m_signerSeqNo)
+    throw Error("Leaf: signer seqNo should be less than the data seqNo");
+}
 
 void
-Leaf::computeHash()
+Leaf::setDataSeqNo(const NonNegativeInteger& dataSeqNo)
 {
-  ndn::ConstBufferPtr digest = ndn::crypto::sha256(m_data->buf(), m_data->size());
-  this->setHash(digest);
+  if (dataSeqNo < m_signerSeqNo)
+    throw Error("Leaf: signer seqNo should be less than the data seqNo");
+
+  m_wire.reset();
+  m_dataSeqNo = dataSeqNo;
+}
+
+void
+Leaf::setDataName(const Name& dataName)
+{
+  m_wire.reset();
+  m_dataName = dataName;
+}
+
+void
+Leaf::setTimestamp(const Timestamp& timestamp)
+{
+  m_wire.reset();
+  m_timestamp = timestamp;
+}
+
+void
+Leaf::setSignerSeqNo(const NonNegativeInteger& signerSeqNo)
+{
+  if (m_dataSeqNo < signerSeqNo)
+    throw Error("Leaf: signer seqNo should be less than the data seqNo");
+
+  m_wire.reset();
+  m_signerSeqNo = signerSeqNo;
+}
+
+void
+Leaf::setLoggerName(const Name& loggerName)
+{
+  m_loggerName = loggerName;
+}
+
+ndn::ConstBufferPtr
+Leaf::getHash() const
+{
+  wireEncode();
+  return ndn::crypto::sha256(m_wire.wire(), m_wire.size());
+}
+
+shared_ptr<Data>
+Leaf::encode() const
+{
+  auto data = make_shared<Data>();
+
+  ndn::ConstBufferPtr hash = getHash();
+
+  // Name
+  Name dataName = m_loggerName;
+  dataName.appendNumber(m_dataSeqNo).append(hash->buf(), hash->size());
+  data->setName(dataName);
+
+  // Content
+  data->setContent(wireEncode());
+
+  // Signature
+  ndn::DigestSha256 sig;
+  data->setSignature(sig);
+
+  Block sigValue(tlv::SignatureValue,
+                 ndn::crypto::sha256(data->wireEncode().value(),
+                                     data->wireEncode().value_size() -
+                                     data->getSignature().getValue().size()));
+  data->setSignatureValue(sigValue);
+
+  data->wireEncode();
+
+  return data;
+}
+
+void
+Leaf::decode(const Data& data)
+{
+  const Name& dataName = data.getName();
+
+  if (!m_loggerName.isPrefixOf(dataName))
+    throw Error("decode: leaf data name does not match logger name");
+
+  if (m_loggerName.size() + N_LOGGER_LEAF_SUFFIX != dataName.size())
+    throw Error("decode: leaf data name does not follow the naming convention");
+
+  ndn::ConstBufferPtr leafHash;
+  NonNegativeInteger dataSeqNo;
+  try {
+    leafHash = make_shared<ndn::Buffer>(dataName.get(OFFSET_LEAF_HASH).value(),
+                                        dataName.get(OFFSET_LEAF_HASH).value_size());
+
+    dataSeqNo = dataName.get(OFFSET_LEAF_SEQNO).toNumber();
+  }
+  catch (tlv::Error&) {
+    throw Error("decode: logger name encoding error");
+  }
+
+  wireDecode(data.getContent().blockFromValue());
+
+  if (*leafHash != *getHash())
+    throw Error("decode: inconsistent hash");
+
+  if (m_dataSeqNo != dataSeqNo)
+    throw Error("decode: seqNo does not match");
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+Leaf::wireEncode(ndn::EncodingImpl<TAG>& block) const
+{
+  size_t totalLength = 0;
+
+  totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::SignerSeqNo, m_signerSeqNo);
+  totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::DataSeqNo, m_dataSeqNo);
+  totalLength += ndn::prependNonNegativeIntegerBlock(block, tlv::Timestamp, m_timestamp);
+  totalLength += m_dataName.wireEncode(block);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::LoggerLeaf);
+
+  return totalLength;
+}
+
+template size_t
+Leaf::wireEncode<ndn::encoding::EncoderTag>(ndn::EncodingImpl<ndn::encoding::EncoderTag>&) const;
+
+template size_t
+Leaf::wireEncode<ndn::encoding::EstimatorTag>(ndn::EncodingImpl<ndn::encoding::EstimatorTag>&) const;
+
+
+const Block&
+Leaf::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+Leaf::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::LoggerLeaf)
+    throw tlv::Error("Unexpected TLV type when decoding logger leaf");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be dataName
+  if (it != m_wire.elements_end() && it->type() == tlv::Name) {
+    m_dataName.wireDecode(*it);
+    it++;
+  }
+  else
+    throw Error("The first sub-TLV is not Name");
+
+  // the second block must be timestamp
+  if (it != m_wire.elements_end() && it->type() == tlv::Timestamp) {
+    m_timestamp = readNonNegativeInteger(*it);
+    it++;
+  }
+  else
+    throw Error("The second sub-TLV is not Timestamp");
+
+  // the third block must be DataSeqNo
+  if (it != m_wire.elements_end() && it->type() == tlv::DataSeqNo) {
+    m_dataSeqNo = readNonNegativeInteger(*it);
+    it++;
+  }
+  else
+    throw Error("The third sub-TLV is not DataSeqNo");
+
+  // the third block must be SignerSeqNo
+  if (it != m_wire.elements_end() && it->type() == tlv::SignerSeqNo) {
+    m_signerSeqNo = readNonNegativeInteger(*it);
+    it++;
+  }
+  else
+    throw Error("The fourth sub-TLV is not SignerSeqNo");
+
+  if (it != m_wire.elements_end())
+    throw Error("No more sub-TLV in LoggerLeaf");
 }
 
 } // namespace nsl
diff --git a/core/leaf.hpp b/core/leaf.hpp
index 9576c09..3f8b0a5 100644
--- a/core/leaf.hpp
+++ b/core/leaf.hpp
@@ -16,56 +16,128 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
-#ifndef NLS_CORE_LEAF_HPP
-#define NLS_CORE_LEAF_HPP
 
-#include <vector>
-#include <ndn-cxx/util/crypto.hpp>
-#include "node.hpp"
+#ifndef NSL_CORE_LEAF_HPP
+#define NSL_CORE_LEAF_HPP
+
+#include "common.hpp"
+#include "util/non-negative-integer.hpp"
+#include "util/timestamp.hpp"
+#include <ndn-cxx/encoding/buffer.hpp>
 
 namespace nsl {
 
-class Leaf : public Node
+class Leaf
 {
 public:
-
-  Leaf()
-    : Node()
+  class Error : public std::runtime_error
   {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  Leaf();
+
+  Leaf(const Name& dataName,
+       const Timestamp& timestamp,
+       const NonNegativeInteger& leafSeqNo,
+       const NonNegativeInteger& signerSeqNo,
+       const Name& loggerName = EMPTY_NAME);
+
+  void
+  setDataSeqNo(const NonNegativeInteger& dataSeqNo);
+
+  const NonNegativeInteger&
+  getDataSeqNo() const
+  {
+    return m_dataSeqNo;
   }
 
+  void
+  setDataName(const Name& dataName);
 
-  Leaf(ndn::ConstBufferPtr data, uint64_t sequenceNumber, uint64_t level, time_t timestamp)
-    : Node(sequenceNumber, level, timestamp), m_data(data)
+  const Name&
+  getDataName() const
   {
+    return m_dataName;
   }
 
+  void
+  setTimestamp(const Timestamp& timestamp);
 
-  Leaf(const Leaf& new_leaf)
-    : Node(new_leaf.getIndex().number, new_leaf.getIndex().level, new_leaf.getTimestamp())
+  const Timestamp&
+  getTimestamp() const
   {
-    m_data = new_leaf.getData();
-    this->setHash(new_leaf.getHash());
+    return m_timestamp;
   }
 
+  void
+  setSignerSeqNo(const NonNegativeInteger& signerSeqNo);
 
-  ~Leaf()
+  const NonNegativeInteger&
+  getSignerSeqNo() const
   {
+    return m_signerSeqNo;
+  }
+
+  void
+  setLoggerName(const Name& loggerName);
+
+  const Name&
+  getLoggerName() const
+  {
+    return m_loggerName;
   }
 
   ndn::ConstBufferPtr
-  getData() const;
+  getHash() const;
 
+  shared_ptr<Data>
+  encode() const;
 
   void
-  computeHash();
+  decode(const Data& data);
+
+NSL_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /// @brief Encode to a wire format or estimate wire format
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  /// @brief Encode to a wire format
+  const Block&
+  wireEncode() const;
+
+  /// @brief Decode from a wire format
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const Name EMPTY_NAME;
+
+NSL_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  static const size_t N_LOGGER_LEAF_SUFFIX;
+  static const ssize_t OFFSET_LEAF_SEQNO;
+  static const ssize_t OFFSET_LEAF_HASH;
 
 private:
-  ndn::ConstBufferPtr m_data;
+  Name m_dataName;
+  Timestamp m_timestamp;
+  NonNegativeInteger m_dataSeqNo;
+  NonNegativeInteger m_signerSeqNo;
+
+  mutable Block m_wire;
+
+  Name m_loggerName;
 };
 
 } // namespace nsl
 
-#endif // NLS_CORE_LEAF_HPP
+#endif // NSL_CORE_LEAF_HPP
diff --git a/core/merkle-tree-cache.cpp b/core/merkle-tree-cache.cpp
deleted file mode 100644
index a7f2dc0..0000000
--- a/core/merkle-tree-cache.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-
-#include "merkle-tree-cache.hpp"
-
-
-
-namespace nsl {
-
-typedef std::map<Index, int>::iterator tree_iter;
-typedef std::map<uint64_t, ndn::ConstBufferPtr>::iterator leaf_iter;
-
-Index
-MerkleTreeCache::findSubTree(Index nodeIndex)
-{
-  if(nodeIndex.level % 6 == 0 && nodeIndex.level != 0)
-    {
-      return nodeIndex;
-    }
-  else
-    {
-      uint8_t step = (uint64_t(nodeIndex.level / 6) + 1) * 6 - nodeIndex.level;
-      for (int i = 0; i < step; i++)
-        {
-          nodeIndex.number -= nodeIndex.number % int(pow(2, nodeIndex.level + 1));
-          nodeIndex.level += 1;
-        }
-      return nodeIndex;
-    }
-}
-
-Index
-MerkleTreeCache::getParentRootIndex(Index thisRootIndex)
-{
-  Index parentIndex;
-  parentIndex.number = thisRootIndex.number;
-  parentIndex.level = thisRootIndex.level;
-  for (int i = 0; i < 6; i++)
-    {
-      parentIndex.number -= parentIndex.number%int(pow(2, parentIndex.level + 1));
-      parentIndex.level += 1;
-    }
-  return parentIndex;
-}
-
-
-void
-MerkleTreeCache::removeSubTree()
-{
-  if (doesCacheFull() > 1)
-    {
-      // find out the least recent used subtree
-      tree_iter _i = m_timeFromLastUse.begin();
-      int idle_time_max = -1;
-      Index rm_index_max = _i->first;
-      int idle_time_min = _i->second;
-      Index rm_index_min = _i->first;
-      for (_i = m_timeFromLastUse.begin(); _i != m_timeFromLastUse.end(); _i++)
-        {
-          if (_i->second > idle_time_max && m_cachedTree[_i->first]->getRemainPosition() == 0)
-            {
-              idle_time_max = _i->second;
-              rm_index_max = _i->first;
-            }
-          if (_i->second < idle_time_min)
-            {
-              idle_time_min = _i->second;
-              rm_index_min = _i->first;
-            }
-        }
-
-      // refresh the timer
-      for (_i = m_timeFromLastUse.begin(); _i != m_timeFromLastUse.end(); _i++)
-        {
-          _i->second -= idle_time_min;
-        }
-      // update to database and remove subtree from cache and timer,only when there is full subtree
-      if (m_cachedTree[rm_index_max]->getRemainPosition() == 0 && idle_time_max >= 0)
-        {
-          m_database.addSubTree(m_cachedTree[rm_index_max]);
-          m_cachedTree.erase(rm_index_max);
-          m_timeFromLastUse.erase(rm_index_max);
-        }
-    }
-}
-
-void
-MerkleTreeCache::removeLeaf()
-{
-  if (doesCacheFull() % 2 != 0)
-    {
-      // randomly pick a old leaf to remove
-      leaf_iter _i = m_leavesData.begin();
-      while (_i->first == m_nLeaves - 1)
-        {
-          _i++;
-        }
-      m_database.addLeafInfo(_i->first, _i->second);
-      m_leavesData.erase(_i->first);
-    }
-}
-
-
-
-
-
-// Do not have to deal with NOT-IN-MEMORY issue because not full tree will not in database
-void
-MerkleTreeCache::addLeaf(Leaf newLeaf)
-{
-  ndn::ConstBufferPtr data = newLeaf.getData();
-  removeLeaf(); // test whether is full, if so, delete an old item
-  m_leavesData[newLeaf.getIndex().number] = data;
-  Index leafIndex = newLeaf.getIndex();
-  ndn::ConstBufferPtr hash = newLeaf.getHash();
-
-  Index subTreeRoot = findSubTree(leafIndex);
-  if (m_nLeaves > 0)
-    {
-      // Not full so that always in memory
-      m_cachedTree[subTreeRoot]->addNode(hash);
-      m_nLeaves += 1;
-    }
-  else
-    {
-      SubTreePtr newTree(new SubTree(subTreeRoot,
-                                     ndn::bind(&MerkleTreeCache::update, this,
-                                               subTreeRoot, _1, _2)));
-      newTree->addNode(hash);
-      removeSubTree();
-      m_cachedTree[subTreeRoot] = newTree;
-      m_nLeaves = 1;
-      m_nLevels = 1;
-    }
-
-  for (tree_iter _i = m_timeFromLastUse.begin(); _i != m_timeFromLastUse.end(); _i++)
-    {
-      _i->second += 1;
-    }
-  m_timeFromLastUse[subTreeRoot] = 0; // if not exist, automatically create one and set to 0
-}
-
-
-// Deal with loading from database
-// database update
-// consider add to database when a subtree is full
-void
-MerkleTreeCache::update(Index subRootIndex, uint8_t subRemainNum, ndn::ConstBufferPtr subRootHash)
-{
-  if ((subRootIndex.level / 6) < m_nLevels)
-    {
-      Index parentRoot = getParentRootIndex(subRootIndex);
-
-      // bring in memory if parentRoot not in
-      if (m_cachedTree.count(parentRoot) <= 0)
-        {
-          loadSubTreeFromDatabase(parentRoot);
-        }
-      m_cachedTree[parentRoot]->updateLeafHash(subRootIndex, subRootHash);
-      m_timeFromLastUse[parentRoot] = 0;
-    }
-
-  if (subRemainNum == 0) // add the current full subtree into the database
-    {
-      Index parentRoot = getParentRootIndex(subRootIndex);
-      if ((subRootIndex.level / 6) >= m_nLevels) // if it is the top subtree
-        {
-          SubTreePtr newTree(new SubTree(parentRoot,
-                                         ndn::bind(&MerkleTreeCache::update, this,
-                                                   parentRoot, _1, _2)));
-          removeSubTree();
-          m_cachedTree[parentRoot] = newTree;
-          m_nLevels += 1;
-          m_timeFromLastUse[parentRoot] = 0;
-          m_cachedTree[parentRoot]->updateLeafHash(subRootIndex, subRootHash);
-        }
-      Index newRoot;
-      newRoot.level = subRootIndex.level;
-      newRoot.number = subRootIndex.number + int(pow(2, subRootIndex.level));
-      // whether the updated subtree is already full,
-      // but its child subtree is not full.
-      // To avoid create multiple sibling new subtree
-      if (m_cachedTree.count(newRoot) == 0)
-        {
-          SubTreePtr newTree(new SubTree(newRoot,
-                                         ndn::bind(&MerkleTreeCache::update, this,
-                                                   newRoot, _1, _2)));
-          removeSubTree();
-          m_cachedTree[newRoot] = newTree;
-          m_timeFromLastUse[newRoot] = 0;
-        }
-    }
-}
-
-
-NodePtr
-MerkleTreeCache::queryNode(Index nodeIndex)
-{
-  // update timer
-  for (tree_iter _i = m_timeFromLastUse.begin(); _i != m_timeFromLastUse.end(); _i++)
-    {
-      _i->second += 1;
-    }
-
-  Index rootIndex = findSubTree(nodeIndex);
-  ndn::ConstBufferPtr hash;
-  if (m_cachedTree.count(rootIndex) == 0)
-    {
-      loadSubTreeFromDatabase(rootIndex);
-    }
-  hash = m_cachedTree[rootIndex]->getHash(nodeIndex);
-
-  if (nodeIndex.level == 0)
-    {
-      if (m_leavesData.count(nodeIndex.number) == 0)
-        {
-          loadLeafFromDatabase(nodeIndex.number);
-        }
-      NodePtr node_ptr(new Leaf(m_leavesData[nodeIndex.number],
-                                nodeIndex.number, nodeIndex.level, 0));
-      node_ptr->setHash(hash);
-      return node_ptr;
-    }
-  else
-    {
-      NodePtr node_ptr(new IntermediateNode(nodeIndex.number, nodeIndex.level, 0));
-      node_ptr->setHash(hash);
-      ((IntermediateNode*)node_ptr.get())->setIsFull(m_nLeaves);
-      return node_ptr;
-    }
-}
-
-
-bool
-MerkleTreeCache::doesNodeExist(Index nodeIndex)
-{
-  Index rootIndex = findSubTree(nodeIndex);
-  if (m_cachedTree.count(rootIndex) > 0)
-    {
-      return true;
-    }
-  else
-    {
-      bool result = m_database.doesSubTreeExist(rootIndex);
-      return result;
-    }
-}
-
-
-
-SubTreePtr
-MerkleTreeCache::decoding(std::string subTreeInfo)
-{
-  uint64_t seq = 0;
-  unsigned char tmp = 0;
-  for (int i = 7; i >= 0; i--)
-    {
-      tmp = subTreeInfo[i];
-      seq += tmp;
-      seq = seq << 8;
-    }
-  seq = seq >> 8;
-  uint64_t lev = 0;
-  for (int i = 15; i >= 8; i--)
-    {
-      tmp = subTreeInfo[i];
-      lev += tmp;
-      lev = lev << 8;
-    }
-  lev = lev >> 8;
-  Index rootIndex;
-  rootIndex.number = seq;
-  rootIndex.level = lev;
-  SubTreePtr newTree(new SubTree(rootIndex,
-                                 ndn::bind(&MerkleTreeCache::update, this,
-                                           rootIndex, _1, _2)));
-  uint8_t remain = subTreeInfo[16]; // not useful
-  if (remain == 0)
-    {
-      std::vector<ndn::BufferPtr> hashes;
-      for (int i = 0; i < 127; i++)
-        {
-          ndn::Buffer buf;
-          for(int j = 17 + 32 * i; j < 49 + 32 * i; j++)
-            {
-              buf.push_back(subTreeInfo[j]);
-            }
-          ndn::BufferPtr thisBuf = ndn::make_shared<ndn::Buffer>(buf);
-          hashes.push_back(thisBuf);
-        }
-      newTree->resumeFromString(remain, hashes);
-      return newTree;
-    }
-  else
-    {
-      std::vector<ndn::BufferPtr> hashes;
-      uint8_t lastNo = 126 - remain;
-      for (int i = 63; i <= lastNo; i++)
-        {
-          ndn::Buffer buf;
-          for(int j = 17 + 32 * i; j < 49 + 32 * i; j++)
-            {
-              buf.push_back(subTreeInfo[j]);
-            }
-          ndn::BufferPtr thisBuf = ndn::make_shared<ndn::Buffer>(buf);
-          hashes.push_back(thisBuf);
-        }
-      newTree->resumeFromString(remain, hashes);
-      return newTree;
-    }
-}
-
-
-void
-MerkleTreeCache::loadSubTreeFromDatabase(Index rootIndex)
-{
-  // Detect the cache limitation
-  removeSubTree();
-  std::string tmp_str = m_database.getSubTree(rootIndex);
-  SubTreePtr newtree = decoding(tmp_str);
-  m_cachedTree[rootIndex] = newtree;
-  m_timeFromLastUse[rootIndex] = 0;
-}
-
-void
-MerkleTreeCache::loadLeafFromDatabase(uint64_t sequence)
-{
-  // Detect the cache limitation
-  removeLeaf();
-  ndn::ConstBufferPtr newleaf = m_database.getLeafInfo(sequence);
-  m_leavesData[sequence] = newleaf;
-}
-
-
-} // namespace nsl
diff --git a/core/merkle-tree-cache.hpp b/core/merkle-tree-cache.hpp
deleted file mode 100644
index 97e8908..0000000
--- a/core/merkle-tree-cache.hpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-#ifndef NLS_CORE_MERKLE_TREE_CACHE_HPP
-#define NLS_CORE_MERKLE_TREE_CACHE_HPP
-
-#include <map>
-#include <vector>
-
-#include "sub-tree.hpp"
-#include "leaf.hpp"
-#include "intermediate-node.hpp"
-#include "merkle-tree-sqlite3.hpp"
-
-
-namespace nsl {
-
-
-typedef ndn::shared_ptr<const SubTree> ConstSubTreePtr;
-typedef ndn::shared_ptr<SubTree> SubTreePtr;
-typedef ndn::shared_ptr<const Node> ConstNodePtr;
-typedef ndn::shared_ptr<Node> NodePtr;
-
-class MerkleTreeCache
-{
-public:
-
-  MerkleTreeCache()
-    :m_nLevels(0),
-     m_nLeaves(0)
-  {
-  }
-
-  ~MerkleTreeCache()
-  {
-  }
-
-  uint8_t
-  getLevel()
-  {
-    return m_nLevels;
-  }
-
-  uint64_t
-  getLeaves()
-  {
-    return m_nLeaves;
-  }
-
-  SubTreePtr
-  getSubTree(Index rootIndex)
-  {
-    if (m_cachedTree.count(rootIndex) > 0)
-      {
-        //std::cout<<"I'm here!"<<int(m_cachedTree[rootIndex]->getRemainPosition())<<std::endl;
-        return m_cachedTree[rootIndex];
-      }
-    else
-      {
-        std::string treeString = m_database.getSubTree(rootIndex);
-        SubTreePtr newtree = decoding(treeString);
-        return newtree;
-      }
-  }
-
-  // Do the update when a subtree is full
-  // Iteratively: find parent --> check full --> ... --> if not full -->
-  // create subtree --> create subsubtree --> ... --> until down to the leaf
-  // invoke a subtree.updateHash(), and decide whether to add new subtrees according to the callback
-  // remainPosition value.
-  void
-  update(Index subRootIndex, uint8_t subRemainNum, ndn::ConstBufferPtr subRootHash);
-
-  void
-  addLeaf(Leaf newLeaf);
-
-  NodePtr
-  queryNode(Index nodeIndex);
-
-  bool
-  doesNodeExist(Index nodeIndex);
-
-  void
-  loadSubTreeFromDatabase(Index rootIndex);
-
-  void
-  loadLeafFromDatabase(uint64_t sequence);
-
-
-
-  SubTreePtr
-  decoding(std::string subTreeInfo);
-
-  // remove the comment to test sqlite3 function
-  // MerkleTreeSqlite3 m_database;
-
-  // To show the exact size of the cache
-  // std::map<Index, SubTreePtr> m_cachedTree;
-  // std::map<uint64_t, ndn::ConstBufferPtr> m_leavesData;
-
-
-private:
-
-  // find which subTree the node belongs to (not include root node)
-  Index
-  findSubTree(Index nodeIndex);
-
-  // find a subTree's parent root index
-  Index
-  getParentRootIndex(Index thisRootIndex);
-
-
-  // To be finished
-  uint8_t
-  doesCacheFull()
-  {
-    if (m_cachedTree.size() >= 3 && m_leavesData.size() >= 64)
-      {
-        return 3;
-      }
-    else if (m_cachedTree.size() >= 3 && m_leavesData.size() < 64)
-      {
-        return 2;
-      }
-    else if (m_cachedTree.size() < 3 && m_leavesData.size() >= 64)
-      {
-        return 1;
-      }
-    else
-      {
-        return 0;
-      }
-  }
-
-  // choose a cache item to remove,
-  // exactly remove items from cache only when: 1)have full subtrees 2)cache is full
-  void
-  removeSubTree();
-
-  void
-  removeLeaf();
-
-private:
-  // partly in cache, completely in db
-  std::map<Index, SubTreePtr> m_cachedTree;
-  std::map<uint64_t, ndn::ConstBufferPtr> m_leavesData; //starts from 0(same as leaf)
-
-  // completely in memory, add & delete with time
-  std::map<Index, int> m_timeFromLastUse;
-  uint8_t m_nLevels; // levels counted based on subtree unit
-  uint64_t m_nLeaves; // sequence number + 1
-
-  // sqlite3 database
-  MerkleTreeSqlite3 m_database;
-};
-
-} // namespace nsl
-
-#endif // NLS_CORE_MERKLE_TREE_CACHE_HPP
diff --git a/core/merkle-tree-sqlite3.cpp b/core/merkle-tree-sqlite3.cpp
deleted file mode 100644
index 1844ad4..0000000
--- a/core/merkle-tree-sqlite3.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-
-#include "merkle-tree-sqlite3.hpp"
-#include <stdlib.h>
-#include <boost/filesystem.hpp>
-
-
-namespace nsl {
-
-static const std::string INIT_SUBTREE_TABLE = "\
-CREATE TABLE IF NOT EXISTS                                           \n \
-  SubTree(                                                           \n \
-      subTree_sequence     INTEGER,                                  \n \
-      subTree_level        INTEGER,                                  \n \
-      subTree_info         BLOB,                                     \n \
-                                                                     \
-      PRIMARY KEY (subTree_sequence, subTree_level)                  \n \
-  );                                                                 \n \
-                                                                     \
-CREATE INDEX subTree_index ON SubTree(subTree_sequence);             \n \
-";
-
-static const std::string INIT_LEAF_TABLE = "\
-CREATE TABLE IF NOT EXISTS                                           \n \
-  Leaf(                                                              \n \
-      leaf_sequence     INTEGER,                                     \n \
-      leaf_info         BLOB,                                        \n \
-                                                                     \
-      PRIMARY KEY (leaf_sequence)                                    \n \
-  );                                                                 \n \
-                                                                     \
-CREATE INDEX leaf_index ON Leaf(leaf_sequence);                      \n \
-";
-
-/**
- * A utility function to call the normal sqlite3_bind_text where the value and length are
- * value.c_str() and value.size().
- */
-static int sqlite3_bind_text(sqlite3_stmt* statement,
-                             int index,
-                             const std::string& value,
-                             void(*destructor)(void*))
-{
-  return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
-}
-
-
-MerkleTreeSqlite3::MerkleTreeSqlite3()
-{
-  boost::filesystem::path identityDir = boost::filesystem::path("/Users/GPZ/Develop/nslDB");
-  boost::filesystem::create_directories(identityDir);
-
-  /// @todo Add define for windows/unix in wscript. The following may completely fail on windows
-  int res = sqlite3_open_v2((identityDir / "nsl-merkle-tree.db").c_str(), &m_database,
-                            SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
-#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
-                            "unix-dotfile"
-#else
-                            0
-#endif
-                            );
-
-  if (res != SQLITE_OK)
-    std::cout << "DB cannot be opened/created";
-
-  //Check if SubTree table exists;
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT name FROM sqlite_master WHERE type='table' And name='SubTree'",
-                     -1, &statement, 0);
-  res = sqlite3_step(statement);
-
-  bool SubTreeTableExists = false;
-  if (res == SQLITE_ROW)
-    SubTreeTableExists = true;
-
-  sqlite3_finalize(statement);
-
-  if (!SubTreeTableExists)
-    {
-      char* errorMessage = 0;
-      res = sqlite3_exec(m_database, INIT_SUBTREE_TABLE.c_str(), NULL, NULL, &errorMessage);
-
-      if (res != SQLITE_OK && errorMessage != 0)
-        {
-          sqlite3_free(errorMessage);
-        }
-    }
-
-  //Check if Leaf table exists;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT name FROM sqlite_master WHERE type='table' And name='Leaf'",
-                     -1, &statement, 0);
-  res = sqlite3_step(statement);
-
-  bool LeafTableExists = false;
-  if (res == SQLITE_ROW)
-    LeafTableExists = true;
-
-  sqlite3_finalize(statement);
-
-  if (!LeafTableExists)
-    {
-      char* errorMessage = 0;
-      res = sqlite3_exec(m_database, INIT_LEAF_TABLE.c_str(), NULL, NULL, &errorMessage);
-
-      if (res != SQLITE_OK && errorMessage != 0)
-        {
-          sqlite3_free(errorMessage);
-        }
-    }
-
-}
-
-
-MerkleTreeSqlite3::~MerkleTreeSqlite3()
-{
-}
-
-
-void
-MerkleTreeSqlite3::addSubTree(SubTreePtr oldSubTree)
-{
-  Index old_idx = oldSubTree->getRootIndex();
-  std::string old_info = oldSubTree->encoding();
-
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "INSERT OR REPLACE INTO SubTree \
-                      (subTree_sequence, subTree_level, subTree_info)   \
-                      values (?, ?, ?)",
-                     -1, &statement, 0);
-  sqlite3_bind_int64(statement, 1, old_idx.number);
-  sqlite3_bind_int64(statement, 2, old_idx.level);
-  sqlite3_bind_text(statement, 3, old_info, SQLITE_TRANSIENT);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-
-std::string
-MerkleTreeSqlite3::getSubTree(Index rootIndex)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT subTree_info FROM SubTree \
-                      WHERE subTree_sequence=? AND subTree_level=?",
-                     -1, &statement, 0);
-  sqlite3_bind_int64(statement, 1, rootIndex.number);
-  sqlite3_bind_int64(statement, 2, rootIndex.level);
-  int res = sqlite3_step(statement);
-  std::string result;
-  if (res == SQLITE_ROW)
-    {
-      result = std::string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)),
-                           sqlite3_column_bytes(statement, 0));
-      sqlite3_finalize(statement);
-      return result;
-    }
-  else
-    {
-      sqlite3_finalize(statement);
-      return result;
-    }
-}
-
-
-bool
-MerkleTreeSqlite3::doesSubTreeExist(Index rootIndex)
-{
-  bool result = false;
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT count(*) FROM SubTree WHERE subTree_sequence=? AND subTree_level=?",
-                     -1, &statement, 0);
-  sqlite3_bind_int64(statement, 1, rootIndex.number);
-  sqlite3_bind_int64(statement, 2, rootIndex.level);
-  int res = sqlite3_step(statement);
-  if (res == SQLITE_ROW)
-    {
-      int countAll = sqlite3_column_int(statement, 0);
-      if (countAll > 0)
-        result = true;
-    }
-  sqlite3_finalize(statement);
-  return result;
-}
-
-
-void
-MerkleTreeSqlite3::deleteSubTree(Index rootIndex)
-{
-  sqlite3_stmt* stmt;
-  sqlite3_prepare_v2(m_database, "DELETE FROM SubTree WHERE subTree_sequence=? AND subTree_level=?",
-                     -1, &stmt, 0);
-  sqlite3_bind_int64(stmt, 1, rootIndex.number);
-  sqlite3_bind_int64(stmt, 2, rootIndex.level);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-}
-
-
-void
-MerkleTreeSqlite3::getAllSubTree(std::vector<std::string> subTreeInfoList)
-{
-  sqlite3_stmt* stmt;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT subTree_info FROM SubTree",
-                     -1, &stmt, 0);
-  while (sqlite3_step(stmt) == SQLITE_ROW)
-    subTreeInfoList.push_back(std::string(reinterpret_cast<const char *>
-                                          (sqlite3_column_text(stmt, 0)),
-                                          sqlite3_column_bytes(stmt, 0)));
-
-  sqlite3_finalize(stmt);
-}
-
-
-// For leafInfo
-
-void
-MerkleTreeSqlite3::addLeafInfo(uint64_t sequence, ndn::ConstBufferPtr buf_ptr)
-{
-
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "INSERT OR REPLACE INTO Leaf  \
-                      (leaf_sequence, leaf_info)   \
-                      values (?, ?)", -1, &statement, 0);
-  sqlite3_bind_int64(statement, 1, sequence);
-  sqlite3_bind_blob(statement, 2, buf_ptr->buf(), buf_ptr->size(), SQLITE_STATIC);
-  sqlite3_step(statement);
-  sqlite3_finalize(statement);
-}
-
-
-ndn::ConstBufferPtr
-MerkleTreeSqlite3::getLeafInfo(uint64_t sequence)
-{
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT leaf_info FROM Leaf \
-                      WHERE leaf_sequence=?", -1, &statement, 0);
-  sqlite3_bind_int64(statement, 1, sequence);
-  int res = sqlite3_step(statement);
-  if (res == SQLITE_ROW)
-    {
-      ndn::Buffer res_buf(sqlite3_column_blob(statement, 0), sqlite3_column_bytes(statement, 0));
-      ndn::ConstBufferPtr result = ndn::make_shared<ndn::Buffer>(res_buf);
-      sqlite3_finalize(statement);
-      return result;
-    }
-  else
-    {
-      sqlite3_finalize(statement);
-      return ndn::ConstBufferPtr();
-    }
-}
-
-
-bool
-MerkleTreeSqlite3::doesLeafInfoExist(uint64_t sequence)
-{
-  bool result = false;
-  sqlite3_stmt* statement;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT count(*) FROM Leaf WHERE leaf_sequence=?",
-                     -1, &statement, 0);
-  sqlite3_bind_int64(statement, 1, sequence);
-  int res = sqlite3_step(statement);
-  if (res == SQLITE_ROW)
-    {
-      int countAll = sqlite3_column_int(statement, 0);
-      if (countAll > 0)
-        result = true;
-    }
-  sqlite3_finalize(statement);
-  return result;
-}
-
-
-void
-MerkleTreeSqlite3::deleteLeafInfo(uint64_t sequence)
-{
-  sqlite3_stmt* stmt;
-  sqlite3_prepare_v2(m_database, "DELETE FROM Leaf WHERE leaf_sequence=?",
-                     -1, &stmt, 0);
-  sqlite3_bind_int64(stmt, 1, sequence);
-  sqlite3_step(stmt);
-  sqlite3_finalize(stmt);
-}
-
-
-void
-MerkleTreeSqlite3::getAllLeafInfo(std::map<uint64_t, ndn::ConstBufferPtr> leaves)
-{
-  sqlite3_stmt* stmt;
-  sqlite3_prepare_v2(m_database,
-                     "SELECT leaf_sequence, leaf_info FROM Leaf",
-                     -1, &stmt, 0);
-  while (sqlite3_step(stmt) == SQLITE_ROW)
-    {
-      uint64_t seq = sqlite3_column_int64(stmt, 0);
-      ndn::ConstBufferPtr buf = ndn::make_shared<ndn::Buffer>(sqlite3_column_blob(stmt, 1),
-                                                              sqlite3_column_bytes(stmt, 1));
-      leaves[seq] = buf;
-    }
-
-  sqlite3_finalize(stmt);
-}
-
-
-} // namespace nsl
diff --git a/core/merkle-tree-sqlite3.hpp b/core/merkle-tree-sqlite3.hpp
deleted file mode 100644
index 617d20c..0000000
--- a/core/merkle-tree-sqlite3.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-
-#ifndef NLS_CORE_MERKLE_TREE_SQLITE3_HPP
-#define NLS_CORE_MERKLE_TREE_SQLITE3_HPP
-
-#include <sqlite3.h>
-#include <map>
-#include "sub-tree.hpp"
-typedef ndn::shared_ptr<const nsl::SubTree> ConstSubTreePtr;
-typedef ndn::shared_ptr<nsl::SubTree> SubTreePtr;
-
-struct sqlite3;
-
-namespace nsl {
-
-class MerkleTreeSqlite3
-{
-public:
-
-  MerkleTreeSqlite3();
-
-  ~MerkleTreeSqlite3();
-
-  // SubTree
-  void
-  addSubTree(SubTreePtr oldSubTree);
-
-  std::string
-  getSubTree(Index rootIndex);
-
-  bool
-  doesSubTreeExist(Index rootIndex);
-
-  void
-  deleteSubTree(Index rootIndex);
-
-  void
-  getAllSubTree(std::vector<std::string> subTreeInfoList);
-
-
-  // LeafInfo (no need of encoding/decoding scheme)
-  void
-  addLeafInfo(uint64_t sequence, ndn::ConstBufferPtr buf_ptr);
-
-  ndn::ConstBufferPtr
-  getLeafInfo(uint64_t sequence);
-
-  bool
-  doesLeafInfoExist(uint64_t sequence);
-
-  void
-  deleteLeafInfo(uint64_t sequence);
-
-  void
-  getAllLeafInfo(std::map<uint64_t, ndn::ConstBufferPtr> leaves);
-
-
-private:
-  sqlite3* m_database;
-
-};
-
-
-} // namespace nsl
-
-
-#endif // NLS_CORE_MERKLE_TREE_SQLITE3_HPP
diff --git a/core/merkle-tree.cpp b/core/merkle-tree.cpp
index f74af33..a579350 100644
--- a/core/merkle-tree.cpp
+++ b/core/merkle-tree.cpp
@@ -16,125 +16,205 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
+
 #include "merkle-tree.hpp"
 
 namespace nsl {
 
-MerkleTree::MerkleTree()
+MerkleTree::MerkleTree(Db& db)
+  : m_db(db)
+  , m_nextLeafSeqNo(0)
 {
-  m_nLevels = 0;
-  m_nLeaves = 0;
 }
 
-
-ConstNodePtr
-MerkleTree::getNode(const Index& index)
+MerkleTree::MerkleTree(const Name& loggerName, Db& db)
+  : m_loggerName(loggerName)
+  , m_db(db)
+  , m_nextLeafSeqNo(0)
 {
-  ConstNodePtr p_leav;
-  if (m_cache.doesNodeExist(index))
-    {
-      p_leav = m_cache.queryNode(index);
-      return p_leav;
+  loadPendingSubTrees();
+}
+
+MerkleTree::~MerkleTree()
+{
+  savePendingTree();
+}
+
+void
+MerkleTree::setLoggerName(const Name& loggerName)
+{
+  m_loggerName = loggerName;
+}
+
+bool
+MerkleTree::addLeaf(const NonNegativeInteger& seqNo, ndn::ConstBufferPtr hash)
+{
+  auto baseTree = m_pendingTrees[SubTreeBinary::SUB_TREE_DEPTH - 1];
+  BOOST_ASSERT(baseTree != nullptr);
+
+  NodePtr leaf = make_shared<Node>(seqNo, 0, seqNo + 1, hash);
+  return baseTree->addLeaf(leaf);
+}
+
+void
+MerkleTree::savePendingTree()
+{
+  size_t level = m_rootSubTree->getPeakIndex().level;
+  size_t step = SubTreeBinary::SUB_TREE_DEPTH - 1;
+
+  for (size_t i = level; i > 0; i -= step) {
+    auto pendingTree = m_pendingTrees[i];
+    BOOST_ASSERT(pendingTree != nullptr);
+
+    auto data = pendingTree->encode();
+    if (data != nullptr) {
+      m_db.insertSubTreeData(pendingTree->getPeakIndex().level, pendingTree->getPeakIndex().seqNo,
+                             *data, false, pendingTree->getNextLeafSeqNo());
     }
+  }
+}
+
+shared_ptr<Data>
+MerkleTree::getPendingSubTreeData(size_t level)
+{
+  auto it = m_pendingTrees.find(level);
+  if (it != m_pendingTrees.end())
+    return it->second->encode();
   else
-    return p_leav;
+    return nullptr;
 }
 
-
-uint64_t
-MerkleTree::getLeafNum() const
+// private:
+void
+MerkleTree::loadPendingSubTrees()
 {
-  return m_nLeaves;
+  std::vector<shared_ptr<Data>> subtreeDatas = m_db.getPendingSubTrees();
+
+  shared_ptr<SubTreeBinary> subtree;
+  if (subtreeDatas.empty()) {
+    subtree = make_shared<SubTreeBinary>(m_loggerName,
+      Node::Index(0, SubTreeBinary::SUB_TREE_DEPTH - 1),
+      [this] (const Node::Index& idx) {
+        // std::cerr << "complete: " << idx.level << ", " << idx.seqNo << std::endl;
+        this->getNewRoot(idx);
+      },
+      [this] (const Node::Index& idx,
+              const NonNegativeInteger& seqNo,
+              ndn::ConstBufferPtr hash) {
+        // std::cerr << "update: " << idx.level << ", " << idx.seqNo << std::endl;
+        // std::cerr << "seqNo: " << seqNo << std::endl;
+        this->m_nextLeafSeqNo = seqNo;
+        this->m_hash = hash;
+      });
+    m_pendingTrees[SubTreeBinary::SUB_TREE_DEPTH - 1] = subtree;
+    m_rootSubTree = subtree;
+    return;
+  }
+
+  subtree = make_shared<SubTreeBinary>(m_loggerName,
+    [this] (const Node::Index& idx) { this->getNewRoot(idx); },
+    [this] (const Node::Index& idx,
+            const NonNegativeInteger& seqNo,
+            ndn::ConstBufferPtr hash) {
+      this->m_nextLeafSeqNo = seqNo;
+      this->m_hash = hash;
+    });
+
+  subtree->decode(*subtreeDatas[0]);
+  m_pendingTrees[subtree->getPeakIndex().level] = subtree;
+  m_rootSubTree = subtree;
+
+  shared_ptr<SubTreeBinary> parentTree = subtree;
+  for (size_t i = 1; i < subtreeDatas.size(); i++) {
+    subtree = make_shared<SubTreeBinary>(m_loggerName,
+      [this] (const Node::Index& idx) {
+        this->getNewSibling(idx);
+      },
+      [parentTree] (const Node::Index&,
+           const NonNegativeInteger& seqNo,
+           ndn::ConstBufferPtr hash) {
+        parentTree->updateLeaf(seqNo, hash);
+      });
+
+    subtree->decode(*subtreeDatas[i]);
+    if (parentTree->getPeakIndex().level + 1 - SubTreeBinary::SUB_TREE_DEPTH !=
+        subtree->getPeakIndex().level)
+      throw Error("loadPendingSubTrees: inconsistent pending subtree level");
+
+    if (parentTree->getNextLeafSeqNo() != subtree->getNextLeafSeqNo())
+      throw Error("loadPendingSubTrees: inconsistent pending subtree next leaf seqNo");
+
+    m_pendingTrees[subtree->getPeakIndex().level] = subtree;
+    parentTree = subtree;
+  }
 }
 
-
-uint64_t
-MerkleTree::getLevel() const
+void
+MerkleTree::getNewRoot(const Node::Index& idx)
 {
-  return m_nLevels;
+  // save the old root tree into db
+  auto oldRoot = m_pendingTrees[idx.level];
+  BOOST_ASSERT(oldRoot != nullptr);
+  m_db.insertSubTreeData(idx.level, idx.seqNo, *oldRoot->encode());
+
+  // create a new root tree
+  Node::Index newRootIdx(0, idx.level + SubTreeBinary::SUB_TREE_DEPTH - 1);
+  auto newRoot = make_shared<SubTreeBinary>(m_loggerName, newRootIdx,
+    [this] (const Node::Index& idx) {
+      // std::cerr << "complete: " << idx.level << ", " << idx.seqNo << std::endl;
+      this->getNewRoot(idx);
+    },
+    [this] (const Node::Index& index,
+         const NonNegativeInteger& seqNo,
+         ndn::ConstBufferPtr hash) {
+      // std::cerr << "update: " << index.level << ", " << index.seqNo << std::endl;
+      // std::cerr << "seqNo: " << seqNo << std::endl;
+      this->m_nextLeafSeqNo = seqNo;
+      this->m_hash = hash;
+    });
+
+  m_pendingTrees[newRoot->getPeakIndex().level] = newRoot;
+  m_rootSubTree = newRoot;
+
+  bool result = newRoot->updateLeaf(idx.seqNo + idx.range, oldRoot->getRoot()->getHash());
+  BOOST_ASSERT(result);
+
+  // create a sibling
+  getNewSibling(idx);
 }
 
-
-
-uint64_t
-MerkleTree::addLeaf(ndn::ConstBufferPtr info)
+void
+MerkleTree::getNewSibling(const Node::Index& idx)
 {
-  Leaf new_leaf(info, m_nLeaves, 0, 0);
-  new_leaf.computeHash(); // computeHash() has been written.
-  m_nLeaves++;
-  if (m_nLeaves > int(pow(2, int(m_nLevels) - 1)))
-    {
-      m_nLevels++;
-    }
-  m_cache.addLeaf(new_leaf);
-  return m_nLeaves - 1;
+  // save old sibling
+  auto oldSibling = m_pendingTrees[idx.level];
+  BOOST_ASSERT(oldSibling != nullptr);
+  m_db.insertSubTreeData(idx.level, idx.seqNo, *oldSibling->encode());
+
+  // get parent tree
+  Node::Index parentIdx(0, idx.level + SubTreeBinary::SUB_TREE_DEPTH - 1);
+  auto parent = m_pendingTrees[parentIdx.level];
+  BOOST_ASSERT(parent != nullptr);
+
+  // create a new sibling
+  Node::Index newSiblingIdx(idx.seqNo + idx.range, idx.level);
+  // std::cerr << "new Sibling: " << newSiblingIdx.level << ", " << newSiblingIdx.seqNo << std::endl;
+  auto newSibling = make_shared<SubTreeBinary>(m_loggerName, newSiblingIdx,
+    [this] (const Node::Index& idx) { this->getNewSibling(idx); },
+    [parent] (const Node::Index& index,
+         const NonNegativeInteger& seqNo,
+         ndn::ConstBufferPtr hash) {
+      // std::cerr << "update: " << index.level << ", " << index.seqNo << std::endl;
+      // std::cerr << "seqNo: " << seqNo << std::endl;
+      // std::cerr << "parent: " << parent->getRoot()->getIndex().level << ", " <<
+      //                            parent->getRoot()->getIndex().seqNo << std::endl;
+      bool result = parent->updateLeaf(seqNo, hash);
+      BOOST_ASSERT(result);
+    });
+
+  m_pendingTrees[newSibling->getPeakIndex().level] = newSibling;
 }
 
-
-std::vector<ConstNodePtr>
-MerkleTree::generateProof(uint64_t version1, uint64_t version2)
-{
-  std::vector<ConstNodePtr> proof;
-  if (version1 >= version2)
-    {
-      return proof;
-    }
-
-  //add a memberproof from version2
-  Index this_idx;
-  this_idx.number = version2;
-  this_idx.level = 0;
-  ConstNodePtr p_leav;
-  p_leav = m_cache.queryNode(this_idx);
-  proof.push_back(p_leav);
-  if ((this_idx.number % 2) != 0)
-    {
-      this_idx.number -= 1;
-      p_leav = m_cache.queryNode(this_idx);
-      proof.push_back(p_leav);
-    }
-  this_idx.level += 1;
-  this_idx.number -= this_idx.number % 2;
-  for (int i = 1; i < m_nLevels - 1 ; i++)
-    {
-      if (this_idx.number % int(pow(2, i + 1)) != 0)
-        {
-          this_idx.number -= int(pow(2, i));
-          p_leav = m_cache.queryNode(this_idx);
-          proof.push_back(p_leav);
-        }
-      this_idx.level += 1;
-      this_idx.number -= this_idx.number % int(pow(2, i + 1));
-    }
-
-  //add another path from version1
-  this_idx.number = version1;
-  this_idx.level = 0;
-  p_leav = m_cache.queryNode(this_idx);
-  proof.push_back(p_leav);
-  if ((this_idx.number % 2) != 0)
-    {
-      this_idx.number -= 1;
-      p_leav = m_cache.queryNode(this_idx);
-      proof.push_back(p_leav);
-    }
-  this_idx.level += 1;
-  this_idx.number -= this_idx.number % 2;
-  for (int i = 1; i < m_nLevels - 1 ; i++)
-    {
-      if (this_idx.number % int(pow(2, i + 1)) != 0)
-        {
-          this_idx.number -= int(pow(2, i));
-          p_leav = m_cache.queryNode(this_idx);
-          proof.push_back(p_leav);
-        }
-      this_idx.level += 1;
-      this_idx.number -= this_idx.number % int(pow(2, i + 1));
-    }
-
-  return proof;
-}
-
-} // namespace nsl
+}// namespace nsl
diff --git a/core/merkle-tree.hpp b/core/merkle-tree.hpp
index ccf73c5..3e877f1 100644
--- a/core/merkle-tree.hpp
+++ b/core/merkle-tree.hpp
@@ -16,60 +16,93 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
-#ifndef NLS_CORE_MERKLE_TREE_HPP
-#define NLS_CORE_MERKLE_TREE_HPP
 
-#include <map>
+#ifndef NSL_CORE_MERKLE_TREE_HPP
+#define NSL_CORE_MERKLE_TREE_HPP
+
+#include "common.hpp"
+#include "db.hpp"
+#include "sub-tree-binary.hpp"
 #include <vector>
 
-#include <stddef.h>
-#include <stdint.h>
-#include <time.h>
-
-#include "leaf.hpp"
-#include "intermediate-node.hpp"
-#include "merkle-tree-cache.hpp"
-
 namespace nsl {
 
 class MerkleTree
 {
 public:
-  MerkleTree();
-
-  ~MerkleTree()
+  class Error : public std::runtime_error
   {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  /**
+   * @brief Constructor
+   */
+  MerkleTree(Db& db);
+
+  MerkleTree(const Name& loggerName, Db& db);
+
+  ~MerkleTree();
+
+  void
+  setLoggerName(const Name& loggerName);
+
+  const NonNegativeInteger&
+  getNextLeafSeqNo() const
+  {
+    return m_nextLeafSeqNo;
   }
 
-  ConstNodePtr
-  getNode(const Index& index);
+  const ndn::ConstBufferPtr&
+  getRootHash() const
+  {
+    return m_hash;
+  }
 
-  uint64_t
-  getLeafNum() const;
+  bool
+  addLeaf(const NonNegativeInteger& seqNo, ndn::ConstBufferPtr hash);
 
-  uint64_t
-  getLevel() const;
+  void
+  loadPendingSubTrees();
 
+  void
+  savePendingTree();
 
-  //return root hash value
-  uint64_t
-  addLeaf(ndn::ConstBufferPtr info);
+  shared_ptr<Data>
+  getPendingSubTreeData(size_t level);
 
+  std::vector<ConstSubTreeBinaryPtr>
+  getExistenceProof(const NonNegativeInteger& seqNo);
 
-  std::vector<ConstNodePtr>
-  generateProof(uint64_t version1, uint64_t version2); // version equals to leaf's index number
-
+  std::vector<ConstSubTreeBinaryPtr>
+  getConsistencyProof(const NonNegativeInteger& seqNo);
 
 private:
-  MerkleTreeCache m_cache;
-  uint64_t m_nLevels;
-  uint64_t m_nLeaves;
+  void
+  getNewRoot(const Node::Index& idx);
 
+  void
+  getNewSibling(const Node::Index& idx);
+
+private:
+  Name m_loggerName;
+  Db& m_db;
+
+  shared_ptr<SubTreeBinary> m_rootSubTree;
+  NonNegativeInteger m_nextLeafSeqNo;
+  ndn::ConstBufferPtr m_hash;
+
+  std::map<size_t, shared_ptr<SubTreeBinary>> m_pendingTrees;
 };
 
+}// namespace nsl
 
-} // namespace nsl
-
-#endif // NLS_CORE_MERKLE_TREE_HPP
+#endif // NSL_CORE_MERKLE_TREE_HPP
diff --git a/core/node.cpp b/core/node.cpp
index 66921cd..11e1cd0 100644
--- a/core/node.cpp
+++ b/core/node.cpp
@@ -16,48 +16,108 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
 #include "node.hpp"
 
+#include <ndn-cxx/util/digest.hpp>
+#include <boost/lexical_cast.hpp>
+
 namespace nsl {
 
-Node::Node(uint64_t sequenceNumber, uint64_t level, time_t timestamp)
+ndn::ConstBufferPtr Node::EMPTY_HASH;
+
+Node::Index::Index(const NonNegativeInteger& nodeSeq, size_t nodeLevel)
+  : seqNo(nodeSeq)
+  , level(nodeLevel)
+  , range(1 << nodeLevel)
 {
-  m_index.number = sequenceNumber;
-  m_index.level = level;
-  m_timeStamp = timestamp;
+  if (seqNo % range != 0)
+    throw Error("Index: index level and seqNo do not match: (" +
+                boost::lexical_cast<std::string>(seqNo) + ", " +
+                boost::lexical_cast<std::string>(level) + ")");
 }
 
-
-const Index&
-Node::getIndex() const
+bool
+Node::Index::operator<(const Index& other) const
 {
-  return m_index;
+  if (seqNo < other.seqNo) {
+    return true;
+  }
+  else if (seqNo == other.seqNo) {
+    return level < other.level;
+  }
+  else {
+    return false;
+  }
 }
 
-
-
-time_t
-Node::getTimestamp() const
+bool
+Node::Index::operator==(const Index& other) const
 {
-  return m_timeStamp;
+  return equals(other);
 }
 
+bool
+Node::Index::operator!=(const Index& other) const
+{
+  return !equals(other);
+}
 
+bool
+Node::Index::equals(const Index& other) const
+{
+  if (seqNo == other.seqNo && level == other.level) {
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
+Node::Node(const NonNegativeInteger& nodeSeqNo,
+           size_t nodeLevel,
+           const NonNegativeInteger& leafSeqNo,
+           ndn::ConstBufferPtr hash)
+  : m_index(nodeSeqNo, nodeLevel)
+  , m_hash(hash)
+{
+  if (leafSeqNo == 0 && m_index.seqNo > leafSeqNo)
+    m_leafSeqNo = m_index.seqNo;
+  else
+    setLeafSeqNo(leafSeqNo);
+}
 
 void
-Node::setHash(ndn::ConstBufferPtr digest)
+Node::setLeafSeqNo(const NonNegativeInteger& leafSeqNo)
 {
-  m_hash = digest;
+  if (leafSeqNo > m_index.seqNo + m_index.range || leafSeqNo < m_index.seqNo)
+    throw Error("Node: leaf seqNo is out of range");
+
+  m_leafSeqNo = leafSeqNo;
 }
 
+void
+Node::setHash(ndn::ConstBufferPtr hash)
+{
+  m_hash = hash;
+}
 
+bool
+Node::isFull() const
+{
+  return m_index.seqNo + m_index.range == m_leafSeqNo;
+}
 
 ndn::ConstBufferPtr
-Node::getHash() const
+Node::getEmptyHash()
 {
-  return m_hash;
+  if (EMPTY_HASH == nullptr) {
+    ndn::util::Sha256 sha256;
+    EMPTY_HASH = sha256.computeDigest();
+  }
+
+  return EMPTY_HASH;
 }
 
 } // namespace nsl
diff --git a/core/node.hpp b/core/node.hpp
index be2ed92..c3d0572 100644
--- a/core/node.hpp
+++ b/core/node.hpp
@@ -16,92 +16,109 @@
  * You should have received a copy of the GNU General Public License along with
  * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
+ * See AUTHORS.md for complete list of nsl authors and contributors.
  */
 
-#ifndef NLS_CORE_NODE_HPP
-#define NLS_CORE_NODE_HPP
-#include <stddef.h>
-#include <time.h>
+#ifndef NSL_CORE_NODE_HPP
+#define NSL_CORE_NODE_HPP
 
-#include <ndn-cxx/util/crypto.hpp>
+#include "common.hpp"
+#include "util/non-negative-integer.hpp"
+#include <ndn-cxx/encoding/buffer.hpp>
 
 namespace nsl {
 
-class Index
-{
-public:
-  Index()
-  {
-  }
-
-  Index(const Index& idx)
-    : number(idx.number),
-      level(idx.level)
-  {
-  }
-
-  bool operator<(const Index& other) const
-  {
-    if (number < other.number)
-      {
-        return true;
-      }
-    else if (number == other.number)
-      {
-        return level < other.level;
-      }
-    else
-      {
-        return false;
-      }
-
-  }
-
-public:
-  uint64_t number;
-  uint64_t level;
-};
-
-
 class Node
 {
 public:
-
-  Node()
+  class Error : public std::runtime_error
   {
-  }
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
 
-
-  Node(uint64_t sequenceNumber, uint64_t level, time_t timestamp);
-
-
-  ~Node()
+  class Index
   {
-  }
+  public:
+    explicit
+    Index(const NonNegativeInteger& seqNo = 0, size_t level = 0);
 
+    /**
+     * @brief compare two indices
+     *
+     * A index is larger than the other if its seqNo is larger than the other,
+     * or their seqNos are equal but its level is lower.
+     */
+    bool
+    operator<(const Index& other) const;
+
+    bool
+    operator==(const Index& other) const;
+
+    bool
+    operator!=(const Index& other) const;
+
+    bool
+    equals(const Index& other) const;
+
+  public:
+    NonNegativeInteger seqNo;
+    size_t level;
+    NonNegativeInteger range;
+  };
+
+public:
+  Node(const NonNegativeInteger& seqNo,
+       size_t level,
+       const NonNegativeInteger& leafSeqNo = 0,
+       ndn::ConstBufferPtr hash = nullptr);
 
   const Index&
-  getIndex() const;
-
-
-  time_t
-  getTimestamp() const;
-
+  getIndex() const
+  {
+    return m_index;
+  }
 
   void
-  setHash(ndn::ConstBufferPtr digest);
+  setLeafSeqNo(const NonNegativeInteger& leafSeqNo);
 
+  const NonNegativeInteger&
+  getLeafSeqNo() const
+  {
+    return m_leafSeqNo;
+  }
+
+  void
+  setHash(ndn::ConstBufferPtr hash);
 
   ndn::ConstBufferPtr
-  getHash() const;
+  getHash() const
+  {
+    return m_hash;
+  }
+
+  bool
+  isFull() const;
+
+  static ndn::ConstBufferPtr
+  getEmptyHash();
+
+protected:
+  Index m_index;
+  NonNegativeInteger m_leafSeqNo;
+  ndn::ConstBufferPtr m_hash;
 
 private:
-  ndn::ConstBufferPtr m_hash;
-  Index m_index;   // Node index.number starts from 0 (the index of current root)
-  time_t m_timeStamp;
+  static ndn::ConstBufferPtr EMPTY_HASH;
 };
 
+typedef shared_ptr<Node> NodePtr;
+typedef shared_ptr<const Node> ConstNodePtr;
+
 } // namespace nsl
 
-#endif // NLS_CORE_NODE_HPP
+#endif // NSL_CORE_NODE_HPP
diff --git a/core/sub-tree-binary.cpp b/core/sub-tree-binary.cpp
new file mode 100644
index 0000000..be9c2d3
--- /dev/null
+++ b/core/sub-tree-binary.cpp
@@ -0,0 +1,471 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "sub-tree-binary.hpp"
+
+#include <ndn-cxx/util/digest.hpp>
+#include <ndn-cxx/util/crypto.hpp>
+#include <ndn-cxx/security/digest-sha256.hpp>
+
+namespace nsl {
+
+const time::milliseconds SubTreeBinary::INCOMPLETE_FRESHNESS_PERIOD(60000);
+const std::string SubTreeBinary::COMPONENT_COMPLETE("complete");
+const ssize_t SubTreeBinary::OFFSET_ROOTHASH = -1;
+const ssize_t SubTreeBinary::OFFSET_COMPLETE = -2;
+const ssize_t SubTreeBinary::OFFSET_SEQNO = -3;
+const ssize_t SubTreeBinary::OFFSET_LEVEL = -4;
+const size_t SubTreeBinary::N_LOGGER_SUFFIX = 4;
+const size_t SubTreeBinary::SUB_TREE_DEPTH = 6;
+
+
+SubTreeBinary::SubTreeBinary(const Name& loggerName,
+                             const CompleteCallback& completeCallback,
+                             const RootUpdateCallback& rootUpdateCallback)
+  : m_loggerName(loggerName)
+  , m_completeCallback(completeCallback)
+  , m_rootUpdateCallback(rootUpdateCallback)
+{
+}
+
+SubTreeBinary::SubTreeBinary(const Name& loggerName,
+                             const Node::Index& peakIndex,
+                             const CompleteCallback& completeCallback,
+                             const RootUpdateCallback& rootUpdateCallback)
+  : m_loggerName(loggerName)
+  , m_completeCallback(completeCallback)
+  , m_rootUpdateCallback(rootUpdateCallback)
+{
+  initialize(peakIndex);
+}
+
+const NonNegativeInteger&
+SubTreeBinary::getNextLeafSeqNo() const
+{
+  if (m_actualRoot != nullptr)
+    return m_actualRoot->getLeafSeqNo();
+
+  return m_peakIndex.seqNo;
+}
+
+ndn::ConstBufferPtr
+SubTreeBinary::getRootHash() const
+{
+  if (m_actualRoot != nullptr)
+    return m_actualRoot->getHash();
+
+  return nullptr;
+}
+
+ConstNodePtr
+SubTreeBinary::getNode(const Node::Index& index) const
+{
+  auto it = m_nodes.find(index);
+  if (it != m_nodes.end()) {
+    return it->second;
+  }
+
+  return nullptr;
+}
+
+bool
+SubTreeBinary::addLeaf(NodePtr leaf)
+{
+  // sanity check: must be a valid leaf
+  if (leaf->getIndex().level != m_leafLevel ||
+      leaf->getIndex().seqNo < m_minSeqNo ||
+      leaf->getIndex().seqNo >= m_maxSeqNo)
+    return false;
+
+  // sanity check: must be the expected next leaf
+  if (leaf->getIndex().seqNo != m_pendingLeafSeqNo ||
+      !m_isPendingLeafEmpty)
+    return false;
+
+  // add the leaf
+  m_nodes[leaf->getIndex()] = leaf;
+
+  // update actual root (guarantee we will have a root)
+  updateActualRoot(leaf);
+
+  // update nodes and their hashes
+  updateParentNode(leaf);
+
+  if (leaf->isFull()) {
+    m_pendingLeafSeqNo = leaf->getIndex().seqNo + leaf->getIndex().range;
+    m_isPendingLeafEmpty = true;
+  }
+  else {
+    m_isPendingLeafEmpty = false;
+  }
+
+  return true;
+}
+
+bool
+SubTreeBinary::updateLeaf(const NonNegativeInteger& nextSeqNo, ndn::ConstBufferPtr hash)
+{
+  // std::cerr << "NextSeqNo: " << nextSeqNo << std::endl;
+  // std::cerr << "minSeqNo: " << m_minSeqNo << std::endl;
+  // std::cerr << "maxSeqNo: " << m_maxSeqNo << std::endl;
+
+  // sanity check
+  if (nextSeqNo < m_minSeqNo || nextSeqNo > m_maxSeqNo)
+    return false;
+
+  // std::cerr << "2" << std::endl;
+  // determine leaf index
+  NonNegativeInteger leafSeqNo = ((nextSeqNo - 1) >> m_leafLevel) << m_leafLevel;
+  if (m_pendingLeafSeqNo != leafSeqNo)
+    return false;
+
+  Node::Index index(leafSeqNo, m_leafLevel);
+  auto leaf = m_nodes[index];
+
+  if (leaf == nullptr) {
+    leaf = make_shared<Node>(leafSeqNo, m_leafLevel, nextSeqNo, hash);
+    m_nodes[index] = leaf;
+    updateActualRoot(leaf);
+  }
+  else {
+    leaf->setLeafSeqNo(nextSeqNo);
+    leaf->setHash(hash);
+  }
+
+  if (nextSeqNo == leafSeqNo + (1 << m_leafLevel)) {
+    m_pendingLeafSeqNo = nextSeqNo;
+    m_isPendingLeafEmpty = true;
+  }
+
+  updateParentNode(leaf);
+
+  return true;
+}
+
+bool
+SubTreeBinary::isFull() const
+{
+  if (m_actualRoot != nullptr &&
+      m_actualRoot->getIndex() == m_peakIndex &&
+      m_actualRoot->isFull())
+    return true;
+
+  return false;
+}
+
+shared_ptr<Data>
+SubTreeBinary::encode() const
+{
+  if (m_actualRoot == nullptr) {
+    auto emptyData = make_shared<Data>();
+    // Name
+    Name emptyName = m_loggerName;
+    emptyName.appendNumber(m_peakIndex.level)
+      .appendNumber(m_peakIndex.seqNo)
+      .appendNumber(m_peakIndex.seqNo)
+      .append(Node::getEmptyHash()->buf(), Node::getEmptyHash()->size());
+    emptyData->setName(emptyName);
+
+    // MetaInfo
+    emptyData->setFreshnessPeriod(time::milliseconds(0));
+
+    // Signature
+    ndn::DigestSha256 sig;
+    emptyData->setSignature(sig);
+
+    Block sigValue(tlv::SignatureValue,
+                   ndn::crypto::sha256(emptyData->wireEncode().value(),
+                                       emptyData->wireEncode().value_size() -
+                                       emptyData->getSignature().getValue().size()));
+    emptyData->setSignatureValue(sigValue);
+
+    emptyData->wireEncode();
+
+    return emptyData;
+  }
+
+  // Name
+  Name dataName = m_loggerName;
+  dataName.appendNumber(m_actualRoot->getIndex().level)
+    .appendNumber(m_actualRoot->getIndex().seqNo);
+  if (isFull())
+    dataName.append(COMPONENT_COMPLETE.c_str());
+  else
+    dataName.appendNumber(m_actualRoot->getLeafSeqNo());
+  dataName.append(m_actualRoot->getHash()->buf(), m_actualRoot->getHash()->size());
+
+  auto data = make_shared<Data>(dataName);
+
+  // MetaInfo
+  if (!isFull())
+    data->setFreshnessPeriod(INCOMPLETE_FRESHNESS_PERIOD);
+
+  // Content
+  auto buffer = make_shared<ndn::Buffer>();
+  NonNegativeInteger range = 1 << m_leafLevel;
+  for (NonNegativeInteger i = m_minSeqNo; i < m_maxSeqNo; i += range) {
+    auto it = m_nodes.find(Node::Index(i, m_leafLevel));
+    if (it == m_nodes.end())
+      break;
+
+    auto leaf = it->second;
+    if (leaf == nullptr)
+      break;
+    BOOST_ASSERT(leaf->getHash() != nullptr);
+    BOOST_ASSERT(leaf->getHash()->size() == 32);
+    buffer->insert(buffer->end(), leaf->getHash()->begin(), leaf->getHash()->end());
+  }
+  data->setContent(buffer->buf(), buffer->size());
+
+  // Signature
+  ndn::DigestSha256 sig;
+  data->setSignature(sig);
+
+  Block sigValue(tlv::SignatureValue,
+                 ndn::crypto::sha256(data->wireEncode().value(),
+                                     data->wireEncode().value_size() -
+                                     data->getSignature().getValue().size()));
+  data->setSignatureValue(sigValue);
+
+  data->wireEncode();
+  return data;
+}
+
+void
+SubTreeBinary::decode(const Data& data)
+{
+  bool isComplete = false;
+  NonNegativeInteger nextSeqNo;
+  ndn::ConstBufferPtr rootHash;
+  NonNegativeInteger seqNo;
+  size_t level;
+
+  const Name& dataName = data.getName();
+
+  if (!m_loggerName.isPrefixOf(dataName))
+    throw Error("decode: logger name does not match");
+
+  if (m_loggerName.size() + N_LOGGER_SUFFIX != dataName.size())
+    throw Error("decode: data name does not follow the naming convention");
+
+  try {
+    if (dataName.get(OFFSET_COMPLETE).toUri() == COMPONENT_COMPLETE)
+      isComplete = true;
+    else
+      nextSeqNo = dataName.get(OFFSET_COMPLETE).toNumber();
+
+    rootHash = make_shared<ndn::Buffer>(dataName.get(OFFSET_ROOTHASH).value(),
+                                        dataName.get(OFFSET_ROOTHASH).value_size());
+
+    seqNo = dataName.get(OFFSET_SEQNO).toNumber();
+    level = dataName.get(OFFSET_LEVEL).toNumber();
+  }
+  catch (tlv::Error&) {
+    throw Error("decode: logger name encoding error");
+  }
+
+  if (seqNo == 0) {
+    size_t peakLevel = 0;
+    if (level % (SUB_TREE_DEPTH - 1) != 0)
+      peakLevel = ((level + SUB_TREE_DEPTH - 1) / (SUB_TREE_DEPTH - 1)) * (SUB_TREE_DEPTH - 1);
+    else
+      peakLevel = level;
+
+    if (nextSeqNo == 1 << peakLevel)
+      peakLevel = peakLevel + SUB_TREE_DEPTH - 1;
+
+    initialize(Node::Index(seqNo, peakLevel));
+  }
+  else
+    initialize(Node::Index(seqNo, level));
+
+  if (isComplete)
+    nextSeqNo = seqNo + (1 << level);
+  else if (nextSeqNo == seqNo) // empty tree
+    return;
+
+  if (rootHash->size() != 32)
+    throw Error("decode: wrong root hash size");
+
+  if (nextSeqNo <= seqNo || nextSeqNo > seqNo + (1 << level))
+    throw Error("decode: wrong current leaf SeqNo");
+
+  int nLeaves = (nextSeqNo - seqNo - 1) / (1 << m_leafLevel) + 1;
+
+  // std::cerr << data.getName() << std::endl;
+  // std::cerr << nextSeqNo << std::endl;
+  // std::cerr << nLeaves * 32 << std::endl;
+  // std::cerr << data.getContent().value_size() << std::endl;
+
+  if (nLeaves * 32 != data.getContent().value_size())
+    throw Error("decode: inconsistent content");
+
+  const uint8_t* offset = data.getContent().value();
+  NonNegativeInteger seqNoInterval = 1 << m_leafLevel;
+  int i = 0;
+  for (; i < nLeaves - 1; i++) {
+    auto node = make_shared<Node>(seqNo + (i * seqNoInterval),
+                                  m_peakIndex.level + 1 - SUB_TREE_DEPTH,
+                                  seqNo + (i * seqNoInterval) + seqNoInterval,
+                                  make_shared<ndn::Buffer>(offset + (i * 32), 32));
+    addLeaf(node);
+  }
+
+  auto node = make_shared<Node>(seqNo + (i * seqNoInterval),
+                                m_peakIndex.level + 1 - SUB_TREE_DEPTH,
+                                nextSeqNo,
+                                make_shared<ndn::Buffer>(offset + (i * 32), 32));
+  addLeaf(node);
+
+  if (*rootHash != *getRoot()->getHash())
+    throw Error("decode: Inconsistent hash");
+}
+
+Node::Index
+SubTreeBinary::toSubTreePeakIndex(const Node::Index& index, bool notRoot)
+{
+  size_t peakLevel =
+    ((index.level + SUB_TREE_DEPTH - 1) / (SUB_TREE_DEPTH - 1)) * (SUB_TREE_DEPTH - 1);
+
+  size_t leafLevel = peakLevel + 1 - SUB_TREE_DEPTH;
+
+  if (index.level % (SUB_TREE_DEPTH - 1) == 0 && index.level > 0 && !notRoot) {
+    peakLevel -= (SUB_TREE_DEPTH - 1);
+    leafLevel -= (SUB_TREE_DEPTH - 1);
+  }
+
+  NonNegativeInteger peakSeqNo = (index.seqNo >> peakLevel) << peakLevel;
+
+  return Node::Index(peakSeqNo, peakLevel);
+}
+
+void
+SubTreeBinary::initialize(const Node::Index& peakIndex)
+{
+  m_peakIndex = peakIndex;
+
+  if (peakIndex.level + 1 < SUB_TREE_DEPTH ||
+      peakIndex.level % (SUB_TREE_DEPTH - 1) != 0)
+    throw Error("SubTreeBinary: peak level does not match the depth");
+
+  m_leafLevel = peakIndex.level + 1 - SUB_TREE_DEPTH;
+
+  m_minSeqNo = peakIndex.seqNo;
+  m_maxSeqNo = peakIndex.seqNo + peakIndex.range;
+
+  m_pendingLeafSeqNo = m_minSeqNo;
+  m_isPendingLeafEmpty = true;
+}
+
+
+
+void
+SubTreeBinary::updateActualRoot(NodePtr node)
+{
+  if (m_actualRoot == nullptr) {
+    // if actual root is not set yet
+    if (node->getIndex().seqNo == 0) { // root sub-tree
+      m_actualRoot = node;
+      m_rootUpdateCallback(node->getIndex(), node->getLeafSeqNo(), node->getHash());
+      return;
+    }
+    else {
+      m_actualRoot = make_shared<Node>(m_peakIndex.seqNo, m_peakIndex.level);
+      m_nodes[m_actualRoot->getIndex()] = m_actualRoot;
+      return;
+    }
+  }
+
+  if (m_actualRoot->getIndex() == m_peakIndex)
+    return;
+
+  if ((node->getIndex().seqNo >> m_actualRoot->getIndex().level) != 0) {
+    // a new actual root at a higher is needed
+    m_actualRoot = make_shared<Node>(m_minSeqNo, m_actualRoot->getIndex().level + 1);
+    m_nodes[m_actualRoot->getIndex()] = m_actualRoot;
+    return;
+  }
+}
+
+void
+SubTreeBinary::updateParentNode(NodePtr node)
+{
+  if (node->getIndex() == m_actualRoot->getIndex()) { // root does not have a parent
+    return;
+  }
+
+  size_t parentLevel = node->getIndex().level + 1;
+  NodePtr parentNode;
+
+  if ((node->getIndex().seqNo >> node->getIndex().level) % 2 == 0) { // left child
+    // parent may not exist
+    Node::Index parentIndex(node->getIndex().seqNo, parentLevel);
+    parentNode = m_nodes[parentIndex];
+
+    ndn::util::Sha256 sha256;
+    sha256 << parentIndex.level << parentIndex.seqNo;
+    sha256.update(node->getHash()->buf(), node->getHash()->size());
+    sha256.update(Node::getEmptyHash()->buf(), Node::getEmptyHash()->size());
+
+    if (parentNode == nullptr) {
+      parentNode = make_shared<Node>(node->getIndex().seqNo,
+                                     parentLevel,
+                                     node->getLeafSeqNo(),
+                                     sha256.computeDigest());
+    }
+    else {
+      parentNode->setHash(sha256.computeDigest());
+      parentNode->setLeafSeqNo(node->getLeafSeqNo());
+    }
+
+    m_nodes[parentNode->getIndex()] = parentNode;
+  }
+  else { // right child
+    // parent must exist
+    NonNegativeInteger parentSeqNo = node->getIndex().seqNo - node->getIndex().range;
+
+    Node::Index parentIndex(parentSeqNo, parentLevel);
+    Node::Index siblingIndex(parentSeqNo, parentLevel - 1);
+
+    parentNode = m_nodes[parentIndex];
+    auto siblingNode = m_nodes[siblingIndex];
+
+    ndn::util::Sha256 sha256;
+    sha256 << parentNode->getIndex().level << parentNode->getIndex().seqNo;
+    sha256.update(siblingNode->getHash()->buf(), siblingNode->getHash()->size());
+    sha256.update(node->getHash()->buf(), node->getHash()->size());
+
+    parentNode->setHash(sha256.computeDigest());
+    parentNode->setLeafSeqNo(node->getLeafSeqNo());
+  }
+
+  if (parentNode->getIndex() == m_actualRoot->getIndex()) { // reach root
+    m_rootUpdateCallback(parentNode->getIndex(),
+                         parentNode->getLeafSeqNo(),
+                         parentNode->getHash());
+    if (parentNode->getIndex() == m_peakIndex && parentNode->isFull())
+      m_completeCallback(parentNode->getIndex());
+  }
+  else
+    updateParentNode(parentNode);
+}
+
+} // namespace nsl
diff --git a/core/sub-tree-binary.hpp b/core/sub-tree-binary.hpp
new file mode 100644
index 0000000..15a0e3e
--- /dev/null
+++ b/core/sub-tree-binary.hpp
@@ -0,0 +1,182 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#ifndef NSL_CORE_SUB_TREE_HPP
+#define NSL_CORE_SUB_TREE_HPP
+
+#include "node.hpp"
+
+namespace nsl {
+
+typedef std::function<void(const Node::Index&)> CompleteCallback;
+typedef std::function<void(const Node::Index&,
+                           const NonNegativeInteger&,
+                           ndn::ConstBufferPtr)> RootUpdateCallback;
+
+class SubTreeBinary
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  /**
+   * @brief Constructor
+   *
+   * Create an empty subtree.
+   *
+   * @param loggerName The name of logger
+   * @param completeCallback Callback when the subtree is complete
+   * @param rootUpdateCallback Callback when the subtree root is updated
+   */
+  SubTreeBinary(const Name& loggerName,
+                const CompleteCallback& completeCallback,
+                const RootUpdateCallback& rootUpdateCallback);
+  /**
+   * @brief Constructor
+   *
+   * Create a subtree with its first leaf node hash.
+   *
+   * @param loggerName The name of logger
+   * @param rootIndex The index of sub tree root when it is full
+   * @param completeCallback Callback when the subtree is complete
+   * @param rootUpdateCallback Callback when the subtree root is updated
+   */
+  SubTreeBinary(const Name& loggerName,
+                const Node::Index& rootIndex,
+                const CompleteCallback& completeCallback,
+                const RootUpdateCallback& rootUpdateCallback);
+
+  const Node::Index&
+  getPeakIndex() const
+  {
+    return m_peakIndex;
+  }
+
+  const NonNegativeInteger&
+  getMinSeqNo() const
+  {
+    return m_minSeqNo;
+  }
+
+  const NonNegativeInteger&
+  getMaxSeqNo() const
+  {
+    return m_maxSeqNo;
+  }
+
+  size_t
+  getLeafLevel() const
+  {
+    return m_leafLevel;
+  }
+
+  const NonNegativeInteger&
+  getNextLeafSeqNo() const;
+
+  /**
+   * @brief get the root of the subtree
+   *
+   * @return pointer to the root, nullptr if no leaf added
+   */
+  ConstNodePtr
+  getRoot() const
+  {
+    return m_actualRoot;
+  }
+
+  ndn::ConstBufferPtr
+  getRootHash() const;
+
+  ConstNodePtr
+  getNode(const Node::Index& index) const;
+
+  bool
+  addLeaf(NodePtr leaf);
+
+  bool
+  updateLeaf(const NonNegativeInteger& nextSeqNo, ndn::ConstBufferPtr hash);
+
+  bool
+  isFull() const;
+
+  shared_ptr<Data>
+  encode() const;
+
+  void
+  decode(const Data& data);
+
+public:
+  static Node::Index
+  toSubTreePeakIndex(const Node::Index& index, bool notRoot = true);
+
+private:
+  void
+  initialize(const Node::Index& peakIndex);
+
+  void
+  updateActualRoot(NodePtr node);
+
+  void
+  updateParentNode(NodePtr node);
+
+public:
+  static const size_t SUB_TREE_DEPTH;
+
+NSL_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  static const time::milliseconds INCOMPLETE_FRESHNESS_PERIOD;
+  static const std::string COMPONENT_COMPLETE;
+  static const ssize_t OFFSET_ROOTHASH;
+  static const ssize_t OFFSET_COMPLETE;
+  static const ssize_t OFFSET_SEQNO;
+  static const ssize_t OFFSET_LEVEL;
+  static const size_t N_LOGGER_SUFFIX;
+
+private:
+  Name m_loggerName;
+  Node::Index m_peakIndex;
+  NonNegativeInteger m_minSeqNo;
+  NonNegativeInteger m_maxSeqNo;
+  size_t m_leafLevel;
+
+  CompleteCallback m_completeCallback;
+  RootUpdateCallback m_rootUpdateCallback;
+
+  NodePtr m_actualRoot;
+  bool m_isPendingLeafEmpty;
+  NonNegativeInteger m_pendingLeafSeqNo;
+
+  std::map<Node::Index, NodePtr> m_nodes;
+};
+
+typedef shared_ptr<SubTreeBinary> SubTreeBinaryPtr;
+typedef shared_ptr<const SubTreeBinary> ConstSubTreeBinaryPtr;
+
+} // namespace nsl
+
+#endif // NSL_CORE_SUB_TREE_HPP
diff --git a/core/sub-tree.cpp b/core/sub-tree.cpp
deleted file mode 100644
index 46f3f5c..0000000
--- a/core/sub-tree.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-
-#include "sub-tree.hpp"
-#include "Auditor.hpp"
-#include <math.h>
-
-
-namespace nsl {
-
-void
-SubTree::addNode(ndn::ConstBufferPtr hash_ptr)
-{
-  if(m_remainPosition > 0)
-    {
-      uint8_t seqNo = 127 - m_remainPosition;
-      m_nodeHashes[seqNo] = ndn::make_shared<ndn::Buffer>(*hash_ptr);
-      m_remainPosition -= 1;
-      updateHash();
-    }
-}
-
-void
-SubTree::updateHash()
-{
-  uint8_t i_ = 6;
-  uint8_t lastNo = 126 - m_remainPosition;
-  for (; i_ > 0; i_--)
-    {
-      for (int i = int(pow(2, i_)) - 1; i <= lastNo; i+= 2)
-        {
-          if ((i + 1) <= lastNo)
-            {
-              uint8_t up_idx = (i-1) / 2;
-              Auditor hasher;
-              ndn::ConstBufferPtr buf = hasher.computeHash(m_nodeHashes[i],
-                                                           m_nodeHashes[i + 1]);
-              m_nodeHashes[up_idx] = ndn::make_shared<ndn::Buffer>(*buf);
-            }
-          else
-            {
-              uint8_t up_idx = (i-1) / 2;
-              Auditor hasher;
-              ndn::ConstBufferPtr buf = hasher.computeHashOneSide(m_nodeHashes[i]);
-              m_nodeHashes[up_idx] = ndn::make_shared<ndn::Buffer>(*buf);
-            }
-        }
-      lastNo = (lastNo - 1) / 2;
-    }
-  m_callBackUpdate(m_remainPosition, m_nodeHashes[0]);
-}
-
-
-
-
-void
-SubTree::updateLeafHash(Index subRootIndex, ndn::ConstBufferPtr hash)
-{
-  uint8_t lastNo = 126 - m_remainPosition;
-  uint64_t sequenceNo = subRootIndex.number;
-  uint64_t level = subRootIndex.level;
-  uint8_t indexBase = int(pow(2, m_root.level - level) - 1);
-  uint8_t indexOffset = (sequenceNo - m_root.number) / int(pow(2, level));
-  m_nodeHashes[indexBase + indexOffset] = ndn::make_shared<ndn::Buffer>(*hash);
-  if (lastNo < indexBase + indexOffset) // update value ? add new value
-    {
-      m_remainPosition -= 1;
-    }
-  updateHash();
-}
-
-ndn::ConstBufferPtr
-SubTree::getHash(Index nodeIndex)
-{
-  uint64_t sequenceNo = nodeIndex.number;
-  uint64_t level = nodeIndex.level;
-  uint8_t indexBase = int(pow(2, m_root.level - level) - 1);
-  uint8_t indexOffset = (sequenceNo - m_root.number) / int(pow(2, level));
-  return m_nodeHashes[indexBase + indexOffset];
-}
-
-
-
-
-Index
-SubTree::getRootIndex()
-{
-  return m_root;
-}
-
-uint8_t
-SubTree::getRemainPosition()
-{
-  return m_remainPosition;
-}
-
-Index
-SubTree::getParentRootIndex()
-{
-  Index parentIndex;
-  parentIndex.number = m_root.number;
-  parentIndex.level = m_root.level;
-  for (int i = 0; i < 6; i++)
-    {
-      parentIndex.number -= parentIndex.number%int(pow(2, parentIndex.level + 1));
-      parentIndex.level += 1;
-    }
-  return parentIndex;
-}
-
-
-
-std::string
-SubTree::encoding()
-{
-  std::string subTreeInfo = "";
-  uint64_t seq = m_root.number;
-  uint64_t lev = m_root.level;
-  unsigned char div_seq[8];
-  unsigned char div_lev[8];
-  for (int i = 0; i < 8; i++)
-    {
-      div_seq[i] = (seq >> (8*i)) & 0xFF;
-      div_lev[i] = (lev >> (8*i)) & 0xFF;
-    }
-  for (int i = 0; i < 8; i++)
-    {
-      subTreeInfo += div_seq[i];
-    }
-  for (int i = 0; i < 8; i++)
-    {
-      subTreeInfo += div_lev[i];
-    }
-  subTreeInfo += m_remainPosition;
-  for (int i = 0; i < 127; i++)
-    {
-      for (int j = 0; j < m_nodeHashes[i]->size(); j++)
-        {
-          subTreeInfo += (*m_nodeHashes[i])[j];
-        }
-      uint8_t flag = 0;
-      for (int j = m_nodeHashes[i]->size(); j < 32; j++)
-        {
-          subTreeInfo += flag;
-        }
-    }
-  return subTreeInfo;
-}
-
-void
-SubTree::resumeFromString(uint8_t remain, std::vector<ndn::BufferPtr> hashes)
-{
-  m_remainPosition = remain;
-  if (remain == 0)
-    {
-      for (int i = 0; i < hashes.size(); i++)
-        {
-          m_nodeHashes[i] = hashes[i];
-        }
-    }
-  else
-    {
-      for (int i = 0; i < hashes.size(); i++)
-        {
-          m_nodeHashes[63 + i] = hashes[i];
-        }
-      uint8_t i_ = 6;
-      uint8_t lastNo = 126 - m_remainPosition;
-      for (; i_ > 0; i_--)
-        {
-          for (int i = int(pow(2, i_)) - 1; i <= lastNo; i+= 2)
-            {
-              if ((i + 1) <= lastNo)
-                {
-                  uint8_t up_idx = (i-1) / 2;
-                  Auditor hasher;
-                  ndn::ConstBufferPtr buf = hasher.computeHash(m_nodeHashes[i],
-                                                               m_nodeHashes[i + 1]);
-                  m_nodeHashes[up_idx] = ndn::make_shared<ndn::Buffer>(*buf);
-                }
-              else
-                {
-                  uint8_t up_idx = (i-1) / 2;
-                  Auditor hasher;
-                  ndn::ConstBufferPtr buf = hasher.computeHashOneSide(m_nodeHashes[i]);
-                  m_nodeHashes[up_idx] = ndn::make_shared<ndn::Buffer>(*buf);
-                }
-            }
-          lastNo = (lastNo - 1) / 2;
-        }
-    }
-}
-
-
-} // namespace nsl
diff --git a/core/sub-tree.hpp b/core/sub-tree.hpp
deleted file mode 100644
index 55a0f53..0000000
--- a/core/sub-tree.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014,  Regents of the University of California
- *
- * This file is part of NSL (NDN Signature Logger).
- * See AUTHORS.md for complete list of NSL authors and contributors.
- *
- * NSL 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.
- *
- * NSL 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
- * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * @author Peizhen Guo <patrick.guopz@gmail.com>
- */
-#ifndef NLS_CORE_SUB_TREE_CACHE_HPP
-#define NLS_CORE_SUB_TREE_CACHE_HPP
-
-#include <ndn-cxx/encoding/buffer.hpp>
-#include <stdint.h>
-#include <string.h>
-
-#include "node.hpp"
-
-namespace nsl {
-
-typedef ndn::function<void(uint8_t, ndn::ConstBufferPtr)> CallBack;
-
-class SubTree
-{
-public:
-  SubTree()
-  {
-  }
-
-  SubTree(Index rootIndex, CallBack callBackFunction)
-    : m_root(rootIndex),
-      m_remainPosition(64),
-      m_callBackUpdate(callBackFunction)
-  {
-    for (int i = 0; i < 127; i++)
-      {
-        m_nodeHashes.push_back(ndn::BufferPtr(new ndn::Buffer));
-      }
-  }
-
-  ~SubTree()
-  {
-  }
-
-  void
-  addNode(ndn::ConstBufferPtr hash_ptr);
-
-  Index
-  getRootIndex();
-
-  uint8_t
-  getRemainPosition();
-
-  Index
-  getParentRootIndex();
-
-  ndn::ConstBufferPtr
-  getHash(Index nodeIndex);
-
-  // change when subtree's root hash below it changes
-  void
-  updateLeafHash(Index subRootIndex, ndn::ConstBufferPtr hash);
-
-
-  // decode is implemented in MerkleTreeCache class
-  std::string
-  encoding();
-
-  void
-  resumeFromString(uint8_t remain, std::vector<ndn::BufferPtr> hashes);
-
-private:
-
-  void
-  updateHash();
-
-
-private:
-
-  //Based on the following sequence number
-  //         0
-  //    1          2
-  //  3   4     5     6
-  // 7 8 9 10 11 12 13 14
-  std::vector<ndn::BufferPtr> m_nodeHashes;
-  Index m_root;
-  uint8_t m_remainPosition;
-  CallBack m_callBackUpdate;
-};
-
-
-} // namespace nsl
-
-#endif // NLS_CORE_SUB_TREE_CACHE_HPP
diff --git a/core/tlv.hpp b/core/tlv.hpp
index e69de29..6dd7cac 100644
--- a/core/tlv.hpp
+++ b/core/tlv.hpp
@@ -0,0 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+
+#ifndef NSL_CORE_TLV_HPP
+#define NSL_CORE_TLV_HPP
+
+namespace nsl {
+namespace tlv {
+
+/**
+ * @brief Type value of leaf related TLVs
+ */
+enum {
+  LoggerLeaf  = 128, // 0x80
+  Timestamp   = 129, // 0x81
+  DataSeqNo   = 130, // 0x82
+  SignerSeqNo = 131  // 0x83
+};
+
+} // namespace tlv
+} // namespace nsl
+
+#endif // NSL_CORE_TLV_HPP
diff --git a/core/util/non-negative-integer.hpp b/core/util/non-negative-integer.hpp
new file mode 100644
index 0000000..eecef0f
--- /dev/null
+++ b/core/util/non-negative-integer.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 NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#ifndef NSL_UTIL_NON_NEGATIVE_INTEGER_HPP
+#define NSL_UTIL_NON_NEGATIVE_INTEGER_HPP
+
+namespace nsl {
+
+typedef uint64_t NonNegativeInteger;
+
+} // namespace nsl
+
+#endif // NSL_UTIL_NON_NEGATIVE_INTEGER_HPP
diff --git a/core/util/timestamp.hpp b/core/util/timestamp.hpp
new file mode 100644
index 0000000..a955e1c
--- /dev/null
+++ b/core/util/timestamp.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 NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#ifndef NSL_UTIL_TIMESTAMP_HPP
+#define NSL_UTIL_TIMESTAMP_HPP
+
+namespace nsl {
+
+typedef uint64_t Timestamp;
+
+} // namespace nsl
+
+#endif // NSL_UTIL_TIMESTAMP_HPP
