diff --git a/tests/other/skiplist-list.hpp b/tests/other/skiplist-list.hpp
deleted file mode 100644
index ca71c7f..0000000
--- a/tests/other/skiplist-list.hpp
+++ /dev/null
@@ -1,481 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2017, Regents of the University of California.
- *
- * This file is part of NDN repo-ng (Next generation of NDN repository).
- * See AUTHORS.md for complete list of repo-ng authors and contributors.
- *
- * repo-ng is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef REPO_TESTS_OTHER_SKIPLIST_LIST_HPP
-#define REPO_TESTS_OTHER_SKIPLIST_LIST_HPP
-
-#include "common.hpp"
-
-#include <random>
-
-namespace update1 {
-
-class SkipList32Levels25Probabilty
-{
-public:
-  static size_t
-  getMaxLevels()
-  {
-    return 32;
-  }
-
-  static double
-  getProbability()
-  {
-    return 0.25;  // 25%
-  }
-};
-
-template<typename T>
-struct SkipListNode
-{
-  typedef SkipListNode<T>* SkipListNodePointer;
-  T data;
-  std::list<SkipListNodePointer> prevs;
-  std::list<SkipListNodePointer> nexts;
-};
-
-template<typename T, class Ref, class Ptr>
-class SkipListIterator : public std::iterator<std::bidirectional_iterator_tag, T>
-{
-public:
-  typedef SkipListNode<T>* NodePointer;
-  NodePointer node;
-
-  typedef SkipListIterator<T, Ref, Ptr> Self;
-  typedef T value_type;
-  typedef Ptr pointer;
-  typedef Ref reference;
-  typedef ptrdiff_t difference_type;
-  typedef SkipListIterator<T, const T&, const T*> const_iterator;
-  /// alias of const_iterator
-  typedef const_iterator iterator;
-
-public:
-  // constructor
-  SkipListIterator()
-  {
-  }
-
-  explicit
-  SkipListIterator(NodePointer x)
-    : node(x)
-  {
-  }
-
-  SkipListIterator(const SkipListIterator& x)
-    : node(x.node)
-  {
-  }
-
-  bool
-  operator==(const const_iterator& x) const
-  {
-    return node == x.node;
-  }
-
-  bool
-  operator!=(const const_iterator& x) const
-  {
-    return node != x.node;
-  }
-
-  reference
-  operator*() const
-  {
-    return (*node).data;
-  }
-
-  pointer
-  operator->() const
-  {
-    return &(operator*());
-  }
-
-  Self&
-  operator++()
-  {
-    node = node->nexts.front();
-    return *this;
-  }
-
-  Self
-  operator++(int)
-  {
-    Self tmp = *this;
-    ++*this;
-    return tmp;
-  }
-
-  Self&
-  operator--()
-  {
-    node = node->prevs.front();
-    return *this;
-  }
-
-  Self
-  operator--(int)
-  {
-    Self tmp = *this;
-    --*this;
-    return tmp;
-  }
-};
-
-/**
- * @brief SkipList
- *
- * Examples of internal structure:
- * "A <-i-> B" means A->nexts[i] = B and B->prevs[i] = A
- *
- * case 1: an empty skip list
- * m_head <-0-> m_head
- *
- * case 2: a skip list with only one level and only one node
- * m_head <-0-> A <-0-> m_head
- *
- * case 3: a skip list with three nodes, node A and B appear on one level,
- * node C appears on two levels
- * m_head         <-1->         C <-1-> m_head
- * m_head <-0-> A <-0-> B <-0-> C <-0-> m_head
- */
-
-template<typename T, typename Compare = std::less<T>,
-         typename Traits = SkipList32Levels25Probabilty>
-class SkipList
-{
-public:
-  typedef T value_type;
-  typedef value_type* pointer;
-  typedef const value_type* const_pointer;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-  typedef SkipListNode<T> Node;
-  typedef Node* NodePointer;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef SkipListIterator<T, const T&, const T*> const_iterator;
-  /// alias of const_iterator
-  typedef const_iterator iterator;
-  typedef SkipListNode<T>* SkipListNodePointer;
-
-public:
-  explicit
-  SkipList()
-  {
-    initializeHead();
-  }
-
-  ~SkipList()
-  {
-    clear();
-    delete(m_head);
-  }
-
-  const_iterator
-  begin() const
-  {
-    return const_iterator(*(*m_head).nexts.begin());
-  }
-
-  const_iterator
-  end() const
-  {
-    return const_iterator(m_head);
-  }
-
-  bool
-  empty() const
-  {
-    return *(m_head->nexts.begin()) == m_head;
-  }
-
-  size_t
-  size() const
-  {
-    return m_size;
-  }
-
-  const_iterator
-  lower_bound(const T& x) const;
-
-  const_iterator
-  find(const T& x) const;
-
-  std::pair<const_iterator, bool>
-  insert(const T& x);
-
-  const_iterator
-  erase(const_iterator it);
-
-protected:
-
-  /**
-   * @brief initialize the node
-   */
-  NodePointer
-  createNode()
-  {
-    NodePointer p = new Node;
-    return p;
-  }
-
-  /**
-   * @brief initialize the node with given value
-   * @param x to be set to the value of node
-   */
-  NodePointer
-  createNode(const T& x)
-  {
-    NodePointer p = new Node;
-    m_dataAllocator.construct(&(p->data), x);
-    return p;
-  }
-
-  /**
-   * @brief destructor of the node
-   * @param p pointer to the node to be destructed
-   */
-  void
-  destroyNode(NodePointer p)
-  {
-    delete(p);
-  }
-
-  /**
-   * @brief initialize the head
-   */
-  void
-  initializeHead()
-  {
-    m_head = createNode();
-    m_head->prevs.push_back(m_head);
-    m_head->nexts.push_back(m_head);
-    m_size = 0;
-  }
-
-  /**
-   * @brief destroy all the nodes of skiplist except the head
-   */
-  void
-  clear()
-  {
-    NodePointer cur = m_head->nexts.front();
-    while (cur != m_head) {
-      NodePointer tmp = cur;
-      cur = cur->nexts.front();
-      destroyNode(tmp);
-    }
-    m_head->nexts.front() = m_head;
-    m_head->prevs.front() = m_head;
-  }
-
-  /**
-   * @brief pick a random height for inserted skiplist entry
-   */
-  size_t
-  pickRandomLevel() const
-  {
-    static std::mt19937 gen(std::random_device{}());
-    static std::geometric_distribution<size_t> dist(Traits::getProbability());
-    return std::min(dist(gen), Traits::getMaxLevels());
-  }
-
-protected:
-  NodePointer m_head;
-  std::allocator<T> m_dataAllocator;
-  Compare m_compare;
-  size_t m_size;
-};
-
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::lower_bound(const T& x) const
-{
-  size_t nLevels = m_head->nexts.size();
-  NodePointer p = m_head;
-  NodePointer q = p->nexts.back();
-  for (int i = nLevels - 1; i >= 0; --i) {
-    typename std::list<SkipListNodePointer>::iterator it_p = p->nexts.begin();
-    for (int j = 0; j < i; j++) {
-      it_p++;
-    }
-    q = *it_p;
-    if (q != m_head) {
-      while (m_compare(q->data, x)) {
-        p = *it_p;
-        it_p = p->nexts.begin();
-        for (int j = 0; j < i; j++) {
-          it_p++;
-        }
-        q = *it_p;
-        if (q == m_head) {
-          break;
-        }
-      }
-    }
-  }
-  return const_iterator(q);
-}
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::find(const T& x) const
-{
-  const_iterator it = this->lower_bound(x);
-  if (it == this->end() || *it != x)
-    return this->end();
-  return it;
-}
-
-template<typename T, typename Compare, typename Traits>
-std::pair<typename SkipList<T, Compare, Traits>::const_iterator, bool>
-SkipList<T, Compare, Traits>::insert(const T& x)
-{
-  size_t nLevels = m_head->nexts.size();
-  // 1. find insert position
-  std::vector<NodePointer> insertPositions(nLevels);
-  NodePointer p = m_head;
-  NodePointer q = p->nexts.back();
-  for (int i = nLevels - 1; i >= 0; --i) {
-    typename std::list<SkipListNodePointer>::iterator it_p = p->nexts.begin();
-    for (int j = 0; j < i; j++) {
-      it_p++;
-    }
-    q = *it_p;
-    if (q != m_head) {
-      while (m_compare(q->data, x)) {
-        p = *it_p;
-        it_p = p->nexts.begin();
-        for (int j = 0; j < i; j++) {
-          it_p++;
-        }
-        q = *it_p;
-        if (q == m_head) {
-          break;
-        }
-      }
-    }
-    insertPositions[i] = p;
-  }
-  // 2. whether q->data == x?
-  if (q != m_head)
-    if (!m_compare(q->data, x) && !m_compare(x, q->data)) {
-      return std::pair<const_iterator, bool>(const_iterator(q), false);
-    }
-  // 3. construct new node;
-  NodePointer newNode = createNode(x);
-  // 4. pick random nLevels
-  size_t newLevel = pickRandomLevel();
-  // 5. insert the new node
-  newNode->nexts.resize(newLevel + 1);
-  newNode->prevs.resize(newLevel + 1);
-  if (newLevel > nLevels - 1) {
-    m_head->nexts.resize(newLevel + 1, m_head);
-    m_head->prevs.resize(newLevel + 1, m_head);
-    insertPositions.resize(newLevel + 1, m_head);
-  }
-  for (size_t i = 0; i <= newLevel; i++) {
-    typename std::list<SkipListNodePointer>::iterator it_newNode_next = newNode->nexts.begin();
-    for (size_t j = 0; j < i; j++) {
-      it_newNode_next++;
-    }
-    typename std::list<SkipListNodePointer>::iterator it_insert_next = insertPositions[i]->nexts.begin();
-    for (size_t j = 0; j < i; j++) {
-      it_insert_next++;
-    }
-    *it_newNode_next = *it_insert_next;
-
-    typename std::list<SkipListNodePointer>::iterator it_newNode_prev = newNode->prevs.begin();
-    for (size_t j = 0; j < i; j++) {
-      it_newNode_prev++;
-    }
-    *it_newNode_prev = insertPositions[i];
-
-    it_insert_next = insertPositions[i]->nexts.begin();
-    for (size_t j = 0; j < i; j++) {
-      it_insert_next++;
-    }
-    *it_insert_next = newNode;
-    it_newNode_next = newNode->nexts.begin();
-    for (size_t j = 0; j < i; j++) {
-      it_newNode_next++;
-    }
-    typename std::list<SkipListNodePointer>::iterator it_newNode_next_prev = (*it_newNode_next)->prevs.begin();
-    for (size_t j = 0; j < i; j++) {
-      it_newNode_next_prev++;
-    }
-    *it_newNode_next_prev = newNode;
-  }
-
-  ++m_size;
-  return std::pair<const_iterator, bool>(const_iterator(newNode), true);
-}
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::erase(typename SkipList<T, Compare, Traits>::const_iterator it)
-{
-  NodePointer eraseNode = it.node;
-  if (!empty() && eraseNode != m_head) {
-    NodePointer returnNode = eraseNode->nexts.front();
-    size_t nLevels = eraseNode->nexts.size();
-    for (int i = nLevels - 1; i >= 0; --i) {
-      typename std::list<SkipListNodePointer>::iterator it_erase_next = eraseNode->nexts.begin();
-      for (int j = 0; j < i; j++) {
-        it_erase_next++;
-      }
-
-      typename std::list<SkipListNodePointer>::iterator it_erase_next_prev = (*it_erase_next)->prevs.begin();
-      for (int j = 0; j < i; j++) {
-        it_erase_next_prev++;
-      }
-
-      typename std::list<SkipListNodePointer>::iterator it_erase_prev = eraseNode->prevs.begin();
-      for (int j = 0; j < i; j++) {
-        it_erase_prev++;
-      }
-      *it_erase_next_prev = *it_erase_prev;
-
-      typename std::list<SkipListNodePointer>::iterator it_erase_prev_next = (*it_erase_prev)->nexts.begin();
-      for (int j = 0; j < i; j++) {
-        it_erase_prev_next++;
-      }
-
-      *it_erase_prev_next = *it_erase_next;
-      // clear empty nLevels
-      if ((*it_erase_next == *it_erase_prev) && i > 0) {
-        m_head->nexts.pop_back();
-        m_head->prevs.pop_back();
-      }
-    }
-    destroyNode(eraseNode);
-    --m_size;
-    return const_iterator(returnNode);
-  }
-  else {
-    return end();
-  }
-}
-
-} // namespace update1
-
-#endif // REPO_TESTS_OTHER_SKIPLIST_LIST_HPP
diff --git a/tests/other/skiplist-prev.hpp b/tests/other/skiplist-prev.hpp
deleted file mode 100644
index c19ca29..0000000
--- a/tests/other/skiplist-prev.hpp
+++ /dev/null
@@ -1,441 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2017, Regents of the University of California.
- *
- * This file is part of NDN repo-ng (Next generation of NDN repository).
- * See AUTHORS.md for complete list of repo-ng authors and contributors.
- *
- * repo-ng is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef REPO_TESTS_OTHER_SKIPLIST_PREV_HPP
-#define REPO_TESTS_OTHER_SKIPLIST_PREV_HPP
-
-#include "common.hpp"
-
-#include <random>
-
-namespace prev {
-
-class SkipList32Levels25Probabilty
-{
-public:
-  static size_t
-  getMaxLevels()
-  {
-    return 32;
-  }
-
-  static double
-  getProbability()
-  {
-    return 0.25;  // 25%
-  }
-};
-
-template<typename T>
-struct SkipListNode
-{
-  typedef SkipListNode<T>* SkipListNodePointer;
-  T data;
-  std::vector<SkipListNodePointer> prevs;
-  std::vector<SkipListNodePointer> nexts;
-};
-
-template<typename T, class Ref, class Ptr>
-class SkipListIterator : public std::iterator<std::bidirectional_iterator_tag, T>
-{
-public:
-  typedef SkipListNode<T>* NodePointer;
-  NodePointer node;
-
-  typedef SkipListIterator<T, Ref, Ptr> Self;
-  typedef T value_type;
-  typedef Ptr pointer;
-  typedef Ref reference;
-  typedef ptrdiff_t difference_type;
-  typedef SkipListIterator<T, const T&, const T*> const_iterator;
-  /// alias of const_iterator
-  typedef const_iterator iterator;
-
-public:
-  // constructor
-  SkipListIterator()
-  {
-  }
-
-  explicit
-  SkipListIterator(NodePointer x)
-    : node(x)
-  {
-  }
-
-  SkipListIterator(const SkipListIterator& x)
-    : node(x.node)
-  {
-  }
-
-  bool
-  operator==(const const_iterator& x) const
-  {
-    return node == x.node;
-  }
-
-  bool
-  operator!=(const const_iterator& x) const
-  {
-    return node != x.node;
-  }
-
-  reference
-  operator*() const
-  {
-    return (*node).data;
-  }
-
-  pointer
-  operator->() const
-  {
-    return &(operator*());
-  }
-
-  Self&
-  operator++()
-  {
-    node = node->nexts[0];
-    return *this;
-  }
-
-  Self
-  operator++(int)
-  {
-    Self tmp = *this;
-    ++*this;
-    return tmp;
-  }
-
-  Self&
-  operator--()
-  {
-    node = node->prevs[0];
-    return *this;
-  }
-
-  Self
-  operator--(int)
-  {
-    Self tmp = *this;
-    --*this;
-    return tmp;
-  }
-};
-
-/*
- * @brief SkipList
- *
- * Examples of internal structure:
- * "A <-i-> B" means A->nexts[i] = B and B->prevs[i] = A
- *
- * case 1: an empty skip list
- * m_head <-0-> m_head
- *
- * case 2: a skip list with only one level and only one node
- * m_head <-0-> A <-0-> m_head
- *
- * case 3: a skip list with three nodes, node A and B appear on one level,
- * node C appears on two levels
- * m_head         <-1->         C <-1-> m_head
- * m_head <-0-> A <-0-> B <-0-> C <-0-> m_head
- */
-
-template<typename T, typename Compare = std::less<T>,
-         typename Traits = SkipList32Levels25Probabilty>
-class SkipList
-{
-public:
-  typedef T value_type;
-  typedef value_type* pointer;
-  typedef const value_type* const_pointer;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-  typedef SkipListNode<T> Node;
-  typedef Node* NodePointer;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef SkipListIterator<T, const T&, const T*> const_iterator;
-  /// alias of const_iterator
-  typedef const_iterator iterator;
-
-public:
-  explicit
-  SkipList()
-  {
-    initializeHead();
-  }
-
-  ~SkipList()
-  {
-    clear();
-    deallocateNode(m_head);
-  }
-
-  const_iterator
-  begin() const
-  {
-    return const_iterator(*(*m_head).nexts.begin());
-  }
-
-  const_iterator
-  end() const
-  {
-    return const_iterator(m_head);
-  }
-
-  bool
-  empty() const
-  {
-    return *(m_head->nexts.begin()) == m_head;
-  }
-
-  size_t
-  size() const
-  {
-    return m_size;
-  }
-
-  const_iterator
-  lower_bound(const T& x) const;
-
-  const_iterator
-  find(const T& x) const;
-
-  std::pair<const_iterator, bool>
-  insert(const T& x);
-
-  const_iterator
-  erase(const_iterator it);
-
-protected:
-  /*
-   * @brief allocate memory for node
-   */
-  NodePointer
-  allocateNode()
-  {
-    return m_skiplistAllocator.allocate(sizeof(Node));
-  }
-
-  /*
-   * @brief deallocate memory of node
-   */
-  void
-  deallocateNode(NodePointer p)
-  {
-    m_skiplistAllocator.deallocate(p, sizeof(Node));
-  }
-
-  /*
-   * @brief initialize the node
-   */
-  NodePointer
-  createNode()
-  {
-    NodePointer p = allocateNode();
-    Node node;
-    m_skiplistAllocator.construct(p, node);
-    return p;
-  }
-
-  /*
-   * @brief initialize the node with given value
-   * @para to be set to the value of node
-   */
-  NodePointer
-  createNode(const T& x)
-  {
-    NodePointer p = allocateNode();
-    Node node;
-    m_skiplistAllocator.construct(p, node);
-    m_dataAllocator.construct(&(p->data), x);
-    return p;
-  }
-
-  /*
-   * @brief destructror of the node
-   * @para given pointer of node to be destructed
-   */
-  void
-  destroyNode(NodePointer p)
-  {
-    m_skiplistAllocator.destroy(p);
-    deallocateNode(p);
-  }
-
-  /*
-   * @brief initialize the head
-   */
-  void
-  initializeHead()
-  {
-    m_head = createNode();
-    m_head->prevs.push_back(m_head);
-    m_head->nexts.push_back(m_head);
-    m_size = 0;
-  }
-
-  /*
-   * @brief destroy all the nodes of skiplist except the head
-   */
-  void
-  clear()
-  {
-    NodePointer cur = m_head->nexts[0];
-    while (cur != m_head) {
-      NodePointer tmp = cur;
-      cur = cur->nexts[0];
-      destroyNode(tmp);
-    }
-    m_head->nexts[0] = m_head;
-    m_head->prevs[0] = m_head;
-  }
-
-  /*
-   * @brief pick a random height for inserted skiplist entry
-   */
-  size_t
-  pickRandomLevel() const
-  {
-    static std::mt19937 gen(std::random_device{}());
-    static std::geometric_distribution<size_t> dist(Traits::getProbability());
-    return std::min(dist(gen), Traits::getMaxLevels());
-  }
-
-protected:
-  NodePointer m_head;
-  std::allocator<Node> m_skiplistAllocator;
-  std::allocator<T> m_dataAllocator;
-  Compare m_compare;
-  size_t m_size;
-};
-
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::lower_bound(const T& x) const
-{
-  size_t nLevels = m_head->nexts.size();
-  NodePointer p = m_head;
-  NodePointer q = p->nexts[nLevels - 1];
-  for (int i = nLevels - 1; i >= 0; --i) {
-    q = p->nexts[i];
-    if (q != m_head) {
-      while (m_compare(q->data, x)) {
-        p = p->nexts[i];
-        q = p->nexts[i];
-        if (q == m_head) {
-          break;
-        }
-      }
-    }
-  }
-  return const_iterator(q);
-}
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::find(const T& x) const
-{
-  const_iterator it = this->lower_bound(x);
-  if (it == this->end() || *it != x)
-    return this->end();
-  return it;
-}
-
-template<typename T, typename Compare, typename Traits>
-std::pair<typename SkipList<T, Compare, Traits>::const_iterator, bool>
-SkipList<T, Compare, Traits>::insert(const T& x)
-{
-  size_t nLevels = m_head->nexts.size();
-  // 1. find insert position
-  std::vector<NodePointer> insertPositions(nLevels);
-  NodePointer p = m_head;
-  NodePointer q = p->nexts[nLevels - 1];
-  for (int i = nLevels - 1; i >= 0; --i) {
-    q = p->nexts[i];
-    if (q != m_head) {
-      while (m_compare(q->data, x)) {
-        p = p->nexts[i];
-        q = p->nexts[i];
-        if (q == m_head) {
-          break;
-        }
-      }
-    }
-    insertPositions[i] = p;
-  }
-  // 2. whether q->data == x?
-  if (q != m_head)
-    if (!m_compare(q->data, x) && !m_compare(x, q->data)) {
-      return std::pair<const_iterator, bool>(const_iterator(q), false);
-    }
-  // 3. construct new node;
-  NodePointer newNode = createNode(x);
-  // 4. pick random nLevels
-  size_t newLevel = pickRandomLevel();
-  // 5. insert the new node
-  newNode->nexts.resize(newLevel + 1);
-  newNode->prevs.resize(newLevel + 1);
-  if (newLevel > nLevels - 1) {
-    m_head->nexts.resize(newLevel + 1, m_head);
-    m_head->prevs.resize(newLevel + 1, m_head);
-    insertPositions.resize(newLevel + 1, m_head);
-  }
-  for (size_t i = 0; i <= newLevel; i++) {
-    newNode->nexts[i] = insertPositions[i]->nexts[i];
-    newNode->prevs[i] = insertPositions[i];
-    insertPositions[i]->nexts[i] = newNode;
-    newNode->nexts[i]->prevs[i] = newNode;
-  }
-
-  ++m_size;
-  return std::pair<const_iterator, bool>(const_iterator(newNode), true);
-}
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::erase(typename SkipList<T, Compare, Traits>::const_iterator it)
-{
-  NodePointer eraseNode = it.node;
-  if (!empty() && eraseNode != m_head) {
-    NodePointer returnNode = eraseNode->nexts[0];
-    size_t nLevels = eraseNode->nexts.size();
-    for (int i = nLevels - 1; i >= 0; --i) {
-      eraseNode->nexts[i]->prevs[i] = eraseNode->prevs[i];
-      eraseNode->prevs[i]->nexts[i] = eraseNode->nexts[i];
-      // clear empty nLevels
-      if ((eraseNode->nexts[i] == eraseNode->prevs[i]) && i > 0) {
-        m_head->nexts.pop_back();
-        m_head->prevs.pop_back();
-      }
-    }
-    destroyNode(eraseNode);
-    --m_size;
-    return const_iterator(returnNode);
-  }
-  else {
-    return end();
-  }
-}
-
-} // namespace prev
-
-#endif // REPO_TESTS_OTHER_SKIPLIST_PREV_HPP
diff --git a/tests/other/skiplist-smoketest.cpp b/tests/other/skiplist-smoketest.cpp
deleted file mode 100644
index 645c7a2..0000000
--- a/tests/other/skiplist-smoketest.cpp
+++ /dev/null
@@ -1,128 +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 NDN repo-ng (Next generation of NDN repository).
- * See AUTHORS.md for complete list of repo-ng authors and contributors.
- *
- * repo-ng is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "skiplist-list.hpp" // This skiplist is updated by weiqi.
-                              // The internal structure of skiplist node is std::list
-
-#include "skiplist-vector.hpp" // This skiplist is revised is revised based on the version above
-                               // The internal structure of skiplist node is std::vector
-
-#include "skiplist-prev.hpp" // This skiplist is that of previous commit
-
-#include <iostream>
-#include <set>
-
-using namespace ndn::time;
-
-namespace repo {
-namespace tests {
-
-void
-testSkipList()
-{
-  typedef update1::SkipList<int, std::greater<int> > IntGtContainer;
-  IntGtContainer sl;
-  steady_clock::TimePoint start = steady_clock::now();
-  for (int i = 0; i < 100000; ++i) {
-    sl.insert(i);
-  }
-  milliseconds duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  start = steady_clock::now();
-  std::cout << "SkipList-list insert 100000 integers cost " << duration.count() << "ms" << std::endl;
-  for (int i = 0; i< 100000; ++i) {
-    sl.lower_bound(i);
-  }
-  duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  std::cout << "SkipList-list lower_bound 100000 integers cost " << duration.count() << "ms" << std::endl;
-}
-
-void
-testSkipVector()
-{
-  typedef update2::SkipList<int, std::greater<int> > IntGtContainer;
-  IntGtContainer container;
-  steady_clock::TimePoint start = steady_clock::now();
-  for (int i = 0; i < 100000; ++i) {
-    container.insert(i);
-  }
-  milliseconds duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  start = steady_clock::now();
-  std::cout << "Skiplist-vector insert 100000 integers cost " << duration.count() << "ms" << std::endl;
-  for (int i = 0; i< 100000; ++i) {
-    container.lower_bound(i);
-  }
-  duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  std::cout << "Skiplist-vector lower_bound 100000 integers cost " << duration.count() << "ms" << std::endl;
-}
-
-void
-testSkipPrev()
-{
-  typedef prev::SkipList<int, std::greater<int> > IntGtContainer;
-  IntGtContainer container;
-  steady_clock::TimePoint start = steady_clock::now();
-  for (int i = 0; i < 100000; ++i) {
-    container.insert(i);
-  }
-  milliseconds duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  start = steady_clock::now();
-  std::cout << "Skiplist-prev insert 100000 integers cost " << duration.count() << "ms" << std::endl;
-  for (int i = 0; i< 100000; ++i) {
-    container.lower_bound(i);
-  }
-  duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  std::cout << "Skiplist-prev lower_bound 100000 integers cost " << duration.count() << "ms" << std::endl;
-}
-
-void
-testSet()
-{
-  typedef std::set<int, std::greater<int> > IntGtContainer;
-  IntGtContainer container;
-  steady_clock::TimePoint start = steady_clock::now();
-  for (int i = 0; i < 100000; ++i) {
-    container.insert(i);
-  }
-  milliseconds duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  start = steady_clock::now();
-  std::cout << "Set insert 100000 integers cost " << duration.count() << "ms" << std::endl;
-  for (int i = 0; i< 100000; ++i) {
-    container.lower_bound(i);
-  }
-  duration = duration_cast<milliseconds>(steady_clock::now() - start);
-  std::cout << "Set lower_bound 100000 integers cost " << duration.count() << "ms" << std::endl;
-}
-
-void runTestCases() {
-  testSkipList();
-  testSkipVector();
-  testSkipPrev();
-  testSet();
-}
-
-} // namespace tests
-} // namespace repo
-
-int
-main(int argc, char** argv)
-{
-  repo::tests::runTestCases();
-
-  return 0;
-}
\ No newline at end of file
diff --git a/tests/other/skiplist-vector.hpp b/tests/other/skiplist-vector.hpp
deleted file mode 100644
index 8ef1ed9..0000000
--- a/tests/other/skiplist-vector.hpp
+++ /dev/null
@@ -1,420 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2017, Regents of the University of California.
- *
- * This file is part of NDN repo-ng (Next generation of NDN repository).
- * See AUTHORS.md for complete list of repo-ng authors and contributors.
- *
- * repo-ng is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef REPO_TESTS_OTHER_SKIPLIST_VECTOR_HPP
-#define REPO_TESTS_OTHER_SKIPLIST_VECTOR_HPP
-
-#include "common.hpp"
-
-#include <random>
-
-namespace update2 {
-
-class SkipList32Levels25Probabilty
-{
-public:
-  static size_t
-  getMaxLevels()
-  {
-    return 32;
-  }
-
-  static double
-  getProbability()
-  {
-    return 0.25;  // 25%
-  }
-};
-
-template<typename T>
-struct SkipListNode
-{
-  typedef SkipListNode<T>* SkipListNodePointer;
-  T data;
-  std::vector<SkipListNodePointer> prevs;
-  std::vector<SkipListNodePointer> nexts;
-};
-
-template<typename T, class Ref, class Ptr>
-class SkipListIterator : public std::iterator<std::bidirectional_iterator_tag, T>
-{
-public:
-  typedef SkipListNode<T>* NodePointer;
-  NodePointer node;
-
-  typedef SkipListIterator<T, Ref, Ptr> Self;
-  typedef T value_type;
-  typedef Ptr pointer;
-  typedef Ref reference;
-  typedef ptrdiff_t difference_type;
-  typedef SkipListIterator<T, const T&, const T*> const_iterator;
-  /// alias of const_iterator
-  typedef const_iterator iterator;
-
-public:
-  // constructor
-  SkipListIterator()
-  {
-  }
-
-  explicit
-  SkipListIterator(NodePointer x)
-    : node(x)
-  {
-  }
-
-  SkipListIterator(const SkipListIterator& x)
-    : node(x.node)
-  {
-  }
-
-  bool
-  operator==(const const_iterator& x) const
-  {
-    return node == x.node;
-  }
-
-  bool
-  operator!=(const const_iterator& x) const
-  {
-    return node != x.node;
-  }
-
-  reference
-  operator*() const
-  {
-    return (*node).data;
-  }
-
-  pointer
-  operator->() const
-  {
-    return &(operator*());
-  }
-
-  Self&
-  operator++()
-  {
-    node = node->nexts.front();
-    return *this;
-  }
-
-  Self
-  operator++(int)
-  {
-    Self tmp = *this;
-    ++*this;
-    return tmp;
-  }
-
-  Self&
-  operator--()
-  {
-    node = node->prevs.front();
-    return *this;
-  }
-
-  Self
-  operator--(int)
-  {
-    Self tmp = *this;
-    --*this;
-    return tmp;
-  }
-};
-
-/*
- * @brief SkipList
- *
- * Examples of internal structure:
- * "A <-i-> B" means A->nexts[i] = B and B->prevs[i] = A
- *
- * case 1: an empty skip list
- * m_head <-0-> m_head
- *
- * case 2: a skip list with only one level and only one node
- * m_head <-0-> A <-0-> m_head
- *
- * case 3: a skip list with three nodes, node A and B appear on one level,
- * node C appears on two levels
- * m_head         <-1->         C <-1-> m_head
- * m_head <-0-> A <-0-> B <-0-> C <-0-> m_head
- */
-
-template<typename T, typename Compare = std::less<T>,
-         typename Traits = SkipList32Levels25Probabilty>
-class SkipList
-{
-public:
-  typedef T value_type;
-  typedef value_type* pointer;
-  typedef const value_type* const_pointer;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-  typedef SkipListNode<T> Node;
-  typedef Node* NodePointer;
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef SkipListIterator<T, const T&, const T*> const_iterator;
-  /// alias of const_iterator
-  typedef const_iterator iterator;
-  typedef SkipListNode<T>* SkipListNodePointer;
-
-public:
-  explicit
-  SkipList()
-  {
-    initializeHead();
-  }
-
-  ~SkipList()
-  {
-    clear();
-    delete(m_head);
-  }
-
-  const_iterator
-  begin() const
-  {
-    return const_iterator(*(*m_head).nexts.begin());
-  }
-
-  const_iterator
-  end() const
-  {
-    return const_iterator(m_head);
-  }
-
-  bool
-  empty() const
-  {
-    return *(m_head->nexts.begin()) == m_head;
-  }
-
-  size_t
-  size() const
-  {
-    return m_size;
-  }
-
-  const_iterator
-  lower_bound(const T& x) const;
-
-  const_iterator
-  find(const T& x) const;
-
-  std::pair<const_iterator, bool>
-  insert(const T& x);
-
-  const_iterator
-  erase(const_iterator it);
-
-protected:
-
-  /*
-   * @brief initialize the node
-   */
-  NodePointer
-  createNode()
-  {
-    NodePointer p = new Node;
-    return p;
-  }
-
-  /*
-   * @brief initialize the node with given value
-   * @para to be set to the value of node
-   */
-  NodePointer
-  createNode(const T& x)
-  {
-    NodePointer p = new Node;
-    m_dataAllocator.construct(&(p->data), x);
-    return p;
-  }
-
-  /*
-   * @brief destructror of the node
-   * @para given pointer of node to be destructed
-   */
-  void
-  destroyNode(NodePointer p)
-  {
-    delete(p);
-  }
-
-  /*
-   * @brief initialize the head
-   */
-  void
-  initializeHead()
-  {
-    m_head = createNode();
-    m_head->prevs.push_back(m_head);
-    m_head->nexts.push_back(m_head);
-    m_size = 0;
-  }
-
-  /*
-   * @brief destroy all the nodes of skiplist except the head
-   */
-  void
-  clear()
-  {
-    NodePointer cur = m_head->nexts[0];
-    while (cur != m_head) {
-      NodePointer tmp = cur;
-      cur = cur->nexts[0];
-      destroyNode(tmp);
-    }
-    m_head->nexts[0] = m_head;
-    m_head->prevs[0] = m_head;
-  }
-
-  /*
-   * @brief pick a random height for inserted skiplist entry
-   */
-  size_t
-  pickRandomLevel() const
-  {
-    static std::mt19937 gen(std::random_device{}());
-    static std::geometric_distribution<size_t> dist(Traits::getProbability());
-    return std::min(dist(gen), Traits::getMaxLevels());
-  }
-
-protected:
-  NodePointer m_head;
-  std::allocator<T> m_dataAllocator;
-  Compare m_compare;
-  size_t m_size;
-};
-
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::lower_bound(const T& x) const
-{
-  size_t nLevels = m_head->nexts.size();
-  NodePointer p = m_head;
-  NodePointer q = p->nexts[nLevels - 1];
-  for (int i = nLevels - 1; i >= 0; --i) {
-    q = p->nexts[i];
-    if (q != m_head) {
-      while (m_compare(q->data, x)) {
-        p = p->nexts[i];
-        q = p->nexts[i];
-        if (q == m_head) {
-          break;
-        }
-      }
-    }
-  }
-  return const_iterator(q);
-}
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::find(const T& x) const
-{
-  const_iterator it = this->lower_bound(x);
-  if (it == this->end() || *it != x)
-    return this->end();
-  return it;
-}
-
-template<typename T, typename Compare, typename Traits>
-std::pair<typename SkipList<T, Compare, Traits>::const_iterator, bool>
-SkipList<T, Compare, Traits>::insert(const T& x)
-{
-  size_t nLevels = m_head->nexts.size();
-  // 1. find insert position
-  std::vector<NodePointer> insertPositions(nLevels);
-  NodePointer p = m_head;
-  NodePointer q = p->nexts[nLevels - 1];
-  for (int i = nLevels - 1; i >= 0; --i) {
-    q = p->nexts[i];
-    if (q != m_head) {
-      while (m_compare(q->data, x)) {
-        p = p->nexts[i];
-        q = p->nexts[i];
-        if (q == m_head) {
-          break;
-        }
-      }
-    }
-    insertPositions[i] = p;
-  }
-  // 2. whether q->data == x?
-  if (q != m_head)
-    if (!m_compare(q->data, x) && !m_compare(x, q->data)) {
-      return std::pair<const_iterator, bool>(const_iterator(q), false);
-    }
-  // 3. construct new node;
-  NodePointer newNode = createNode(x);
-  // 4. pick random nLevels
-  size_t newLevel = pickRandomLevel();
-  // 5. insert the new node
-  newNode->nexts.resize(newLevel + 1);
-  newNode->prevs.resize(newLevel + 1);
-  if (newLevel > nLevels - 1) {
-    m_head->nexts.resize(newLevel + 1, m_head);
-    m_head->prevs.resize(newLevel + 1, m_head);
-    insertPositions.resize(newLevel + 1, m_head);
-  }
-  for (size_t i = 0; i <= newLevel; i++) {
-    newNode->nexts[i] = insertPositions[i]->nexts[i];
-    newNode->prevs[i] = insertPositions[i];
-    insertPositions[i]->nexts[i] = newNode;
-    newNode->nexts[i]->prevs[i] = newNode;
-  }
-
-  ++m_size;
-  return std::pair<const_iterator, bool>(const_iterator(newNode), true);
-}
-
-template<typename T, typename Compare, typename Traits>
-typename SkipList<T, Compare, Traits>::const_iterator
-SkipList<T, Compare, Traits>::erase(typename SkipList<T, Compare, Traits>::const_iterator it)
-{
-  NodePointer eraseNode = it.node;
-  if (!empty() && eraseNode != m_head) {
-    NodePointer returnNode = eraseNode->nexts[0];
-    size_t nLevels = eraseNode->nexts.size();
-    for (int i = nLevels - 1; i >= 0; --i) {
-      eraseNode->nexts[i]->prevs[i] = eraseNode->prevs[i];
-      eraseNode->prevs[i]->nexts[i] = eraseNode->nexts[i];
-      // clear empty nLevels
-      if ((eraseNode->nexts[i] == eraseNode->prevs[i]) && i > 0) {
-        m_head->nexts.pop_back();
-        m_head->prevs.pop_back();
-      }
-    }
-    destroyNode(eraseNode);
-    --m_size;
-    return const_iterator(returnNode);
-  }
-  else {
-    return end();
-  }
-
-}
-
-} // namespace update2
-
-#endif // REPO_TESTS_OTHER_SKIPLIST_VECTOR_HPP
diff --git a/tests/other/wscript b/tests/other/wscript
deleted file mode 100644
index 6bb9fb6..0000000
--- a/tests/other/wscript
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-top = '../..'
-
-def build(bld):
-    bld.program(target="../../skiplist-smoketest",
-                source="skiplist-smoketest.cpp",
-                use='ndn-repo-objects',
-                install_path=None,
-                )
\ No newline at end of file
diff --git a/wscript b/wscript
index ed3e3c4..a4b84fe 100644
--- a/wscript
+++ b/wscript
@@ -75,7 +75,6 @@
         )
 
     bld.recurse('tests')
-    bld.recurse('tests/other')
     bld.recurse('tools')
     bld.recurse('examples')
 
