diff --git a/daemon/table/cs-entry.cpp b/daemon/table/cs-entry.cpp
index 1262065..be6202c 100644
--- a/daemon/table/cs-entry.cpp
+++ b/daemon/table/cs-entry.cpp
@@ -21,64 +21,121 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
  */
 
 #include "cs-entry.hpp"
-#include "core/logger.hpp"
 
 namespace nfd {
 namespace cs {
 
-NFD_LOG_INIT("CsEntry");
-
-void
-Entry::release()
+Entry::Entry(const Name& name)
+  : m_queryName(name)
 {
-  BOOST_ASSERT(m_layerIterators.empty());
+  BOOST_ASSERT(this->isQuery());
+}
 
-  m_dataPacket.reset();
+Entry::Entry(shared_ptr<const Data> data, bool isUnsolicited)
+  : queueType(Cs::QUEUE_NONE)
+  , m_data(data)
+  , m_isUnsolicited(isUnsolicited)
+{
+  BOOST_ASSERT(!this->isQuery());
+}
+
+bool
+Entry::isQuery() const
+{
+  return m_data == nullptr;
+}
+
+shared_ptr<const Data>
+Entry::getData() const
+{
+  BOOST_ASSERT(!this->isQuery());
+  return m_data;
+}
+
+const Name&
+Entry::getFullName() const
+{
+  BOOST_ASSERT(!this->isQuery());
+  return m_data->getFullName();
+}
+
+bool
+Entry::canStale() const
+{
+  BOOST_ASSERT(!this->isQuery());
+  return m_data->getFreshnessPeriod() >= time::milliseconds::zero();
+}
+
+bool
+Entry::isStale() const
+{
+  BOOST_ASSERT(!this->isQuery());
+  return time::steady_clock::now() > m_staleAt;
 }
 
 void
-Entry::setData(const Data& data, bool isUnsolicited)
+Entry::refresh()
 {
-  m_isUnsolicited = isUnsolicited;
-  m_dataPacket = data.shared_from_this();
+  BOOST_ASSERT(!this->isQuery());
+  if (this->canStale()) {
+    m_staleAt = time::steady_clock::now() + time::milliseconds(m_data->getFreshnessPeriod());
+  }
+  else {
+    m_staleAt = time::steady_clock::TimePoint::max();
+  }
+}
 
-  updateStaleTime();
+bool
+Entry::isUnsolicited() const
+{
+  BOOST_ASSERT(!this->isQuery());
+  return m_isUnsolicited;
 }
 
 void
-Entry::updateStaleTime()
+Entry::unsetUnsolicited()
 {
-  m_staleAt = time::steady_clock::now() + m_dataPacket->getFreshnessPeriod();
+  BOOST_ASSERT(!this->isQuery());
+  m_isUnsolicited = false;
 }
 
-void
-Entry::setIterator(int layer, const Entry::LayerIterators::mapped_type& layerIterator)
+bool
+Entry::canSatisfy(const Interest& interest) const
 {
-  m_layerIterators[layer] = layerIterator;
+  BOOST_ASSERT(!this->isQuery());
+  if (!interest.matchesData(*m_data)) {
+    return false;
+  }
+
+  if (interest.getMustBeFresh() == static_cast<int>(true) && this->isStale()) {
+    return false;
+  }
+
+  return true;
 }
 
-void
-Entry::removeIterator(int layer)
+bool
+Entry::operator<(const Entry& other) const
 {
-  m_layerIterators.erase(layer);
-}
-
-void
-Entry::printIterators() const
-{
-  for (LayerIterators::const_iterator it = m_layerIterators.begin();
-       it != m_layerIterators.end();
-       ++it)
-    {
-      NFD_LOG_TRACE("[" << it->first << "]" << " " << &(*it->second));
+  if (this->isQuery()) {
+    if (other.isQuery()) {
+      return m_queryName < other.m_queryName;
     }
+    else {
+      return m_queryName < other.m_queryName;
+    }
+  }
+  else {
+    if (other.isQuery()) {
+      return this->getFullName() < other.m_queryName;
+    }
+    else {
+      return this->getFullName() < other.getFullName();
+    }
+  }
 }
 
 } // namespace cs
diff --git a/daemon/table/cs-entry.hpp b/daemon/table/cs-entry.hpp
index 0373e60..12a65b0 100644
--- a/daemon/table/cs-entry.hpp
+++ b/daemon/table/cs-entry.hpp
@@ -21,149 +21,82 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
  */
 
 #ifndef NFD_DAEMON_TABLE_CS_ENTRY_HPP
 #define NFD_DAEMON_TABLE_CS_ENTRY_HPP
 
-#include "common.hpp"
+#include "cs.hpp"
+#include "core/scheduler.hpp"
 
 namespace nfd {
 namespace cs {
 
-class Entry;
-
-/** \brief represents a CS entry
+/** \brief an Entry in ContentStore
+ *  \note This type is internal to ContentStore.
+ *
+ *  An Entry is either a stored Entry which contains a Data packet and related attributes,
+ *  or a query Entry which contains a Name that is LessComparable to other stored/query Entry
+ *  and is used to lookup a container of entries.
  */
-class Entry : noncopyable
+class Entry
 {
 public:
-  typedef std::map<int, std::list<Entry*>::iterator > LayerIterators;
-
-  Entry();
-
-  /** \brief releases reference counts on shared objects
+  /** \brief construct Entry for query
+   *  \note Name is implicitly convertible to Entry, so that Name can be passed to
+   *        lookup functions on a container of Entry
    */
-  void
-  release();
+  Entry(const Name& name);
 
-  /** \brief returns the name of the Data packet stored in the CS entry
-   *  \return{ NDN name }
+  /** \brief construct Entry for storage
    */
-  const Name&
-  getName() const;
+  Entry(shared_ptr<const Data> data, bool isUnsolicited);
 
-  /** \brief returns the full name (including implicit digest) of the Data packet stored
-   *         in the CS entry
-   *  \return{ NDN name }
-   */
+  shared_ptr<const Data>
+  getData() const;
+
   const Name&
   getFullName() const;
 
-  /** \brief Data packet is unsolicited if this particular NDN node
-   *  did not receive an Interest packet for it, or the Interest packet has already expired
-   *  \return{ True if the Data packet is unsolicited; otherwise False  }
+  /** \return true if entry can become stale, false if entry is never stale
    */
   bool
+  canStale() const;
+
+  bool
+  isStale() const;
+
+  void
+  refresh();
+
+  bool
   isUnsolicited() const;
 
-  /** \brief returns the absolute time when Data becomes expired
-   *  \return{ Time (resolution up to time::milliseconds) }
-   */
-  const time::steady_clock::TimePoint&
-  getStaleTime() const;
-
-  /** \brief returns the Data packet stored in the CS entry
-   */
-  const Data&
-  getData() const;
-
-  /** \brief changes the content of CS entry and recomputes digest
-   */
   void
-  setData(const Data& data, bool isUnsolicited);
+  unsetUnsolicited();
 
-  /** \brief refreshes the time when Data becomes expired
-   *  according to the current absolute time.
-   */
-  void
-  updateStaleTime();
+  bool
+  canSatisfy(const Interest& interest) const;
 
-  /** \brief saves the iterator pointing to the CS entry on a specific layer of skip list
-   */
-  void
-  setIterator(int layer, const LayerIterators::mapped_type& layerIterator);
-
-  /** \brief removes the iterator pointing to the CS entry on a specific layer of skip list
-   */
-  void
-  removeIterator(int layer);
-
-  /** \brief returns the table containing <layer, iterator> pairs.
-   */
-  const LayerIterators&
-  getIterators() const;
+  bool
+  operator<(const Entry& other) const;
 
 private:
-  /** \brief prints <layer, iterator> pairs.
-   */
-  void
-  printIterators() const;
+  bool
+  isQuery() const;
+
+public:
+  Cs::QueueType queueType;
+  Cs::QueueIt queueIt;
+  scheduler::EventId moveStaleEvent;
 
 private:
+  Name m_queryName;
+  shared_ptr<const Data> m_data;
   time::steady_clock::TimePoint m_staleAt;
-  shared_ptr<const Data> m_dataPacket;
-
   bool m_isUnsolicited;
-
-  LayerIterators m_layerIterators;
 };
 
-inline
-Entry::Entry()
-{
-}
-
-inline const Name&
-Entry::getName() const
-{
-  return m_dataPacket->getName();
-}
-
-inline const Name&
-Entry::getFullName() const
-{
-  return m_dataPacket->getFullName();
-}
-
-inline const Data&
-Entry::getData() const
-{
-  return *m_dataPacket;
-}
-
-inline bool
-Entry::isUnsolicited() const
-{
-  return m_isUnsolicited;
-}
-
-inline const time::steady_clock::TimePoint&
-Entry::getStaleTime() const
-{
-  return m_staleAt;
-}
-
-inline const Entry::LayerIterators&
-Entry::getIterators() const
-{
-  return m_layerIterators;
-}
-
 } // namespace cs
 } // namespace nfd
 
diff --git a/daemon/table/cs.cpp b/daemon/table/cs.cpp
index e575694..822cb84 100644
--- a/daemon/table/cs.cpp
+++ b/daemon/table/cs.cpp
@@ -21,806 +21,214 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
  */
 
 #include "cs.hpp"
+#include "cs-entry.hpp"
 #include "core/logger.hpp"
-#include "core/random.hpp"
-
-#include <ndn-cxx/util/crypto.hpp>
-#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>
-
-#include <boost/random/bernoulli_distribution.hpp>
-
-/// max skip list layers
-static const size_t SKIPLIST_MAX_LAYERS = 32;
-/// probability for an entry in layer N to appear also in layer N+1
-static const double SKIPLIST_PROBABILITY = 0.25;
+#include <numeric>
 
 NFD_LOG_INIT("ContentStore");
 
 namespace nfd {
+namespace cs {
 
 Cs::Cs(size_t nMaxPackets)
-  : m_nMaxPackets(nMaxPackets)
-  , m_nPackets(0)
+  : m_limit(nMaxPackets)
 {
-  SkipListLayer* zeroLayer = new SkipListLayer();
-  m_skipList.push_back(zeroLayer);
-
-  for (size_t i = 0; i < m_nMaxPackets; i++)
-    m_freeCsEntries.push(new cs::Entry());
+  BOOST_ASSERT(nMaxPackets > 0);
 }
 
 Cs::~Cs()
 {
-  // evict all items from CS
-  while (evictItem())
-    ;
-
-  BOOST_ASSERT(m_freeCsEntries.size() == m_nMaxPackets);
-
-  while (!m_freeCsEntries.empty())
-    {
-      delete m_freeCsEntries.front();
-      m_freeCsEntries.pop();
-    }
-}
-
-size_t
-Cs::size() const
-{
-  return m_nPackets; // size of the first layer in a skip list
+  // It's necessary to put this empty destructor in cs.cpp,
+  // because cs::Entry has incomplete type in cs.hpp.
 }
 
 void
 Cs::setLimit(size_t nMaxPackets)
 {
-  size_t oldNMaxPackets = m_nMaxPackets;
-  m_nMaxPackets = nMaxPackets;
-
-  while (size() > m_nMaxPackets) {
-    evictItem();
-  }
-
-  if (m_nMaxPackets >= oldNMaxPackets) {
-    for (size_t i = oldNMaxPackets; i < m_nMaxPackets; i++) {
-      m_freeCsEntries.push(new cs::Entry());
-    }
-  }
-  else {
-    for (size_t i = oldNMaxPackets; i > m_nMaxPackets; i--) {
-      delete m_freeCsEntries.front();
-      m_freeCsEntries.pop();
-    }
-  }
+  BOOST_ASSERT(nMaxPackets > 0);
+  m_limit = nMaxPackets;
+  this->evict();
 }
 
 size_t
-Cs::getLimit() const
+Cs::size() const
 {
-  return m_nMaxPackets;
-}
-
-//Reference: "Skip Lists: A Probabilistic Alternative to Balanced Trees" by W.Pugh
-std::pair<cs::Entry*, bool>
-Cs::insertToSkipList(const Data& data, bool isUnsolicited)
-{
-  NFD_LOG_TRACE("insertToSkipList() " << data.getFullName() << ", "
-                << "skipList size " << size());
-
-  BOOST_ASSERT(m_cleanupIndex.size() <= size());
-  BOOST_ASSERT(m_freeCsEntries.size() > 0);
-
-  // take entry for the memory pool
-  cs::Entry* entry = m_freeCsEntries.front();
-  m_freeCsEntries.pop();
-  m_nPackets++;
-  entry->setData(data, isUnsolicited);
-
-  bool insertInFront = false;
-  bool isIterated = false;
-  SkipList::reverse_iterator topLayer = m_skipList.rbegin();
-  SkipListLayer::iterator updateTable[SKIPLIST_MAX_LAYERS];
-  SkipListLayer::iterator head = (*topLayer)->begin();
-
-  if (!(*topLayer)->empty())
-    {
-      //start from the upper layer towards bottom
-      int layer = m_skipList.size() - 1;
-      for (SkipList::reverse_iterator rit = topLayer; rit != m_skipList.rend(); ++rit)
-        {
-          //if we didn't do any iterations on the higher layers, start from the begin() again
-          if (!isIterated)
-            head = (*rit)->begin();
-
-          updateTable[layer] = head;
-
-          if (head != (*rit)->end())
-            {
-              // it can happen when begin() contains the element in front of which we need to insert
-              if (!isIterated && ((*head)->getFullName() >= entry->getFullName()))
-                {
-                  --updateTable[layer];
-                  insertInFront = true;
-                }
-              else
-                {
-                  SkipListLayer::iterator it = head;
-
-                  while ((*it)->getFullName() < entry->getFullName())
-                    {
-                      head = it;
-                      updateTable[layer] = it;
-                      isIterated = true;
-
-                      ++it;
-                      if (it == (*rit)->end())
-                        break;
-                    }
-                }
-            }
-
-          if (layer > 0)
-            head = (*head)->getIterators().find(layer - 1)->second; // move HEAD to the lower layer
-
-          layer--;
-        }
-    }
-  else
-    {
-      updateTable[0] = (*topLayer)->begin(); //initialization
-    }
-
-  head = updateTable[0];
-  ++head; // look at the next slot to check if it contains a duplicate
-
-  bool isCsEmpty = (size() == 0);
-  bool isInBoundaries = (head != (*m_skipList.begin())->end());
-  bool isNameIdentical = false;
-  if (!isCsEmpty && isInBoundaries)
-    {
-      isNameIdentical = (*head)->getFullName() == entry->getFullName();
-    }
-
-  //check if this is a duplicate packet
-  if (isNameIdentical)
-    {
-      NFD_LOG_TRACE("Duplicate name (with digest)");
-
-      (*head)->setData(data, isUnsolicited); //updates stale time
-
-      // new entry not needed, returning to the pool
-      entry->release();
-      m_freeCsEntries.push(entry);
-      m_nPackets--;
-
-      return std::make_pair(*head, false);
-    }
-
-  NFD_LOG_TRACE("Not a duplicate");
-
-  size_t randomLayer = pickRandomLayer();
-
-  while (m_skipList.size() < randomLayer + 1)
-    {
-      SkipListLayer* newLayer = new SkipListLayer();
-      m_skipList.push_back(newLayer);
-
-      updateTable[(m_skipList.size() - 1)] = newLayer->begin();
-    }
-
-  size_t layer = 0;
-  for (SkipList::iterator i = m_skipList.begin();
-       i != m_skipList.end() && layer <= randomLayer; ++i)
-    {
-      if (updateTable[layer] == (*i)->end() && !insertInFront)
-        {
-          (*i)->push_back(entry);
-          SkipListLayer::iterator last = (*i)->end();
-          --last;
-          entry->setIterator(layer, last);
-
-          NFD_LOG_TRACE("pushback " << &(*last));
-        }
-      else if (updateTable[layer] == (*i)->end() && insertInFront)
-        {
-          (*i)->push_front(entry);
-          entry->setIterator(layer, (*i)->begin());
-
-          NFD_LOG_TRACE("pushfront ");
-        }
-      else
-        {
-          NFD_LOG_TRACE("insertafter");
-          ++updateTable[layer]; // insert after
-          SkipListLayer::iterator position = (*i)->insert(updateTable[layer], entry);
-          entry->setIterator(layer, position); // save iterator where item was inserted
-        }
-      layer++;
-    }
-
-  return std::make_pair(entry, true);
+  return m_table.size();
 }
 
 bool
 Cs::insert(const Data& data, bool isUnsolicited)
 {
-  NFD_LOG_TRACE("insert() " << data.getFullName());
+  NFD_LOG_DEBUG("insert " << data.getFullName());
 
-  if (isFull())
-    {
-      evictItem();
-    }
+  bool isNewEntry = false; TableIt it;
+  // use .insert because gcc46 does not support .emplace
+  std::tie(it, isNewEntry) = m_table.insert(Entry(data.shared_from_this(), isUnsolicited));
+  Entry& entry = const_cast<Entry&>(*it);
 
-  //pointer and insertion status
-  std::pair<cs::Entry*, bool> entry = insertToSkipList(data, isUnsolicited);
-
-  //new entry
-  if (static_cast<bool>(entry.first) && (entry.second == true))
-    {
-      m_cleanupIndex.push_back(entry.first);
-      return true;
-    }
-
-  return false;
-}
-
-size_t
-Cs::pickRandomLayer() const
-{
-  static boost::random::bernoulli_distribution<> dist(SKIPLIST_PROBABILITY);
-  // TODO rewrite using geometry_distribution
-  size_t layer;
-  for (layer = 0; layer < SKIPLIST_MAX_LAYERS; ++layer) {
-    if (!dist(getGlobalRng())) {
-      break;
+  if (!isNewEntry) { // existing entry
+    this->detachQueue(it);
+    // XXX This doesn't forbid unsolicited Data from refreshing a solicited entry.
+    if (entry.isUnsolicited() && !isUnsolicited) {
+      entry.unsetUnsolicited();
     }
   }
-  return layer;
+  entry.refresh();
+  this->attachQueue(it);
+
+  // check there are same amount of entries in the table and in queues
+  BOOST_ASSERT(m_table.size() == std::accumulate(m_queues, m_queues + QUEUE_UBOUND, 0U,
+      [] (size_t sum, const Queue queue) { return sum + queue.size(); }));
+
+  this->evict(); // XXX The new entry could be evicted, but it shouldn't matter.
+
+  return true;
 }
 
 bool
-Cs::isFull() const
+Cs::isNewRightmostCandidate(const Name& prefix, TableIt a, TableIt b)
 {
-  if (size() >= m_nMaxPackets) //size of the first layer vs. max size
-    return true;
-
-  return false;
-}
-
-bool
-Cs::eraseFromSkipList(cs::Entry* entry)
-{
-  NFD_LOG_TRACE("eraseFromSkipList() "  << entry->getFullName());
-  NFD_LOG_TRACE("SkipList size " << size());
-
-  bool isErased = false;
-
-  const std::map<int, std::list<cs::Entry*>::iterator>& iterators = entry->getIterators();
-
-  if (!iterators.empty())
-    {
-      int layer = 0;
-
-      for (SkipList::iterator it = m_skipList.begin(); it != m_skipList.end(); )
-        {
-          std::map<int, std::list<cs::Entry*>::iterator>::const_iterator i = iterators.find(layer);
-
-          if (i != iterators.end())
-            {
-              (*it)->erase(i->second);
-              entry->removeIterator(layer);
-              isErased = true;
-
-              //remove layers that do not contain any elements (starting from the second layer)
-              if ((layer != 0) && (*it)->empty())
-                {
-                  delete *it;
-                  it = m_skipList.erase(it);
-                }
-              else
-                ++it;
-
-              layer++;
-            }
-          else
-            break;
-      }
-    }
-
-  //delete entry;
-  if (isErased)
-  {
-    entry->release();
-    m_freeCsEntries.push(entry);
-    m_nPackets--;
-  }
-
-  return isErased;
-}
-
-bool
-Cs::evictItem()
-{
-  NFD_LOG_TRACE("evictItem()");
-
-  if (!m_cleanupIndex.get<unsolicited>().empty()) {
-    CleanupIndex::index<unsolicited>::type::const_iterator firstSolicited =
-      m_cleanupIndex.get<unsolicited>().upper_bound(false);
-
-    if (firstSolicited != m_cleanupIndex.get<unsolicited>().begin()) {
-      --firstSolicited;
-      BOOST_ASSERT((*firstSolicited)->isUnsolicited());
-      NFD_LOG_TRACE("Evict from unsolicited queue");
-
-      eraseFromSkipList(*firstSolicited);
-      m_cleanupIndex.get<unsolicited>().erase(firstSolicited);
-      return true;
-    }
-    else {
-      BOOST_ASSERT(!(*m_cleanupIndex.get<unsolicited>().begin())->isUnsolicited());
-    }
-  }
-
-  if (!m_cleanupIndex.get<byStaleness>().empty() &&
-      (*m_cleanupIndex.get<byStaleness>().begin())->getStaleTime() < time::steady_clock::now())
-  {
-    NFD_LOG_TRACE("Evict from staleness queue");
-
-    eraseFromSkipList(*m_cleanupIndex.get<byStaleness>().begin());
-    m_cleanupIndex.get<byStaleness>().erase(m_cleanupIndex.get<byStaleness>().begin());
+  if (a->getFullName().size() == prefix.size()) {
     return true;
   }
-
-  if (!m_cleanupIndex.get<byArrival>().empty())
-  {
-    NFD_LOG_TRACE("Evict from arrival queue");
-
-    eraseFromSkipList(*m_cleanupIndex.get<byArrival>().begin());
-    m_cleanupIndex.get<byArrival>().erase(m_cleanupIndex.get<byArrival>().begin());
-    return true;
-  }
-
-  return false;
+  return b->getFullName().at(prefix.size()) > a->getFullName().at(prefix.size());
 }
 
 const Data*
 Cs::find(const Interest& interest) const
 {
-  NFD_LOG_TRACE("find() " << interest.getName());
+  const Name& prefix = interest.getName();
+  bool isRightmost = interest.getChildSelector() == 1;
+  NFD_LOG_DEBUG("find " << prefix << (isRightmost ? " R" : " L"));
+  TableIt rightmostCandidate = m_table.end();
 
-  bool isIterated = false;
-  SkipList::const_reverse_iterator topLayer = m_skipList.rbegin();
-  SkipListLayer::iterator head = (*topLayer)->begin();
-
-  if (!(*topLayer)->empty())
-    {
-      //start from the upper layer towards bottom
-      int layer = m_skipList.size() - 1;
-      for (SkipList::const_reverse_iterator rit = topLayer; rit != m_skipList.rend(); ++rit)
-        {
-          //if we didn't do any iterations on the higher layers, start from the begin() again
-          if (!isIterated)
-            head = (*rit)->begin();
-
-          if (head != (*rit)->end())
-            {
-              // it happens when begin() contains the element we want to find
-              if (!isIterated && (interest.getName().isPrefixOf((*head)->getFullName())))
-                {
-                  if (layer > 0)
-                    {
-                      layer--;
-                      continue; // try lower layer
-                    }
-                  else
-                    {
-                      isIterated = true;
-                    }
-                }
-              else
-                {
-                  SkipListLayer::iterator it = head;
-
-                  while ((*it)->getFullName() < interest.getName())
-                    {
-                      NFD_LOG_TRACE((*it)->getFullName() << " < " << interest.getName());
-                      head = it;
-                      isIterated = true;
-
-                      ++it;
-                      if (it == (*rit)->end())
-                        break;
-                    }
-                }
-            }
-
-          if (layer > 0)
-            {
-              head = (*head)->getIterators().find(layer - 1)->second; // move HEAD to the lower layer
-            }
-          else //if we reached the first layer
-            {
-              if (isIterated)
-                return selectChild(interest, head);
-            }
-
-          layer--;
-        }
+  TableIt left = m_table.lower_bound(prefix);
+  TableIt right = m_table.end();
+  if (prefix.size() > 0) {
+    right = m_table.lower_bound(prefix.getSuccessor());
+  }
+  for (TableIt it = left; it != right; ++it) {
+    const Entry& entry = *it;
+    if (!entry.canSatisfy(interest)) {
+      NFD_LOG_TRACE("cannotSatisfy " << entry.getFullName());
+      continue;
+    }
+    NFD_LOG_TRACE("canSatisfy " << entry.getFullName());
+    if (!isRightmost) {
+      return entry.getData().get();
     }
 
-  return 0;
-}
-
-const Data*
-Cs::selectChild(const Interest& interest, SkipListLayer::iterator startingPoint) const
-{
-  BOOST_ASSERT(startingPoint != (*m_skipList.begin())->end());
-
-  if (startingPoint != (*m_skipList.begin())->begin())
-    {
-      BOOST_ASSERT((*startingPoint)->getFullName() < interest.getName());
+    if (rightmostCandidate == m_table.end() ||
+        isNewRightmostCandidate(prefix, rightmostCandidate, it)) {
+      NFD_LOG_TRACE("rightmostCandidate=" << entry.getFullName());
+      rightmostCandidate = it;
     }
-
-  NFD_LOG_TRACE("selectChild() " << interest.getChildSelector() << " "
-                << (*startingPoint)->getFullName());
-
-  bool hasLeftmostSelector = (interest.getChildSelector() <= 0);
-  bool hasRightmostSelector = !hasLeftmostSelector;
-
-  if (hasLeftmostSelector)
-    {
-      bool doesInterestContainDigest = recognizeInterestWithDigest(interest, *startingPoint);
-      bool isInPrefix = false;
-
-      if (doesInterestContainDigest)
-        {
-          isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getFullName());
-        }
-      else
-        {
-          isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getFullName());
-        }
-
-      if (isInPrefix)
-        {
-          if (doesComplyWithSelectors(interest, *startingPoint, doesInterestContainDigest))
-            {
-              return &(*startingPoint)->getData();
-            }
-        }
-    }
-
-  //iterate to the right
-  SkipListLayer::iterator rightmost = startingPoint;
-  if (startingPoint != (*m_skipList.begin())->end())
-    {
-      SkipListLayer::iterator rightmostCandidate = startingPoint;
-      Name currentChildPrefix("");
-
-      while (true)
-        {
-          ++rightmostCandidate;
-
-          bool isInBoundaries = (rightmostCandidate != (*m_skipList.begin())->end());
-          bool isInPrefix = false;
-          bool doesInterestContainDigest = false;
-          if (isInBoundaries)
-            {
-              doesInterestContainDigest = recognizeInterestWithDigest(interest,
-                                                                      *rightmostCandidate);
-
-              if (doesInterestContainDigest)
-                {
-                  isInPrefix = interest.getName().getPrefix(-1)
-                                 .isPrefixOf((*rightmostCandidate)->getFullName());
-                }
-              else
-                {
-                  isInPrefix = interest.getName().isPrefixOf((*rightmostCandidate)->getFullName());
-                }
-            }
-
-          if (isInPrefix)
-            {
-              if (doesComplyWithSelectors(interest, *rightmostCandidate, doesInterestContainDigest))
-                {
-                  if (hasLeftmostSelector)
-                    {
-                      return &(*rightmostCandidate)->getData();
-                    }
-
-                  if (hasRightmostSelector)
-                    {
-                      if (doesInterestContainDigest)
-                        {
-                          // get prefix which is one component longer than Interest name
-                          // (without digest)
-                          const Name& childPrefix = (*rightmostCandidate)->getFullName()
-                                                      .getPrefix(interest.getName().size());
-                          NFD_LOG_TRACE("Child prefix" << childPrefix);
-
-                          if (currentChildPrefix.empty() || (childPrefix != currentChildPrefix))
-                            {
-                              currentChildPrefix = childPrefix;
-                              rightmost = rightmostCandidate;
-                            }
-                        }
-                      else
-                        {
-                          // get prefix which is one component longer than Interest name
-                          const Name& childPrefix = (*rightmostCandidate)->getFullName()
-                                                      .getPrefix(interest.getName().size() + 1);
-                          NFD_LOG_TRACE("Child prefix" << childPrefix);
-
-                          if (currentChildPrefix.empty() || (childPrefix != currentChildPrefix))
-                            {
-                              currentChildPrefix = childPrefix;
-                              rightmost = rightmostCandidate;
-                            }
-                        }
-                    }
-                }
-            }
-          else
-            break;
-        }
-    }
-
-  if (rightmost != startingPoint)
-    {
-      return &(*rightmost)->getData();
-    }
-
-  if (hasRightmostSelector) // if rightmost was not found, try starting point
-    {
-      bool doesInterestContainDigest = recognizeInterestWithDigest(interest, *startingPoint);
-      bool isInPrefix = false;
-
-      if (doesInterestContainDigest)
-        {
-          isInPrefix = interest.getName().getPrefix(-1).isPrefixOf((*startingPoint)->getFullName());
-        }
-      else
-        {
-          isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getFullName());
-        }
-
-      if (isInPrefix)
-        {
-          if (doesComplyWithSelectors(interest, *startingPoint, doesInterestContainDigest))
-            {
-              return &(*startingPoint)->getData();
-            }
-        }
-    }
-
-  return 0;
-}
-
-bool
-Cs::doesComplyWithSelectors(const Interest& interest,
-                            cs::Entry* entry,
-                            bool doesInterestContainDigest) const
-{
-  NFD_LOG_TRACE("doesComplyWithSelectors()");
-
-  /// \todo The following detection is not correct
-  ///       1. If Interest name ends with 32-octet component doesn't mean that this component is
-  ///          digest
-  ///       2. Only min/max selectors (both 0) can be specified, all other selectors do not
-  ///          make sense for interests with digest (though not sure if we need to enforce this)
-
-  if (doesInterestContainDigest)
-    {
-      if (interest.getName().get(-1) != entry->getFullName().get(-1))
-        {
-          NFD_LOG_TRACE("violates implicit digest");
-          return false;
-        }
-    }
-
-  if (!doesInterestContainDigest)
-    {
-      if (interest.getMinSuffixComponents() >= 0)
-        {
-          size_t minDataNameLength = interest.getName().size() + interest.getMinSuffixComponents();
-
-          bool isSatisfied = (minDataNameLength <= entry->getFullName().size());
-          if (!isSatisfied)
-            {
-              NFD_LOG_TRACE("violates minComponents");
-              return false;
-            }
-        }
-
-      if (interest.getMaxSuffixComponents() >= 0)
-        {
-          size_t maxDataNameLength = interest.getName().size() + interest.getMaxSuffixComponents();
-
-          bool isSatisfied = (maxDataNameLength >= entry->getFullName().size());
-          if (!isSatisfied)
-            {
-              NFD_LOG_TRACE("violates maxComponents");
-              return false;
-            }
-        }
-    }
-
-  if (interest.getMustBeFresh() && entry->getStaleTime() < time::steady_clock::now())
-    {
-      NFD_LOG_TRACE("violates mustBeFresh");
-      return false;
-    }
-
-  if (!interest.getPublisherPublicKeyLocator().empty())
-    {
-      if (entry->getData().getSignature().getType() == ndn::Signature::Sha256WithRsa)
-        {
-          ndn::SignatureSha256WithRsa rsaSignature(entry->getData().getSignature());
-          if (rsaSignature.getKeyLocator() != interest.getPublisherPublicKeyLocator())
-            {
-              NFD_LOG_TRACE("violates publisher key selector");
-              return false;
-            }
-        }
-      else
-        {
-          NFD_LOG_TRACE("violates publisher key selector");
-          return false;
-        }
-    }
-
-  if (doesInterestContainDigest)
-    {
-      const ndn::name::Component& lastComponent = entry->getFullName().get(-1);
-
-      if (!lastComponent.empty())
-        {
-          if (interest.getExclude().isExcluded(lastComponent))
-            {
-              NFD_LOG_TRACE("violates exclusion");
-              return false;
-            }
-        }
-    }
-  else
-    {
-      if (entry->getFullName().size() >= interest.getName().size() + 1)
-        {
-          const ndn::name::Component& nextComponent = entry->getFullName()
-                                                        .get(interest.getName().size());
-          if (!nextComponent.empty())
-            {
-              if (interest.getExclude().isExcluded(nextComponent))
-                {
-                  NFD_LOG_TRACE("violates exclusion");
-                  return false;
-                }
-            }
-        }
-    }
-
-  NFD_LOG_TRACE("complies");
-  return true;
-}
-
-bool
-Cs::recognizeInterestWithDigest(const Interest& interest, cs::Entry* entry) const
-{
-  // only when min selector is not specified or specified with value of 0
-  // and Interest's name length is exactly the length of the name of CS entry
-  if (interest.getMinSuffixComponents() <= 0 &&
-      interest.getName().size() == (entry->getFullName().size()))
-    {
-      const ndn::name::Component& last = interest.getName().get(-1);
-      if (last.value_size() == ndn::crypto::SHA256_DIGEST_SIZE)
-        {
-          NFD_LOG_TRACE("digest recognized");
-          return true;
-        }
-    }
-
-  return false;
+  }
+  if (isRightmost) {
+    return rightmostCandidate == m_table.end() ? nullptr :
+                                 rightmostCandidate->getData().get();
+  }
+  return nullptr;
 }
 
 void
-Cs::erase(const Name& exactName)
+Cs::attachQueue(TableIt it)
 {
-  NFD_LOG_TRACE("insert() " << exactName << ", "
-                << "skipList size " << size());
+  Entry& entry = const_cast<Entry&>(*it);
 
-  bool isIterated = false;
-  SkipListLayer::iterator updateTable[SKIPLIST_MAX_LAYERS];
-  SkipList::reverse_iterator topLayer = m_skipList.rbegin();
-  SkipListLayer::iterator head = (*topLayer)->begin();
+  if (entry.queueType != QUEUE_NONE) {
+    this->detachQueue(it);
+  }
 
-  if (!(*topLayer)->empty())
-    {
-      //start from the upper layer towards bottom
-      int layer = m_skipList.size() - 1;
-      for (SkipList::reverse_iterator rit = topLayer; rit != m_skipList.rend(); ++rit)
-        {
-          //if we didn't do any iterations on the higher layers, start from the begin() again
-          if (!isIterated)
-            head = (*rit)->begin();
+  if (entry.isUnsolicited()) {
+    entry.queueType = QUEUE_UNSOLICITED;
+  }
+  else if (entry.isStale()) {
+    entry.queueType = QUEUE_STALE;
+  }
+  else {
+    entry.queueType = QUEUE_FIFO;
 
-          updateTable[layer] = head;
-
-          if (head != (*rit)->end())
-            {
-              // it can happen when begin() contains the element we want to remove
-              if (!isIterated && ((*head)->getFullName() == exactName))
-                {
-                  eraseFromSkipList(*head);
-                  return;
-                }
-              else
-                {
-                  SkipListLayer::iterator it = head;
-
-                  while ((*it)->getFullName() < exactName)
-                    {
-                      head = it;
-                      updateTable[layer] = it;
-                      isIterated = true;
-
-                      ++it;
-                      if (it == (*rit)->end())
-                        break;
-                    }
-                }
-            }
-
-          if (layer > 0)
-            head = (*head)->getIterators().find(layer - 1)->second; // move HEAD to the lower layer
-
-          layer--;
-        }
+    if (entry.canStale()) {
+      entry.moveStaleEvent = scheduler::schedule(entry.getData()->getFreshnessPeriod(),
+                             bind(&Cs::moveToStaleQueue, this, it));
     }
-  else
-    {
-      return;
-    }
+  }
 
-  head = updateTable[0];
-  ++head; // look at the next slot to check if it contains the item we want to remove
-
-  bool isCsEmpty = (size() == 0);
-  bool isInBoundaries = (head != (*m_skipList.begin())->end());
-  bool isNameIdentical = false;
-  if (!isCsEmpty && isInBoundaries)
-    {
-      NFD_LOG_TRACE("Identical? " << (*head)->getFullName());
-      isNameIdentical = (*head)->getFullName() == exactName;
-    }
-
-  if (isNameIdentical)
-    {
-      NFD_LOG_TRACE("Found target " << (*head)->getFullName());
-      eraseFromSkipList(*head);
-    }
+  Queue& queue = m_queues[entry.queueType];
+  entry.queueIt = queue.insert(queue.end(), it);
 }
 
 void
-Cs::printSkipList() const
+Cs::detachQueue(TableIt it)
 {
-  NFD_LOG_TRACE("print()");
-  //start from the upper layer towards bottom
-  int layer = m_skipList.size() - 1;
-  for (SkipList::const_reverse_iterator rit = m_skipList.rbegin(); rit != m_skipList.rend(); ++rit)
-    {
-      for (SkipListLayer::iterator it = (*rit)->begin(); it != (*rit)->end(); ++it)
-        {
-          NFD_LOG_TRACE("Layer " << layer << " " << (*it)->getFullName());
-        }
-      layer--;
-    }
+  Entry& entry = const_cast<Entry&>(*it);
+
+  BOOST_ASSERT(entry.queueType != QUEUE_NONE);
+
+  if (entry.queueType == QUEUE_FIFO) {
+    scheduler::cancel(entry.moveStaleEvent);
+  }
+
+  m_queues[entry.queueType].erase(entry.queueIt);
+  entry.queueType = QUEUE_NONE;
 }
 
-} //namespace nfd
+void
+Cs::moveToStaleQueue(TableIt it)
+{
+  Entry& entry = const_cast<Entry&>(*it);
+
+  BOOST_ASSERT(entry.queueType == QUEUE_FIFO);
+  m_queues[QUEUE_FIFO].erase(entry.queueIt);
+
+  entry.queueType = QUEUE_STALE;
+  Queue& queue = m_queues[QUEUE_STALE];
+  entry.queueIt = queue.insert(queue.end(), it);
+}
+
+std::tuple<Cs::TableIt, std::string>
+Cs::evictPick()
+{
+  if (!m_queues[QUEUE_UNSOLICITED].empty()) {
+    return std::make_tuple(m_queues[QUEUE_UNSOLICITED].front(), "unsolicited");
+  }
+  if (!m_queues[QUEUE_STALE].empty()) {
+    return std::make_tuple(m_queues[QUEUE_STALE].front(), "stale");
+  }
+  if (!m_queues[QUEUE_FIFO].empty()) {
+    return std::make_tuple(m_queues[QUEUE_FIFO].front(), "fifo");
+  }
+
+  BOOST_ASSERT(false);
+  return std::make_tuple(m_table.end(), "error");
+}
+
+
+void
+Cs::evict()
+{
+  while (this->size() > m_limit) {
+    TableIt it; std::string reason;
+    std::tie(it, reason) = this->evictPick();
+
+    NFD_LOG_DEBUG("evict " << it->getFullName() << " " << reason);
+    this->detachQueue(it);
+    m_table.erase(it);
+  }
+}
+
+void
+Cs::dump()
+{
+  NFD_LOG_DEBUG("dump table");
+  for (const Entry& entry : m_table) {
+    NFD_LOG_TRACE(entry.getFullName());
+  }
+}
+
+} // namespace cs
+} // namespace nfd
diff --git a/daemon/table/cs.hpp b/daemon/table/cs.hpp
index f683a20..4eadd40 100644
--- a/daemon/table/cs.hpp
+++ b/daemon/table/cs.hpp
@@ -21,92 +21,41 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** \file
  *
- * \author Ilya Moiseenko <http://ilyamoiseenko.com/>
- * \author Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
- * \author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ *  \brief implements the ContentStore
+ *
+ *  This ContentStore implementation consists of two data structures,
+ *  a Table, and a set of cleanup queues.
+ *
+ *  The Table is a container (std::set) sorted by full Names of stored Data packets.
+ *  Data packets are wrapped in Entry objects.
+ *  Each Entry contain the Data packet itself,
+ *  and a few addition attributes such as the staleness of the Data packet.
+ *
+ *  The cleanup queues are three doubly linked lists which stores Table iterators.
+ *  The three queues keep track of unsolicited, stale, and fresh Data packet, respectively.
+ *  Table iterator is placed into, removed from, and moved between suitable queues
+ *  whenever an Entry is added, removed, or has other attribute changes.
+ *  The Table iterator of an Entry should be in exactly one queue at any moment.
+ *  Within each queue, the iterators are kept in first-in-first-out order.
+ *  Eviction procedure exhausts the first queue before moving onto the next queue,
+ *  in the order of unsolicited, stale, and fresh queue.
  */
 
 #ifndef NFD_DAEMON_TABLE_CS_HPP
 #define NFD_DAEMON_TABLE_CS_HPP
 
 #include "common.hpp"
-#include "cs-entry.hpp"
-
-#include <boost/multi_index/member.hpp>
-#include <boost/multi_index_container.hpp>
-#include <boost/multi_index/ordered_index.hpp>
-#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/multi_index/identity.hpp>
-
-#include <queue>
 
 namespace nfd {
+namespace cs {
 
-typedef std::list<cs::Entry*> SkipListLayer;
-typedef std::list<SkipListLayer*> SkipList;
+class Entry;
 
-class StalenessComparator
-{
-public:
-  bool
-  operator()(const cs::Entry* entry1, const cs::Entry* entry2) const
-  {
-    return entry1->getStaleTime() < entry2->getStaleTime();
-  }
-};
-
-class UnsolicitedComparator
-{
-public:
-  bool
-  operator()(const cs::Entry* entry1, const cs::Entry* entry2) const
-  {
-    return entry1->isUnsolicited();
-  }
-
-  bool
-  operator()(bool isUnsolicited, const cs::Entry* entry) const
-  {
-    if (isUnsolicited)
-      return true;
-    else
-      return !entry->isUnsolicited();
-  }
-};
-
-// tags
-class unsolicited;
-class byStaleness;
-class byArrival;
-
-typedef boost::multi_index_container<
-  cs::Entry*,
-  boost::multi_index::indexed_by<
-
-    // by arrival (FIFO)
-    boost::multi_index::sequenced<
-      boost::multi_index::tag<byArrival>
-    >,
-
-    // index by staleness time
-    boost::multi_index::ordered_non_unique<
-      boost::multi_index::tag<byStaleness>,
-      boost::multi_index::identity<cs::Entry*>,
-      StalenessComparator
-    >,
-
-    // unsolicited Data is in the front
-    boost::multi_index::ordered_non_unique<
-      boost::multi_index::tag<unsolicited>,
-      boost::multi_index::identity<cs::Entry*>,
-      UnsolicitedComparator
-    >
-
-  >
-> CleanupIndex;
-
-/** \brief represents Content Store
+/** \brief represents the ContentStore
  */
 class Cs : noncopyable
 {
@@ -117,123 +66,101 @@
   ~Cs();
 
   /** \brief inserts a Data packet
-   *  This method does not consider the payload of the Data packet.
-   *
-   *  Packets are considered duplicate if the name matches.
-   *  The new Data packet with the identical name, but a different payload
-   *  is not placed in the Content Store
-   *  \return{ whether the Data is added }
+   *  \return true
    */
   bool
   insert(const Data& data, bool isUnsolicited = false);
 
-  /** \brief finds the best match Data for an Interest
-   *  \return{ the best match, if any; otherwise 0 }
+  /** \brief finds the best matching Data packet
    */
   const Data*
   find(const Interest& interest) const;
 
-  /** \brief deletes CS entry by the exact name
-   */
   void
-  erase(const Name& exactName);
+  erase(const Name& exactName)
+  {
+    BOOST_ASSERT_MSG(false, "not implemented");
+  }
 
-  /** \brief sets maximum allowed size of Content Store (in packets)
+  /** \brief changes capacity (in number of packets)
    */
   void
   setLimit(size_t nMaxPackets);
 
-  /** \brief returns maximum allowed size of Content Store (in packets)
-   *  \return{ number of packets that can be stored in Content Store }
+  /** \return capacity (in number of packets)
    */
   size_t
-  getLimit() const;
+  getLimit() const
+  {
+    return m_limit;
+  }
 
-  /** \brief returns current size of Content Store measured in packets
-   *  \return{ number of packets located in Content Store }
+  /** \return number of stored packets
    */
   size_t
   size() const;
 
-protected:
-  /** \brief removes one Data packet from Content Store based on replacement policy
-   *  \return{ whether the Data was removed }
-   */
-  bool
-  evictItem();
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  dump();
+
+public:
+  typedef std::set<Entry> Table;
+  typedef Table::const_iterator TableIt;
+  typedef std::list<TableIt> Queue;
+  typedef Queue::iterator QueueIt;
+  enum QueueType {
+    QUEUE_UNSOLICITED,
+    QUEUE_STALE,
+    QUEUE_FIFO,
+    QUEUE_UBOUND,
+    QUEUE_NONE = QUEUE_UBOUND
+  };
 
 private:
-  /** \brief returns True if the Content Store is at its maximum capacity
-   *  \return{ True if Content Store is full; otherwise False}
+  /** \brief determines whether b should be the rightmost candidate instead of a
    */
-  bool
-  isFull() const;
+  static bool
+  isNewRightmostCandidate(const Name& prefix, TableIt a, TableIt b);
 
-  /** \brief Computes the layer where new Content Store Entry is placed
-   *
-   *  Reference: "Skip Lists: A Probabilistic Alternative to Balanced Trees" by W.Pugh
-   *  \return{ returns random layer (number) in a skip list}
-   */
-  size_t
-  pickRandomLayer() const;
-
-  /** \brief Inserts a new Content Store Entry in a skip list
-   *  \return{ returns a pair containing a pointer to the CS Entry,
-   *  and a flag indicating if the entry was newly created (True) or refreshed (False) }
-   */
-  std::pair<cs::Entry*, bool>
-  insertToSkipList(const Data& data, bool isUnsolicited = false);
-
-  /** \brief Removes a specific CS Entry from all layers of a skip list
-   *  \return{ returns True if CS Entry was succesfully removed and False if CS Entry was not found}
-   */
-  bool
-  eraseFromSkipList(cs::Entry* entry);
-
-  /** \brief Prints contents of the skip list, starting from the top layer
+  /** \brief attaches an entry to a suitable cleanup queue
+   *  \note if the entry is already attached to a queue, it's automatically detached
    */
   void
-  printSkipList() const;
+  attachQueue(TableIt it);
 
-  /** \brief Implements child selector (leftmost, rightmost, undeclared).
-   *  Operates on the first layer of a skip list.
-   *
-   *  startingPoint must be less than Interest Name.
-   *  startingPoint can be equal to Interest Name only when the item is in the begin() position.
-   *
-   *  Iterates toward greater Names, terminates when CS entry falls out of Interest prefix.
-   *  When childSelector = leftmost, returns first CS entry that satisfies other selectors.
-   *  When childSelector = rightmost, it goes till the end, and returns CS entry that satisfies
-   *  other selectors. Returned CS entry is the leftmost child of the rightmost child.
-   *  \return{ the best match, if any; otherwise 0 }
+  /** \brief detaches an entry from its current cleanup queue
+   *  \warning if the entry is unattached, this will cause undefined behavior
    */
-  const Data*
-  selectChild(const Interest& interest, SkipListLayer::iterator startingPoint) const;
+  void
+  detachQueue(TableIt it);
 
-  /** \brief checks if Content Store entry satisfies Interest selectors (MinSuffixComponents,
-   *  MaxSuffixComponents, Implicit Digest, MustBeFresh)
-   *  \return{ true if satisfies all selectors; false otherwise }
+  /** \brief moves an entry from FIFO queue to STALE queue
    */
-  bool
-  doesComplyWithSelectors(const Interest& interest,
-                          cs::Entry* entry,
-                          bool doesInterestContainDigest) const;
+  void
+  moveToStaleQueue(TableIt it);
 
-  /** \brief interprets minSuffixComponent and name lengths to understand if Interest contains
-   *  implicit digest of the data
-   *  \return{ True if Interest name contains digest; False otherwise }
+  /** \brief picks an entry for eviction
    */
-  bool
-  recognizeInterestWithDigest(const Interest& interest, cs::Entry* entry) const;
+  std::tuple<TableIt, std::string/*reason*/>
+  evictPick();
+
+  /** \brief evicts zero or more entries so that number of stored entries
+   *         is not greater than capacity
+   */
+  void
+  evict();
 
 private:
-  SkipList m_skipList;
-  CleanupIndex m_cleanupIndex;
-  size_t m_nMaxPackets; // user defined maximum size of the Content Store in packets
-  size_t m_nPackets;    // current number of packets in Content Store
-  std::queue<cs::Entry*> m_freeCsEntries; // memory pool
+  size_t m_limit;
+  Table m_table;
+  Queue m_queues[QUEUE_UBOUND];
 };
 
+} // namespace cs
+
+using cs::Cs;
+
 } // namespace nfd
 
 #endif // NFD_DAEMON_TABLE_CS_HPP
