diff --git a/daemon/common.hpp b/daemon/common.hpp
index 650541e..3a39f99 100644
--- a/daemon/common.hpp
+++ b/daemon/common.hpp
@@ -36,6 +36,7 @@
 
 #include <vector>
 #include <list>
+#include <queue>
 #include <set>
 #include <sstream>
 #include <istream>
diff --git a/daemon/table/cs-entry.cpp b/daemon/table/cs-entry.cpp
new file mode 100644
index 0000000..108a050
--- /dev/null
+++ b/daemon/table/cs-entry.cpp
@@ -0,0 +1,142 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ *
+ * Author: Ilya Moiseenko <iliamo@ucla.edu>
+ */
+
+#include "cs-entry.hpp"
+
+namespace nfd {
+namespace cs {
+
+NFD_LOG_INIT("CsEntry");
+
+Entry::Entry(const Data& data, bool isUnsolicited)
+  : m_dataPacket(data.shared_from_this())
+  , m_isUnsolicited(isUnsolicited)
+  , m_wasRefreshedByDuplicate(false)
+  , m_nameWithDigest(data.getName())
+{
+  updateStaleTime();
+  m_nameWithDigest.append(ndn::name::Component(getDigest()));
+}
+
+
+Entry::~Entry()
+{
+}
+
+const Name&
+Entry::getName() const
+{
+  return m_nameWithDigest;
+}
+
+const Data&
+Entry::getData() const
+{
+  return *m_dataPacket;
+}
+
+void
+Entry::setData(const Data& data)
+{
+  /// \todo This method may not be necessary (if it is real duplicate,
+  ///       there is no reason to recalculate the same digest
+
+  m_dataPacket = data.shared_from_this();
+  m_digest.reset();
+  m_wasRefreshedByDuplicate = true;
+
+  updateStaleTime();
+
+  m_nameWithDigest = data.getName();
+  m_nameWithDigest.append(ndn::name::Component(getDigest()));
+}
+
+void
+Entry::setData(const Data& data, const ndn::ConstBufferPtr& digest)
+{
+  /// \todo This method may not be necessary (if it is real duplicate,
+  ///       there is no reason to recalculate the same digest
+
+  m_dataPacket = data.shared_from_this();
+  m_digest = digest;
+  m_wasRefreshedByDuplicate = true;
+
+  updateStaleTime();
+
+  m_nameWithDigest = data.getName();
+  m_nameWithDigest.append(ndn::name::Component(getDigest()));
+}
+
+bool
+Entry::isUnsolicited() const
+{
+  return m_isUnsolicited;
+}
+
+const time::Point&
+Entry::getStaleTime() const
+{
+  return m_staleAt;
+}
+
+void
+Entry::updateStaleTime()
+{
+  time::Duration freshness = time::milliseconds(m_dataPacket->getFreshnessPeriod());
+  m_staleAt = time::now() + freshness;
+}
+
+bool
+Entry::wasRefreshedByDuplicate() const
+{
+  return m_wasRefreshedByDuplicate;
+}
+
+const ndn::ConstBufferPtr&
+Entry::getDigest() const
+{
+  if (!static_cast<bool>(m_digest))
+    {
+      const Block& block = m_dataPacket->wireEncode();
+      m_digest = ndn::crypto::sha256(block.wire(), block.size());
+    }
+
+  return m_digest;
+}
+
+void
+Entry::setIterator(int layer, const Entry::LayerIterators::mapped_type& layerIterator)
+{
+  m_layerIterators[layer] = layerIterator;
+}
+
+void
+Entry::removeIterator(int layer)
+{
+  m_layerIterators.erase(layer);
+}
+
+const Entry::LayerIterators&
+Entry::getIterators() const
+{
+  return m_layerIterators;
+}
+
+void
+Entry::printIterators() const
+{
+  for (LayerIterators::const_iterator it = m_layerIterators.begin();
+       it != m_layerIterators.end();
+       ++it)
+    {
+      NFD_LOG_DEBUG("[" << it->first << "]" << " " << &(*it->second));
+    }
+}
+
+} // namespace cs
+} // namespace nfd
diff --git a/daemon/table/cs-entry.hpp b/daemon/table/cs-entry.hpp
index 2502105..7d31442 100644
--- a/daemon/table/cs-entry.hpp
+++ b/daemon/table/cs-entry.hpp
@@ -2,22 +2,117 @@
 /**
  * Copyright (C) 2014 Named Data Networking Project
  * See COPYING for copyright and distribution information.
+ *
+ * Author: Ilya Moiseenko <iliamo@ucla.edu>
  */
 
 #ifndef NFD_TABLE_CS_ENTRY_HPP
 #define NFD_TABLE_CS_ENTRY_HPP
 
 #include "common.hpp"
+#include "core/time.hpp"
+#include <ndn-cpp-dev/util/crypto.hpp>
 
 namespace nfd {
+
 namespace cs {
 
-/** \class Entry
- *  \brief represents a CS entry
- */
+class Entry;
 
+/** \brief represents a CS entry
+ */
 class Entry : noncopyable
 {
+public:
+  typedef std::map<int, std::list< shared_ptr<Entry> >::iterator> LayerIterators;
+
+  Entry(const Data& data, bool isUnsolicited = false);
+
+  ~Entry();
+
+  /** \brief returns the name of the Data packet stored in the CS entry
+   *  \return{ NDN name }
+   */
+  const Name&
+  getName() 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  }
+   */
+  bool
+  isUnsolicited() const;
+
+  /** \brief Returns True if CS entry was refreshed by a duplicate Data packet
+   */
+  bool
+  wasRefreshedByDuplicate() const;
+
+  /** \brief returns the absolute time when Data becomes expired
+   *  \return{ Time (resolution up to milliseconds) }
+   */
+  const time::Point&
+  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);
+
+  /** \brief changes the content of CS entry and modifies digest
+   */
+  void
+  setData(const Data& data, const ndn::ConstBufferPtr& digest);
+
+  /** \brief refreshes the time when Data becomes expired
+   *  according to the current absolute time.
+   */
+  void
+  updateStaleTime();
+
+  /** \brief returns the digest of the Data packet stored in the CS entry.
+   */
+  const ndn::ConstBufferPtr&
+  getDigest() 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;
+
+private:
+  /** \brief prints <layer, iterator> pairs.
+   */
+  void
+  printIterators() const;
+
+private:
+  time::Point m_staleAt;
+  shared_ptr<const Data> m_dataPacket;
+
+  bool m_isUnsolicited;
+  bool m_wasRefreshedByDuplicate;
+
+  Name m_nameWithDigest;
+
+  mutable ndn::ConstBufferPtr m_digest;
+
+  LayerIterators m_layerIterators;
 };
 
 } // namespace cs
