**breaking** consolidate src/tlv/*lsa* into src/lsa/*lsa*

Lsa de/serialize functions are replaced by wireEncode/Decode.
Update LSA wire formats. Change TLV assignments as required.
Update nlsrc to print using new encoding.

refs: #4787

Change-Id: Ie8d40b7836d51ea5bb444c8db208dc2b3a0d1cec
diff --git a/src/adjacency-list.cpp b/src/adjacency-list.cpp
index d2ada2b..b83a982 100644
--- a/src/adjacency-list.cpp
+++ b/src/adjacency-list.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -31,32 +31,15 @@
 
 INIT_LOGGER(AdjacencyList);
 
-AdjacencyList::AdjacencyList()
-{
-}
-
-AdjacencyList::~AdjacencyList()
-{
-}
-
-int32_t
+bool
 AdjacencyList::insert(Adjacent& adjacent)
 {
   std::list<Adjacent>::iterator it = find(adjacent.getName());
   if (it != m_adjList.end()) {
-    return -1;
+    return false;
   }
   m_adjList.push_back(adjacent);
-  return 0;
-}
-
-void
-AdjacencyList::addAdjacents(AdjacencyList& adl)
-{
-  for (std::list<Adjacent>::iterator it = adl.getAdjList().begin();
-       it != adl.getAdjList().end(); ++it) {
-    insert((*it));
-  }
+  return true;
 }
 
 Adjacent
diff --git a/src/adjacency-list.hpp b/src/adjacency-list.hpp
index 3b82a7c..955e668 100644
--- a/src/adjacency-list.hpp
+++ b/src/adjacency-list.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2018,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -36,20 +36,7 @@
   typedef std::list<Adjacent>::const_iterator const_iterator;
   typedef std::list<Adjacent>::iterator iterator;
 
-  AdjacencyList();
-  ~AdjacencyList();
-
-  /*! \brief Inserts an adjacency into the list.
-
-    \param adjacent The adjacency that we want to add to this list.
-
-    \retval 0 Indicates success.
-    \retval 1 Indicates failure.
-
-    This function attempts to insert the supplied adjacency into this
-    object, which is an adjacency list.
-   */
-  int32_t
+  bool
   insert(Adjacent& adjacent);
 
   std::list<Adjacent>&
@@ -76,16 +63,6 @@
   void
   setTimedOutInterestCount(const ndn::Name& neighbor, uint32_t count);
 
-  /*! \brief Copies the adjacencies in a list to this one.
-
-    \param adl The adjacency list, the entries of which we want to
-    copy into this object.
-
-    Copies the entries contained in one list into this object.
-   */
-  void
-  addAdjacents(AdjacencyList& adl);
-
   /*! \brief Determines whether this list can be used to build an adj. LSA.
     \param interestRetryNo The maximum number of hello-interest
       retries to contact a neighbor.
@@ -122,9 +99,7 @@
   void
   reset()
   {
-    if (m_adjList.size() > 0) {
-      m_adjList.clear();
-    }
+    m_adjList.clear();
   }
 
   AdjacencyList::iterator
diff --git a/src/adjacent.cpp b/src/adjacent.cpp
index 1ae047e..9e85d4a 100644
--- a/src/adjacent.cpp
+++ b/src/adjacent.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -20,11 +20,7 @@
 
 #include "adjacent.hpp"
 #include "logger.hpp"
-
-#include <iostream>
-#include <string>
-#include <cmath>
-#include <limits>
+#include "tlv/tlv-nlsr.hpp"
 
 namespace nlsr {
 
@@ -43,6 +39,11 @@
 {
 }
 
+Adjacent::Adjacent(const ndn::Block& block)
+{
+  wireDecode(block);
+}
+
 Adjacent::Adjacent(const ndn::Name& an)
     : m_name(an)
     , m_faceUri()
@@ -78,6 +79,87 @@
   m_linkCost = lc;
 }
 
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
+
+template<ndn::encoding::Tag TAG>
+size_t
+Adjacent::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
+{
+  size_t totalLength = 0;
+
+  totalLength += prependDoubleBlock(encoder, ndn::tlv::nlsr::Cost, m_linkCost);
+
+  totalLength += prependStringBlock(encoder, ndn::tlv::nlsr::Uri, m_faceUri.toString());
+
+  totalLength += m_name.wireEncode(encoder);
+
+  totalLength += encoder.prependVarNumber(totalLength);
+  totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Adjacency);
+
+  return totalLength;
+}
+
+const ndn::Block&
+Adjacent::wireEncode() const
+{
+  if (m_wire.hasWire()) {
+    return m_wire;
+  }
+
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+
+  return m_wire;
+}
+
+void
+Adjacent::wireDecode(const ndn::Block& wire)
+{
+  m_name.clear();
+  m_faceUri = ndn::FaceUri();
+  m_linkCost = 0;
+
+  m_wire = wire;
+
+  if (m_wire.type() != ndn::tlv::nlsr::Adjacency) {
+    BOOST_THROW_EXCEPTION(Error("Expected Adjacency Block, but Block is of a different type: #" +
+                                ndn::to_string(m_wire.type())));
+  }
+
+  m_wire.parse();
+
+  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
+    m_name.wireDecode(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required Name field"));
+  }
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Uri) {
+    m_faceUri = ndn::FaceUri(readString(*val));
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required Uri field"));
+  }
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Cost) {
+    m_linkCost = ndn::encoding::readDouble(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required Cost field"));
+  }
+}
+
 bool
 Adjacent::operator==(const Adjacent& adjacent) const
 {
@@ -98,9 +180,11 @@
 std::ostream&
 operator<<(std::ostream& os, const Adjacent& adjacent)
 {
-  os << "Adjacent: " << adjacent.m_name << "\n Connecting FaceUri: " << adjacent.m_faceUri
-     << "\n Link cost: " << adjacent.m_linkCost << "\n Status: " << adjacent.m_status
-     << "\n Interest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
+  os << "Adjacent: " << adjacent.m_name
+     << "\n\t\tConnecting FaceUri: " << adjacent.m_faceUri
+     << "\n\t\tLink cost: " << adjacent.m_linkCost
+     << "\n\t\tStatus: " << adjacent.m_status
+     << "\n\t\tInterest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
   return os;
 }
 
diff --git a/src/adjacent.hpp b/src/adjacent.hpp
index 7930791..178ae78 100644
--- a/src/adjacent.hpp
+++ b/src/adjacent.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -20,7 +20,6 @@
 
 #include <string>
 #include <cmath>
-#include <boost/cstdint.hpp>
 
 #include <ndn-cxx/face.hpp>
 #include <ndn-cxx/net/face-uri.hpp>
@@ -34,11 +33,28 @@
  *
  * Represents another node that we expect to be running NLSR that we
  * should be able to reach over a direct Face connection.
+ *
+ * Data abstraction for Adjacent
+ *  Adjacent := ADJACENCY-TYPE TLV-LENGTH
+ *               Name
+ *               FaceUri
+ *               LinkCost
+ *               AdjacencyStatus
+ *               AdjacencyInterestTimedOutNo
  */
 class Adjacent
 {
-
 public:
+  class Error : public ndn::tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : ndn::tlv::Error(what)
+    {
+    }
+  };
+
   enum Status
   {
     STATUS_UNKNOWN = -1,
@@ -48,6 +64,8 @@
 
   Adjacent();
 
+  Adjacent(const ndn::Block& block);
+
   Adjacent(const ndn::Name& an);
 
   Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
@@ -60,9 +78,10 @@
   }
 
   void
-  setName(const ndn::Name& an)
+  setName(const ndn::Name& name)
   {
-    m_name = an;
+    m_wire.reset();
+    m_name = name;
   }
 
   const ndn::FaceUri&
@@ -74,6 +93,7 @@
   void
   setFaceUri(const ndn::FaceUri& faceUri)
   {
+    m_wire.reset();
     m_faceUri = faceUri;
   }
 
@@ -95,6 +115,7 @@
   void
   setStatus(Status s)
   {
+    m_wire.reset();
     m_status = s;
   }
 
@@ -107,6 +128,7 @@
   void
   setInterestTimedOutNo(uint32_t iton)
   {
+    m_wire.reset();
     m_interestTimedOutNo = iton;
   }
 
@@ -153,6 +175,16 @@
     return m_faceUri == faceUri;
   }
 
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  const ndn::Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
 public:
   static const double DEFAULT_LINK_COST;
   static const double NON_ADJACENT_COST;
@@ -165,17 +197,21 @@
   /*! m_linkCost The semi-arbitrary cost to traverse the link. */
   double m_linkCost;
   /*! m_status Whether the neighbor is active or not */
-  Status m_status;
+  Status m_status = STATUS_UNKNOWN;
   /*! m_interestTimedOutNo How many failed Hello interests we have sent since the last reply */
-  uint32_t m_interestTimedOutNo;
+  uint32_t m_interestTimedOutNo = 0;
   /*! m_faceId The NFD-assigned ID for the neighbor, used to
    * determine whether a Face is available */
   uint64_t m_faceId;
 
+  mutable ndn::Block m_wire;
+
   friend std::ostream&
   operator<<(std::ostream& os, const Adjacent& adjacent);
 };
 
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Adjacent);
+
 std::ostream&
 operator<<(std::ostream& os, const Adjacent& adjacent);
 
diff --git a/src/communication/sync-logic-handler.cpp b/src/communication/sync-logic-handler.cpp
index 308457e..9dd2659 100644
--- a/src/communication/sync-logic-handler.cpp
+++ b/src/communication/sync-logic-handler.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -22,7 +22,7 @@
 #include "sync-logic-handler.hpp"
 #include "common.hpp"
 #include "conf-parameter.hpp"
-#include "lsa.hpp"
+#include "lsa/lsa.hpp"
 #include "logger.hpp"
 #include "utility/name-helper.hpp"
 
@@ -39,15 +39,15 @@
   , m_syncFace(face)
   , m_isLsaNew(isLsaNew)
   , m_confParam(conf)
