diff --git a/src/lsa-segment-storage.cpp b/src/lsa-segment-storage.cpp
new file mode 100644
index 0000000..a567aab
--- /dev/null
+++ b/src/lsa-segment-storage.cpp
@@ -0,0 +1,158 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2018,  The University of Memphis,
+ *                           Regents of the University of California,
+ *                           Arizona Board of Regents.
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NLSR 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "lsa-segment-storage.hpp"
+#include "logger.hpp"
+#include "lsa.hpp"
+#include "utility/name-helper.hpp"
+
+namespace nlsr {
+
+INIT_LOGGER(LsaSegmentStorage);
+
+LsaSegmentStorage::LsaSegmentStorage(ndn::Scheduler& scheduler,
+                                     const ndn::time::seconds lsaDeletionTimepoint)
+  : m_scheduler(scheduler)
+  , m_lsaDeletionTimepoint(lsaDeletionTimepoint)
+{
+}
+
+void
+LsaSegmentStorage::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
+{
+  fetcher.afterSegmentValidated.connect(std::bind(&LsaSegmentStorage::afterFetcherSignalEmitted,
+                                                  this, _1));
+}
+
+const ndn::Data*
+LsaSegmentStorage::getLsaSegment(const ndn::Interest& interest)
+{
+  ndn::Name lsaSegmentsKey = interest.getName();
+
+  // If this the first interest then it does not contain the segment number,
+  // so need to append zero segment component at the end to match with the data
+  if (lsaSegmentsKey.size() > 0) {
+    if (!lsaSegmentsKey.get(-1).isSegment()) {
+      lsaSegmentsKey.appendSegment(0);
+    }
+
+    auto it = m_lsaSegments.find(lsaSegmentsKey);
+    if (it == m_lsaSegments.end()) {
+      NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " cannot be found in the lsa storage");
+
+      return nullptr;
+    }
+    else {
+      NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " is in the storage.");
+      return &(it->second);
+    }
+  }
+  else {
+    NLSR_LOG_ERROR("Received interest has empty name.");
+    return nullptr;
+  }
+}
+
+void
+LsaSegmentStorage::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
+{
+  NLSR_LOG_TRACE("Received a LSA segment: " << lsaSegment.getName());
+
+  // lsaSegmentName is /<router-prefix>/<LS type>/<sequence no.>/<version no.>/<segment no.>
+  auto lsaSegmentName = lsaSegment.getName();
+
+  if (lsaSegmentName.size() > 0) {
+    // lsaSegmentsKey is /<router-prefix>/<LS type>/<sequence no.>/<segment no.>
+    ndn::Name lsaSegmentsKey(lsaSegmentName.getPrefix(lsaSegmentName.size() - 2));
+    lsaSegmentsKey.append(lsaSegmentName.get(-1));
+
+    // No need to store same LSA multiple time
+    if (m_lsaSegments.find(lsaSegmentsKey) == m_lsaSegments.end()) {
+      NLSR_LOG_TRACE("Received LSA segment is new. Storing it in the storage.\n"
+                      << "                  LSA data name: " << lsaSegmentName);
+
+      // Delete the same LSA with lower sequence number
+      deleteOldLsas(lsaSegmentName);
+
+      m_lsaSegments[lsaSegmentsKey] = lsaSegment;
+    }
+    else {
+      NLSR_LOG_TRACE("The received segment is already in the storage.");
+    }
+
+    // schedule the segment deletion
+    scheduleLsaSegmentDeletion(lsaSegmentsKey);
+  }
+  else {
+    NLSR_LOG_ERROR("The received LSA segment has empty name.");
+  }
+}
+
+void
+LsaSegmentStorage::deleteOldLsas(const ndn::Name& newLsaName)
+{
+  auto newLsaKey = newLsaName.getPrefix(newLsaName.size() - 3);
+  auto newSeqNo = newLsaName.get(-3).toNumber();
+
+  std::vector<decltype(m_lsaSegments)::key_type> lsaToDelete;
+
+  for (auto& segment : m_lsaSegments) {
+    ndn::Name segmentKey = segment.first;
+    auto oldSeqNo = segmentKey.get(-2).toNumber();
+    auto existingLsaKey = segmentKey.getPrefix(segmentKey.size() - 2);
+
+    if (newLsaKey == existingLsaKey) {
+      if (newSeqNo > oldSeqNo) { // in the key the second last component is the sequence number
+        NLSR_LOG_TRACE("Outdated LSA: " << segmentKey << " with seq no: " <<
+                       oldSeqNo << " is deleted.");
+        lsaToDelete.push_back(segmentKey);
+      }
+    }
+  }
+
+  for (auto& segmentKey : lsaToDelete) {
+    m_lsaSegments.erase(segmentKey);
+  }
+}
+
+void
+LsaSegmentStorage::scheduleLsaSegmentDeletion(const ndn::Name& lsaSegmentsKey)
+{
+  m_scheduler.scheduleEvent(m_lsaDeletionTimepoint,
+                            [&, this] {
+                              m_lsaSegments.erase(lsaSegmentsKey);
+                            });
+}
+
+void
+LsaSegmentStorage::insertSegment(const ndn::Name& segmentKey,
+                                 const ndn::Data& segmentValue)
+{
+  m_lsaSegments[segmentKey] = segmentValue;
+}
+
+void
+LsaSegmentStorage::deleteSegment(const ndn::Name& segmentKey)
+{
+  m_lsaSegments.erase(segmentKey);
+}
+
+} // namespace nlsr
\ No newline at end of file