diff --git a/daemon/table/cs.cpp b/daemon/table/cs.cpp
index d85b2d0..a68c541 100644
--- a/daemon/table/cs.cpp
+++ b/daemon/table/cs.cpp
@@ -2,33 +2,765 @@
 /**
  * Copyright (C) 2014 Named Data Networking Project
  * See COPYING for copyright and distribution information.
+ *
+ * Author: Ilya Moiseenko <iliamo@ucla.edu>
  */
 
-// XXX This is a fake CS that does not cache anything.
-
 #include "cs.hpp"
+#include <ndn-cpp-dev/util/crypto.hpp>
+
+#define SKIPLIST_MAX_LAYERS 32
+#define SKIPLIST_PROBABILITY 50         // 50% ( p = 1/2 )
+
+NFD_LOG_INIT("ContentStore");
 
 namespace nfd {
 
-Cs::Cs()
+Cs::Cs(int nMaxPackets)
+  : m_nMaxPackets(nMaxPackets)
 {
+  srand (time::now());
+  SkipListLayer* zeroLayer = new SkipListLayer();
+  m_skipList.push_back(zeroLayer);
 }
-  
+
 Cs::~Cs()
 {
+  /// \todo Fix memory leak
+}
+
+size_t
+Cs::size() const
+{
+  return (*m_skipList.begin())->size(); // size of the first layer in a skip list
+}
+
+void
+Cs::setLimit(size_t nMaxPackets)
+{
+  m_nMaxPackets = nMaxPackets;
+
+  while (isFull())
+    {
+      evictItem();
+    }
+}
+
+size_t
+Cs::getLimit() const
+{
+  return m_nMaxPackets;
+}
+
+//Reference: "Skip Lists: A Probabilistic Alternative to Balanced Trees" by W.Pugh
+std::pair< shared_ptr<cs::Entry>, bool>
+Cs::insertToSkipList(const Data& data, bool isUnsolicited)
+{
+  NFD_LOG_INFO("insertToSkipList() " << data.getName());
+  NFD_LOG_DEBUG("SkipList size " << size());
+
+  shared_ptr<cs::Entry> entry = make_shared<cs::Entry>(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)->getName() >= entry->getName()) )
+                {
+                  --updateTable[layer];
+                  insertInFront = true;
+                }
+              else
+                {
+                  SkipListLayer::iterator it = head;
+
+                  while ((*it)->getName() < entry->getName())
+                    {
+                      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)->getName() == entry->getName();
+    }
+
+  //check if this is a duplicate packet
+  if (isNameIdentical)
+    {
+      NFD_LOG_DEBUG("Duplicate name (with digest)");
+
+      (*head)->setData(data, entry->getDigest()); //updates stale time
+
+      return std::make_pair(*head, false);
+    }
+
+  NFD_LOG_DEBUG("Not a duplicate");
+
+  int randomLayer = pickRandomLayer();
+
+  if (randomLayer > (m_skipList.size() - 1))
+    {
+      while ( (m_skipList.size() - 1) < randomLayer)
+        {
+          SkipListLayer* newLayer = new SkipListLayer();
+          m_skipList.push_back(newLayer);
+
+          updateTable[(m_skipList.size() - 1)] = newLayer->begin();
+        }
+    }
+
+  int 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_DEBUG("pushback " << &(*last));
+        }
+      else if (updateTable[layer] == (*i)->end() && insertInFront)
+        {
+          (*i)->push_front(entry);
+          entry->setIterator(layer, (*i)->begin());
+
+          NFD_LOG_DEBUG("pushfront ");
+        }
+      else
+        {
+          NFD_LOG_DEBUG("insertafter");
+          ++updateTable[layer]; // insert after
+          SkipListLayer::iterator position = (*i)->insert(updateTable[layer], entry);
+          entry->setIterator(layer, position); // save iterator where item was inserted
+        }
+      layer++;
+    }
+
+  printSkipList();
+
+  return std::make_pair(entry, true);
 }
 
 bool
-Cs::insert(const Data& data)
+Cs::insert(const Data& data, bool isUnsolicited)
 {
+  NFD_LOG_INFO("insert() " << data.getName());
+
+  if (isFull())
+    {
+      evictItem();
+    }
+
+  //pointer and insertion status
+  std::pair< shared_ptr<cs::Entry>, bool> entry = insertToSkipList(data, isUnsolicited);
+
+  //new entry
+  if (entry.first && (entry.second == true))
+    {
+      m_contentByArrival.push(entry.first);
+      m_contentByStaleness.push(entry.first);
+
+      if (entry.first->isUnsolicited())
+        m_unsolicitedContent.push(entry.first);
+
+      return true;
+    }
+
   return false;
 }