-  , m_nameLsaUserPrefix(ndn::Name(m_confParam.getSyncUserPrefix()).append(std::to_string(Lsa::Type::NAME)))
+  , m_nameLsaUserPrefix(ndn::Name(m_confParam.getSyncUserPrefix()).append(boost::lexical_cast<std::string>(Lsa::Type::NAME)))
   , m_syncLogic(m_syncFace, m_confParam.getSyncProtocol(), m_confParam.getSyncPrefix(),
                 m_nameLsaUserPrefix, m_confParam.getSyncInterestLifetime(),
                 std::bind(&SyncLogicHandler::processUpdate, this, _1, _2))
 {
   m_adjLsaUserPrefix = ndn::Name(m_confParam.getSyncUserPrefix())
-                         .append(std::to_string(Lsa::Type::ADJACENCY));
+                         .append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
   m_coorLsaUserPrefix = ndn::Name(m_confParam.getSyncUserPrefix())
-                         .append(std::to_string(Lsa::Type::COORDINATE));
+                         .append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
 
   if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF ||
       m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_DRY_RUN) {
diff --git a/src/communication/sync-logic-handler.hpp b/src/communication/sync-logic-handler.hpp
index 4dc2d3d..47f6c9a 100644
--- a/src/communication/sync-logic-handler.hpp
+++ b/src/communication/sync-logic-handler.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -25,7 +25,7 @@
 #include "conf-parameter.hpp"
 #include "test-access-control.hpp"
 #include "signals.hpp"
-#include "lsa.hpp"
+#include "lsa/lsa.hpp"
 #include "sync-protocol-adapter.hpp"
 
 #include <ndn-cxx/face.hpp>
diff --git a/src/lsa.cpp b/src/lsa.cpp
deleted file mode 100644
index 5930e99..0000000
--- a/src/lsa.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2019,  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.hpp"
-#include "nlsr.hpp"
-#include "name-prefix-list.hpp"
-#include "adjacent.hpp"
-#include "logger.hpp"
-
-#include <string>
-#include <iostream>
-#include <sstream>
-#include <algorithm>
-#include <cmath>
-#include <limits>
-#include <boost/algorithm/string.hpp>
-
-namespace nlsr {
-
-INIT_LOGGER(Lsa);
-
-std::string
-Lsa::getData() const
-{
-  std::ostringstream os;
-  os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
-     << ndn::time::toIsoString(m_expirationTimePoint) << "|";
-  return os.str();
-}
-
-const ndn::Name
-Lsa::getKey() const
-{
-  return ndn::Name(m_origRouter).append(std::to_string(getType()));
-}
-
-bool
-Lsa::deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator)
-{
-  m_origRouter = ndn::Name(*iterator++);
-  if (m_origRouter.size() <= 0)
-    return false;
-  if (*iterator++ != std::to_string(getType()))
-    return false;
-  m_lsSeqNo = boost::lexical_cast<uint32_t>(*iterator++);
-  m_expirationTimePoint = ndn::time::fromIsoString(*iterator++);
-  return true;
-}
-
-NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
-                 const ndn::time::system_clock::TimePoint& lt,
-                 NamePrefixList& npl)
-{
-  m_origRouter = origR;
-  m_lsSeqNo = lsn;
-  m_expirationTimePoint = lt;
-  for (const auto& name : npl.getNames()) {
-    addName(name);
-  }
-}
-
-std::string
-NameLsa::serialize() const
-{
-  std::ostringstream os;
-  os << getData() << m_npl.size();
-  for (const auto& name : m_npl.getNames()) {
-    os << "|" << name;
-  }
-  os << "|";
-  return os.str();
-}
-
-bool
-NameLsa::deserialize(const std::string& content) noexcept
-{
-  uint32_t numName = 0;
-  boost::char_separator<char> sep("|");
-  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
-  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
-                                               tokens.begin();
-
-  try {
-    if (!deserializeCommon(tok_iter))
-      return false;
-    numName = boost::lexical_cast<uint32_t>(*tok_iter++);
-    for (uint32_t i = 0; i < numName; i++) {
-      ndn::Name name(*tok_iter++);
-      addName(name);
-    }
-  }
-  catch (const std::exception& e) {
-    NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
-    return false;
-  }
-  return true;
-}
-
-bool
-NameLsa::isEqualContent(const NameLsa& other) const
-{
-  return m_npl == other.getNpl();
-}
-
-void
-NameLsa::writeLog() const
-{
-  NLSR_LOG_DEBUG(*this);
-}
-
-CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
-                             const ndn::time::system_clock::TimePoint& lt,
-                             double r, std::vector<double> theta)
-{
-  m_origRouter = origR;
-  m_lsSeqNo = lsn;
-  m_expirationTimePoint = lt;
-  m_corRad = r;
-  m_angles = theta;
-}
-
-bool
-CoordinateLsa::isEqualContent(const CoordinateLsa& clsa) const
-{
-  if (clsa.getCorTheta().size() != m_angles.size()) {
-    return false;
-  }
-
-  std::vector<double> m_angles2 = clsa.getCorTheta();
-  for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
-    if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
-      return false;
-    }
-  }
-
-  return (std::abs(m_corRad - clsa.getCorRadius()) <
-          std::numeric_limits<double>::epsilon());
-}
-
-std::string
-CoordinateLsa::serialize() const
-{
-  std::ostringstream os;
-  os << getData() << m_corRad << "|" << m_angles.size() << "|";
-  for (const auto& angle: m_angles) {
-    os << angle << "|";
-  }
-  return os.str();
-}
-
-bool
-CoordinateLsa::deserialize(const std::string& content) noexcept
-{
-  boost::char_separator<char> sep("|");
-  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
-  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
-                                               tokens.begin();
-
-  try {
-    if (!deserializeCommon(tok_iter))
-      return false;
-    m_corRad = boost::lexical_cast<double>(*tok_iter++);
-    int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
-    for (int i = 0; i < numAngles; i++) {
-      m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
-    }
-  }
-  catch (const std::exception& e) {
-    NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
-    return false;
-  }
-  return true;
-}
-
-void
-CoordinateLsa::writeLog() const
-{
-  NLSR_LOG_DEBUG(*this);
-}
-
-AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
-               const ndn::time::system_clock::TimePoint& lt,
-               uint32_t nl , AdjacencyList& adl)
-{
-  m_origRouter = origR;
-  m_lsSeqNo = lsn;
-  m_expirationTimePoint = lt;
-  m_noLink = nl;
-  std::list<Adjacent> al = adl.getAdjList();
-  for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
-    if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
-      addAdjacent((*it));
-    }
-  }
-}
-
-bool
-AdjLsa::isEqualContent(const AdjLsa& alsa) const
-{
-  return m_adl == alsa.getAdl();
-}
-
-std::string
-AdjLsa::serialize() const
-{
-  std::ostringstream os;
-  os << getData() << m_adl.size();
-  for (const auto& adjacent : m_adl.getAdjList()) {
-    os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
-       << "|" << adjacent.getLinkCost();
-  }
-  os << "|";
-  return os.str();
-}
-
-bool
-AdjLsa::deserialize(const std::string& content) noexcept
-{
-  uint32_t numLink = 0;
-  boost::char_separator<char> sep("|");
-  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
-  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
-                                               tokens.begin();
-
-  try {
-    if (!deserializeCommon(tok_iter))
-      return false;
-    numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
-    for (uint32_t i = 0; i < numLink; i++) {
-      ndn::Name adjName(*tok_iter++);
-      std::string connectingFaceUri(*tok_iter++);
-      double linkCost = boost::lexical_cast<double>(*tok_iter++);
-
-      Adjacent adjacent(adjName, ndn::FaceUri(connectingFaceUri), linkCost,
-                        Adjacent::STATUS_INACTIVE, 0, 0);
-      addAdjacent(adjacent);
-    }
-  }
-  // Ignore neighbors with negative cost received from the Adjacent LSA data.
-  catch (const ndn::tlv::Error& e) {
-    NLSR_LOG_ERROR(e.what());
-  }
-  catch (const std::exception& e) {
-    NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
-    return false;
-  }
-  return true;
-}
-
-void
-AdjLsa::writeLog() const
-{
-  NLSR_LOG_DEBUG(*this);
-}
-
-std::ostream&
-operator<<(std::ostream& os, const AdjLsa& lsa)
-{
-  os << lsa.toString();
-  os << "-Adjacents:";
-
-  int adjacencyIndex = 1;
-
-  for (const Adjacent& adjacency : lsa.m_adl) {
-  os << "--Adjacent" << adjacencyIndex++ << ":\n"
-     << "---Adjacent Name: " << adjacency.getName() << "\n"
-     << "---Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
-     << "---Link Cost: " << adjacency.getLinkCost() << "\n";
-  }
-  os << "adj_lsa_end";
-
-  return os;
-}
-
-std::ostream&
-operator<<(std::ostream& os, const CoordinateLsa& lsa)
-{
-  os << lsa.toString();
-  os << "--Hyperbolic Radius: " << lsa.m_corRad << "\n";
-  int i = 0;
-  for (const auto& value : lsa.m_angles) {
-    os << "---Hyperbolic Theta: " << i++ << ": " << value << "\n";
-  }
-  os << "cor_lsa_end";
-
-  return os;
-}
-
-std::ostream&
-operator<<(std::ostream& os, const NameLsa& lsa)
-{
-  os << lsa.toString();
-  os << "--Names:\n";
-  int i = 0;
-  auto names = lsa.m_npl.getNames();
-  for (const auto& name : names) {
-    os << "---Name " << i++ << ": " << name << "\n";
-  }
-  os << "name_lsa_end";
-
-  return os;
-}
-
-std::ostream&
-operator<<(std::ostream& os, const Lsa::Type& type)
-{
-  os << std::to_string(type);
-  return os;
-}
-
-std::istream&
-operator>>(std::istream& is, Lsa::Type& type)
-{
-  std::string typeString;
-  is >> typeString;
-  if (typeString == "ADJACENCY") {
-    type = Lsa::Type::ADJACENCY;
-  }
-  else if (typeString == "COORDINATE") {
-    type = Lsa::Type::COORDINATE;
-  }
-  else if (typeString == "NAME") {
-    type = Lsa::Type::NAME;
-  }
-  else {
-    type = Lsa::Type::BASE;
-  }
-  return is;
-}
-
-std::string
-Lsa::toString() const
-{
-  std::ostringstream os;
-  os << "LSA of type " << getType() << ":\n-Origin Router: " << getOrigRouter()
-     << "\n-Sequence Number: " << getLsSeqNo() << "\n-Expiration Point: "
-     << getExpirationTimePoint() << "\n";
-  return os.str();
-}
-
-} // namespace nlsr
-
-namespace std {
-std::string
-to_string(const nlsr::Lsa::Type& type)
-{
-  switch (type) {
-  case nlsr::Lsa::Type::ADJACENCY:
-     return "ADJACENCY";
-  case nlsr::Lsa::Type::COORDINATE:
-    return "COORDINATE";
-  case nlsr::Lsa::Type::NAME:
-    return "NAME";
-  case nlsr::Lsa::Type::MOCK:
-    return "MOCK";
-  default:
-    return "BASE";
-  }
-}
-
-} // namespace std
diff --git a/src/lsa.hpp b/src/lsa.hpp
deleted file mode 100644
index 13a5b6c..0000000
--- a/src/lsa.hpp
+++ /dev/null
@@ -1,401 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2019,  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/>.
- */
-
-#ifndef NLSR_LSA_HPP
-#define NLSR_LSA_HPP
-
-#include "name-prefix-list.hpp"
-#include "adjacent.hpp"
-#include "adjacency-list.hpp"
-
-#include <ndn-cxx/util/scheduler.hpp>
-#include <ndn-cxx/util/time.hpp>
-#include <boost/tokenizer.hpp>
-
-namespace nlsr {
-
-class Lsa
-{
-public:
-  enum class Type {
-    ADJACENCY,
-    COORDINATE,
-    NAME,
-    BASE,
-    MOCK
-  };
-
-  virtual
-  ~Lsa() = default;
-
-  virtual Type
-  getType() const
-  {
-    return Type::BASE;
-  }
-
-  void
-  setLsSeqNo(uint32_t lsn)
-  {
-    m_lsSeqNo = lsn;
-  }
-
-  uint32_t
-  getLsSeqNo() const
-  {
-    return m_lsSeqNo;
-  }
-
-  const ndn::Name&
-  getOrigRouter() const
-  {
-    return m_origRouter;
-  }
-
-  void
-  setOrigRouter(const ndn::Name& org)
-  {
-    m_origRouter = org;
-  }
-
-  const ndn::time::system_clock::TimePoint&
-  getExpirationTimePoint() const
-  {
-    return m_expirationTimePoint;
-  }
-
-  void
-  setExpirationTimePoint(const ndn::time::system_clock::TimePoint& lt)
-  {
-    m_expirationTimePoint = lt;
-  }
-
-  void
-  setExpiringEventId(ndn::scheduler::EventId eid)
-  {
-    m_expiringEventId = std::move(eid);
-  }
-
-  ndn::scheduler::EventId
-  getExpiringEventId() const
-  {
-    return m_expiringEventId;
-  }
-
-  /*! \brief Return the data that this LSA represents.
-   */
-  virtual std::string
-  serialize() const = 0;
-
-  /*! \brief Gets the key for this LSA.
-
-    Format is: \<router name\>/\<LSA type>\
-   */
-  const ndn::Name
-  getKey() const;
-
-  /*! \brief Populate this LSA with content from the string "content".
-    \param content The string containing a valid serialization of LSA content.
-
-    This method populates "this" LSA with data from the string.
-   */
-  virtual bool
-  deserialize(const std::string& content) noexcept = 0;
-
-  virtual void
-  writeLog() const = 0;
-
-protected:
-  /*! Get data common to all LSA types.
-
-    This method should be called by all LSA classes in their
-    serialize() method.
-   */
-  std::string
-  getData() const;
-
-  /*! Print data common to all LSA types.
-   */
-  std::string
-  toString() const;
-
-  bool
-  deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator);
-
-protected:
-  ndn::Name m_origRouter;
-  uint32_t m_lsSeqNo = 0;
-  ndn::time::system_clock::TimePoint m_expirationTimePoint;
-  ndn::scheduler::EventId m_expiringEventId;
-};
-
-class NameLsa : public Lsa
-{
-public:
-  NameLsa() = default;
-
-  NameLsa(const ndn::Name& origR, uint32_t lsn,
-          const ndn::time::system_clock::TimePoint& lt,
-          NamePrefixList& npl);
-
-  Lsa::Type
-  getType() const override
-  {
-    return Lsa::Type::NAME;
-  }
-
-  NamePrefixList&
-  getNpl()
-  {
-    return m_npl;
-  }
-
-  const NamePrefixList&
-  getNpl() const
-  {
-    return m_npl;
-  }
-
-  void
-  addName(const ndn::Name& name)
-  {
-    m_npl.insert(name);
-  }
-
-  void
-  removeName(const ndn::Name& name)
-  {
-    m_npl.remove(name);
-  }
-
-  /*! \brief Initializes this LSA object with content's data.
-
-    \param content The data (e.g. name prefixes) to initialize this LSA with.
-
-    This function initializes this object to represent the data
-    contained in content. The format for this is the same as for
-    getData(); getData() returns data of this format, in other words.
-   */
-  bool
-  deserialize(const std::string& content) noexcept override;
-
-  bool
-  isEqualContent(const NameLsa& other) const;
-
-  void
-  writeLog() const override;
-
-  /*! \brief Returns the data that this name LSA has.
-
-    Format is: \<original router
-    prefix\>|name|\<seq. no.\>|\<exp. time\>|\<prefix 1\>|\<prefix
-    2\>|...|\<prefix n\>|
-   */
-  std::string
-  serialize() const override;
-
-private:
-  NamePrefixList m_npl;
-
-  friend std::ostream&
-  operator<<(std::ostream& os, const NameLsa& lsa);
-};
-
-class AdjLsa : public Lsa
-{
-public:
-  typedef AdjacencyList::const_iterator const_iterator;
-
-  AdjLsa() = default;
-
-  AdjLsa(const ndn::Name& origR, uint32_t lsn,
-         const ndn::time::system_clock::TimePoint& lt,
-         uint32_t nl , AdjacencyList& adl);
-
-  Lsa::Type
-  getType() const override
-  {
-    return Lsa::Type::ADJACENCY;
-  }
-
-  AdjacencyList&
-  getAdl()
-  {
-    return m_adl;
-  }
-
-  const AdjacencyList&
-  getAdl() const
-  {
-    return m_adl;
-  }
-
-  void
-  addAdjacent(Adjacent adj)
-  {
-    m_adl.insert(adj);
-  }
-
-  /*! \brief Initializes this adj. LSA from the supplied content.
-
-    \param content The content that this LSA is to have, formatted
-    according to getData().
-   */
-  bool
-  deserialize(const std::string& content) noexcept override;
-
-  uint32_t
-  getNoLink()
-  {
-    return m_noLink;
-  }
-
-  bool
-  isEqualContent(const AdjLsa& alsa) const;
-
-  void
-  writeLog() const override;
-
-  const_iterator
-  begin() const
-  {
-    return m_adl.begin();
-  }
-
-  const_iterator
-  end() const
-  {
-    return m_adl.end();
-  }
-
-  /*! \brief Returns the data this adjacency LSA has.
-
-    The format is: \<original
-    router\>|adjacency|\<seq. no.\>|\<exp. time\>|\<size\>|\<adjacency prefix
-    1\>|\<face uri 1\>|\<cost 1\>|...|\<adjacency prefix n\>|\<face uri
-    n\>|\<cost n\>|
-   */
-  std::string
-  serialize() const override;
-
-private:
-  uint32_t m_noLink;
-  AdjacencyList m_adl;
-
-  friend std::ostream&
-  operator<<(std::ostream& os, const AdjLsa& lsa);
-};
-
-class CoordinateLsa : public Lsa
-{
-public:
-  CoordinateLsa() = default;
-
-  CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
-                const ndn::time::system_clock::TimePoint& lt,
-                double r, std::vector<double> theta);
-
-  Lsa::Type
-  getType() const override
-  {
-    return Lsa::Type::COORDINATE;
-  }
-
-  /*! \brief Initializes this coordinate LSA with the data in content.
-
-    \param content The string content that is used to build the LSA.
-
-    This function initializes this LSA object to represent the data
-    specified by the parameter. The format that it is expecting is the
-    same as for getData();
-  */
-  bool
-  deserialize(const std::string& content) noexcept override;
-
-  double
-  getCorRadius() const
-  {
-    return m_corRad;
-  }
-
-  void
-  setCorRadius(double cr)
-  {
-    m_corRad = cr;
-  }
-
-  const std::vector<double>
-  getCorTheta() const
-  {
-    return m_angles;
-  }
-
-  void
-  setCorTheta(std::vector<double> ct)
-  {
-    m_angles = ct;
-  }
-
-  bool
-  isEqualContent(const CoordinateLsa& clsa) const;
-
-  void
-  writeLog() const override;
-
-  /*! \brief Returns the data that this coordinate LSA represents.
-
-    The format is: \<original
-    router\>|coordinate|\<seq. no.\>|\<exp. time\>|\<radians\>|\<theta\>|
-  */
-  std::string
-  serialize() const override;
-
-private:
-  double m_corRad = 0.0;
-  std::vector<double> m_angles;
-
-  friend std::ostream&
-  operator<<(std::ostream& os, const CoordinateLsa& lsa);
-};
-
-std::ostream&
-operator<<(std::ostream& os, const AdjLsa& lsa);
-
-std::ostream&
-operator<<(std::ostream& os, const CoordinateLsa& lsa);
-
-std::ostream&
-operator<<(std::ostream& os, const NameLsa& lsa);
-
-std::ostream&
-operator<<(std::ostream& os, const Lsa::Type& type);
-
-std::istream&
-operator>>(std::istream& is, Lsa::Type& type);
-
-} // namespace nlsr
-
-namespace std {
-std::string
-to_string(const nlsr::Lsa::Type& type);
-} // namespace std
-
-#endif // NLSR_LSA_HPP
diff --git a/src/lsa/adj-lsa.cpp b/src/lsa/adj-lsa.cpp
new file mode 100644
index 0000000..e2d0a2b
--- /dev/null
+++ b/src/lsa/adj-lsa.cpp
@@ -0,0 +1,144 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  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 "adj-lsa.hpp"
+#include "tlv/tlv-nlsr.hpp"
+
+namespace nlsr {
+
+AdjLsa::AdjLsa(const ndn::Name& originRouter, uint32_t seqNo,
+               const ndn::time::system_clock::TimePoint& timepoint,
+               uint32_t noLink, AdjacencyList& adl)
+  : Lsa(originRouter, seqNo, timepoint)
+  , m_noLink(noLink)
+{
+  for (const auto& adjacent : adl.getAdjList()) {
+    if (adjacent.getStatus() == Adjacent::STATUS_ACTIVE) {
+      addAdjacent(adjacent);
+    }
+  }
+}
+
+AdjLsa::AdjLsa(const ndn::Block& block)
+{
+  wireDecode(block);
+}
+
+bool
+AdjLsa::isEqualContent(const AdjLsa& alsa) const
+{
+  return m_adl == alsa.getAdl();
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+AdjLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
+{
+  size_t totalLength = 0;
+
+  auto list = m_adl.getAdjList();
+  for (auto it = list.rbegin(); it != list.rend(); ++it) {
+    totalLength += it->wireEncode(block);
+  }
+
+  totalLength += Lsa::wireEncode(block);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(ndn::tlv::nlsr::AdjacencyLsa);
+
+  return totalLength;
+}
+
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
+
+const ndn::Block&
+AdjLsa::wireEncode() const
+{
+  if (m_wire.hasWire() && m_baseWire.hasWire()) {
+    return m_wire;
+  }
+
+  ndn::EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  ndn::EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+
+  return m_wire;
+}
+
+void
+AdjLsa::wireDecode(const ndn::Block& wire)
+{
+  m_wire = wire;
+
+  if (m_wire.type() != ndn::tlv::nlsr::AdjacencyLsa) {
+    BOOST_THROW_EXCEPTION(Error("Expected AdjacencyLsa Block, but Block is of a different type: #" +
+                                ndn::to_string(m_wire.type())));
+  }
+
+  m_wire.parse();
+
+  ndn::Block::element_const_iterator val = m_wire.elements_begin();
+
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
+    Lsa::wireDecode(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required Lsa field"));
+  }
+
+  AdjacencyList adl;
+  for (; val != m_wire.elements_end(); ++val) {
+    if (val->type() == ndn::tlv::nlsr::Adjacency) {
+      Adjacent adj = Adjacent(*val);
+      adl.insert(adj);
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Expected Adjacency Block, but Block is of a different type: #" +
+                                  ndn::to_string(m_wire.type())));
+    }
+  }
+  m_adl = adl;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const AdjLsa& lsa)
+{
+  os << lsa.toString();
+  os << "      Adjacents:\n";
+
+  int adjacencyIndex = 0;
+
+  for (const Adjacent& adjacency : lsa.getAdl()) {
+  os << "        Adjacent " << adjacencyIndex++
+     << ": (name=" << adjacency.getName()
+     << ", uri="   << adjacency.getFaceUri()
+     << ", cost="  << adjacency.getLinkCost() << ")\n";
+  }
+
+  return os;
+}
+
+} // namespace nlsr
\ No newline at end of file
diff --git a/src/lsa/adj-lsa.hpp b/src/lsa/adj-lsa.hpp
new file mode 100644
index 0000000..12e9346
--- /dev/null
+++ b/src/lsa/adj-lsa.hpp
@@ -0,0 +1,123 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  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/>.
+ **/
+
+#ifndef NLSR_LSA_ADJ_LSA_HPP
+#define NLSR_LSA_ADJ_LSA_HPP
+
+#include "lsa.hpp"
+#include "test-access-control.hpp"
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for AdjLsa
+   AdjacencyLsa := ADJACENCY-LSA-TYPE TLV-LENGTH
+                     Lsa
+                     Adjacency*
+
+ */
+class AdjLsa : public Lsa
+{
+public:
+  typedef AdjacencyList::const_iterator const_iterator;
+
+  AdjLsa() = default;
+
+  AdjLsa(const ndn::Name& originR, uint32_t seqNo,
+         const ndn::time::system_clock::TimePoint& timepoint,
+         uint32_t noLink, AdjacencyList& adl);
+
+  AdjLsa(const ndn::Block& block);
+
+  Lsa::Type
+  getType() const override
+  {
+    return Lsa::Type::ADJACENCY;
+  }
+
+  const AdjacencyList&
+  getAdl() const
+  {
+    return m_adl;
+  }
+
+  void
+  resetAdl()
+  {
+    m_wire.reset();
+    m_adl.reset();
+  }
+
+  void
+  addAdjacent(Adjacent adj)
+  {
+    m_wire.reset();
+    m_adl.insert(adj);
+  }
+
+  uint32_t
+  getNoLink()
+  {
+    return m_noLink;
+  }
+
+  bool
+  isEqualContent(const AdjLsa& alsa) const;
+
+  const_iterator
+  begin() const
+  {
+    return m_adl.begin();
+  }
+
+  const_iterator
+  end() const
+  {
+    return m_adl.end();
+  }
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  const ndn::Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+private:
+  uint32_t m_noLink;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  AdjacencyList m_adl;
+
+  mutable ndn::Block m_wire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(AdjLsa);
+
+std::ostream&
+operator<<(std::ostream& os, const AdjLsa& lsa);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_ADJ_LSA_HPP
diff --git a/src/tlv/coordinate-lsa.cpp b/src/lsa/coordinate-lsa.cpp
similarity index 61%
rename from src/tlv/coordinate-lsa.cpp
rename to src/lsa/coordinate-lsa.cpp
index f05b682..a73ab76 100644
--- a/src/tlv/coordinate-lsa.cpp
+++ b/src/lsa/coordinate-lsa.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2019,  The University of Memphis,
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -17,24 +17,21 @@
  *
  * 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 "coordinate-lsa.hpp"
-#include "tlv-nlsr.hpp"
+#include "tlv/tlv-nlsr.hpp"
 
-#include <ndn-cxx/util/concepts.hpp>
-#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
 
 namespace nlsr {
-namespace tlv {
 
-BOOST_CONCEPT_ASSERT((ndn::WireEncodable<CoordinateLsa>));
-BOOST_CONCEPT_ASSERT((ndn::WireDecodable<CoordinateLsa>));
-static_assert(std::is_base_of<ndn::tlv::Error, CoordinateLsa::Error>::value,
-              "CoordinateLsa::Error must inherit from tlv::Error");
-
-CoordinateLsa::CoordinateLsa()
-  : m_hyperbolicRadius(0.0)
+CoordinateLsa::CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+                             const ndn::time::system_clock::TimePoint& timepoint,
+                             double radius, std::vector<double> angles)
+  : Lsa(originRouter, seqNo, timepoint)
+  , m_hyperbolicRadius(radius)
+  , m_hyperbolicAngles(angles)
 {
 }
 
@@ -43,19 +40,38 @@
   wireDecode(block);
 }
 
+bool
+CoordinateLsa::isEqualContent(const CoordinateLsa& clsa) const
+{
+  if (clsa.getCorTheta().size() != m_hyperbolicAngles.size()) {
+    return false;
+  }
+
+  std::vector<double> m_angles2 = clsa.getCorTheta();
+  for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
+    if (std::abs(m_hyperbolicAngles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
+      return false;
+    }
+  }
+
+  return (std::abs(m_hyperbolicRadius - clsa.getCorRadius()) <
+          std::numeric_limits<double>::epsilon());
+}
+
 template<ndn::encoding::Tag TAG>
 size_t
 CoordinateLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
 {
   size_t totalLength = 0;
 
-  for (auto it = m_hyperbolicAngle.rbegin(); it != m_hyperbolicAngle.rend(); ++it) {
+  for (auto it = m_hyperbolicAngles.rbegin(); it != m_hyperbolicAngles.rend(); ++it) {
     totalLength += ndn::encoding::prependDoubleBlock(block, ndn::tlv::nlsr::HyperbolicAngle, *it);
   }
 
-  totalLength += ndn::encoding::prependDoubleBlock(block, ndn::tlv::nlsr::HyperbolicRadius, m_hyperbolicRadius);
+  totalLength += ndn::encoding::prependDoubleBlock(block, ndn::tlv::nlsr::HyperbolicRadius,
+                                                   m_hyperbolicRadius);
 
-  totalLength += m_lsaInfo.wireEncode(block);
+  totalLength += Lsa::wireEncode(block);
 
   totalLength += block.prependVarNumber(totalLength);
   totalLength += block.prependVarNumber(ndn::tlv::nlsr::CoordinateLsa);
@@ -68,7 +84,7 @@
 const ndn::Block&
 CoordinateLsa::wireEncode() const
 {
-  if (m_wire.hasWire()) {
+  if (m_wire.hasWire() && m_baseWire.hasWire()) {
     return m_wire;
   }
 
@@ -86,9 +102,6 @@
 void
 CoordinateLsa::wireDecode(const ndn::Block& wire)
 {
-  m_hyperbolicRadius = 0.0;
-  m_hyperbolicAngle.clear();
-
   m_wire = wire;
 
   if (m_wire.type() != ndn::tlv::nlsr::CoordinateLsa) {
@@ -102,12 +115,12 @@
 
   ndn::Block::element_const_iterator val = m_wire.elements_begin();
 
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::LsaInfo) {
-    m_lsaInfo.wireDecode(*val);
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
+    Lsa::wireDecode(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Missing required LsaInfo field"));
+    BOOST_THROW_EXCEPTION(Error("Missing required Lsa field"));
   }
 
   if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::HyperbolicRadius) {
@@ -118,35 +131,29 @@
     BOOST_THROW_EXCEPTION(Error("Missing required HyperbolicRadius field"));
   }
 
+  std::vector<double> angles;
   for (; val != m_wire.elements_end(); ++val) {
     if (val->type() == ndn::tlv::nlsr::HyperbolicAngle) {
-      m_hyperbolicAngle.push_back(ndn::encoding::readDouble(*val));
+      angles.push_back(ndn::encoding::readDouble(*val));
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Missing required HyperbolicAngle field"));
     }
   }
+  m_hyperbolicAngles = angles;
 }
 
 std::ostream&
-operator<<(std::ostream& os, const CoordinateLsa& coordinateLsa)
+operator<<(std::ostream& os, const CoordinateLsa& lsa)
 {
-  os << "CoordinateLsa("
-     << coordinateLsa.getLsaInfo() << ", "
-     << "HyperbolicRadius: " << coordinateLsa.getHyperbolicRadius() << ", ";
-
-  os << "HyperbolicAngles: ";
+  os << lsa.toString();
+  os << "      Hyperbolic Radius  : " << lsa.getCorRadius() << "\n";
   int i = 0;
-  for (const auto& value: coordinateLsa.getHyperbolicAngle()) {
-    if (i == 0) {
-      os << value;
-    }
-    else {
-      os << ", " << value;
-    }
-    ++i;
+  for (const auto& value : lsa.getCorTheta()) {
+    os << "      Hyperbolic Theta " << i++ << " : " << value << "\n";
   }
-  os << ")";
 
   return os;
 }
 
-} // namespace tlv
-} // namespace nlsr
+} // namespace nlsr
\ No newline at end of file
diff --git a/src/lsa/coordinate-lsa.hpp b/src/lsa/coordinate-lsa.hpp
new file mode 100644
index 0000000..abeea2c
--- /dev/null
+++ b/src/lsa/coordinate-lsa.hpp
@@ -0,0 +1,106 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  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/>.
+ **/
+
+#ifndef NLSR_LSA_COORDINATE_LSA_HPP
+#define NLSR_LSA_COORDINATE_LSA_HPP
+
+#include "lsa.hpp"
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for CoordinateLsa
+   CoordinateLsa := COORDINATE-LSA-TYPE TLV-LENGTH
+                      Lsa
+                      HyperbolicRadius
+                      HyperbolicAngle+
+ */
+class CoordinateLsa : public Lsa
+{
+public:
+  CoordinateLsa() = default;
+
+  CoordinateLsa(const ndn::Name& originRouter, uint32_t seqNo,
+                const ndn::time::system_clock::TimePoint& timepoint,
+                double radius, std::vector<double> angles);
+
+  CoordinateLsa(const ndn::Block& block);
+
+  Lsa::Type
+  getType() const override
+  {
+    return Lsa::Type::COORDINATE;
+  }
+
+  double
+  getCorRadius() const
+  {
+    return m_hyperbolicRadius;
+  }
+
+  void
+  setCorRadius(double cr)
+  {
+    m_wire.reset();
+    m_hyperbolicRadius = cr;
+  }
+
+  const std::vector<double>
+  getCorTheta() const
+  {
+    return m_hyperbolicAngles;
+  }
+
+  void
+  setCorTheta(std::vector<double> ct)
+  {
+    m_wire.reset();
+    m_hyperbolicAngles = ct;
+  }
+
+  bool
+  isEqualContent(const CoordinateLsa& clsa) const;
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  const ndn::Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+private:
+  double m_hyperbolicRadius = 0.0;
+  std::vector<double> m_hyperbolicAngles;
+
+  mutable ndn::Block m_wire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
+
+std::ostream&
+operator<<(std::ostream& os, const CoordinateLsa& lsa);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_COORDINATE_LSA_HPP
diff --git a/src/lsa/lsa.cpp b/src/lsa/lsa.cpp
new file mode 100644
index 0000000..c0d6435
--- /dev/null
+++ b/src/lsa/lsa.cpp
@@ -0,0 +1,167 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  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.hpp"
+#include "nlsr.hpp"
+#include "name-prefix-list.hpp"
+#include "adjacent.hpp"
+#include "tlv/tlv-nlsr.hpp"
+
+namespace nlsr {
+
+Lsa::Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+         ndn::time::system_clock::TimePoint expirationTimePoint)
+  : m_originRouter(originRouter)
+  , m_seqNo(seqNo)
+  , m_expirationTimePoint(expirationTimePoint)
+{
+}
+
+ndn::Name
+Lsa::getKey() const
+{
+  return ndn::Name(m_originRouter).append(boost::lexical_cast<std::string>((getType())));
+}
+
+template<ndn::encoding::Tag TAG>
+size_t
+Lsa::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
+{
+  size_t totalLength = 0;
+
+  totalLength += prependStringBlock(encoder,
+                                    ndn::tlv::nlsr::ExpirationTime,
+                                    ndn::time::toString(m_expirationTimePoint));
+
+  totalLength += prependNonNegativeIntegerBlock(encoder, ndn::tlv::nlsr::SequenceNumber,
+                                                m_seqNo);
+
+  totalLength += m_originRouter.wireEncode(encoder);
+
+  totalLength += encoder.prependVarNumber(totalLength);
+  totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Lsa);
+
+  return totalLength;
+}
+
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
+
+void
+Lsa::wireDecode(const ndn::Block& wire)
+{
+  m_originRouter.clear();
+  m_seqNo = 0;
+
+  m_baseWire = wire;
+
+  if (m_baseWire.type() != ndn::tlv::nlsr::Lsa) {
+    std::stringstream error;
+    error << "Expected Lsa Block, but Block is of a different type: #"
+          << m_baseWire.type();
+    BOOST_THROW_EXCEPTION(Error(error.str()));
+  }
+
+  m_baseWire.parse();
+
+  ndn::Block::element_const_iterator val = m_baseWire.elements_begin();
+
+  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::Name) {
+    m_originRouter.wireDecode(*val);
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("OriginRouter: Missing required Name field"));
+  }
+
+  ++val;
+
+  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
+    m_seqNo = ndn::readNonNegativeInteger(*val);
+    ++val;
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required SequenceNumber field"));
+  }
+
+  if (val != m_baseWire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationTime) {
+    m_expirationTimePoint = ndn::time::fromString(readString(*val));
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Missing required ExpirationTimePoint field"));
+  }
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Lsa::Type& type)
+{
+  switch (type) {
+  case nlsr::Lsa::Type::ADJACENCY:
+    os << "ADJACENCY";
+    break;
+
+  case nlsr::Lsa::Type::COORDINATE:
+    os << "COORDINATE";
+    break;
+
+  case nlsr::Lsa::Type::NAME:
+    os << "NAME";
+    break;
+
+  default:
+    os << "BASE";
+    break;
+  }
+  return os;
+}
+
+std::istream&
+operator>>(std::istream& is, Lsa::Type& type)
+{
+  std::string typeString;
+  is >> typeString;
+  if (typeString == "ADJACENCY") {
+    type = Lsa::Type::ADJACENCY;
+  }
+  else if (typeString == "COORDINATE") {
+    type = Lsa::Type::COORDINATE;
+  }
+  else if (typeString == "NAME") {
+    type = Lsa::Type::NAME;
+  }
+  else {
+    type = Lsa::Type::BASE;
+  }
+  return is;
+}
+
+std::string
+Lsa::toString() const
+{
+  std::ostringstream os;
+  auto duration = getExpirationTimePoint() - ndn::time::system_clock::now();
+  os << "    " << getType() << " LSA:\n"
+     << "      Origin Router      : " << getOriginRouter() << "\n"
+     << "      Sequence Number    : " << getSeqNo() << "\n"
+     << "      Expires in         : " << ndn::time::duration_cast<ndn::time::milliseconds>(duration)
+     << "\n";
+  return os.str();
+}
+
+} // namespace nlsr
diff --git a/src/lsa/lsa.hpp b/src/lsa/lsa.hpp
new file mode 100644
index 0000000..1bd4382
--- /dev/null
+++ b/src/lsa/lsa.hpp
@@ -0,0 +1,160 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2020,  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/>.
+ */
+
+#ifndef NLSR_LSA_LSA_HPP
+#define NLSR_LSA_LSA_HPP
+
+#include "name-prefix-list.hpp"
+#include "adjacent.hpp"
+#include "adjacency-list.hpp"
+#include "test-access-control.hpp"
+
+#include <ndn-cxx/util/scheduler.hpp>
+#include <ndn-cxx/util/time.hpp>
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for Lsa
+   Lsa := LSA-TYPE TLV-LENGTH
+            Name
+            SequenceNumber
+            ExpirationTimePoint
+ */
+class Lsa
+{
+public:
+  class Error : public ndn::tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : ndn::tlv::Error(what)
+    {
+    }
+  };
+
+  enum class Type {
+    ADJACENCY,
+    COORDINATE,
+    NAME,
+    BASE
+  };
+
+protected:
+  Lsa(const ndn::Name& originRouter, uint32_t seqNo,
+      ndn::time::system_clock::TimePoint expirationTimePoint);
+
+  Lsa() = default;
+
+public:
+  virtual
+  ~Lsa() = default;
+
+  virtual Type
+  getType() const
+  {
+    return Type::BASE;
+  }
+
+  void
+  setSeqNo(uint64_t seqNo)
+  {
+    m_seqNo = seqNo;
+    m_baseWire.reset();
+  }
+
+  uint64_t
+  getSeqNo() const
+  {
+    return m_seqNo;
+  }
+
+  const ndn::Name&
+  getOriginRouter() const
+  {
+    return m_originRouter;
+  }
+
+  const ndn::time::system_clock::TimePoint&
+  getExpirationTimePoint() const
+  {
+    return m_expirationTimePoint;
+  }
+
+  void
+  setExpirationTimePoint(const ndn::time::system_clock::TimePoint& lt)
+  {
+    m_expirationTimePoint = lt;
+    m_baseWire.reset();
+  }
+
+  void
+  setExpiringEventId(ndn::scheduler::EventId eid)
+  {
+    m_expiringEventId = std::move(eid);
+  }
+
+  ndn::scheduler::EventId
+  getExpiringEventId() const
+  {
+    return m_expiringEventId;
+  }
+
+  /*! \brief Gets the key for this LSA.
+
+    Format is: \<router name\>/\<LSA type>\
+   */
+  ndn::Name
+  getKey() const;
+
+  /*! Get data common to all LSA types.
+   */
+  std::string
+  toString() const;
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+PUBLIC_WITH_TESTS_ELSE_PROTECTED:
+  ndn::Name m_originRouter;
+  uint64_t m_seqNo = 0;
+  ndn::time::system_clock::TimePoint m_expirationTimePoint;
+  ndn::scheduler::EventId m_expiringEventId;
+
+  mutable ndn::Block m_baseWire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Lsa);
+
+std::ostream&
+operator<<(std::ostream& os, const Lsa::Type& type);
+
+std::istream&
+operator>>(std::istream& is, Lsa::Type& type);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_LSA_HPP
diff --git a/src/tlv/name-lsa.cpp b/src/lsa/name-lsa.cpp
similarity index 70%
rename from src/tlv/name-lsa.cpp
rename to src/lsa/name-lsa.cpp
index 82f3860..37b7408 100644
--- a/src/tlv/name-lsa.cpp
+++ b/src/lsa/name-lsa.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2014-2018,  The University of Memphis,
+/**
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -17,25 +17,21 @@
  *
  * 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 "name-lsa.hpp"
-#include "tlv-nlsr.hpp"
-
-#include <ndn-cxx/util/concepts.hpp>
-#include <ndn-cxx/encoding/block-helpers.hpp>
+#include "tlv/tlv-nlsr.hpp"
 
 namespace nlsr {
-namespace tlv {
 
-BOOST_CONCEPT_ASSERT((ndn::WireEncodable<NameLsa>));
-BOOST_CONCEPT_ASSERT((ndn::WireDecodable<NameLsa>));
-static_assert(std::is_base_of<ndn::tlv::Error, NameLsa::Error>::value,
-              "NameLsa::Error must inherit from tlv::Error");
-
-NameLsa::NameLsa()
-  : m_hasNames(false)
+NameLsa::NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+                 const ndn::time::system_clock::TimePoint& timepoint,
+                 NamePrefixList& npl)
+  : Lsa(originRouter, seqNo, timepoint)
 {
+  for (const auto& name : npl.getNames()) {
+    addName(name);
+  }
 }
 
 NameLsa::NameLsa(const ndn::Block& block)
@@ -49,12 +45,13 @@
 {
   size_t totalLength = 0;
 
-  for (std::list<ndn::Name>::const_reverse_iterator it = m_names.rbegin();
-       it != m_names.rend(); ++it) {
+  auto names = m_npl.getNames();
+
+  for (auto it = names.rbegin();  it != names.rend(); ++it) {
     totalLength += it->wireEncode(block);
   }
 
-  totalLength += m_lsaInfo.wireEncode(block);
+  totalLength += Lsa::wireEncode(block);
 
   totalLength += block.prependVarNumber(totalLength);
   totalLength += block.prependVarNumber(ndn::tlv::nlsr::NameLsa);
@@ -67,7 +64,7 @@
 const ndn::Block&
 NameLsa::wireEncode() const
 {
-  if (m_wire.hasWire()) {
+  if (m_wire.hasWire() && m_baseWire.hasWire()) {
     return m_wire;
   }
 
@@ -85,9 +82,6 @@
 void
 NameLsa::wireDecode(const ndn::Block& wire)
 {
-  m_hasNames = false;
-  m_names.clear();
-
   m_wire = wire;
 
   if (m_wire.type() != ndn::tlv::nlsr::NameLsa) {
@@ -99,40 +93,46 @@
 
   ndn::Block::element_const_iterator val = m_wire.elements_begin();
 
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::LsaInfo) {
-    m_lsaInfo.wireDecode(*val);
+  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Lsa) {
+    Lsa::wireDecode(*val);
     ++val;
   }
   else {
-    BOOST_THROW_EXCEPTION(Error("Missing required LsaInfo field"));
+    BOOST_THROW_EXCEPTION(Error("Missing required Lsa field"));
   }
 
+  NamePrefixList npl;
   for (; val != m_wire.elements_end(); ++val) {
     if (val->type() == ndn::tlv::Name) {
-      m_names.push_back(ndn::Name(*val));
-      m_hasNames = true;
+      npl.insert(ndn::Name(*val));
     }
     else {
       BOOST_THROW_EXCEPTION(Error("Expected Name Block, but Block is of a different type: #" +
                                   ndn::to_string(m_wire.type())));
     }
   }
+
+  m_npl = npl;
+}
+
+bool
+NameLsa::isEqualContent(const NameLsa& other) const
+{
+  return m_npl == other.getNpl();
 }
 
 std::ostream&
-operator<<(std::ostream& os, const NameLsa& nameLsa)
+operator<<(std::ostream& os, const NameLsa& lsa)
 {
-  os << "NameLsa("
-     << nameLsa.getLsaInfo();
-
-  for (const auto& name : nameLsa) {
-    os << ", Name: " << name;
+  os << lsa.toString();
+  os << "      Names:\n";
+  int i = 0;
+  auto names = lsa.getNpl().getNames();
+  for (const auto& name : names) {
+    os << "        Name " << i++ << ": " << name << "\n";
   }
 
-  os << ")";
-
   return os;
 }
 
-} // namespace tlv
 } // namespace nlsr
diff --git a/src/lsa/name-lsa.hpp b/src/lsa/name-lsa.hpp
new file mode 100644
index 0000000..3223839
--- /dev/null
+++ b/src/lsa/name-lsa.hpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2020,  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/>.
+ **/
+
+#ifndef NLSR_LSA_NAME_LSA_HPP
+#define NLSR_LSA_NAME_LSA_HPP
+
+#include "lsa.hpp"
+
+namespace nlsr {
+
+/*!
+   \brief Data abstraction for NameLsa
+   NameLsa := NAME-LSA-TYPE TLV-LENGTH
+                Lsa
+                Name+
+ */
+class NameLsa : public Lsa
+{
+public:
+  NameLsa() = default;
+
+  NameLsa(const ndn::Name& originRouter, uint32_t seqNo,
+          const ndn::time::system_clock::TimePoint& timepoint,
+          NamePrefixList& npl);
+
+  NameLsa(const ndn::Block& block);
+
+  Lsa::Type
+  getType() const override
+  {
+    return Lsa::Type::NAME;
+  }
+
+  NamePrefixList&
+  getNpl()
+  {
+    return m_npl;
+  }
+
+  const NamePrefixList&
+  getNpl() const
+  {
+    return m_npl;
+  }
+
+  void
+  addName(const ndn::Name& name)
+  {
+    m_wire.reset();
+    m_npl.insert(name);
+  }
+
+  void
+  removeName(const ndn::Name& name)
+  {
+    m_wire.reset();
+    m_npl.remove(name);
+  }
+
+  bool
+  isEqualContent(const NameLsa& other) const;
+
+  template<ndn::encoding::Tag TAG>
+  size_t
+  wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+  const ndn::Block&
+  wireEncode() const;
+
+  void
+  wireDecode(const ndn::Block& wire);
+
+private:
+  NamePrefixList m_npl;
+  mutable ndn::Block m_wire;
+};
+
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
+
+std::ostream&
+operator<<(std::ostream& os, const NameLsa& lsa);
+
+} // namespace nlsr
+
+#endif // NLSR_LSA_NAME_LSA_HPP
diff --git a/src/lsdb.cpp b/src/lsdb.cpp
index fe0464e..e3fe9d3 100644
--- a/src/lsdb.cpp
+++ b/src/lsdb.cpp
@@ -106,16 +106,7 @@
 void
 Lsdb::afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName)
 {
-  auto data = std::make_shared<ndn::Data>(ndn::Name(interestName));
-  try {
-    data->setContent(ndn::Block(bufferPtr));
-  }
-  catch (const std::exception& e) {
-    NDN_LOG_ERROR("LSA content not recognized: " << e.what());
-    return;
-  }
-
-  NLSR_LOG_DEBUG("Received data for LSA(name): " << data->getName());
+  NLSR_LOG_DEBUG("Received data for LSA interest: " << interestName);
 
   ndn::Name lsaName = interestName.getSubName(0, interestName.size()-1);
   uint64_t seqNo = interestName[-1].toNumber();
@@ -125,13 +116,52 @@
   }
   else if (seqNo > m_highestSeqNo[lsaName]) {
     m_highestSeqNo[lsaName] = seqNo;
-    NLSR_LOG_TRACE("SeqNo for LSA(name): " << data->getName() << "  updated");
+    NLSR_LOG_TRACE("SeqNo for LSA(name): " << interestName << "  updated");
   }
   else if (seqNo < m_highestSeqNo[lsaName]) {
     return;
   }
 
