diff --git a/core/merkle-tree-cache.cpp b/core/merkle-tree-cache.cpp
new file mode 100644
index 0000000..a7f2dc0
--- /dev/null
+++ b/core/merkle-tree-cache.cpp
@@ -0,0 +1,353 @@
+/* -*- 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
new file mode 100644
index 0000000..97e8908
--- /dev/null
+++ b/core/merkle-tree-cache.hpp
@@ -0,0 +1,176 @@
+/* -*- 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
new file mode 100644
index 0000000..1844ad4
--- /dev/null
+++ b/core/merkle-tree-sqlite3.cpp
@@ -0,0 +1,332 @@
+/* -*- 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
new file mode 100644
index 0000000..617d20c
--- /dev/null
+++ b/core/merkle-tree-sqlite3.hpp
@@ -0,0 +1,86 @@
+/* -*- 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
new file mode 100644
index 0000000..f74af33
--- /dev/null
+++ b/core/merkle-tree.cpp
@@ -0,0 +1,140 @@
+/* -*- 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.hpp"
+
+namespace nsl {
+
+MerkleTree::MerkleTree()
+{
+  m_nLevels = 0;
+  m_nLeaves = 0;
+}
+
+
+ConstNodePtr
+MerkleTree::getNode(const Index& index)
+{
+  ConstNodePtr p_leav;
+  if (m_cache.doesNodeExist(index))
+    {
+      p_leav = m_cache.queryNode(index);
+      return p_leav;
+    }
+  else
+    return p_leav;
+}
+
+
+uint64_t
+MerkleTree::getLeafNum() const
+{
+  return m_nLeaves;
+}
+
+
+uint64_t
+MerkleTree::getLevel() const
+{
+  return m_nLevels;
+}
+
+
+
+uint64_t
+MerkleTree::addLeaf(ndn::ConstBufferPtr info)
+{
+  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;
+}
+
+
+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
diff --git a/core/merkle-tree.hpp b/core/merkle-tree.hpp
new file mode 100644
index 0000000..ccf73c5
--- /dev/null
+++ b/core/merkle-tree.hpp
@@ -0,0 +1,75 @@
+/* -*- 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_HPP
+#define NLS_CORE_MERKLE_TREE_HPP
+
+#include <map>
+#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()
+  {
+  }
+
+  ConstNodePtr
+  getNode(const Index& index);
+
+  uint64_t
+  getLeafNum() const;
+
+  uint64_t
+  getLevel() const;
+
+
+  //return root hash value
+  uint64_t
+  addLeaf(ndn::ConstBufferPtr info);
+
+
+  std::vector<ConstNodePtr>
+  generateProof(uint64_t version1, uint64_t version2); // version equals to leaf's index number
+
+
+private:
+  MerkleTreeCache m_cache;
+  uint64_t m_nLevels;
+  uint64_t m_nLeaves;
+
+};
+
+
+} // namespace nsl
+
+#endif // NLS_CORE_MERKLE_TREE_HPP
diff --git a/core/sub-tree.cpp b/core/sub-tree.cpp
new file mode 100644
index 0000000..46f3f5c
--- /dev/null
+++ b/core/sub-tree.cpp
@@ -0,0 +1,213 @@
+/* -*- 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
new file mode 100644
index 0000000..55a0f53
--- /dev/null
+++ b/core/sub-tree.hpp
@@ -0,0 +1,105 @@
+/* -*- 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