-  
-const Data*
-Cs::find(const Interest& interest)
+
+int
+Cs::pickRandomLayer() const
 {
+  int layer = -1;
+  int randomValue;
+
+  do
+    {
+      layer++;
+      randomValue = rand() % 100 + 1;
+    }
+  while ( (randomValue < SKIPLIST_PROBABILITY) && (layer < SKIPLIST_MAX_LAYERS) );
+
+  return layer;
+}
+
+bool
+Cs::isFull() const
+{
+  if (size() >= m_nMaxPackets) //size of the first layer vs. max size
+    return true;
+
+  return false;
+}
+
+bool
+Cs::eraseFromSkipList(shared_ptr<cs::Entry> entry)
+{
+  NFD_LOG_INFO("eraseFromSkipList() "  << entry->getName());
+  NFD_LOG_DEBUG("SkipList size " << size());
+
+  bool isErased = false;
+
+  int layer = m_skipList.size() - 1;
+  for (SkipList::reverse_iterator rit = m_skipList.rbegin(); rit != m_skipList.rend(); ++rit)
+    {
+      const std::map<int, std::list< shared_ptr<cs::Entry> >::iterator>& iterators = entry->getIterators();
+      std::map<int, std::list< shared_ptr<cs::Entry> >::iterator>::const_iterator it = iterators.find(layer);
+      if (it != iterators.end())
+        {
+          (*rit)->erase(it->second);
+          entry->removeIterator(layer);
+          isErased = true;
+        }
+
+      layer--;
+    }
+
+  printSkipList();
+
+  //remove layers that do not contain any elements (starting from the second layer)
+  for (SkipList::iterator it = (++m_skipList.begin()); it != m_skipList.end();)
+    {
+      if ((*it)->empty())
+        {
+          it = m_skipList.erase(it);
+        }
+      else
+        ++it;
+    }
+
+  return isErased;
+}
+
+bool
+Cs::evictItem()
+{
+  NFD_LOG_INFO("evictItem()");
+
+  //because there is a possibility that this item is in a queue, but no longer in skiplist
+  while ( !m_unsolicitedContent.empty() )
+    {
+      NFD_LOG_DEBUG("Evict from unsolicited queue");
+
+      shared_ptr<cs::Entry> entry = m_unsolicitedContent.front();
+      m_unsolicitedContent.pop();
+      bool isErased = eraseFromSkipList(entry);
+
+      if (isErased)
+        return true;
+    }
+
+  //because there is a possibility that this item is in a queue, but no longer in skiplist
+  int nIterations = size() * 0.01;  // 1% of the Content Store
+  while ( !m_contentByStaleness.empty() )
+    {
+      NFD_LOG_DEBUG("Evict from staleness queue");
+
+      shared_ptr<cs::Entry> entry = m_contentByStaleness.top();
+
+      //because stale time could be updated by the duplicate packet
+      if (entry->getStaleTime() < time::now())
+        {
+          m_contentByStaleness.pop();
+          bool isErased = eraseFromSkipList(entry);
+
+          if (isErased)
+            return true;
+        }
+      else if ( (entry->getStaleTime() > time::now()) && entry->wasRefreshedByDuplicate() )
+        {
+          m_contentByStaleness.pop();
+          m_contentByStaleness.push(entry); // place in a right order
+
+          nIterations--;
+          // if 1% of the CS are non-expired refreshed CS entries (allocated sequentially),
+          // then stop to prevent too many iterations
+          if ( nIterations <= 0 )
+            break;
+        }
+      else //no further item will be expired, stop
+        {
+          break;
+        }
+    }
+
+  //because there is a possibility that this item is in a queue, but no longer in skiplist
+  while ( !m_contentByArrival.empty() )
+    {
+      NFD_LOG_DEBUG("Evict from arrival queue");
+
+      shared_ptr<cs::Entry> entry = m_contentByArrival.front();
+      m_contentByArrival.pop();
+      bool isErased = eraseFromSkipList(entry);
+
+      if (isErased)
+        return true;
+    }
+
+  return false;
+}
+
+const Data*
+Cs::find(const Interest& interest) const
+{
+  NFD_LOG_INFO("find() " << interest.getName());
+
+  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)->getName())) )
+                {
+                  if (layer > 0)
+                    {
+                      layer--;
+                      continue; // try lower layer
+                    }
+                  else
+                    {
+                      isIterated = true;
+                    }
+                }
+              else
+                {
+                  SkipListLayer::iterator it = head;
+
+                  while ( (*it)->getName() < interest.getName() )
+                    {
+                      NFD_LOG_DEBUG((*it)->getName() << " < " << 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--;
+        }
+    }
+
   return 0;
 }
 
+// because skip list is a probabilistic data structure and the way it is traversed,
+// there is no guarantee that startingPoint is an element preceding the leftmost child
+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)->getName() < interest.getName() );
+    }
+
+  NFD_LOG_INFO("selectChild() " << interest.getChildSelector() << " " << (*startingPoint)->getName());
+
+  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)->getName());
+        }
+      else
+        {
+          isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getName());
+        }
+
+      if (isInPrefix)
+        {
+          if (doesComplyWithSelectors(interest, *startingPoint))
+            {
+              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)->getName());
+                }
+              else
+                {
+                  isInPrefix = interest.getName().isPrefixOf((*rightmostCandidate)->getName());
+                }
+            }
+
+          if (isInPrefix)
+            {
+              if (doesComplyWithSelectors(interest, *rightmostCandidate))
+                {
+                  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)->getName().getPrefix(interest.getName().size());
+                          NFD_LOG_DEBUG("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)->getName().getPrefix(interest.getName().size() + 1);
+                          NFD_LOG_DEBUG("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)->getName());
+        }
+      else
+        {
+          isInPrefix = interest.getName().isPrefixOf((*startingPoint)->getName());
+        }
+
+      if (isInPrefix)
+        {
+          if (doesComplyWithSelectors(interest, *startingPoint))
+            {
+              return &(*startingPoint)->getData();
+            }
+        }
+    }
+
+  return 0;
+}
+
+bool
+Cs::doesComplyWithSelectors(const Interest& interest, shared_ptr<cs::Entry> entry) const
+{
+  NFD_LOG_INFO("doesComplyWithSelectors()");
+
+  /// \todo The following detection is not correct
+  ///       1. If data 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)
+  bool doesInterestContainDigest = recognizeInterestWithDigest(interest, entry);
+  if ( doesInterestContainDigest )
+    {
+      const ndn::name::Component& last = interest.getName().get(-1);
+      const ndn::ConstBufferPtr& digest = entry->getDigest();
+
+      BOOST_ASSERT(digest->size() == last.value_size());
+      BOOST_ASSERT(digest->size() == ndn::crypto::SHA256_DIGEST_SIZE);
+      
+      if (std::memcmp(digest->buf(), last.value(), ndn::crypto::SHA256_DIGEST_SIZE) != 0)
+        {
+          NFD_LOG_DEBUG("violates implicit digest");
+          return false;
+        }
+    }
+
+  if ( !doesInterestContainDigest )
+    {
+      if (interest.getMinSuffixComponents() >= 0)
+        {
+          int minDataNameLength = interest.getName().size() + interest.getMinSuffixComponents();
+
+          bool isSatisfied = minDataNameLength <= entry->getName().size();
+          if ( !isSatisfied )
+            {
+              NFD_LOG_DEBUG("violates minComponents");
+              return false;
+            }
+        }
+
+      if (interest.getMaxSuffixComponents() >= 0)
+        {
+          int maxDataNameLength = interest.getName().size() + interest.getMaxSuffixComponents();
+
+          bool isSatisfied = maxDataNameLength >= entry->getName().size();
+          if ( !isSatisfied )
+            {
+              NFD_LOG_DEBUG("violates maxComponents");
+              return false;
+            }
+        }
+    }
+
+  if (interest.getMustBeFresh() && entry->getStaleTime() < time::now())
+    {
+      NFD_LOG_DEBUG("violates mustBeFresh");
+      return false;
+    }
+
+  if ( doesInterestContainDigest )
+    {
+      const ndn::name::Component& lastComponent = entry->getName().get(-1);
+
+      if ( !lastComponent.empty() )
+        {
+          if (interest.getExclude().isExcluded(lastComponent))
+            {
+              NFD_LOG_DEBUG("violates exclusion");
+              return false;
+            }
+        }
+    }
+  else
+    {
+      if (entry->getName().size() >= interest.getName().size() + 1)
+        {
+          const ndn::name::Component& nextComponent = entry->getName().get(interest.getName().size());
+
+          if ( !nextComponent.empty() )
+            {
+              if (interest.getExclude().isExcluded(nextComponent))
+                {
+                  NFD_LOG_DEBUG("violates exclusion");
+                  return false;
+                }
+            }
+        }
+    }
+
+
+  NFD_LOG_DEBUG("complies!");
+  return true;
+}
+
+bool
+Cs::recognizeInterestWithDigest(const Interest& interest, shared_ptr<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->getName().size()))
+    {
+      const ndn::name::Component& last = interest.getName().get(-1);
+      if (last.value_size() == ndn::crypto::SHA256_DIGEST_SIZE)
+        {
+          NFD_LOG_DEBUG("digest recognized");
+          return true;
+        }
+    }
+
+  return false;
+}
+
+void
+Cs::erase(const Name& exactName)
+{
+  NFD_LOG_INFO("insert() " << exactName);
+  NFD_LOG_DEBUG("SkipList size " << size());
+
+  bool isIterated = false;
+  SkipListLayer::iterator updateTable[SKIPLIST_MAX_LAYERS];
+  SkipList::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::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 we want to remove
+              if ( !isIterated && ((*head)->getName() == exactName) )
+                {
+                  eraseFromSkipList(*head);
+                  return;
+                }
+              else
+                {
+                  SkipListLayer::iterator it = head;
+
+                  while ((*it)->getName() < 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--;
+        }
+    }
+  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_DEBUG("Identical? " << (*head)->getName());
+      isNameIdentical = (*head)->getName() == exactName;
+    }
+
+  if (isNameIdentical)
+    {
+      NFD_LOG_DEBUG("Found target " << (*head)->getName());
+      eraseFromSkipList(*head);
+    }
+
+  printSkipList();
+}
+
+void
+Cs::printSkipList() const
+{
+  NFD_LOG_INFO("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_DEBUG("Layer " << layer << " " << (*it)->getName());
+        }
+      layer--;
+    }
+}
 
 } //namespace nfd