-  onContentValidated(data);
+  std::string chkString("LSA");
+  int32_t lsaPosition = util::getNameComponentPosition(interestName, chkString);
+
+  if (lsaPosition >= 0) {
+    // Extracts the prefix of the originating router from the data.
+    ndn::Name originRouter = m_confParam.getNetwork();
+    originRouter.append(interestName.getSubName(lsaPosition + 1,
+                                                interestName.size() - lsaPosition - 3));
+
+    try {
+      ndn::Block block(bufferPtr);
+      Lsa::Type interestedLsType;
+      std::istringstream(interestName[-2].toUri()) >> interestedLsType;
+
+      if (interestedLsType == Lsa::Type::NAME) {
+        processContentNameLsa(originRouter.append(boost::lexical_cast<std::string>(interestedLsType)),
+                              seqNo,
+                              block);
+      }
+      else if (interestedLsType == Lsa::Type::ADJACENCY) {
+        processContentAdjacencyLsa(originRouter.append(boost::lexical_cast<std::string>(interestedLsType)),
+                                   seqNo,
+                                   block);
+      }
+      else if (interestedLsType == Lsa::Type::COORDINATE) {
+        processContentCoordinateLsa(originRouter.append(boost::lexical_cast<std::string>(interestedLsType)),
+                                    seqNo,
+                                    block);
+      }
+      else {
+        NLSR_LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
+      }
+    }
+    catch (const std::exception& e) {
+      NLSR_LOG_TRACE("LSA data decoding error :( " << e.what());
+      return;
+    }
+
+    lsaIncrementSignal(Statistics::PacketType::RCV_LSA_DATA);
+  }
 }
 
   /*! \brief Compares if a name LSA is the same as the one specified by key
@@ -178,7 +208,7 @@
   // Is the name in the LSDB
   if (nameLsaCheck != nullptr) {
     // And the supplied seq no is the highest so far
-    if (nameLsaCheck->getLsSeqNo() < seqNo) {
+    if (nameLsaCheck->getSeqNo() < seqNo) {
       return true;
     }
     else {
@@ -207,19 +237,19 @@
     addNameLsa(nlsa);
     NLSR_LOG_DEBUG("New Name LSA");
     NLSR_LOG_DEBUG("Adding Name Lsa");
-    nlsa.writeLog();
+    NLSR_LOG_DEBUG(nlsa);
 
-    NLSR_LOG_TRACE("nlsa.getOrigRouter(): " << nlsa.getOrigRouter());
+    NLSR_LOG_TRACE("nlsa.getOriginRouter(): " << nlsa.getOriginRouter());
     NLSR_LOG_TRACE("m_confParam.getRouterPrefix(): " << m_confParam.getRouterPrefix());
 
-    if (nlsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+    if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
       // If this name LSA is from another router, add the advertised
       // prefixes to the NPT.
-      m_namePrefixTable.addEntry(nlsa.getOrigRouter(), nlsa.getOrigRouter());
+      m_namePrefixTable.addEntry(nlsa.getOriginRouter(), nlsa.getOriginRouter());
 
       for (const auto& name : nlsa.getNpl().getNames()) {
         if (name != m_confParam.getRouterPrefix()) {
-          m_namePrefixTable.addEntry(name, nlsa.getOrigRouter());
+          m_namePrefixTable.addEntry(name, nlsa.getOriginRouter());
         }
       }
       auto duration = nlsa.getExpirationTimePoint() - ndn::time::system_clock::now();
@@ -227,19 +257,19 @@
     }
 
     nlsa.setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
-                                                      nlsa.getLsSeqNo(),
+                                                      nlsa.getSeqNo(),
                                                       timeToExpire));
   }
   // Else this is a known name LSA, so we are updating it.
   else {
     NLSR_LOG_TRACE("Known name lsa");
-    NLSR_LOG_TRACE("chkNameLsa->getLsSeqNo(): " << chkNameLsa->getLsSeqNo());
-    NLSR_LOG_TRACE("nlsa.getLsSeqNo(): " << nlsa.getLsSeqNo());
-    if (chkNameLsa->getLsSeqNo() < nlsa.getLsSeqNo()) {
+    NLSR_LOG_TRACE("chkNameLsa->getSeqNo(): " << chkNameLsa->getSeqNo());
+    NLSR_LOG_TRACE("nlsa.getSeqNo(): " << nlsa.getSeqNo());
+    if (chkNameLsa->getSeqNo() < nlsa.getSeqNo()) {
       NLSR_LOG_DEBUG("Updated Name LSA. Updating LSDB");
       NLSR_LOG_DEBUG("Deleting Name Lsa");
-      chkNameLsa->writeLog();
-      chkNameLsa->setLsSeqNo(nlsa.getLsSeqNo());
+      NLSR_LOG_DEBUG(chkNameLsa);
+      chkNameLsa->setSeqNo(nlsa.getSeqNo());
       chkNameLsa->setExpirationTimePoint(nlsa.getExpirationTimePoint());
       chkNameLsa->getNpl().sort();
       nlsa.getNpl().sort();
@@ -252,9 +282,9 @@
                           std::inserter(namesToAdd, namesToAdd.begin()));
       for (const auto& name : namesToAdd) {
         chkNameLsa->addName(name);
-        if (nlsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+        if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
           if (name != m_confParam.getRouterPrefix()) {
-            m_namePrefixTable.addEntry(name, nlsa.getOrigRouter());
+            m_namePrefixTable.addEntry(name, nlsa.getOriginRouter());
           }
         }
       }
@@ -268,23 +298,23 @@
       for (const auto& name : namesToRemove) {
         NLSR_LOG_DEBUG("Removing name LSA no longer advertised: " << name);
         chkNameLsa->removeName(name);
-        if (nlsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+        if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
           if (name != m_confParam.getRouterPrefix()) {
-            m_namePrefixTable.removeEntry(name, nlsa.getOrigRouter());
+            m_namePrefixTable.removeEntry(name, nlsa.getOriginRouter());
           }
         }
       }
 
-      if (nlsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+      if (nlsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
         auto duration = nlsa.getExpirationTimePoint() - ndn::time::system_clock::now();
         timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
       }
       chkNameLsa->getExpiringEventId().cancel();
       chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(nlsa.getKey(),
-                                                               nlsa.getLsSeqNo(),
+                                                               nlsa.getSeqNo(),
                                                                timeToExpire));
       NLSR_LOG_DEBUG("Adding Name Lsa");
-      chkNameLsa->writeLog();
+      NLSR_LOG_DEBUG(chkNameLsa);
     }
   }
   return true;
@@ -309,15 +339,15 @@
                          std::bind(nameLsaCompareByKey, _1, key));
   if (it != m_nameLsdb.end()) {
     NLSR_LOG_DEBUG("Deleting Name Lsa");
-    it->writeLog();
+    NLSR_LOG_DEBUG(*it);
     // If the requested name LSA is not ours, we also need to remove
     // its entries from the NPT.
-    if (it->getOrigRouter() != m_confParam.getRouterPrefix()) {
-      m_namePrefixTable.removeEntry(it->getOrigRouter(), it->getOrigRouter());
+    if (it->getOriginRouter() != m_confParam.getRouterPrefix()) {
+      m_namePrefixTable.removeEntry(it->getOriginRouter(), it->getOriginRouter());
 
       for (const auto& name : it->getNpl().getNames()) {
         if (name != m_confParam.getRouterPrefix()) {
-          m_namePrefixTable.removeEntry(name, it->getOrigRouter());
+          m_namePrefixTable.removeEntry(name, it->getOriginRouter());
         }
       }
     }
@@ -340,7 +370,7 @@
 {
   NLSR_LOG_DEBUG("---------------Name LSDB-------------------");
   for (const auto& nlsa : m_nameLsdb) {
-    nlsa.writeLog();
+    NLSR_LOG_DEBUG(nlsa);
   }
 }
 
@@ -401,7 +431,7 @@
   // Is the coordinate LSA in the LSDB already
   if (clsa != nullptr) {
     // And the seq no is newer (higher) than the current one
-    if (clsa->getLsSeqNo() < seqNo) {
+    if (clsa->getSeqNo() < seqNo) {
       return true;
     }
     else {
@@ -432,33 +462,30 @@
   if (chkCorLsa == nullptr) {
     NLSR_LOG_DEBUG("New Coordinate LSA. Adding to LSDB");
     NLSR_LOG_DEBUG("Adding Coordinate Lsa");
-    clsa.writeLog();
+    NLSR_LOG_DEBUG(clsa);
     addCoordinateLsa(clsa);
 
     // Register the LSA's origin router prefix
-    if (clsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
-      m_namePrefixTable.addEntry(clsa.getOrigRouter(),
-                                           clsa.getOrigRouter());
+    if (clsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
+      m_namePrefixTable.addEntry(clsa.getOriginRouter(), clsa.getOriginRouter());
     }
     if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
       m_routingTable.scheduleRoutingTableCalculation();
     }
     // Set the expiration time for the new LSA.
-    if (clsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
-      ndn::time::system_clock::Duration duration = clsa.getExpirationTimePoint() -
-                                                   ndn::time::system_clock::now();
+    if (clsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
+      auto duration = clsa.getExpirationTimePoint() - ndn::time::system_clock::now();
       timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
     }
-    scheduleCoordinateLsaExpiration(clsa.getKey(),
-                                    clsa.getLsSeqNo(), timeToExpire);
+    scheduleCoordinateLsaExpiration(clsa.getKey(), clsa.getSeqNo(), timeToExpire);
   }
   // We are just updating this LSA.
   else {
-    if (chkCorLsa->getLsSeqNo() < clsa.getLsSeqNo()) {
+    if (chkCorLsa->getSeqNo() < clsa.getSeqNo()) {
       NLSR_LOG_DEBUG("Updated Coordinate LSA. Updating LSDB");
       NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
-      chkCorLsa->writeLog();
-      chkCorLsa->setLsSeqNo(clsa.getLsSeqNo());
+      NLSR_LOG_DEBUG(chkCorLsa);
+      chkCorLsa->setSeqNo(clsa.getSeqNo());
       chkCorLsa->setExpirationTimePoint(clsa.getExpirationTimePoint());
       // If the new LSA contains new routing information, update the LSDB with it.
       if (!chkCorLsa->isEqualContent(clsa)) {
@@ -469,16 +496,16 @@
         }
       }
       // If this is an LSA from another router, refresh its expiration time.
-      if (clsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+      if (clsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
         auto duration = clsa.getExpirationTimePoint() - ndn::time::system_clock::now();
         timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
       }
       chkCorLsa->getExpiringEventId().cancel();
       chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(clsa.getKey(),
-                                                                    clsa.getLsSeqNo(),
+                                                                    clsa.getSeqNo(),
                                                                     timeToExpire));
       NLSR_LOG_DEBUG("Adding Coordinate Lsa");
-      chkCorLsa->writeLog();
+      NLSR_LOG_DEBUG(chkCorLsa);
     }
   }
   return true;
@@ -504,10 +531,10 @@
 
   if (it != m_corLsdb.end()) {
     NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
-    it->writeLog();
+    NLSR_LOG_DEBUG(*it);
 
-    if (it->getOrigRouter() != m_confParam.getRouterPrefix()) {
-      m_namePrefixTable.removeEntry(it->getOrigRouter(), it->getOrigRouter());
+    if (it->getOriginRouter() != m_confParam.getRouterPrefix()) {
+      m_namePrefixTable.removeEntry(it->getOriginRouter(), it->getOriginRouter());
     }
 
     m_corLsdb.erase(it);
@@ -533,7 +560,7 @@
 
   NLSR_LOG_DEBUG("---------------Cor LSDB-------------------");
   for (const auto& corLsa : m_corLsdb) {
-    corLsa.writeLog();
+    NLSR_LOG_DEBUG(corLsa);
   }
 }
 
@@ -601,7 +628,7 @@
         NLSR_LOG_DEBUG("Removing own Adj LSA; no ACTIVE neighbors");
         // Get this router's key
         ndn::Name key = m_confParam.getRouterPrefix();
-        key.append(std::to_string(Lsa::Type::ADJACENCY));
+        key.append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
 
         removeAdjLsa(key);
         // Recompute routing table after removal
@@ -633,10 +660,10 @@
     m_adjLsdb.push_back(alsa);
     // Add any new name prefixes to the NPT
     // Only add NPT entries if this is an adj LSA from another router.
-    if (alsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+    if (alsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
       // Pass the originating router as both the name to register and
       // where it came from.
-      m_namePrefixTable.addEntry(alsa.getOrigRouter(), alsa.getOrigRouter());
+      m_namePrefixTable.addEntry(alsa.getOriginRouter(), alsa.getOriginRouter());
     }
     return true;
   }
@@ -661,7 +688,7 @@
   // If it is in the LSDB
   if (adjLsaCheck != nullptr) {
     // And the supplied seq no is newer (higher) than the current one.
-    if (adjLsaCheck->getLsSeqNo() < seqNo) {
+    if (adjLsaCheck->getSeqNo() < seqNo) {
       return true;
     }
     else {
@@ -688,43 +715,45 @@
   if (chkAdjLsa == nullptr) {
     NLSR_LOG_DEBUG("New Adj LSA. Adding to LSDB");
     NLSR_LOG_DEBUG("Adding Adj Lsa");
-    alsa.writeLog();
+    NLSR_LOG_DEBUG(alsa);
     addAdjLsa(alsa);
 
     m_routingTable.scheduleRoutingTableCalculation();
-    if (alsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+    if (alsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
       ndn::time::system_clock::Duration duration = alsa.getExpirationTimePoint() -
                                                    ndn::time::system_clock::now();
       timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
     }
-    scheduleAdjLsaExpiration(alsa.getKey(), alsa.getLsSeqNo(), timeToExpire);
+    scheduleAdjLsaExpiration(alsa.getKey(), alsa.getSeqNo(), timeToExpire);
   }
   else {
-    if (chkAdjLsa->getLsSeqNo() < alsa.getLsSeqNo()) {
+    if (chkAdjLsa->getSeqNo() < alsa.getSeqNo()) {
       NLSR_LOG_DEBUG("Updated Adj LSA. Updating LSDB");
       NLSR_LOG_DEBUG("Deleting Adj Lsa");
-      chkAdjLsa->writeLog();
-      chkAdjLsa->setLsSeqNo(alsa.getLsSeqNo());
+      NLSR_LOG_DEBUG(chkAdjLsa);
+      chkAdjLsa->setSeqNo(alsa.getSeqNo());
       chkAdjLsa->setExpirationTimePoint(alsa.getExpirationTimePoint());
       // If the new adj LSA has new content, update the contents of
       // the LSDB entry. Additionally, since we've changed the
       // contents of the LSDB, we have to schedule a routing
       // calculation.
       if (!chkAdjLsa->isEqualContent(alsa)) {
-        chkAdjLsa->getAdl().reset();
-        chkAdjLsa->getAdl().addAdjacents(alsa.getAdl());
+        chkAdjLsa->resetAdl();
+        for (const auto& adjacent : alsa.getAdl()) {
+          chkAdjLsa->addAdjacent(adjacent);
+        }
         m_routingTable.scheduleRoutingTableCalculation();
       }
-      if (alsa.getOrigRouter() != m_confParam.getRouterPrefix()) {
+      if (alsa.getOriginRouter() != m_confParam.getRouterPrefix()) {
         auto duration = alsa.getExpirationTimePoint() - ndn::time::system_clock::now();
         timeToExpire = ndn::time::duration_cast<ndn::time::seconds>(duration);
       }
       chkAdjLsa->getExpiringEventId().cancel();
       chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(alsa.getKey(),
-                                                             alsa.getLsSeqNo(),
+                                                             alsa.getSeqNo(),
                                                              timeToExpire));
       NLSR_LOG_DEBUG("Adding Adj Lsa");
-      chkAdjLsa->writeLog();
+      NLSR_LOG_DEBUG(chkAdjLsa);
     }
   }
   return true;
@@ -756,9 +785,9 @@
                          std::bind(adjLsaCompareByKey, _1, key));
   if (it != m_adjLsdb.end()) {
     NLSR_LOG_DEBUG("Deleting Adj Lsa");
-    it->writeLog();
-    if (it->getOrigRouter() != m_confParam.getRouterPrefix()) {
-      m_namePrefixTable.removeEntry(it->getOrigRouter(), it->getOrigRouter());
+    NLSR_LOG_DEBUG(*it);
+    if (it->getOriginRouter() != m_confParam.getRouterPrefix()) {
+      m_namePrefixTable.removeEntry(it->getOriginRouter(), it->getOriginRouter());
     }
     m_adjLsdb.erase(it);
     return true;
@@ -795,21 +824,21 @@
   NameLsa* chkNameLsa = findNameLsa(lsaKey);
   // If this name LSA exists in the LSDB
   if (chkNameLsa != nullptr) {
-    NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkNameLsa->getLsSeqNo());
+    NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkNameLsa->getSeqNo());
     // If its seq no is the one we are expecting.
-    if (chkNameLsa->getLsSeqNo() == seqNo) {
-      if (chkNameLsa->getOrigRouter() == m_thisRouterPrefix) {
+    if (chkNameLsa->getSeqNo() == seqNo) {
+      if (chkNameLsa->getOriginRouter() == m_thisRouterPrefix) {
         NLSR_LOG_DEBUG("Own Name LSA, so refreshing it");
         NLSR_LOG_DEBUG("Deleting Name Lsa");
-        chkNameLsa->writeLog();
-        chkNameLsa->setLsSeqNo(chkNameLsa->getLsSeqNo() + 1);
-        m_sequencingManager.setNameLsaSeq(chkNameLsa->getLsSeqNo());
+        NLSR_LOG_DEBUG(chkNameLsa);
+        chkNameLsa->setSeqNo(chkNameLsa->getSeqNo() + 1);
+        m_sequencingManager.setNameLsaSeq(chkNameLsa->getSeqNo());
         chkNameLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
         NLSR_LOG_DEBUG("Adding Name Lsa");
-        chkNameLsa->writeLog();
+        NLSR_LOG_DEBUG(chkNameLsa);
         // schedule refreshing event again
         chkNameLsa->setExpiringEventId(scheduleNameLsaExpiration(chkNameLsa->getKey(),
-                                                                 chkNameLsa->getLsSeqNo(),
+                                                                 chkNameLsa->getSeqNo(),
                                                                  m_lsaRefreshTime));
         m_sequencingManager.writeSeqNoToFile();
         m_sync.publishRoutingUpdate(Lsa::Type::NAME, m_sequencingManager.getNameLsaSeq());
@@ -838,22 +867,22 @@
   AdjLsa* chkAdjLsa = findAdjLsa(lsaKey);
   // If this is a valid LSA
   if (chkAdjLsa != nullptr) {
-    NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkAdjLsa->getLsSeqNo());
+    NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkAdjLsa->getSeqNo());
     // And if it hasn't been updated for some other reason
-    if (chkAdjLsa->getLsSeqNo() == seqNo) {
+    if (chkAdjLsa->getSeqNo() == seqNo) {
       // If it is our own LSA
-      if (chkAdjLsa->getOrigRouter() == m_thisRouterPrefix) {
+      if (chkAdjLsa->getOriginRouter() == m_thisRouterPrefix) {
         NLSR_LOG_DEBUG("Own Adj LSA, so refreshing it");
         NLSR_LOG_DEBUG("Deleting Adj Lsa");
-        chkAdjLsa->writeLog();
-        chkAdjLsa->setLsSeqNo(chkAdjLsa->getLsSeqNo() + 1);
-        m_sequencingManager.setAdjLsaSeq(chkAdjLsa->getLsSeqNo());
+        NLSR_LOG_DEBUG(chkAdjLsa);
+        chkAdjLsa->setSeqNo(chkAdjLsa->getSeqNo() + 1);
+        m_sequencingManager.setAdjLsaSeq(chkAdjLsa->getSeqNo());
         chkAdjLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
         NLSR_LOG_DEBUG("Adding Adj Lsa");
-        chkAdjLsa->writeLog();
+        NLSR_LOG_DEBUG(chkAdjLsa);
         // schedule refreshing event again
         chkAdjLsa->setExpiringEventId(scheduleAdjLsaExpiration(chkAdjLsa->getKey(),
-                                                               chkAdjLsa->getLsSeqNo(),
+                                                               chkAdjLsa->getSeqNo(),
                                                                m_lsaRefreshTime));
         m_sequencingManager.writeSeqNoToFile();
         m_sync.publishRoutingUpdate(Lsa::Type::ADJACENCY, m_sequencingManager.getAdjLsaSeq());
@@ -886,25 +915,25 @@
   CoordinateLsa* chkCorLsa = findCoordinateLsa(lsaKey);
   // Whether the LSA is in the LSDB or not.
   if (chkCorLsa != nullptr) {
-    NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkCorLsa->getLsSeqNo());
+    NLSR_LOG_DEBUG("LSA Exists with seq no: " << chkCorLsa->getSeqNo());
     // Whether the LSA has been updated without our knowledge.
-    if (chkCorLsa->getLsSeqNo() == seqNo) {
-      if (chkCorLsa->getOrigRouter() == m_thisRouterPrefix) {
+    if (chkCorLsa->getSeqNo() == seqNo) {
+      if (chkCorLsa->getOriginRouter() == m_thisRouterPrefix) {
         NLSR_LOG_DEBUG("Own Cor LSA, so refreshing it");
         NLSR_LOG_DEBUG("Deleting Coordinate Lsa");
-        chkCorLsa->writeLog();
-        chkCorLsa->setLsSeqNo(chkCorLsa->getLsSeqNo() + 1);
+        NLSR_LOG_DEBUG(chkCorLsa);
+        chkCorLsa->setSeqNo(chkCorLsa->getSeqNo() + 1);
         if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
-          m_sequencingManager.setCorLsaSeq(chkCorLsa->getLsSeqNo());
+          m_sequencingManager.setCorLsaSeq(chkCorLsa->getSeqNo());
         }
 
         chkCorLsa->setExpirationTimePoint(getLsaExpirationTimePoint());
         NLSR_LOG_DEBUG("Adding Coordinate Lsa");
-        chkCorLsa->writeLog();
+        NLSR_LOG_DEBUG(chkCorLsa);
         // schedule refreshing event again
         chkCorLsa->setExpiringEventId(scheduleCoordinateLsaExpiration(
                                         chkCorLsa->getKey(),
-                                        chkCorLsa->getLsSeqNo(),
+                                        chkCorLsa->getSeqNo(),
                                         m_lsaRefreshTime));
         // Only sync coordinate LSAs if link-state routing is disabled
         if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
@@ -1083,10 +1112,9 @@
   NameLsa* nameLsa = findNameLsa(lsaKey);
   if (nameLsa != nullptr) {
     NLSR_LOG_TRACE("Verifying SeqNo for NameLsa is same as requested.");
-    if (nameLsa->getLsSeqNo() == seqNo) {
-      std::string content = nameLsa->serialize();
+    if (nameLsa->getSeqNo() == seqNo) {
       m_segmentPublisher.publish(interest.getName(), interest.getName(),
-                                 ndn::encoding::makeStringBlock(ndn::tlv::Content, content),
+                                 nameLsa->wireEncode(),
                                  m_lsaRefreshTime, m_confParam.getSigningInfo());
 
       lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
@@ -1119,10 +1147,9 @@
   AdjLsa* adjLsa = findAdjLsa(lsaKey);
   if (adjLsa != nullptr) {
     NLSR_LOG_TRACE("Verifying SeqNo for AdjLsa is same as requested.");
-    if (adjLsa->getLsSeqNo() == seqNo) {
-      std::string content = adjLsa->serialize();
+    if (adjLsa->getSeqNo() == seqNo) {
       m_segmentPublisher.publish(interest.getName(), interest.getName(),
-                                 ndn::encoding::makeStringBlock(ndn::tlv::Content, content),
+                                 adjLsa->wireEncode(),
                                  m_lsaRefreshTime, m_confParam.getSigningInfo());
 
       lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
@@ -1155,10 +1182,9 @@
   CoordinateLsa* corLsa = findCoordinateLsa(lsaKey);
   if (corLsa != nullptr) {
     NLSR_LOG_TRACE("Verifying SeqNo for CoordinateLsa is same as requested.");
-    if (corLsa->getLsSeqNo() == seqNo) {
-      std::string content = corLsa->serialize();
+    if (corLsa->getSeqNo() == seqNo) {
       m_segmentPublisher.publish(interest.getName(), interest.getName(),
-                                 ndn::encoding::makeStringBlock(ndn::tlv::Content, content),
+                                 corLsa->wireEncode(),
                                  m_lsaRefreshTime, m_confParam.getSigningInfo());
 
       lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_DATA);
@@ -1173,92 +1199,35 @@
 }
 
 void
-Lsdb::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
-{
-  const ndn::Name& dataName = data->getName();
-  NLSR_LOG_DEBUG("Data validation successful for LSA: " << dataName);
-
-  std::string chkString("LSA");
-  int32_t lsaPosition = util::getNameComponentPosition(dataName, chkString);
-
-  if (lsaPosition >= 0) {
-
-    // Extracts the prefix of the originating router from the data.
-    ndn::Name originRouter = m_confParam.getNetwork();
-    originRouter.append(dataName.getSubName(lsaPosition + 1, dataName.size() - lsaPosition - 3));
-
-    uint64_t seqNo = dataName[-1].toNumber();
-    std::string dataContent(reinterpret_cast<const char*>(data->getContent().value()),
-                            data->getContent().value_size());
-
-    Lsa::Type interestedLsType;
-    std::istringstream(dataName[-2].toUri()) >> interestedLsType;
-
-    if (interestedLsType == Lsa::Type::NAME) {
-      processContentNameLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
-                            dataContent);
-    }
-    else if (interestedLsType == Lsa::Type::ADJACENCY) {
-      processContentAdjacencyLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
-                                 dataContent);
-    }
-    else if (interestedLsType == Lsa::Type::COORDINATE) {
-      processContentCoordinateLsa(originRouter.append(std::to_string(interestedLsType)), seqNo,
-                                  dataContent);
-    }
-    else {
-      NLSR_LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
-    }
-
-    lsaIncrementSignal(Statistics::PacketType::RCV_LSA_DATA);
-  }
-}
-
-void
 Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
-                            uint64_t lsSeqNo, std::string& dataContent)
+                            uint64_t lsSeqNo, const ndn::Block& block)
 {
   lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_DATA);
   if (isNameLsaNew(lsaKey, lsSeqNo)) {
-    NameLsa nameLsa;
-    if (nameLsa.deserialize(dataContent)) {
-      installNameLsa(nameLsa);
-    }
-    else {
-      NLSR_LOG_DEBUG("LSA data decoding error :(");
-    }
+    NameLsa nameLsa(block);
+    installNameLsa(nameLsa);
   }
 }
 
 void
 Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
-                                 uint64_t lsSeqNo, std::string& dataContent)
+                                 uint64_t lsSeqNo, const ndn::Block& block)
 {
   lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_DATA);
   if (isAdjLsaNew(lsaKey, lsSeqNo)) {
-    AdjLsa adjLsa;
-    if (adjLsa.deserialize(dataContent)) {
-      installAdjLsa(adjLsa);
-    }
-    else {
-      NLSR_LOG_DEBUG("LSA data decoding error :(");
-    }
+    AdjLsa adjLsa(block);
+    installAdjLsa(adjLsa);
   }
 }
 
 void
 Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
-                                  uint64_t lsSeqNo, std::string& dataContent)
+                                  uint64_t lsSeqNo, const ndn::Block& block)
 {
   lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_DATA);
   if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
-    CoordinateLsa corLsa;
-    if (corLsa.deserialize(dataContent)) {
-      installCoordinateLsa(corLsa);
-    }
-    else {
-      NLSR_LOG_DEBUG("LSA data decoding error :(");
-    }
+    CoordinateLsa corLsa(block);
+    installCoordinateLsa(corLsa);
   }
 }
 
@@ -1280,7 +1249,7 @@
 
   NLSR_LOG_DEBUG("---------------Adj LSDB-------------------");
   for (const auto& adj : m_adjLsdb) {
-    adj.writeLog();
+    NLSR_LOG_DEBUG(adj);
   }
 }
 
@@ -1291,10 +1260,13 @@
   switch (lsType) {
   case Lsa::Type::ADJACENCY:
     return doesAdjLsaExist(key);
+
   case Lsa::Type::COORDINATE:
     return doesCoordinateLsaExist(key);
+
   case Lsa::Type::NAME:
     return doesNameLsaExist(key);
+
   default:
     return false;
   }
@@ -1304,15 +1276,18 @@
 Lsdb::isLsaNew(const ndn::Name& routerName, const Lsa::Type& lsaType,
                const uint64_t& sequenceNumber) {
   ndn::Name lsaKey = routerName;
-  lsaKey.append(std::to_string(lsaType));
+  lsaKey.append(boost::lexical_cast<std::string>(lsaType));
 
   switch (lsaType) {
   case Lsa::Type::ADJACENCY:
     return isAdjLsaNew(lsaKey, sequenceNumber);
+
   case Lsa::Type::COORDINATE:
     return isCoordinateLsaNew(lsaKey, sequenceNumber);
+
   case Lsa::Type::NAME:
     return isNameLsaNew(lsaKey, sequenceNumber);
+
   default:
     return false;
   }
diff --git a/src/lsdb.hpp b/src/lsdb.hpp
index dee7ce2..bdb1d32 100644
--- a/src/lsdb.hpp
+++ b/src/lsdb.hpp
@@ -23,7 +23,10 @@
 #define NLSR_LSDB_HPP
 
 #include "conf-parameter.hpp"
-#include "lsa.hpp"
+#include "lsa/lsa.hpp"
+#include "lsa/name-lsa.hpp"
+#include "lsa/coordinate-lsa.hpp"
+#include "lsa/adj-lsa.hpp"
 #include "sequencing-manager.hpp"
 #include "test-access-control.hpp"
 #include "communication/sync-logic-handler.hpp"
@@ -312,19 +315,16 @@
                                   uint64_t seqNo);
 
   void
-  onContentValidated(const std::shared_ptr<const ndn::Data>& data);
-
-  void
   processContentNameLsa(const ndn::Name& lsaKey,
-                        uint64_t lsSeqNo, std::string& dataContent);
+                        uint64_t lsSeqNo, const ndn::Block& block);
 
   void
   processContentAdjacencyLsa(const ndn::Name& lsaKey,
-                             uint64_t lsSeqNo, std::string& dataContent);
+                             uint64_t lsSeqNo, const ndn::Block& block);
 
   void
   processContentCoordinateLsa(const ndn::Name& lsaKey,
-                              uint64_t lsSeqNo, std::string& dataContent);
+                              uint64_t lsSeqNo, const ndn::Block& block);
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   /*!
@@ -357,7 +357,7 @@
             /<network>/NLSR/LSA/<site>/%C1.Router/<router>/<lsa-type>/<seqNo>
    */
   void
