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