diff --git a/daemon/table/cs.hpp b/daemon/table/cs.hpp
index 0db5ad7..e4c1ae6 100644
--- a/daemon/table/cs.hpp
+++ b/daemon/table/cs.hpp
@@ -2,6 +2,8 @@
 /**
  * Copyright (C) 2014 Named Data Networking Project
  * See COPYING for copyright and distribution information.
+ *
+ * Author: Ilya Moiseenko <iliamo@ucla.edu>
  */
 
 #ifndef NFD_TABLE_CS_HPP
@@ -12,31 +14,144 @@
 
 namespace nfd {
 
-/** \class Cs
- *  \brief represents the ContentStore
+typedef std::list< shared_ptr<cs::Entry> > SkipListLayer;
+typedef std::list<SkipListLayer*> SkipList;
+
+/** \brief represents Content Store
  */
 class Cs : noncopyable
 {
 public:
-  Cs();
-  
+  explicit
+  Cs(int nMaxPackets = 65536); // ~500MB with average packet size = 8KB
+
   ~Cs();
-  
+
   /** \brief inserts a Data packet
-   *  The caller should ensure that this Data packet is admittable,
-   *  ie. not unsolicited from a untrusted source.
-   *  This does not guarantee the Data is added to the cache;
-   *  even if the Data is added, it may be removed anytime in the future.
+   *  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 }
    */
   bool
-  insert(const Data& data);
-  
+  insert(const Data& data, bool isUnsolicited = false);
+
   /** \brief finds the best match Data for an Interest
    *  \return{ the best match, if any; otherwise 0 }
    */
   const Data*
-  find(const Interest& interest);
+  find(const Interest& interest) const;
+
+  /** \brief deletes CS entry by the exact name
+   */
+  void
+  erase(const Name& exactName);
+
+  /** \brief sets maximum allowed size of Content Store (in 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 }
+   */
+  size_t
+  getLimit() const;
+
+  /** \brief returns current size of Content Store measured in packets
+   *  \return{ number of packets located in Content Store }
+   */
+  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();
+
+private:
+  /** \brief returns True if the Content Store is at its maximum capacity
+   *  \return{ True if Content Store is full; otherwise False}
+   */
+  bool
+  isFull() const;
+
+  /** \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}
+   */
+  int
+  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< shared_ptr<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(shared_ptr<cs::Entry> entry);
+
+  /** \brief Prints contents of the skip list, starting from the top layer
+   */
+  void
+  printSkipList() const;
+
+  /** \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 }
+   */
+  const Data*
+  selectChild(const Interest& interest, SkipListLayer::iterator startingPoint) const;
+
+  /** \brief checks if Content Store entry satisfies Interest selectors (MinSuffixComponents,
+   *  MaxSuffixComponents, Implicit Digest, MustBeFresh)
+   *  \return{ true if satisfies all selectors; false otherwise }
+   */
+  bool
+  doesComplyWithSelectors(const Interest& interest, shared_ptr<cs::Entry> entry) const;
+
+  /** \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 }
+   */
+  bool
+  recognizeInterestWithDigest(const Interest& interest, shared_ptr<cs::Entry> entry) const;
+
+private:
+  class StalenessComparator
+  {
+  public:
+    bool
+    operator() (shared_ptr<cs::Entry> entry1, shared_ptr<cs::Entry> entry2)
+    {
+      return entry1->getStaleTime() > entry2->getStaleTime();
+    }
+  };
+
+  SkipList m_skipList;
+  size_t m_nMaxPackets; //user defined maximum size of the Content Store in packets
+
+  std::queue< shared_ptr<cs::Entry> > m_unsolicitedContent; //FIFO for unsolicited Data
+  std::queue< shared_ptr<cs::Entry> > m_contentByArrival;   //FIFO index
+  std::priority_queue< shared_ptr<cs::Entry>, std::vector< shared_ptr<cs::Entry> >, StalenessComparator> m_contentByStaleness; //index by staleness time
 };
 
 } // namespace nfd
