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