-  afterFetchLsa(const ndn::ConstBufferPtr& data, const ndn::Name& interestName);
+  afterFetchLsa(const ndn::ConstBufferPtr& bufferPtr, const ndn::Name& interestName);
 
   void
   emitSegmentValidatedSignal(const ndn::Data& data)
diff --git a/src/name-prefix-list.cpp b/src/name-prefix-list.cpp
index 26f54d4..b5822c5 100644
--- a/src/name-prefix-list.cpp
+++ b/src/name-prefix-list.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2018,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -22,9 +22,6 @@
 #include "name-prefix-list.hpp"
 #include "common.hpp"
 
-#include <iostream>
-#include <algorithm>
-
 namespace nlsr {
 
 NamePrefixList::NamePrefixList() = default;
diff --git a/src/name-prefix-list.hpp b/src/name-prefix-list.hpp
index 0912fb3..f5bac1d 100644
--- a/src/name-prefix-list.hpp
+++ b/src/name-prefix-list.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -22,13 +22,14 @@
 #ifndef NLSR_NAME_PREFIX_LIST_HPP
 #define NLSR_NAME_PREFIX_LIST_HPP
 
+#include "test-access-control.hpp"
+
 #include <list>
 #include <string>
-#include <boost/cstdint.hpp>
 #include <ndn-cxx/name.hpp>
 
-
 namespace nlsr {
+
 class NamePrefixList
 {
 public:
@@ -44,6 +45,7 @@
 
   NamePrefixList(const std::initializer_list<NamePrefixList::NamePair>& namesAndSources);
 
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   template<class ContainerType>
   NamePrefixList(const ContainerType& names)
   {
@@ -52,6 +54,7 @@
     }
   }
 
+public:
   ~NamePrefixList();
 
   /*! \brief inserts name into NamePrefixList
@@ -98,6 +101,12 @@
   const std::vector<std::string>
   getSources(const ndn::Name& name) const;
 
+  void
+  clear()
+  {
+    m_names.clear();
+  }
+
 private:
   /*! Obtain an iterator to the entry matching name.
 
diff --git a/src/publisher/dataset-interest-handler.cpp b/src/publisher/dataset-interest-handler.cpp
index f31cdbd..a574622 100644
--- a/src/publisher/dataset-interest-handler.cpp
+++ b/src/publisher/dataset-interest-handler.cpp
@@ -67,25 +67,8 @@
 DatasetInterestHandler::publishAdjStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
                                          ndn::mgmt::StatusDatasetContext& context)
 {
-  NLSR_LOG_DEBUG("Received interest:  " << interest);
-
-  auto lsaRange = std::make_pair<std::list<AdjLsa>::const_iterator,
-                                 std::list<AdjLsa>::const_iterator>(
-    m_lsdb.getAdjLsdb().cbegin(), m_lsdb.getAdjLsdb().cend());
-  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
-    tlv::AdjacencyLsa tlvLsa;
-    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
-    tlvLsa.setLsaInfo(*tlvLsaInfo);
-
-    for (const Adjacent& adj : lsa->getAdl().getAdjList()) {
-      tlv::Adjacency tlvAdj;
-      tlvAdj.setName(adj.getName());
-      tlvAdj.setUri(adj.getFaceUri().toString());
-      tlvAdj.setCost(adj.getLinkCost());
-      tlvLsa.addAdjacency(tlvAdj);
-    }
-    const ndn::Block& wire = tlvLsa.wireEncode();
-    context.append(wire);
+  for (const auto& adjLsa : m_lsdb.getAdjLsdb()) {
+    context.append(adjLsa.wireEncode());
   }
   context.end();
 }
@@ -94,21 +77,8 @@
 DatasetInterestHandler::publishCoordinateStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
                                                 ndn::mgmt::StatusDatasetContext& context)
 {
-  auto lsaRange = std::make_pair<std::list<CoordinateLsa>::const_iterator,
-                                 std::list<CoordinateLsa>::const_iterator>(
-    m_lsdb.getCoordinateLsdb().cbegin(), m_lsdb.getCoordinateLsdb().cend());
-
-  NLSR_LOG_DEBUG("Received interest:  " << interest);
-  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
-    tlv::CoordinateLsa tlvLsa;
-    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
-    tlvLsa.setLsaInfo(*tlvLsaInfo);
-
-    tlvLsa.setHyperbolicRadius(lsa->getCorRadius());
-    tlvLsa.setHyperbolicAngle(lsa->getCorTheta());
-
-    const ndn::Block& wire = tlvLsa.wireEncode();
-    context.append(wire);
+  for (const auto& coordinateLsa : m_lsdb.getCoordinateLsdb()) {
+    context.append(coordinateLsa.wireEncode());
   }
   context.end();
 }
@@ -117,21 +87,8 @@
 DatasetInterestHandler::publishNameStatus(const ndn::Name& topPrefix, const ndn::Interest& interest,
                                           ndn::mgmt::StatusDatasetContext& context)
 {
-  auto lsaRange = std::make_pair<std::list<NameLsa>::const_iterator, std::list<NameLsa>::const_iterator>(
-    m_lsdb.getNameLsdb().cbegin(), m_lsdb.getNameLsdb().cend());
-  NLSR_LOG_DEBUG("Received interest:  " << interest);
-  for (auto lsa = lsaRange.first; lsa != lsaRange.second; lsa++) {
-    tlv::NameLsa tlvLsa;
-
-    std::shared_ptr<tlv::LsaInfo> tlvLsaInfo = tlv::makeLsaInfo(*lsa);
-    tlvLsa.setLsaInfo(*tlvLsaInfo);
-
-    for (const ndn::Name& name : lsa->getNpl().getNames()) {
-      tlvLsa.addName(name);
-    }
-
-    const ndn::Block& wire = tlvLsa.wireEncode();
-    context.append(wire);
+  for (const auto& nameLsa : m_lsdb.getNameLsdb()) {
+    context.append(nameLsa.wireEncode());
   }
   context.end();
 }
diff --git a/src/publisher/dataset-interest-handler.hpp b/src/publisher/dataset-interest-handler.hpp
index 46262b1..28a6c4c 100644
--- a/src/publisher/dataset-interest-handler.hpp
+++ b/src/publisher/dataset-interest-handler.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -37,9 +37,6 @@
 #include "lsdb.hpp"
 #include "logger.hpp"
 
-#include "tlv/adjacency-lsa.hpp"
-#include "tlv/coordinate-lsa.hpp"
-#include "tlv/name-lsa.hpp"
 #include "tlv/routing-table-status.hpp"
 #include "tlv/routing-table-entry.hpp"
 
diff --git a/src/route/fib-entry.hpp b/src/route/fib-entry.hpp
index 248c0fd..e5542e1 100644
--- a/src/route/fib-entry.hpp
+++ b/src/route/fib-entry.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
diff --git a/src/route/fib.cpp b/src/route/fib.cpp
index cd2b28c..90cddee 100644
--- a/src/route/fib.cpp
+++ b/src/route/fib.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
diff --git a/src/route/fib.hpp b/src/route/fib.hpp
index 25677e3..ba4d87b 100644
--- a/src/route/fib.hpp
+++ b/src/route/fib.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
diff --git a/src/route/map.cpp b/src/route/map.cpp
index f5f928e..3f6513c 100644
--- a/src/route/map.cpp
+++ b/src/route/map.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2018,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -21,7 +21,7 @@
 #include "map.hpp"
 #include "nlsr.hpp"
 #include "adjacent.hpp"
-#include "lsa.hpp"
+#include "lsa/lsa.hpp"
 #include "lsdb.hpp"
 #include "logger.hpp"
 
diff --git a/src/route/map.hpp b/src/route/map.hpp
index b4aa396..c9511bf 100644
--- a/src/route/map.hpp
+++ b/src/route/map.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -24,7 +24,6 @@
 #include "common.hpp"
 #include "map-entry.hpp"
 
-#include <iostream>
 #include <list>
 #include <boost/cstdint.hpp>
 
@@ -81,7 +80,7 @@
   {
     BOOST_STATIC_ASSERT_MSG(is_iterator<IteratorType>::value, "IteratorType must be an iterator!");
     for (auto lsa = begin; lsa != end; lsa++) {
-      addEntry(lsa->getOrigRouter());
+      addEntry(lsa->getOriginRouter());
       for (const auto& adjacent : lsa->getAdl().getAdjList()) {
         addEntry(adjacent.getName());
       }
@@ -98,7 +97,7 @@
   {
     BOOST_STATIC_ASSERT_MSG(is_iterator<IteratorType>::value, "IteratorType must be an iterator!");
     for (auto lsa = begin; lsa != end; lsa++) {
-      addEntry(lsa->getOrigRouter());
+      addEntry(lsa->getOriginRouter());
     }
   }
 
diff --git a/src/route/name-prefix-table.cpp b/src/route/name-prefix-table.cpp
index 65e935c..b38bbea 100644
--- a/src/route/name-prefix-table.cpp
+++ b/src/route/name-prefix-table.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
diff --git a/src/route/name-prefix-table.hpp b/src/route/name-prefix-table.hpp
index 8349453..370e515 100644
--- a/src/route/name-prefix-table.hpp
+++ b/src/route/name-prefix-table.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
diff --git a/src/route/nexthop-list.hpp b/src/route/nexthop-list.hpp
index d9f60f4..e405889 100644
--- a/src/route/nexthop-list.hpp
+++ b/src/route/nexthop-list.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2018,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -24,10 +24,8 @@
 #include "nexthop.hpp"
 #include "adjacent.hpp"
 
-#include <set>
-#include <iostream>
-#include <boost/cstdint.hpp>
 #include <ndn-cxx/face.hpp>
+#include <set>
 
 namespace nlsr {
 
diff --git a/src/route/nexthop.hpp b/src/route/nexthop.hpp
index 4b41308..e24df7b 100644
--- a/src/route/nexthop.hpp
+++ b/src/route/nexthop.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -17,8 +17,9 @@
  * 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/>.
  **/
-#ifndef NLSR_NEXTHOP_HPP
-#define NLSR_NEXTHOP_HPP
+
+#ifndef NLSR_ROUTE_NEXTHOP_HPP
+#define NLSR_ROUTE_NEXTHOP_HPP
 
 #include "test-access-control.hpp"
 
@@ -27,6 +28,7 @@
 #include <boost/cstdint.hpp>
 
 namespace nlsr {
+
 class NextHop
 {
 public:
@@ -121,4 +123,4 @@
 
 } // namespace nlsr
 
-#endif //NLSR_NEXTHOP_HPP
+#endif // NLSR_ROUTE_NEXTHOP_HPP
diff --git a/src/route/routing-table-calculator.cpp b/src/route/routing-table-calculator.cpp
index eb821e8..04cc78f 100644
--- a/src/route/routing-table-calculator.cpp
+++ b/src/route/routing-table-calculator.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -27,7 +27,6 @@
 #include "logger.hpp"
 #include "adjacent.hpp"
 
-#include <iostream>
 #include <boost/math/constants/constants.hpp>
 #include <ndn-cxx/util/logger.hpp>
 #include <cmath>
@@ -66,7 +65,7 @@
 {
   // For each LSA represented in the map
   for (const auto& adjLsa : adjLsaList) {
-    ndn::optional<int32_t> row = pMap.getMappingNoByRouterName(adjLsa.getOrigRouter());
+    ndn::optional<int32_t> row = pMap.getMappingNoByRouterName(adjLsa.getOriginRouter());
 
     std::list<Adjacent> adl = adjLsa.getAdl().getAdjList();
     // For each adjacency represented in the LSA
@@ -499,12 +498,12 @@
   double distance = UNKNOWN_DISTANCE;
 
   ndn::Name srcLsaKey = src;
-  srcLsaKey.append(std::to_string(Lsa::Type::COORDINATE));
+  srcLsaKey.append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
 
   CoordinateLsa* srcLsa = lsdb.findCoordinateLsa(srcLsaKey);
 
   ndn::Name destLsaKey = dest;
-  destLsaKey.append(std::to_string(Lsa::Type::COORDINATE));
+  destLsaKey.append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
 
   CoordinateLsa* destLsa = lsdb.findCoordinateLsa(destLsaKey);
 
diff --git a/src/route/routing-table-calculator.hpp b/src/route/routing-table-calculator.hpp
index 683eb58..16d64d7 100644
--- a/src/route/routing-table-calculator.hpp
+++ b/src/route/routing-table-calculator.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -23,11 +23,11 @@
 #define NLSR_ROUTING_TABLE_CALCULATOR_HPP
 
 #include "common.hpp"
-#include "lsa.hpp"
+#include "lsa/lsa.hpp"
+#include "lsa/adj-lsa.hpp"
 #include "conf-parameter.hpp"
 
 #include <list>
-#include <iostream>
 #include <boost/cstdint.hpp>
 
 #include <ndn-cxx/name.hpp>
diff --git a/src/route/routing-table-entry.hpp b/src/route/routing-table-entry.hpp
index fd98c32..83731b9 100644
--- a/src/route/routing-table-entry.hpp
+++ b/src/route/routing-table-entry.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -24,7 +24,6 @@
 
 #include "nexthop-list.hpp"
 
-#include <iostream>
 #include <ndn-cxx/name.hpp>
 
 namespace nlsr {
diff --git a/src/route/routing-table-pool-entry.cpp b/src/route/routing-table-pool-entry.cpp
index 9102ed0..b214535 100644
--- a/src/route/routing-table-pool-entry.cpp
+++ b/src/route/routing-table-pool-entry.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
diff --git a/src/route/routing-table-pool-entry.hpp b/src/route/routing-table-pool-entry.hpp
index 14e7c7d..48212c3 100644
--- a/src/route/routing-table-pool-entry.hpp
+++ b/src/route/routing-table-pool-entry.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2017,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -25,7 +25,6 @@
 #include "routing-table-entry.hpp"
 #include "nexthop-list.hpp"
 
-#include <iostream>
 #include <ndn-cxx/name.hpp>
 #include <unordered_map>
 
diff --git a/src/route/routing-table.cpp b/src/route/routing-table.cpp
index 60b05f9..3fcd654 100644
--- a/src/route/routing-table.cpp
+++ b/src/route/routing-table.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -64,12 +64,12 @@
     if ((!isHrEnabled &&
          m_lsdb
          .doesLsaExist(ndn::Name{m_confParam.getRouterPrefix()}
-                       .append(std::to_string(Lsa::Type::ADJACENCY)), Lsa::Type::ADJACENCY))
+                       .append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY)), Lsa::Type::ADJACENCY))
         ||
         (isHrEnabled &&
          m_lsdb
          .doesLsaExist(ndn::Name{m_confParam.getRouterPrefix()}
-                       .append(std::to_string(Lsa::Type::COORDINATE)), Lsa::Type::COORDINATE))) {
+                       .append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE)), Lsa::Type::COORDINATE))) {
       if (m_lsdb.getIsBuildAdjLsaSheduled() != 1) {
         NLSR_LOG_TRACE("Clearing old routing table");
         clearRoutingTable();
diff --git a/src/route/routing-table.hpp b/src/route/routing-table.hpp
index c149eb7..af2ba93 100644
--- a/src/route/routing-table.hpp
+++ b/src/route/routing-table.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
@@ -28,9 +28,6 @@
 #include "lsdb.hpp"
 #include "route/fib.hpp"
 
-#include <iostream>
-#include <utility>
-#include <string>
 #include <boost/cstdint.hpp>
 #include <ndn-cxx/util/scheduler.hpp>
 
diff --git a/src/sequencing-manager.cpp b/src/sequencing-manager.cpp
index c7c6c7e..ae0c8b5 100644
--- a/src/sequencing-manager.cpp
+++ b/src/sequencing-manager.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -23,12 +23,10 @@
 #include "logger.hpp"
 
 #include <string>
-#include <iostream>
 #include <fstream>
 #include <pwd.h>
 #include <cstdlib>
 #include <unistd.h>
-#include <boost/algorithm/string.hpp>
 
 namespace nlsr {
 
diff --git a/src/sequencing-manager.hpp b/src/sequencing-manager.hpp
index 307aab5..0c8504f 100644
--- a/src/sequencing-manager.hpp
+++ b/src/sequencing-manager.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
diff --git a/src/signals.hpp b/src/signals.hpp
index a0191ff..6001ead 100644
--- a/src/signals.hpp
+++ b/src/signals.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California
  *
  * This file is part of NLSR (Named-data Link State Routing).
diff --git a/src/tlv/adjacency-lsa.cpp b/src/tlv/adjacency-lsa.cpp
deleted file mode 100644
index 72f138b..0000000
--- a/src/tlv/adjacency-lsa.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- 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 "adjacency-lsa.hpp"
-#include "tlv-nlsr.hpp"
-
-#include <ndn-cxx/util/concepts.hpp>
-#include <ndn-cxx/encoding/block-helpers.hpp>
-
-namespace nlsr {
-namespace tlv {
-
-BOOST_CONCEPT_ASSERT((ndn::WireEncodable<AdjacencyLsa>));
-BOOST_CONCEPT_ASSERT((ndn::WireDecodable<AdjacencyLsa>));
-static_assert(std::is_base_of<ndn::tlv::Error, AdjacencyLsa::Error>::value,
-              "AdjacencyLsa::Error must inherit from tlv::Error");
-
-AdjacencyLsa::AdjacencyLsa()
-  : m_hasAdjacencies(false)
-{
-}
-
-AdjacencyLsa::AdjacencyLsa(const ndn::Block& block)
-{
-  wireDecode(block);
-}
-
-template<ndn::encoding::Tag TAG>
-size_t
-AdjacencyLsa::wireEncode(ndn::EncodingImpl<TAG>& block) const
-{
-  size_t totalLength = 0;
-
-  for (std::list<Adjacency>::const_reverse_iterator it = m_adjacencies.rbegin();
-       it != m_adjacencies.rend(); ++it) {
-    totalLength += it->wireEncode(block);
-  }
-
-  totalLength += m_lsaInfo.wireEncode(block);
-
-  totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(ndn::tlv::nlsr::AdjacencyLsa);
-
-  return totalLength;
-}
-
-NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(AdjacencyLsa);
-
-const ndn::Block&
-AdjacencyLsa::wireEncode() const
-{
-  if (m_wire.hasWire()) {
-    return m_wire;
-  }
-
-  ndn::EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  ndn::EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-
-  return m_wire;
-}
-
-void
-AdjacencyLsa::wireDecode(const ndn::Block& wire)
-{
-  m_hasAdjacencies = false;
-  m_adjacencies.clear();
-
-  m_wire = wire;
-
-  if (m_wire.type() != ndn::tlv::nlsr::AdjacencyLsa) {
-    BOOST_THROW_EXCEPTION(Error("Expected AdjacencyLsa Block, but Block is of a different type: #" +
-                                ndn::to_string(m_wire.type())));
-  }
-
-  m_wire.parse();
-
-  ndn::Block::element_const_iterator val = m_wire.elements_begin();
-
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::LsaInfo) {
-    m_lsaInfo.wireDecode(*val);
-    ++val;
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("Missing required LsaInfo field"));
-  }
-
-  for (; val != m_wire.elements_end(); ++val) {
-    if (val->type() == ndn::tlv::nlsr::Adjacency) {
-      m_adjacencies.push_back(Adjacency(*val));
-      m_hasAdjacencies = true;
-    }
-    else {
-      BOOST_THROW_EXCEPTION(Error("Expected Adjacency Block, but Block is of a different type: #" +
-                                  ndn::to_string(m_wire.type())));
-    }
-  }
-}
-
-std::ostream&
-operator<<(std::ostream& os, const AdjacencyLsa& adjacencyLsa)
-{
-  os << "AdjacencyLsa("
-     << adjacencyLsa.getLsaInfo();
-
-  for (const auto& adjacency : adjacencyLsa) {
-    os << ", " << adjacency;
-  }
-
-  os << ")";
-
-  return os;
-}
-
-} // namespace tlv
-} // namespace nlsr
diff --git a/src/tlv/adjacency-lsa.hpp b/src/tlv/adjacency-lsa.hpp
deleted file mode 100644
index 20c775d..0000000
--- a/src/tlv/adjacency-lsa.hpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* -*- 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/>.
- */
-
-#ifndef NLSR_TLV_ADJACENCY_LSA_HPP
-#define NLSR_TLV_ADJACENCY_LSA_HPP
-
-#include "lsa-info.hpp"
-#include "adjacency.hpp"
-
-#include <ndn-cxx/util/time.hpp>
-#include <ndn-cxx/encoding/block.hpp>
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/encoding/tlv.hpp>
-#include <ndn-cxx/name.hpp>
-
-#include <list>
-
-namespace nlsr {
-namespace tlv {
-
-/*!
-   \brief Data abstraction for AdjacencyLsa
-
-   AdjacencyLsa := ADJACENCY-LSA-TYPE TLV-LENGTH
-                     LsaInfo
-                     Adjacency*
-
-   \sa https://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
- */
-class AdjacencyLsa
-{
-public:
-  class Error : public ndn::tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : ndn::tlv::Error(what)
-    {
-    }
-  };
-
-  typedef std::list<Adjacency> AdjacencyList;
-  typedef AdjacencyList::const_iterator iterator;
-
-  AdjacencyLsa();
-
-  explicit
-  AdjacencyLsa(const ndn::Block& block);
-
-  const LsaInfo&
-  getLsaInfo() const
-  {
-    return m_lsaInfo;
-  }
-
-  AdjacencyLsa&
-  setLsaInfo(const LsaInfo& lsaInfo)
-  {
-    m_lsaInfo = lsaInfo;
-    m_wire.reset();
-    return *this;
-  }
-
-  bool
-  hasAdjacencies() const
-  {
-    return m_hasAdjacencies;
-  }
-
-  const std::list<Adjacency>&
-  getAdjacencies() const
-  {
-    return m_adjacencies;
-  }
-
-  AdjacencyLsa&
-  addAdjacency(const Adjacency& adjacency)
-  {
-    m_adjacencies.push_back(adjacency);
-    m_wire.reset();
-    m_hasAdjacencies = true;
-    return *this;
-  }
-
-  AdjacencyLsa&
-  clearAdjacencies()
-  {
-    m_adjacencies.clear();
-    m_hasAdjacencies = false;
-    return *this;
-  }
-
-  /*! \brief Encodes the Adjacent objects and some info using the method in TAG.
-   *
-   * This function will TLV-format the Adjacent objects and some LSA
-   * info using the implementation speciifed by TAG. Usually this is
-   * called with an estimator first to guess how long the buffer needs
-   * to be, then with an encoder to do the real work. This process is
-   * automated by the other wireEncode.
-   * \sa AdjacencyLsa::wireEncode()
-   */
-  template<ndn::encoding::Tag TAG>
-  size_t
-  wireEncode(ndn::EncodingImpl<TAG>& block) const;
-
-  /*! \brief Create a TLV encoding of this object.
-   *
-   * Create a block containing the TLV encoding of this object. That
-   * involves two steps: estimating the size that the information will
-   * take up, and then creating a buffer of that size and encoding the
-   * information into it. Both steps are accomplished by
-   * AdjacencyLsa::wireEncode(ndn::EncodingImpl<TAG>&)
-   */
-  const ndn::Block&
-  wireEncode() const;
-
-  /*! \brief Populate this object by decoding the one contained in the
-   * given block.
-   */
-  void
-  wireDecode(const ndn::Block& wire);
-
-  iterator
-  begin() const;
-
-  iterator
-  end() const;
-
-private:
-  LsaInfo m_lsaInfo;
-  bool m_hasAdjacencies;
-  AdjacencyList m_adjacencies;
-
-  mutable ndn::Block m_wire;
-};
-
-NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(AdjacencyLsa);
-
-inline AdjacencyLsa::iterator
-AdjacencyLsa::begin() const
-{
-  return m_adjacencies.begin();
-}
-
-inline AdjacencyLsa::iterator
-AdjacencyLsa::end() const
-{
-  return m_adjacencies.end();
-}
-
-std::ostream&
-operator<<(std::ostream& os, const AdjacencyLsa& adjacencyLsa);
-
-} // namespace tlv
-} // namespace nlsr
-
-#endif // NLSR_TLV_ADJACENCY_LSA_HPP
diff --git a/src/tlv/adjacency.cpp b/src/tlv/adjacency.cpp
deleted file mode 100644
index b9adec9..0000000
--- a/src/tlv/adjacency.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- 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 "adjacency.hpp"
-#include "tlv-nlsr.hpp"
-
-#include <ndn-cxx/util/concepts.hpp>
-#include <ndn-cxx/encoding/block-helpers.hpp>
-
-namespace nlsr {
-namespace tlv {
-
-BOOST_CONCEPT_ASSERT((ndn::WireEncodable<Adjacency>));
-BOOST_CONCEPT_ASSERT((ndn::WireDecodable<Adjacency>));
-static_assert(std::is_base_of<ndn::tlv::Error, Adjacency::Error>::value,
-              "Adjacency::Error must inherit from tlv::Error");
-
-Adjacency::Adjacency()
-  : m_cost(0)
-{
-}
-
-Adjacency::Adjacency(const ndn::Block& block)
-{
-  wireDecode(block);
-}
-
-template<ndn::encoding::Tag TAG>
-size_t
-Adjacency::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
-{
-  size_t totalLength = 0;
-
-  totalLength += prependNonNegativeIntegerBlock(encoder, ndn::tlv::nlsr::Cost, m_cost);
-
-  totalLength += encoder.prependByteArrayBlock(
-    ndn::tlv::nlsr::Uri, reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
-
-  totalLength += m_name.wireEncode(encoder);
-
-  totalLength += encoder.prependVarNumber(totalLength);
-  totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::Adjacency);
-
-  return totalLength;
-}
-
-NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Adjacency);
-
-const ndn::Block&
-Adjacency::wireEncode() const
-{
-  if (m_wire.hasWire()) {
-    return m_wire;
-  }
-
-  ndn::EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  ndn::EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-
-  return m_wire;
-}
-
-void
-Adjacency::wireDecode(const ndn::Block& wire)
-{
-  m_name.clear();
-  m_uri = "";
-  m_cost = 0;
-
-  m_wire = wire;
-
-  if (m_wire.type() != ndn::tlv::nlsr::Adjacency) {
-    BOOST_THROW_EXCEPTION(Error("Expected Adjacency Block, but Block is of a different type: #" +
-                                ndn::to_string(m_wire.type())));
-  }
-
-  m_wire.parse();
-
-  ndn::Block::element_const_iterator val = m_wire.elements_begin();
-
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
-    m_name.wireDecode(*val);
-    ++val;
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("Missing required Name field"));
-  }
-
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Uri) {
-    m_uri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
-    ++val;
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("Missing required Uri field"));
-  }
-
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::Cost) {
-    m_cost = ndn::readNonNegativeInteger(*val);
-    ++val;
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("Missing required Cost field"));
-  }
-}
-
-std::ostream&
-operator<<(std::ostream& os, const Adjacency& adjacency)
-{
-  os << "Adjacency("
-     << "Name: " << adjacency.getName() << ", "
-     << "Uri: " << adjacency.getUri() << ", "
-     << "Cost: " << adjacency.getCost() << ")";
-
-  return os;
-}
-
-} // namespace tlv
-} // namespace nlsr
diff --git a/src/tlv/adjacency.hpp b/src/tlv/adjacency.hpp
deleted file mode 100644
index 4046e8f..0000000
--- a/src/tlv/adjacency.hpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/* -*- 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/>.
- */
-
-#ifndef NLSR_TLV_ADJACENCY_HPP
-#define NLSR_TLV_ADJACENCY_HPP
-
-#include <ndn-cxx/util/time.hpp>
-#include <ndn-cxx/encoding/block.hpp>
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/encoding/tlv.hpp>
-#include <ndn-cxx/name.hpp>
-
-namespace nlsr {
-namespace tlv {
-
-/*!
-   \brief Data abstraction for Adjacency
-
-   Adjacency := ADJACENCY-TYPE TLV-LENGTH
-                  Name
-                  Uri
-                  Cost
-
-   \sa https://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
- */
-class Adjacency
-{
-public:
-  class Error : public ndn::tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : ndn::tlv::Error(what)
-    {
-    }
-  };
-
-  Adjacency();
-
-  explicit
-  Adjacency(const ndn::Block& block);
-
-  const ndn::Name&
-  getName() const
-  {
-    return m_name;
-  }
-
-  Adjacency&
-  setName(const ndn::Name& name)
-  {
-    m_name = name;
-    m_wire.reset();
-    return *this;
-  }
-
-  const std::string&
-  getUri() const
-  {
-    return m_uri;
-  }
-
-  Adjacency&
-  setUri(const std::string& uri)
-  {
-    m_uri = uri;
-    m_wire.reset();
-    return *this;
-  }
-
-  uint64_t
-  getCost() const
-  {
-    return m_cost;
-  }
-
-  Adjacency&
-  setCost(uint64_t cost)
-  {
-    m_cost = cost;
-    m_wire.reset();
-    return *this;
-  }
-
-  /*! \brief TLV-encode this object using the implementation in from TAG.
-   *
-   * This method TLV-encodes this Adjacency object using the
-   * implementation given by TAG. Usually two implementations are
-   * provided: a size estimator and a real encoder, which are used in
-   * sequence to allocate the necessary block size and then encode it.
-   * \sa Adjacency::wireEncode()
-   */
-  template<ndn::encoding::Tag TAG>
-  size_t
-  wireEncode(ndn::EncodingImpl<TAG>& block) const;
-
-  /*! \brief Create a TLV encoding of this object.
-   *
-   * This function automates the process of guessing the necessary
-   * size of a block containing this object, and then creating a block
-   * and putting the TLV encoding into it.
-   * \sa Adjacency::wireEncode(ndn::EncodingImpl<TAG>&)
-   */
-  const ndn::Block&
-  wireEncode() const;
-
-  /*! \brief Populate this object by decoding the object contained in
-   * the given block.
-   */
-  void
-  wireDecode(const ndn::Block& wire);
-
-private:
-  ndn::Name m_name;
-  std::string m_uri;
-  uint64_t m_cost;
-
-  mutable ndn::Block m_wire;
-};
-
-NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Adjacency);
-
-std::ostream&
-operator<<(std::ostream& os, const Adjacency& adjacency);
-
-} // namespace tlv
-} // namespace nlsr
-
-#endif // NLSR_TLV_ADJACENCY_HPP
diff --git a/src/tlv/coordinate-lsa.hpp b/src/tlv/coordinate-lsa.hpp
deleted file mode 100644
index 603c119..0000000
--- a/src/tlv/coordinate-lsa.hpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/* -*- 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/>.
- */
-
-#ifndef NLSR_TLV_COORDINATE_LSA_HPP
-#define NLSR_TLV_COORDINATE_LSA_HPP
-
-#include "lsa-info.hpp"
-
-#include <ndn-cxx/util/time.hpp>
-#include <ndn-cxx/encoding/block.hpp>
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/encoding/tlv.hpp>
-#include <ndn-cxx/name.hpp>
-
-namespace nlsr {
-namespace tlv {
-
-/*!
-   \brief Data abstraction for CoordinateLsa
-
-   CoordinateLsa := COORDINATE-LSA-TYPE TLV-LENGTH
-                      LsaInfo
-                      HyperbolicRadius
-                      HyperbolicAngle+
-
-   \sa https://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
- */
-class CoordinateLsa
-{
-public:
-  class Error : public ndn::tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : ndn::tlv::Error(what)
-    {
-    }
-  };
-
-  CoordinateLsa();
-
-  explicit
-  CoordinateLsa(const ndn::Block& block);
-
-  const LsaInfo&
-  getLsaInfo() const
-  {
-    return m_lsaInfo;
-  }
-
-  CoordinateLsa&
-  setLsaInfo(const LsaInfo& lsaInfo)
-  {
-    m_lsaInfo = lsaInfo;
-    m_wire.reset();
-    return *this;
-  }
-
-  double
-  getHyperbolicRadius() const
-  {
-    return m_hyperbolicRadius;
-  }
-
-  CoordinateLsa&
-  setHyperbolicRadius(double hyperbolicRadius)
-  {
-    m_hyperbolicRadius = hyperbolicRadius;
-    m_wire.reset();
-    return *this;
-  }
-
-  const std::vector<double>
-  getHyperbolicAngle() const
-  {
-    return m_hyperbolicAngle;
-  }
-
-  CoordinateLsa&
-  setHyperbolicAngle(const std::vector<double>& hyperbolicAngle)
-  {
-    m_hyperbolicAngle = hyperbolicAngle;
-    m_wire.reset();
-    return *this;
-  }
-
-  /*! \brief Encodes the hyperbolic coordinates and some info using the method in TAG.
-   *
-   * This function will TLV-format the hyperbolic coordinates objects and some LSA
-   * info using the implementation speciifed by TAG. Usually this is
-   * called with an estimator first to guess how long the buffer needs
-   * to be, then with an encoder to do the real work. This process is
-   * automated by the other wireEncode.
-   * \sa CoordinateLsa::wireEncode()
-   */
-  template<ndn::encoding::Tag TAG>
-  size_t
-  wireEncode(ndn::EncodingImpl<TAG>& block) const;
-
-  /*! \brief Create a TLV encoding of this object.
-   *
-   * Create a block containing the TLV encoding of this object. That
-   * involves two steps: estimating the size that the information will
-   * take up, and then creating a buffer of that size and encoding the
-   * information into it. Both steps are accomplished by
-   * CoordinateLsa::wireEncode(ndn::EncodingImpl<TAG>&)
-   */
-  const ndn::Block&
-  wireEncode() const;
-
-  /*! \brief Populate this object by decoding the one contained in the
-   * given block.
-   */
-  void
-  wireDecode(const ndn::Block& wire);
-
-private:
-  LsaInfo m_lsaInfo;
-  double m_hyperbolicRadius;
-  std::vector<double> m_hyperbolicAngle;
-
-  mutable ndn::Block m_wire;
-};
-
-NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(CoordinateLsa);
-
-std::ostream&
-operator<<(std::ostream& os, const CoordinateLsa& coordinateLsa);
-
-} // namespace tlv
-} // namespace nlsr
-
-#endif // NLSR_TLV_COORDINATE_LSA_HPP
diff --git a/src/tlv/lsa-info.cpp b/src/tlv/lsa-info.cpp
deleted file mode 100644
index 5f83863..0000000
--- a/src/tlv/lsa-info.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/* -*- 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-info.hpp"
-#include "tlv-nlsr.hpp"
-
-#include <ndn-cxx/util/concepts.hpp>
-#include <ndn-cxx/encoding/block-helpers.hpp>
-
-namespace nlsr {
-namespace tlv {
-
-BOOST_CONCEPT_ASSERT((ndn::WireEncodable<LsaInfo>));
-BOOST_CONCEPT_ASSERT((ndn::WireDecodable<LsaInfo>));
-static_assert(std::is_base_of<ndn::tlv::Error, LsaInfo::Error>::value,
-              "LsaInfo::Error must inherit from tlv::Error");
-
-const ndn::time::milliseconds LsaInfo::INFINITE_EXPIRATION_PERIOD(ndn::time::milliseconds::max());
-
-LsaInfo::LsaInfo()
-  : m_sequenceNumber(0)
-  , m_expirationPeriod(INFINITE_EXPIRATION_PERIOD)
-  , m_hasInfiniteExpirationPeriod(true)
-{
-}
-
-LsaInfo::LsaInfo(const ndn::Block& block)
-{
-  wireDecode(block);
-}
-
-template<ndn::encoding::Tag TAG>
-size_t
-LsaInfo::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
-{
-  size_t totalLength = 0;
-
-  // Absence of an ExpirationPeriod signifies non-expiration
-  if (!m_hasInfiniteExpirationPeriod) {
-    totalLength += prependNonNegativeIntegerBlock(encoder,
-                                                  ndn::tlv::nlsr::ExpirationPeriod,
-                                                  m_expirationPeriod.count());
-  }
-
-  totalLength += prependNonNegativeIntegerBlock(encoder,
-                                                ndn::tlv::nlsr::SequenceNumber,
-                                                m_sequenceNumber);
-
-  totalLength += prependNestedBlock(encoder, ndn::tlv::nlsr::OriginRouter, m_originRouter);
-
-  totalLength += encoder.prependVarNumber(totalLength);
-  totalLength += encoder.prependVarNumber(ndn::tlv::nlsr::LsaInfo);
-
-  return totalLength;
-}
-
-NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(LsaInfo);
-
-const ndn::Block&
-LsaInfo::wireEncode() const
-{
-  if (m_wire.hasWire()) {
-    return m_wire;
-  }
-
-  ndn::EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  ndn::EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-
-  return m_wire;
-}
-
-void
-LsaInfo::wireDecode(const ndn::Block& wire)
-{
-  m_originRouter.clear();
-  m_sequenceNumber = 0;
-  m_expirationPeriod = ndn::time::milliseconds::min();
-
-  m_wire = wire;
-
-  if (m_wire.type() != ndn::tlv::nlsr::LsaInfo) {
-    std::stringstream error;
-    error << "Expected LsaInfo Block, but Block is of a different type: #"
-          << m_wire.type();
-    BOOST_THROW_EXCEPTION(Error(error.str()));
-  }
-
-  m_wire.parse();
-
-  ndn::Block::element_const_iterator val = m_wire.elements_begin();
-
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::OriginRouter) {
-    val->parse();
-    ndn::Block::element_const_iterator it = val->elements_begin();
-
-    if (it != val->elements_end() && it->type() == ndn::tlv::Name) {
-      m_originRouter.wireDecode(*it);
-    }
-    else {
-      BOOST_THROW_EXCEPTION(Error("OriginRouter: Missing required Name field"));
-    }
-
-    ++val;
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("Missing required OriginRouter field"));
-  }
-
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::SequenceNumber) {
-    m_sequenceNumber = ndn::readNonNegativeInteger(*val);
-    ++val;
-  }
-  else {
-    BOOST_THROW_EXCEPTION(Error("Missing required SequenceNumber field"));
-  }
-
-  if (val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::ExpirationPeriod) {
-    m_expirationPeriod = ndn::time::milliseconds(ndn::readNonNegativeInteger(*val));
-    m_hasInfiniteExpirationPeriod = false;
-  }
-  else {
-    m_expirationPeriod = INFINITE_EXPIRATION_PERIOD;
-    m_hasInfiniteExpirationPeriod = true;
-  }
-}
-
-std::ostream&
-operator<<(std::ostream& os, const LsaInfo& lsaInfo)
-{
-  os << "LsaInfo("
-     << "OriginRouter: " << lsaInfo.getOriginRouter() << ", "
-     << "SequenceNumber: " << lsaInfo.getSequenceNumber() << ", ";
-
-  if (!lsaInfo.hasInfiniteExpirationPeriod()) {
-    os << "ExpirationPeriod: " << lsaInfo.getExpirationPeriod();
-  }
-  else {
-    os << "ExpirationPeriod: Infinity";
-  }
-
-  os << ")";
-
-  return os;
-}
-
-std::shared_ptr<LsaInfo>
-makeLsaInfo(const Lsa& lsa)
-{
-  std::shared_ptr<LsaInfo> lsaInfo = std::make_shared<LsaInfo>();
-
-  lsaInfo->setOriginRouter(lsa.getOrigRouter());
-  lsaInfo->setSequenceNumber(lsa.getLsSeqNo());
-
-  ndn::time::system_clock::duration duration
-    = lsa.getExpirationTimePoint() - ndn::time::system_clock::now();
-
-  lsaInfo->setExpirationPeriod(ndn::time::duration_cast<ndn::time::milliseconds>(duration));
-
-  return lsaInfo;
-}
-
-} // namespace tlv
-} // namespace nlsr
diff --git a/src/tlv/lsa-info.hpp b/src/tlv/lsa-info.hpp
deleted file mode 100644
index 291c428..0000000
--- a/src/tlv/lsa-info.hpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- 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/>.
- */
-
-#ifndef NLSR_TLV_LSA_INFO_HPP
-#define NLSR_TLV_LSA_INFO_HPP
-
-#include "lsa.hpp"
-
-#include <ndn-cxx/util/time.hpp>
-#include <ndn-cxx/encoding/block.hpp>
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/encoding/tlv.hpp>
-#include <ndn-cxx/name.hpp>
-#include <boost/throw_exception.hpp>
-
-namespace nlsr {
-namespace tlv {
-
-/*!
-   \brief Data abstraction for LsaInfo
-
-   LsaInfo := LSA-TYPE TLV-LENGTH
-                OriginRouter
-                SequenceNumber
-                ExpirationPeriod?
-
-   \sa https://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
- */
-class LsaInfo
-{
-public:
-  class Error : public ndn::tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : ndn::tlv::Error(what)
-    {
-    }
-  };
-
-  LsaInfo();
-
-  explicit
-  LsaInfo(const ndn::Block& block);
-
-  const ndn::Name&
-  getOriginRouter() const
-  {
-    return m_originRouter;
-  }
-
-  LsaInfo&
-  setOriginRouter(const ndn::Name& name)
-  {
-    m_originRouter = name;
-    m_wire.reset();
-    return *this;
-  }
-
-  uint64_t
-  getSequenceNumber() const
-  {
-    return m_sequenceNumber;
-  }
-
-  LsaInfo&
-  setSequenceNumber(uint64_t sequenceNumber)
-  {
-    m_sequenceNumber = sequenceNumber;
-    m_wire.reset();
-    return *this;
-  }
-
-  static const ndn::time::milliseconds INFINITE_EXPIRATION_PERIOD;
-
-  const ndn::time::milliseconds&
-  getExpirationPeriod() const
-  {
-    return m_expirationPeriod;
-  }
-
-  LsaInfo&
-  setExpirationPeriod(const ndn::time::milliseconds& expirationPeriod)
-  {
-    m_expirationPeriod = expirationPeriod;
-
-    m_hasInfiniteExpirationPeriod = (m_expirationPeriod == INFINITE_EXPIRATION_PERIOD);
-
-    m_wire.reset();
-    return *this;
-  }
-
-  bool
-  hasInfiniteExpirationPeriod() const
-  {
-    return m_hasInfiniteExpirationPeriod;
-  }
-
-  /*! \brief Encodes LSA info using the method in TAG.
-   *
-   * This function will TLV-format LSA info using the implementation
-   * speciifed by TAG. Usually this is called with an estimator first
-   * to guess how long the buffer needs to be, then with an encoder to
-   * do the real work. This process is automated by the other
-   * wireEncode.
-   * \sa LsaInfo::wireEncode()
-   */
-  template<ndn::encoding::Tag TAG>
-  size_t
-  wireEncode(ndn::EncodingImpl<TAG>& block) const;
-
-  /*! \brief Create a TLV encoding of this object.
-   *
-   * Create a block containing the TLV encoding of this object. That
-   * involves two steps: estimating the size that the information will
-   * take up, and then creating a buffer of that size and encoding the
-   * information into it. Both steps are accomplished by
-   * LsaInfo::wireEncode(ndn::EncodingImpl<TAG>&)
-   */
-  const ndn::Block&
-  wireEncode() const;
-
-  /*! \brief Populate this object by decoding the one contained in the
-   * given block.
-   */
-  void
-  wireDecode(const ndn::Block& wire);
-
-private:
-  ndn::Name m_originRouter;
-  uint64_t m_sequenceNumber;
-  ndn::time::milliseconds m_expirationPeriod;
-  bool m_hasInfiniteExpirationPeriod;
-
-  mutable ndn::Block m_wire;
-};
-
-NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(LsaInfo);
-
-std::ostream&
-operator<<(std::ostream& os, const LsaInfo& lsaInfo);
-
-std::shared_ptr<LsaInfo>
-makeLsaInfo(const Lsa& lsa);
-
-} // namespace tlv
-} // namespace nlsr
-
-#endif // NLSR_TLV_LSA_INFO_HPP
diff --git a/src/tlv/name-lsa.hpp b/src/tlv/name-lsa.hpp
deleted file mode 100644
index 0278631..0000000
--- a/src/tlv/name-lsa.hpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- 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/>.
- */
-
-#ifndef NLSR_TLV_NAME_LSA_HPP
-#define NLSR_TLV_NAME_LSA_HPP
-
-#include "lsa-info.hpp"
-
-#include <ndn-cxx/util/time.hpp>
-#include <ndn-cxx/encoding/block.hpp>
-#include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/encoding/tlv.hpp>
-#include <ndn-cxx/name.hpp>
-
-#include <list>
-
-namespace nlsr {
-namespace tlv {
-
-/*!
-   \brief Data abstraction for NameLsa
-
-   NameLsa := NAME-LSA-TYPE TLV-LENGTH
-                LsaInfo
-                Name+
-
-   \sa https://redmine.named-data.net/projects/nlsr/wiki/LSDB_DataSet
- */
-class NameLsa
-{
-public:
-  class Error : public ndn::tlv::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : ndn::tlv::Error(what)
-    {
-    }
-  };
-
-  typedef std::list<ndn::Name> NameList;
-  typedef NameList::const_iterator iterator;
-
-  NameLsa();
-
-  explicit
-  NameLsa(const ndn::Block& block);
-
-  const LsaInfo&
-  getLsaInfo() const
-  {
-    return m_lsaInfo;
-  }
-
-  NameLsa&
-  setLsaInfo(const LsaInfo& lsaInfo)
-  {
-    m_lsaInfo = lsaInfo;
-    m_wire.reset();
-    return *this;
-  }
-
-  bool
-  hasNames() const
-  {
-    return m_hasNames;
-  }
-
-  const std::list<ndn::Name>&
-  getNames() const
-  {
-    return m_names;
-  }
-
-  NameLsa&
-  addName(const ndn::Name& name)
-  {
-    m_names.push_back(name);
-    m_wire.reset();
-    m_hasNames = true;
-    return *this;
-  }
-
-  NameLsa&
-  clearNames()
-  {
-    m_names.clear();
-    m_hasNames = false;
-    return *this;
-  }
-
-  /*! \brief Encodes the Name objects and some info using the method in TAG.
-   *
-   * This function will TLV-format the Name objects and some LSA
-   * info using the implementation speciifed by TAG. Usually this is
-   * called with an estimator first to guess how long the buffer needs
-   * to be, then with an encoder to do the real work. This process is
-   * automated by the other wireEncode.
-   * \sa NameLsa::wireEncode()
-   */
-  template<ndn::encoding::Tag TAG>
-  size_t
-  wireEncode(ndn::EncodingImpl<TAG>& block) const;
-
-  /*! \brief Create a TLV encoding of this object.
-   *
-   * Create a block containing the TLV encoding of this object. That
-   * involves two steps: estimating the size that the information will
-   * take up, and then creating a buffer of that size and encoding the
-   * information into it. Both steps are accomplished by
-   * NameLsa::wireEncode(ndn::EncodingImpl<TAG>&)
-   */
-  const ndn::Block&
-  wireEncode() const;
-
-  /*! \brief Populate this object by decoding the one contained in the
-   * given block.
-   */
-  void
-  wireDecode(const ndn::Block& wire);
-
-  iterator
-  begin() const;
-
-  iterator
-  end() const;
-
-private:
-  LsaInfo m_lsaInfo;
-  bool m_hasNames;
-  NameList m_names;
-
-  mutable ndn::Block m_wire;
-};
-
-NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(NameLsa);
-
-inline NameLsa::iterator
-NameLsa::begin() const
-{
-  return m_names.begin();
-}
-
-inline NameLsa::iterator
-NameLsa::end() const
-{
-  return m_names.end();
-}
-
-std::ostream&
-operator<<(std::ostream& os, const NameLsa& nameLsa);
-
-} // namespace tlv
-} // namespace nlsr
-
-#endif // NLSR_TLV_NAME_LSA_HPP
diff --git a/src/tlv/nexthop.cpp b/src/tlv/nexthop.cpp
index d05473e..508bf1a 100644
--- a/src/tlv/nexthop.cpp
+++ b/src/tlv/nexthop.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -21,7 +21,6 @@
 
 #include "nexthop.hpp"
 #include "tlv-nlsr.hpp"