diff --git a/tests/fw/forwarder.cpp b/tests/fw/forwarder.cpp
index b9e460c..ecd06ac 100644
--- a/tests/fw/forwarder.cpp
+++ b/tests/fw/forwarder.cpp
@@ -6,6 +6,7 @@
 
 #include "fw/forwarder.hpp"
 #include "tests/face/dummy-face.hpp"
+#include <ndn-cpp-dev/security/key-chain.hpp>
 
 #include "tests/test-common.hpp"
 
@@ -23,7 +24,10 @@
   Name nameABC("ndn:/A/B/C");
   Interest interestAB(nameAB);
   interestAB.setInterestLifetime(4000);
-  Data dataABC(nameABC);
+  shared_ptr<Data> dataABC = make_shared<Data>(nameABC);
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  dataABC->setSignature(fakeSignature);
 
   shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
   shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
@@ -45,7 +49,7 @@
   BOOST_CHECK(face2->m_sentInterests[0].getName().equals(nameAB));
   BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
 
-  face2->receiveData(dataABC);
+  face2->receiveData(*dataABC);
   g_io.run();
   g_io.reset();
   BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
@@ -89,44 +93,62 @@
   forwarder.addFace(face1);
   forwarder.addFace(face2);
 
+  shared_ptr<Data> d1, d2, d3, d4;
+  shared_ptr<Interest> i1, i2, i3, i4;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
   // local face, /localhost: OK
   forwarder.m_dispatchToStrategy_count = 0;
-  forwarder.onIncomingInterest(*face1, Interest("/localhost/A1"));
+  i1 = make_shared<Interest>(Name("/localhost/A1"));
+  forwarder.onIncomingInterest(*face1, *i1);
   BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
 
   // non-local face, /localhost: violate
   forwarder.m_dispatchToStrategy_count = 0;
-  forwarder.onIncomingInterest(*face2, Interest("/localhost/A2"));
+  i2 = make_shared<Interest>(Name("/localhost/A2"));
+  forwarder.onIncomingInterest(*face2, *i2);
   BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 0);
 
   // local face, non-/localhost: OK
   forwarder.m_dispatchToStrategy_count = 0;
-  forwarder.onIncomingInterest(*face1, Interest("/A3"));
+  i3 = make_shared<Interest>(Name("/A3"));
+  forwarder.onIncomingInterest(*face1, *i3);
   BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
 
   // non-local face, non-/localhost: OK
   forwarder.m_dispatchToStrategy_count = 0;
-  forwarder.onIncomingInterest(*face2, Interest("/A4"));
+  i4 = make_shared<Interest>(Name("/A4"));
+  forwarder.onIncomingInterest(*face2, *i4);
   BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
 
   // local face, /localhost: OK
   forwarder.m_onDataUnsolicited_count = 0;
-  forwarder.onIncomingData(*face1, Data("/localhost/B1"));
+  d1 = make_shared<Data>(Name("/localhost/B1"));
+  d1->setSignature(fakeSignature);
+  forwarder.onIncomingData(*face1, *d1);
   BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
 
   // non-local face, /localhost: OK
   forwarder.m_onDataUnsolicited_count = 0;
-  forwarder.onIncomingData(*face2, Data("/localhost/B2"));
+  d2 = make_shared<Data>(Name("/localhost/B2"));
+  d2->setSignature(fakeSignature);
+  forwarder.onIncomingData(*face2, *d2);
   BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 0);
 
   // local face, non-/localhost: OK
   forwarder.m_onDataUnsolicited_count = 0;
-  forwarder.onIncomingData(*face1, Data("/B3"));
+  d3 = make_shared<Data>(Name("/B3"));
+  d3->setSignature(fakeSignature);
+  forwarder.onIncomingData(*face1, *d3);
   BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
 
   // non-local face, non-/localhost: OK
   forwarder.m_onDataUnsolicited_count = 0;
-  forwarder.onIncomingData(*face2, Data("/B4"));
+  d4 = make_shared<Data>(Name("/B4"));
+  d4->setSignature(fakeSignature);
+  forwarder.onIncomingData(*face2, *d4);
   BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
 }
 
diff --git a/tests/table/cs.cpp b/tests/table/cs.cpp
index eeca6b5..cf0929c 100644
--- a/tests/table/cs.cpp
+++ b/tests/table/cs.cpp
@@ -2,28 +2,893 @@
 /**
  * Copyright (C) 2014 Named Data Networking Project
  * See COPYING for copyright and distribution information.
+ *
+ * Author: Ilya Moiseenko <iliamo@ucla.edu>
  */
 
 #include "table/cs.hpp"
+#include "table/cs-entry.hpp"
 
 #include "tests/test-common.hpp"
 
