diff --git a/src/ims/in-memory-storage.cpp b/src/ims/in-memory-storage.cpp
new file mode 100644
index 0000000..0dc7df7
--- /dev/null
+++ b/src/ims/in-memory-storage.cpp
@@ -0,0 +1,449 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "in-memory-storage.hpp"
+#include "in-memory-storage-entry.hpp"
+
+namespace ndn {
+
+const time::milliseconds InMemoryStorage::INFINITE_WINDOW(-1);
+const time::milliseconds InMemoryStorage::ZERO_WINDOW(0);
+
+InMemoryStorage::const_iterator::const_iterator(const Data* ptr, const Cache* cache,
+                                                Cache::index<byFullName>::type::iterator it)
+  : m_ptr(ptr)
+  , m_cache(cache)
+  , m_it(it)
+{
+}
+
+InMemoryStorage::const_iterator&
+InMemoryStorage::const_iterator::operator++()
+{
+  m_it++;
+  if (m_it != m_cache->get<byFullName>().end()) {
+    m_ptr = &((*m_it)->getData());
+  }
+  else {
+    m_ptr = 0;
+  }
+
+  return *this;
+}
+
+InMemoryStorage::const_iterator
+InMemoryStorage::const_iterator::operator++(int)
+{
+  InMemoryStorage::const_iterator i(*this);
+  this->operator++();
+  return i;
+}
+
+const Data&
+InMemoryStorage::const_iterator::operator*()
+{
+  return *m_ptr;
+}
+
+const Data*
+InMemoryStorage::const_iterator::operator->()
+{
+  return m_ptr;
+}
+
+bool
+InMemoryStorage::const_iterator::operator==(const const_iterator& rhs)
+{
+  return m_it == rhs.m_it;
+}
+
+bool
+InMemoryStorage::const_iterator::operator!=(const const_iterator& rhs)
+{
+  return m_it != rhs.m_it;
+}
+
+InMemoryStorage::InMemoryStorage(size_t limit)
+  : m_limit(limit)
+  , m_nPackets(0)
+{
+  init();
+}
+
+InMemoryStorage::InMemoryStorage(boost::asio::io_service& ioService, size_t limit)
+  : m_limit(limit)
+  , m_nPackets(0)
+{
+  m_scheduler = make_unique<Scheduler>(ioService);
+  init();
+}
+
+void
+InMemoryStorage::init()
+{
+  // TODO consider a more suitable initial value
+  m_capacity = 10;
+
+  if (m_limit != std::numeric_limits<size_t>::max() && m_capacity > m_limit) {
+    m_capacity = m_limit;
+  }
+
+  for (size_t i = 0; i < m_capacity; i++) {
+    m_freeEntries.push(new InMemoryStorageEntry());
+  }
+}
+
+InMemoryStorage::~InMemoryStorage()
+{
+  // evict all items from cache
+  Cache::iterator it = m_cache.begin();
+  while (it != m_cache.end()) {
+    it = freeEntry(it);
+  }
+
+  BOOST_ASSERT(m_freeEntries.size() == m_capacity);
+
+  while (!m_freeEntries.empty()) {
+    delete m_freeEntries.top();
+    m_freeEntries.pop();
+  }
+}
+
+void
+InMemoryStorage::setCapacity(size_t capacity)
+{
+  size_t oldCapacity = m_capacity;
+  m_capacity = capacity;
+
+  if (size() > m_capacity) {
+    ssize_t nAllowedFailures = size() - m_capacity;
+    while (size() > m_capacity) {
+      if (!evictItem() && --nAllowedFailures < 0) {
+        BOOST_THROW_EXCEPTION(Error());
+      }
+    }
+  }
+
+  if (m_capacity >= oldCapacity) {
+    for (size_t i = oldCapacity; i < m_capacity; i++) {
+      m_freeEntries.push(new InMemoryStorageEntry());
+    }
+  }
+  else {
+    for (size_t i = oldCapacity; i > m_capacity; i--) {
+      delete m_freeEntries.top();
+      m_freeEntries.pop();
+    }
+  }
+
+  BOOST_ASSERT(size() + m_freeEntries.size() == m_capacity);
+}
+
+void
+InMemoryStorage::insert(const Data& data, const time::milliseconds& mustBeFreshProcessingWindow)
+{
+  //check if identical Data/Name already exists
+  Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>().find(data.getFullName());
+  if (it != m_cache.get<byFullName>().end())
+    return;
+
+  //if full, double the capacity
+  bool doesReachLimit = (getLimit() == getCapacity());
+  if (isFull() && !doesReachLimit) {
+    // note: This is incorrect if 2*capacity overflows, but memory should run out before that
+    size_t newCapacity = std::min(2 * getCapacity(), getLimit());
+    setCapacity(newCapacity);
+  }
+
+  //if full and reach limitation of the capacity, employ replacement policy
+  if (isFull() && doesReachLimit) {
+    evictItem();
+  }
+
+  //insert to cache
+  BOOST_ASSERT(m_freeEntries.size() > 0);
+  // take entry for the memory pool
+  InMemoryStorageEntry* entry = m_freeEntries.top();
+  m_freeEntries.pop();
+  m_nPackets++;
+  entry->setData(data);
+  if (m_scheduler != nullptr && mustBeFreshProcessingWindow > ZERO_WINDOW) {
+    auto eventId = make_unique<util::scheduler::ScopedEventId>(*m_scheduler);
+    *eventId = m_scheduler->scheduleEvent(mustBeFreshProcessingWindow,
+                                          bind(&InMemoryStorageEntry::markStale, entry));
+    entry->setMarkStaleEventId(std::move(eventId));
+  }
+  m_cache.insert(entry);
+
+  //let derived class do something with the entry
+  afterInsert(entry);
+}
+
+shared_ptr<const Data>
+InMemoryStorage::find(const Name& name)
+{
+  Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>().lower_bound(name);
+
+  //if not found, return null
+  if (it == m_cache.get<byFullName>().end()) {
+    return shared_ptr<const Data>();
+  }
+
+  //if the given name is not the prefix of the lower_bound, return null
+  if (!name.isPrefixOf((*it)->getFullName())) {
+    return shared_ptr<const Data>();
+  }
+
+  afterAccess(*it);
+  return ((*it)->getData()).shared_from_this();
+}
+
+shared_ptr<const Data>
+InMemoryStorage::find(const Interest& interest)
+{
+  //if the interest contains implicit digest, it is possible to directly locate a packet.
+  Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>()
+                                                    .find(interest.getName());
+
+  //if a packet is located by its full name, it must be the packet to return.
+  if (it != m_cache.get<byFullName>().end()) {
+    return ((*it)->getData()).shared_from_this();
+  }
+
+  //if the packet is not discovered by last step, either the packet is not in the storage or
+  //the interest doesn't contains implicit digest.
+  it = m_cache.get<byFullName>().lower_bound(interest.getName());
+
+  if (it == m_cache.get<byFullName>().end()) {
+    return shared_ptr<const Data>();
+  }
+
+  //to locate the element that has a just smaller name than the interest's
+  if (it != m_cache.get<byFullName>().begin())
+    it--;
+
+  InMemoryStorageEntry* ret = selectChild(interest, it);
+  if (ret != 0) {
+    //let derived class do something with the entry
+    afterAccess(ret);
+    return ret->getData().shared_from_this();
+  }
+  else {
+    return shared_ptr<const Data>();
+  }
+}
+
+InMemoryStorage::Cache::index<InMemoryStorage::byFullName>::type::iterator
+InMemoryStorage::findNextFresh(Cache::index<byFullName>::type::iterator it) const
+{
+  for (; it != m_cache.get<byFullName>().end(); it++) {
+    if ((*it)->isFresh())
+      return it;
+  }
+
+  return it;
+}
+
+InMemoryStorageEntry*
+InMemoryStorage::selectChild(const Interest& interest,
+                             Cache::index<byFullName>::type::iterator startingPoint) const
+{
+  BOOST_ASSERT(startingPoint != m_cache.get<byFullName>().end());
+
+  if (startingPoint != m_cache.get<byFullName>().begin())
+    {
+      BOOST_ASSERT((*startingPoint)->getFullName() < interest.getName());
+    }
+
+  bool hasLeftmostSelector = (interest.getChildSelector() <= 0);
+  bool hasRightmostSelector = !hasLeftmostSelector;
+
+  // filter out "stale" data
+  if (interest.getMustBeFresh())
+    startingPoint = findNextFresh(startingPoint);
+
+  if (startingPoint == m_cache.get<byFullName>().end()) {
+    return nullptr;
+  }
+
+  if (hasLeftmostSelector)
+    {
+      if (interest.matchesData((*startingPoint)->getData()))
+        {
+          return *startingPoint;
+        }
+    }
+
+  //iterate to the right
+  Cache::index<byFullName>::type::iterator rightmost = startingPoint;
+  if (startingPoint != m_cache.get<byFullName>().end())
+    {
+      Cache::index<byFullName>::type::iterator rightmostCandidate = startingPoint;
+      Name currentChildPrefix("");
+
+      while (true)
+        {
+          ++rightmostCandidate;
+          // filter out "stale" data
+          if (interest.getMustBeFresh())
+            rightmostCandidate = findNextFresh(rightmostCandidate);
+
+          bool isInBoundaries = (rightmostCandidate != m_cache.get<byFullName>().end());
+          bool isInPrefix = false;
+          if (isInBoundaries)
+            {
+              isInPrefix = interest.getName().isPrefixOf((*rightmostCandidate)->getFullName());
+            }
+
+          if (isInPrefix)
+            {
+              if (interest.matchesData((*rightmostCandidate)->getData()))
+                {
+                  if (hasLeftmostSelector)
+                    {
+                      return *rightmostCandidate;
+                    }
+
+                  if (hasRightmostSelector)
+                    {
+                      // get prefix which is one component longer than Interest name
+                      const Name& childPrefix = (*rightmostCandidate)->getFullName()
+                                                  .getPrefix(interest.getName().size() + 1);
+
+                      if (currentChildPrefix.empty() || (childPrefix != currentChildPrefix))
+                        {
+                          currentChildPrefix = childPrefix;
+                          rightmost = rightmostCandidate;
+                        }
+                    }
+                }
+            }
+          else
+            break;
+        }
+    }
+
+  if (rightmost != startingPoint)
+    {
+      return *rightmost;
+    }
+
+  if (hasRightmostSelector) // if rightmost was not found, try starting point
+    {
+      if (interest.matchesData((*startingPoint)->getData()))
+        {
+          return *startingPoint;
+        }
+    }
+
+  return 0;
+}
+
+InMemoryStorage::Cache::iterator
+InMemoryStorage::freeEntry(Cache::iterator it)
+{
+  //push the *empty* entry into mem pool
+  (*it)->release();
+  m_freeEntries.push(*it);
+  m_nPackets--;
+  return m_cache.erase(it);
+}
+
+void
+InMemoryStorage::erase(const Name& prefix, const bool isPrefix)
+{
+  if (isPrefix) {
+    Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>().lower_bound(prefix);
+
+    while (it != m_cache.get<byFullName>().end() && prefix.isPrefixOf((*it)->getName())) {
+      //let derived class do something with the entry
+      beforeErase(*it);
+      it = freeEntry(it);
+    }
+  }
+  else {
+    Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>().find(prefix);
+
+    if (it == m_cache.get<byFullName>().end())
+      return;
+
+    //let derived class do something with the entry
+    beforeErase(*it);
+    freeEntry(it);
+  }
+
+  if (m_freeEntries.size() > (2 * size()))
+    setCapacity(getCapacity() / 2);
+}
+
+void
+InMemoryStorage::eraseImpl(const Name& name)
+{
+  Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>().find(name);
+
+  if (it == m_cache.get<byFullName>().end())
+    return;
+
+  freeEntry(it);
+}
+
+InMemoryStorage::const_iterator
+InMemoryStorage::begin() const
+{
+  Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>().begin();
+
+  return const_iterator(&((*it)->getData()), &m_cache, it);
+}
+
+InMemoryStorage::const_iterator
+InMemoryStorage::end() const
+{
+  Cache::index<byFullName>::type::iterator it = m_cache.get<byFullName>().end();
+
+  return const_iterator(nullptr, &m_cache, it);
+}
+
+void
+InMemoryStorage::afterInsert(InMemoryStorageEntry* entry)
+{
+}
+
+void
+InMemoryStorage::beforeErase(InMemoryStorageEntry* entry)
+{
+}
+
+void
+InMemoryStorage::afterAccess(InMemoryStorageEntry* entry)
+{
+}
+
+void
+InMemoryStorage::printCache(std::ostream& os) const
+{
+  //start from the upper layer towards bottom
+  const Cache::index<byFullName>::type& cacheIndex = m_cache.get<byFullName>();
+  for (Cache::index<byFullName>::type::iterator it = cacheIndex.begin();
+       it != cacheIndex.end(); it++)
+    os << (*it)->getFullName() << std::endl;
+}
+
+} // namespace ndn