-#include "coordinate-lsa.hpp"
 
 #include <ndn-cxx/util/concepts.hpp>
 #include <ndn-cxx/encoding/block-helpers.hpp>
diff --git a/src/tlv/routing-table-entry.cpp b/src/tlv/routing-table-entry.cpp
index c8e6332..255d418 100644
--- a/src/tlv/routing-table-entry.cpp
+++ b/src/tlv/routing-table-entry.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2018,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -80,7 +80,7 @@
   totalLength += m_des.wireEncode(block);
 
   totalLength += block.prependVarNumber(totalLength);
-  totalLength += block.prependVarNumber(ndn::tlv::nlsr::RouteTableEntry);
+  totalLength += block.prependVarNumber(ndn::tlv::nlsr::RoutingTableEntry);
 
   return totalLength;
 }
@@ -113,7 +113,7 @@
 
   m_wire = wire;
 
-  if (m_wire.type() != ndn::tlv::nlsr::RouteTableEntry) {
+  if (m_wire.type() != ndn::tlv::nlsr::RoutingTableEntry) {
     std::stringstream error;
     error << "Expected RoutingTable Block, but Block is of a different type: #"
           << m_wire.type();
diff --git a/src/tlv/routing-table-status.cpp b/src/tlv/routing-table-status.cpp
index a35f88c..00d2c78 100644
--- a/src/tlv/routing-table-status.cpp
+++ b/src/tlv/routing-table-status.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -123,7 +123,7 @@
 
   ndn::Block::element_const_iterator val = m_wire.elements_begin();
 
-  for (; val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::RouteTableEntry; ++val) {
+  for (; val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::RoutingTableEntry; ++val) {
     m_routingtables.push_back(RoutingTable(*val));
     m_hasRoutingtable = true;
   }
diff --git a/src/tlv/tlv-nlsr.hpp b/src/tlv/tlv-nlsr.hpp
index 265b2c6..e7d2253 100644
--- a/src/tlv/tlv-nlsr.hpp
+++ b/src/tlv/tlv-nlsr.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -34,24 +34,23 @@
  *  used in the LSDB Status Dataset.
  */
 enum {
-  LsaInfo          = 128,
-  OriginRouter     = 129,
-  SequenceNumber   = 130,
-  AdjacencyLsa     = 131,
-  Adjacency        = 132,
-  CoordinateLsa    = 133,
-  CostDouble       = 134,
-  HyperbolicRadius = 135,
-  HyperbolicAngle  = 136,
-  NameLsa          = 137,
-  LsdbStatus       = 138,
-  ExpirationPeriod = 139,
-  Cost             = 140,
-  Uri              = 141,
-  Destination      = 142,
-  NextHop          = 143,
-  RoutingTable     = 144,
-  RouteTableEntry  = 145,
+  Lsa                         = 128,
+  SequenceNumber              = 130,
+  AdjacencyLsa                = 131,
+  Adjacency                   = 132,
+  CoordinateLsa               = 133,
+  CostDouble                  = 134,
+  HyperbolicRadius            = 135,
+  HyperbolicAngle             = 136,
+  NameLsa                     = 137,
+  LsdbStatus                  = 138,
+  ExpirationTime              = 139,
+  Cost                        = 140,
+  Uri                         = 141,
+  Destination                 = 142,
+  NextHop                     = 143,
+  RoutingTable                = 144,
+  RoutingTableEntry           = 145
 };
 
 } // namespace nlsr
diff --git a/src/update/manager-base.cpp b/src/update/manager-base.cpp
index ccd00e1..6ca1c4a 100644
--- a/src/update/manager-base.cpp
+++ b/src/update/manager-base.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2019,  The University of Memphis,
+ * Copyright (c) 2014-2020,  The University of Memphis,
  *                           Regents of the University of California,
  *                           Arizona Board of Regents.
  *
@@ -20,7 +20,6 @@
  **/
 
 #include "manager-base.hpp"
-#include <iostream>
 
 namespace nlsr {
 namespace update {