+#include <ndn-cpp-dev/security/key-chain.hpp>
+
 namespace nfd {
 namespace tests {
 
+class CsAccessor : public Cs
+{
+public:
+
+  bool
+  evictItem_accessor()
+  {
+    return evictItem();
+  }
+};
+
 BOOST_FIXTURE_TEST_SUITE(TableCs, BaseFixture)
 
-BOOST_AUTO_TEST_CASE(FakeInsertFind)
+BOOST_AUTO_TEST_CASE(Insertion)
 {
   Cs cs;
   
-  Data data;
-  BOOST_CHECK_EQUAL(cs.insert(data), false);
+  shared_ptr<Data> data = make_shared<Data>("/insertion");
   
-  Interest interest;
-  BOOST_CHECK_EQUAL(static_cast<bool>(cs.find(interest)), false);
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  data->setSignature(fakeSignature);
+  
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
 }
 
+BOOST_AUTO_TEST_CASE(Insertion2)
+{
+  Cs cs;
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+ 
+  shared_ptr<Data> data3 = make_shared<Data>("/c");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+  
+  BOOST_CHECK_EQUAL(cs.size(), 4);
+}
+
+
+BOOST_AUTO_TEST_CASE(DuplicateInsertion)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data0 = make_shared<Data>("/insert/smth");
+  data0->setSignature(fakeSignature);
+  BOOST_CHECK_EQUAL(cs.insert(*data0), true);
+  
+  shared_ptr<Data> data = make_shared<Data>("/insert/duplicate");
+  data->setSignature(fakeSignature);
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+  
+  cs.insert(*data);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+}
+
+
+BOOST_AUTO_TEST_CASE(DuplicateInsertion2)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/insert/duplicate");
+  data->setSignature(fakeSignature);
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+  
+  cs.insert(*data);
+  BOOST_CHECK_EQUAL(cs.size(), 1);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/insert/original");
+  data2->setSignature(fakeSignature);
+  BOOST_CHECK_EQUAL(cs.insert(*data2), true);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(InsertAndFind)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  Name name("/insert/and/find");
+  
+  shared_ptr<Data> data = make_shared<Data>(name);
+  data->setSignature(fakeSignature);
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+  
+  shared_ptr<Interest> interest = make_shared<Interest>(name);
+  
+  const Data* found = cs.find(*interest);
+  
+  BOOST_REQUIRE(found != 0);
+  BOOST_CHECK_EQUAL(data->getName(), found->getName());
+}
+
+BOOST_AUTO_TEST_CASE(InsertAndNotFind)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  Name name("/insert/and/find");
+  shared_ptr<Data> data = make_shared<Data>(name);
+  data->setSignature(fakeSignature);
+  BOOST_CHECK_EQUAL(cs.insert(*data), true);
+  
+  Name name2("/not/find");
+  shared_ptr<Interest> interest = make_shared<Interest>(name2);
+  
+  const Data* found = cs.find(*interest);
+  
+  BOOST_CHECK_EQUAL(found, static_cast<const Data*>(0));
+}
+
+
+BOOST_AUTO_TEST_CASE(InsertAndErase)
+{
+  CsAccessor cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/insertandelete");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  BOOST_CHECK_EQUAL(cs.size(), 1);
+  
+  cs.evictItem_accessor();
+  BOOST_CHECK_EQUAL(cs.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(StalenessQueue)
+{
+  CsAccessor cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  Name name2("/insert/fresh");
+  shared_ptr<Data> data2 = make_shared<Data>(name2);
+  data2->setFreshnessPeriod(5000);
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+  
+  Name name("/insert/expire");
+  shared_ptr<Data> data = make_shared<Data>(name);
+  data->setFreshnessPeriod(500);
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+  
+  sleep(1);
+  
+  cs.evictItem_accessor();
+  BOOST_CHECK_EQUAL(cs.size(), 1);
+  
+  shared_ptr<Interest> interest = make_shared<Interest>(name2);
+  const Data* found = cs.find(*interest);
+  BOOST_REQUIRE(found != 0);
+  BOOST_CHECK_EQUAL(found->getName(), name2);
+}
+
+//even max size
+BOOST_AUTO_TEST_CASE(ReplacementEvenSize)
+{
+  Cs cs(4);
+
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+ 
+  shared_ptr<Data> data3 = make_shared<Data>("/c");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+ 
+  shared_ptr<Data> data5 = make_shared<Data>("/e");
+  data5->setSignature(fakeSignature);
+  cs.insert(*data5);
+  
+  BOOST_CHECK_EQUAL(cs.size(), 4);
+}
+
+//odd max size
+BOOST_AUTO_TEST_CASE(Replacement2)
+{
+  Cs cs(3);
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+ 
+  shared_ptr<Data> data3 = make_shared<Data>("/c");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+  
+  BOOST_CHECK_EQUAL(cs.size(), 3);
+}
+
+BOOST_AUTO_TEST_CASE(InsertAndEraseByName)
+{
+  CsAccessor cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  Name name("/insertandremovebyname");
+  shared_ptr<Data> data = make_shared<Data>(name);
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  uint8_t digest1[32];
+  ndn::ndn_digestSha256(data->wireEncode().wire(), data->wireEncode().size(), digest1);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/a");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = make_shared<Data>("/z");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+
+  BOOST_CHECK_EQUAL(cs.size(), 3);
+  
+  name.append(digest1, 32);
+  cs.erase(name);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(DigestCalculation)
+{
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  shared_ptr<Data> data = make_shared<Data>("/digest/compute");
+  data->setSignature(fakeSignature);
+  
+  uint8_t digest1[32];
+  ndn::ndn_digestSha256(data->wireEncode().wire(), data->wireEncode().size(), digest1);
+  
+  cs::Entry* entry = new cs::Entry(*data, false);
+  
+  BOOST_CHECK_EQUAL_COLLECTIONS(digest1, digest1+32,
+                                entry->getDigest()->buf(), entry->getDigest()->buf()+32);
+}
+
+BOOST_AUTO_TEST_CASE(InsertCanonical)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+  
+  shared_ptr<Data> data3 = make_shared<Data>("/c");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+  
+  shared_ptr<Data> data5 = make_shared<Data>("/c/c/1/2/3/4/5/6");
+  data5->setSignature(fakeSignature);
+  cs.insert(*data5);
+  
+  shared_ptr<Data> data6 = make_shared<Data>("/c/c/1/2/3");
+  data6->setSignature(fakeSignature);
+  cs.insert(*data6);
+  
+  shared_ptr<Data> data7 = make_shared<Data>("/c/c/1");
+  data7->setSignature(fakeSignature);
+  cs.insert(*data7);
+}
+
+BOOST_AUTO_TEST_CASE(EraseCanonical)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+  
+  shared_ptr<Data> data3 = make_shared<Data>("/c");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+  
+  uint8_t digest1[32];
+  ndn::ndn_digestSha256(data->wireEncode().wire(), data->wireEncode().size(), digest1);
+
+  shared_ptr<Data> data5 = make_shared<Data>("/c/c/1/2/3/4/5/6");
+  data5->setSignature(fakeSignature);
+  cs.insert(*data5);
+  
+  shared_ptr<Data> data6 = make_shared<Data>("/c/c/1/2/3");
+  data6->setSignature(fakeSignature);
+  cs.insert(*data6);
+  
+  shared_ptr<Data> data7 = make_shared<Data>("/c/c/1");
+  data7->setSignature(fakeSignature);
+  cs.insert(*data7);
+
+  Name name("/a");
+  name.append(digest1,32);
+  cs.erase(name);
+  BOOST_CHECK_EQUAL(cs.size(), 6);
+}
+
+BOOST_AUTO_TEST_CASE(ImplicitDigestSelector)
+{
+  CsAccessor cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  Name name("/digest/works");
+  shared_ptr<Data> data = make_shared<Data>(name);
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/a");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+
+  shared_ptr<Data> data3 = make_shared<Data>("/z/z/z");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  uint8_t digest1[32];
+  ndn::ndn_digestSha256(data->wireEncode().wire(), data->wireEncode().size(), digest1);
+  
+  uint8_t digest2[32] = {0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1};
+  
+  shared_ptr<Interest> interest = make_shared<Interest>(boost::cref(Name(name).append(digest1, 32)));
+  interest->setMinSuffixComponents(0);
+  interest->setMaxSuffixComponents(0);
+  
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_NE(found, static_cast<const Data*>(0));
+  BOOST_CHECK_EQUAL(found->getName(), name);
+  
+  shared_ptr<Interest> interest2 = make_shared<Interest>(boost::cref(Name(name).append(digest2, 32)));
+  interest2->setMinSuffixComponents(0);
+  interest2->setMaxSuffixComponents(0);
+  
+  const Data* notfound = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(notfound, static_cast<const Data*>(0));
+}
+
+BOOST_AUTO_TEST_CASE(ChildSelector)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+  
+  shared_ptr<Data> data5 = make_shared<Data>("/c/c");
+  data5->setSignature(fakeSignature);
+  cs.insert(*data5);
+  
+  shared_ptr<Data> data6 = make_shared<Data>("/c/f");
+  data6->setSignature(fakeSignature);
+  cs.insert(*data6);
+  
+  shared_ptr<Data> data7 = make_shared<Data>("/c/n");
+  data7->setSignature(fakeSignature);
+  cs.insert(*data7);
+  
+  shared_ptr<Interest> interest = make_shared<Interest>("/c");
+  interest->setChildSelector(1);
+  
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/c/n");
+
+  shared_ptr<Interest> interest2 = make_shared<Interest>("/c");
+  interest2->setChildSelector(0);
+  
+  const Data* found2 = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
+}
+
+BOOST_AUTO_TEST_CASE(ChildSelector2)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+
+  shared_ptr<Data> data = make_shared<Data>("/a/b/1");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/a/b/2");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+  
+  shared_ptr<Data> data3 = make_shared<Data>("/a/z/1");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/a/z/2");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+  
+  shared_ptr<Interest> interest = make_shared<Interest>("/a");
+  interest->setChildSelector(1);
+  
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/a/z/1");
+}
+
+BOOST_AUTO_TEST_CASE(MustBeFreshSelector)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  Name name("/insert/nonfresh");
+  shared_ptr<Data> data = make_shared<Data>(name);
+  data->setFreshnessPeriod(500);
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  sleep(1);
+  
+  shared_ptr<Interest> interest = make_shared<Interest>(name);
+  interest->setMustBeFresh(true);
+  
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found, static_cast<const Data*>(0));
+}
+
+BOOST_AUTO_TEST_CASE(MinMaxComponentsSelector)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+  
+  shared_ptr<Data> data5 = make_shared<Data>("/c/c/1/2/3/4/5/6");
+  data5->setSignature(fakeSignature);
+  cs.insert(*data5);
+  
+  shared_ptr<Data> data6 = make_shared<Data>("/c/c/6/7/8/9");
+  data6->setSignature(fakeSignature);
+  cs.insert(*data6);
+  
+  shared_ptr<Data> data7 = make_shared<Data>("/c/c/1/2/3");
+  data7->setSignature(fakeSignature);
+  cs.insert(*data7);
+  
+  shared_ptr<Data> data8 = make_shared<Data>("/c/c/1");
+  data8->setSignature(fakeSignature);
+  cs.insert(*data8);
+  
+  shared_ptr<Interest> interest = make_shared<Interest>("/c/c");
+  interest->setMinSuffixComponents(3);
+  interest->setChildSelector(0);
+  
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/c/c/1/2/3/4/5/6");
+
+  shared_ptr<Interest> interest2 = make_shared<Interest>("/c/c");
+  interest2->setMinSuffixComponents(4);
+  interest2->setChildSelector(1);
+  
+  const Data* found2 = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(found2->getName(), "/c/c/6/7/8/9");
+  
+  shared_ptr<Interest> interest3 = make_shared<Interest>("/c/c");
+  interest3->setMaxSuffixComponents(2);
+  interest3->setChildSelector(1);
+  
+  const Data* found3 = cs.find(*interest3);
+  BOOST_CHECK_EQUAL(found3->getName(), "/c/c/1");
+}
+
+BOOST_AUTO_TEST_CASE(ExcludeSelector)
+{
+  Cs cs;
+  
+  ndn::SignatureSha256WithRsa fakeSignature;
+  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+  
+  shared_ptr<Data> data = make_shared<Data>("/a");
+  data->setSignature(fakeSignature);
+  cs.insert(*data);
+  
+  shared_ptr<Data> data2 = make_shared<Data>("/b");
+  data2->setSignature(fakeSignature);
+  cs.insert(*data2);
+  
+  shared_ptr<Data> data3 = make_shared<Data>("/c/a");
+  data3->setSignature(fakeSignature);
+  cs.insert(*data3);
+  
+  shared_ptr<Data> data4 = make_shared<Data>("/d");
+  data4->setSignature(fakeSignature);
+  cs.insert(*data4);
+
+  shared_ptr<Data> data5 = make_shared<Data>("/c/c");
+  data5->setSignature(fakeSignature);
+  cs.insert(*data5);
+  
+  shared_ptr<Data> data6 = make_shared<Data>("/c/f");
+  data6->setSignature(fakeSignature);
+  cs.insert(*data6);
+  
+  shared_ptr<Data> data7 = make_shared<Data>("/c/n");
+  data7->setSignature(fakeSignature);
+  cs.insert(*data7);
+  
+  shared_ptr<Interest> interest = make_shared<Interest>("/c");
+  interest->setChildSelector(1);
+  Exclude e;
+  e.excludeOne (Name::Component("n"));
+  interest->setExclude(e);
+  
+  const Data* found = cs.find(*interest);
+  BOOST_CHECK_EQUAL(found->getName(), "/c/f");
+
+  shared_ptr<Interest> interest2 = make_shared<Interest>("/c");
+  interest2->setChildSelector(0);
+  
+  Exclude e2;
+  e2.excludeOne (Name::Component("a"));
+  interest2->setExclude(e2);
+
+  const Data* found2 = cs.find(*interest2);
+  BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
+  
+  shared_ptr<Interest> interest3 = make_shared<Interest>("/c");
+  interest3->setChildSelector(0);
+  
+  Exclude e3;
+  e3.excludeOne (Name::Component("c"));
+  interest3->setExclude(e3);
+
+  const Data* found3 = cs.find(*interest3);
+  BOOST_CHECK_EQUAL(found3->getName(), "/c/a");
+}
+
+//
+
+class FindFixture : protected BaseFixture
+{
+protected:
+  void
+  insert(uint32_t id, const Name& name)
+  {
+    shared_ptr<Data> data = make_shared<Data>(name);
+    data->setFreshnessPeriod(99999);
+    data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
+    
+    ndn::SignatureSha256WithRsa fakeSignature;
+    fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));
+    data->setSignature(fakeSignature);
+    
+    m_cs.insert(*data);
+  }
+  
+  Interest&
+  startInterest(const Name& name)
+  {
+    m_interest = make_shared<Interest>(name);
+    return *m_interest;
+  }
+  
+  uint32_t
+  find()
+  {
+    const Data* found = m_cs.find(*m_interest);
+    if (found == 0) {
+      return 0;
+    }
+    const Block& content = found->getContent();
+    if (content.value_size() != sizeof(uint32_t)) {
+      return 0;
+    }
+    return *reinterpret_cast<const uint32_t*>(content.value());
+  }
+  
+protected:
+  Cs m_cs;
+  shared_ptr<Interest> m_interest;
+};
+
+BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
+
+BOOST_AUTO_TEST_CASE(EmptyDataName)
+{
+  insert(1, "ndn:/");
+  
+  startInterest("ndn:/");
+  BOOST_CHECK_EQUAL(find(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(EmptyInterestName)
+{
+  insert(1, "ndn:/A");
+  
+  startInterest("ndn:/");
+  BOOST_CHECK_EQUAL(find(), 1);
+}
+
+BOOST_AUTO_TEST_CASE(Leftmost)
+{
+  insert(1, "ndn:/A");
+  insert(2, "ndn:/B/p/1");
+  insert(3, "ndn:/B/p/2");
+  insert(4, "ndn:/B/q/1");
+  insert(5, "ndn:/B/q/2");
+  insert(6, "ndn:/C");
+  
+  startInterest("ndn:/B");
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(Rightmost)
+{
+  insert(1, "ndn:/A");
+  insert(2, "ndn:/B/p/1");
+  insert(3, "ndn:/B/p/2");
+  insert(4, "ndn:/B/q/1");
+  insert(5, "ndn:/B/q/2");
+  insert(6, "ndn:/C");
+  
+  startInterest("ndn:/B")
+    .setChildSelector(1);
+  BOOST_CHECK_EQUAL(find(), 4);
+}
+
+BOOST_AUTO_TEST_CASE(Leftmost_ExactName1)
+{
+  insert(1, "ndn:/");
+  insert(2, "ndn:/A/B");
+  insert(3, "ndn:/A/C");
+  insert(4, "ndn:/A");
+  insert(5, "ndn:/D");
+  
+  // Intuitively you would think Data 4 should be between Data 1 and 2,
+  // but Data 4 has full Name ndn:/A/<32-octet hash>.
+  startInterest("ndn:/A");
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(Leftmost_ExactName33)
+{
+  insert(1, "ndn:/");
+  insert(2, "ndn:/A");
+  insert(3, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 33 'B's
+  insert(4, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
+  insert(5, "ndn:/D");
+  
+  // Data 2 is returned, because <32-octet hash> is less than Data 3.
+  startInterest("ndn:/A");
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_CASE(MinSuffixComponents)
+{
+  insert(1, "ndn:/A/1/2/3/4");
+  insert(2, "ndn:/B/1/2/3");
+  insert(3, "ndn:/C/1/2");
+  insert(4, "ndn:/D/1");
+  insert(5, "ndn:/E");
+  insert(6, "ndn:/");
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(0);
+  BOOST_CHECK_EQUAL(find(), 6);
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(1);
+  BOOST_CHECK_EQUAL(find(), 6);
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(2);
+  BOOST_CHECK_EQUAL(find(), 5);
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(3);
+  BOOST_CHECK_EQUAL(find(), 4);
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(4);
+  BOOST_CHECK_EQUAL(find(), 3);
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(5);
+  BOOST_CHECK_EQUAL(find(), 2);
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(6);
+  BOOST_CHECK_EQUAL(find(), 1);
+  
+  startInterest("ndn:/")
+    .setChildSelector(1)
+    .setMinSuffixComponents(7);
+  BOOST_CHECK_EQUAL(find(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
+{
+  insert(1, "ndn:/");
+  insert(2, "ndn:/A");
+  insert(3, "ndn:/A/B");
+  insert(4, "ndn:/A/B/C");
+  insert(5, "ndn:/A/B/C/D");
+  insert(6, "ndn:/A/B/C/D/E");
+  // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
+  
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(0);
+  BOOST_CHECK_EQUAL(find(), 0);
+  
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(1);
+  BOOST_CHECK_EQUAL(find(), 1);
+  
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(2);
+  BOOST_CHECK_EQUAL(find(), 2);
+  
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(3);
+  BOOST_CHECK_EQUAL(find(), 3);
+  
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(4);
+  BOOST_CHECK_EQUAL(find(), 4);
+  
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(5);
+  BOOST_CHECK_EQUAL(find(), 5);
+  
+  startInterest("ndn:/")
+    .setMaxSuffixComponents(6);
+  BOOST_CHECK_EQUAL(find(), 6);
+}
+
+BOOST_AUTO_TEST_CASE(DigestOrder)
+{
+  insert(1, "ndn:/A");
+  insert(2, "ndn:/A");
+  // We don't know which comes first, but there must be some order
+  
+  startInterest("ndn:/A")
+    .setChildSelector(0);
+  uint32_t leftmost = find();
+  
+  startInterest("ndn:/A")
+    .setChildSelector(1);
+  uint32_t rightmost = find();
+  
+  BOOST_CHECK_NE(leftmost, rightmost);
+}
+
+BOOST_AUTO_TEST_CASE(DigestExclude)
+{
+  insert(1, "ndn:/A/B");
+  insert(2, "ndn:/A");
+  insert(3, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
+  
+  startInterest("ndn:/A")
+    .setExclude(Exclude().excludeBefore(ndn::name::Component(reinterpret_cast<const uint8_t*>(
+        "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+        "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"), 31))); // 31 0xFF's
+  BOOST_CHECK_EQUAL(find(), 2);
+  
+  startInterest("ndn:/A")
+    .setChildSelector(1)
+    .setExclude(Exclude().excludeAfter(ndn::name::Component(reinterpret_cast<const uint8_t*>(
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+        "\x00"), 33))); // 33 0x00's
+  BOOST_CHECK_EQUAL(find(), 2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace tests
