**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 {
diff --git a/tests/communication/test-sync-logic-handler.cpp b/tests/communication/test-sync-logic-handler.cpp
index de99239..bdd8a3e 100644
--- a/tests/communication/test-sync-logic-handler.cpp
+++ b/tests/communication/test-sync-logic-handler.cpp
@@ -23,7 +23,6 @@
 #include "tests/test-common.hpp"
 #include "common.hpp"
 #include "nlsr.hpp"
-#include "lsa.hpp"
 
 #include <ndn-cxx/util/dummy-client-face.hpp>
 
@@ -101,7 +100,7 @@
   uint64_t syncSeqNo = 1;
 
   for (const Lsa::Type& lsaType : lsaTypes) {
-    std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
+    std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(lsaType);
 
     // Actual testing done here -- signal function callback
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
@@ -127,7 +126,7 @@
   std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::COORDINATE};
 
   for (const Lsa::Type& lsaType : lsaTypes) {
-    std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
+    std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(lsaType);
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
       [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
@@ -151,7 +150,7 @@
   uint64_t syncSeqNo = 1;
 
   for (const Lsa::Type& lsaType : this->lsaTypes) {
-    std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
+    std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(lsaType);
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
       [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
@@ -178,7 +177,7 @@
     ndn::Name updateName = ndn::Name{this->conf.getLsaPrefix()};
     updateName.append(this->conf.getSiteName())
               .append(this->conf.getRouterName())
-              .append(std::to_string(lsaType));
+              .append(boost::lexical_cast<std::string>(lsaType));
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
       [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
@@ -200,7 +199,7 @@
 
   for (const Lsa::Type& lsaType : this->lsaTypes) {
     ndn::Name updateName{this->conf.getSiteName()};
-    updateName.append(this->conf.getRouterName()).append(std::to_string(lsaType));
+    updateName.append(this->conf.getRouterName()).append(boost::lexical_cast<std::string>(lsaType));
 
     ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
       [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
@@ -231,7 +230,7 @@
         BOOST_FAIL("An update for an LSA with non-new sequence number should not emit!");
       });
 
-  std::string updateName = this->updateNamePrefix + std::to_string(Lsa::Type::NAME);
+  std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(Lsa::Type::NAME);
 
   this->receiveUpdate(updateName, sequenceNumber);
 }
@@ -247,11 +246,11 @@
   expectedPrefix.append(this->conf.getRouterName());
 
   BOOST_CHECK_EQUAL(this->sync.m_nameLsaUserPrefix,
-                    ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::NAME)));
+                    ndn::Name(expectedPrefix).append(boost::lexical_cast<std::string>(Lsa::Type::NAME)));
   BOOST_CHECK_EQUAL(this->sync.m_adjLsaUserPrefix,
-                    ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::ADJACENCY)));
+                    ndn::Name(expectedPrefix).append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY)));
   BOOST_CHECK_EQUAL(this->sync.m_coorLsaUserPrefix,
-                    ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::COORDINATE)));
+                    ndn::Name(expectedPrefix).append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE)));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/mocks/lsa.cpp b/tests/mocks/lsa.cpp
deleted file mode 100644
index a9ea498..0000000
--- a/tests/mocks/lsa.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  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"
-
-namespace nlsr {
-namespace test {
-
-std::string
-MockLsa::serialize() const
-{
-  return "";
-}
-
-bool
-MockLsa::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 {
-    deserializeCommon(tok_iter);
-  }
-  catch (const std::exception& e) {
-    return false;
-  }
-  return true;
-}
-
-void
-MockLsa::writeLog() const
-{
-}
-
-} // namespace test
-} // namespace nlsr
diff --git a/tests/mocks/lsa.hpp b/tests/mocks/lsa.hpp
deleted file mode 100644
index e1ee2aa..0000000
--- a/tests/mocks/lsa.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  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_TESTS_MOCKS_LSA_HPP
-#define NLSR_TESTS_MOCKS_LSA_HPP
-
-#include "src/lsa.hpp"
-
-#include <boost/tokenizer.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/lexical_cast.hpp>
-
-namespace nlsr {
-namespace test {
-
-class MockLsa : public Lsa
-{
-public:
-  MockLsa()
-  {
-  }
-
-  std::string
-  serialize() const override;
-
-  bool
-  deserialize(const std::string& content) noexcept override;
-
-  void
-  writeLog() const override;
-};
-
-} // namespace test
-} // namespace nlsr
-
-#endif // NLSR_TESTS_MOCKS_LSA_HPP
diff --git a/tests/publisher/publisher-fixture.hpp b/tests/publisher/publisher-fixture.hpp
index be97a34..18a51f0 100644
--- a/tests/publisher/publisher-fixture.hpp
+++ b/tests/publisher/publisher-fixture.hpp
@@ -64,40 +64,6 @@
     lsa.addAdjacent(std::move(adjacency));
   }
 
-  void
-  checkTlvLsaInfo(const tlv::LsaInfo& info, Lsa& lsa)
-  {
-    BOOST_CHECK_EQUAL(info.getOriginRouter(), lsa.getOrigRouter());
-    BOOST_CHECK_EQUAL(info.getSequenceNumber(), lsa.getLsSeqNo());
-    BOOST_CHECK_LE(info.getExpirationPeriod(), ndn::time::milliseconds(0));
-  }
-
-  void
-  checkTlvAdjLsa(const ndn::Block& block, AdjLsa& lsa)
-  {
-    BOOST_CHECK_EQUAL(block.type(), ndn::tlv::nlsr::AdjacencyLsa);
-
-    tlv::AdjacencyLsa tlvLsa;
-    BOOST_REQUIRE_NO_THROW(tlvLsa.wireDecode(block));
-
-    checkTlvAdjLsa(tlvLsa, lsa);
-  }
-
-  void
-  checkTlvAdjLsa(const tlv::AdjacencyLsa& tlvLsa, AdjLsa& lsa)
-  {
-    checkTlvLsaInfo(tlvLsa.getLsaInfo(), lsa);
-
-    std::list<tlv::Adjacency>::const_iterator it = tlvLsa.getAdjacencies().begin();
-
-    for (const Adjacent& adjacency : lsa.getAdl().getAdjList()) {
-      BOOST_CHECK_EQUAL(it->getName(), adjacency.getName());
-      BOOST_CHECK_EQUAL(it->getUri(), adjacency.getFaceUri().toString());
-      BOOST_CHECK_EQUAL(it->getCost(), adjacency.getLinkCost());
-      ++it;
-    }
-  }
-
   NextHop
   createNextHop(const std::string& faceUri, double cost)
   {
@@ -113,50 +79,6 @@
     return lsa;
   }
 
-  void
-  checkTlvCoordinateLsa(const ndn::Block& block, CoordinateLsa& lsa)
-  {
-    BOOST_CHECK_EQUAL(block.type(), ndn::tlv::nlsr::CoordinateLsa);
-
-    tlv::CoordinateLsa tlvLsa;
-    BOOST_REQUIRE_NO_THROW(tlvLsa.wireDecode(block));
-
-    checkTlvCoordinateLsa(tlvLsa, lsa);
-  }
-
-  void
-  checkTlvCoordinateLsa(const tlv::CoordinateLsa& tlvLsa, CoordinateLsa& lsa)
-  {
-    checkTlvLsaInfo(tlvLsa.getLsaInfo(), lsa);
-
-    BOOST_CHECK_EQUAL(tlvLsa.getHyperbolicRadius(), lsa.getCorRadius());
-    BOOST_CHECK(tlvLsa.getHyperbolicAngle() == lsa.getCorTheta());
-  }
-
-  void
-  checkTlvNameLsa(const ndn::Block& block, NameLsa& lsa)
-  {
-    BOOST_CHECK_EQUAL(block.type(), ndn::tlv::nlsr::NameLsa);
-
-    tlv::NameLsa tlvLsa;
-    BOOST_REQUIRE_NO_THROW(tlvLsa.wireDecode(block));
-
-    checkTlvNameLsa(tlvLsa, lsa);
-  }
-
-  void
-  checkTlvNameLsa(const tlv::NameLsa& tlvLsa, NameLsa& lsa)
-  {
-    checkTlvLsaInfo(tlvLsa.getLsaInfo(), lsa);
-
-    std::list<ndn::Name>::const_iterator it = tlvLsa.getNames().begin();
-
-    for (const ndn::Name& name : lsa.getNpl().getNames()) {
-      BOOST_CHECK_EQUAL(*it, name);
-      ++it;
-    }
-  }
-
 public:
   ndn::util::DummyClientFace face;
   ConfParameter conf;
diff --git a/tests/publisher/test-dataset-interest-handler.cpp b/tests/publisher/test-dataset-interest-handler.cpp
index b25576f..7342f62 100644
--- a/tests/publisher/test-dataset-interest-handler.cpp
+++ b/tests/publisher/test-dataset-interest-handler.cpp
@@ -56,7 +56,7 @@
 
   // Install adjacency LSA
   AdjLsa adjLsa;
-  adjLsa.setOrigRouter("/RouterA");
+  adjLsa.m_originRouter = "/RouterA";
   addAdjacency(adjLsa, "/RouterA/adjacency1", "udp://face-1", 10);
   lsdb.installAdjLsa(adjLsa);
 
@@ -68,7 +68,7 @@
 
   // Install Name LSA
   NameLsa nameLsa;
-  nameLsa.setOrigRouter("/RouterA");
+  nameLsa.m_originRouter = "/RouterA";
   nameLsa.addName("/RouterA/name1");
   lsdb.installNameLsa(nameLsa);
 
@@ -113,7 +113,7 @@
 
   // Install adjacencies LSA
   AdjLsa adjLsa;
-  adjLsa.setOrigRouter("/RouterA");
+  adjLsa.m_originRouter = "/RouterA";
   addAdjacency(adjLsa, "/RouterA/adjacency1", "udp://face-1", 10);
   lsdb.installAdjLsa(adjLsa);
 
diff --git a/tests/security/test-certificate-store.cpp b/tests/security/test-certificate-store.cpp
index b09bd5a..0009c17 100644
--- a/tests/security/test-certificate-store.cpp
+++ b/tests/security/test-certificate-store.cpp
@@ -174,7 +174,7 @@
   lsaInterestName.append(conf.getLsaPrefix().getSubName(1));
   lsaInterestName.append(conf.getSiteName());
   lsaInterestName.append(conf.getRouterName());
-  lsaInterestName.append(std::to_string(Lsa::Type::NAME));
+  lsaInterestName.append(boost::lexical_cast<std::string>(Lsa::Type::NAME));
   lsaInterestName.appendNumber(nlsr.m_lsdb.m_sequencingManager.getNameLsaSeq() + 1);
 
   lsdb.expressInterest(lsaInterestName, 0);
@@ -188,8 +188,8 @@
 
   ndn::Data data(lsaDataName);
   data.setFreshnessPeriod(ndn::time::seconds(10));
-  ndn::Data dummyData;
-  data.setContent(dummyData.getContent());
+  NameLsa nameLsa;
+  data.setContent(nameLsa.wireEncode());
   data.setFinalBlock(lsaDataName[-1]);
 
   // Sign data with this NLSR's key (in real it would be different NLSR)
@@ -200,10 +200,10 @@
 
   // Make NLSR validate data signed by its own key
   conf.getValidator().validate(data,
-                               [] (const ndn::Data&) { BOOST_CHECK(true); },
-                               [] (const ndn::Data&, const ndn::security::v2::ValidationError&) {
-                                 BOOST_CHECK(false);
-                               });
+                                 [] (const ndn::Data&) { BOOST_CHECK(true); },
+                                 [] (const ndn::Data&, const ndn::security::v2::ValidationError&) {
+                                   BOOST_CHECK(false);
+                                 });
 
   lsdb.emitSegmentValidatedSignal(data);
   const auto keyName = data.getSignature().getKeyLocator().getName();
diff --git a/tests/test-adjacent.cpp b/tests/test-adjacent.cpp
index a65ef97..3d61a3a 100644
--- a/tests/test-adjacent.cpp
+++ b/tests/test-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).
diff --git a/tests/test-hyperbolic-calculator.cpp b/tests/test-hyperbolic-calculator.cpp
index 0011ce9..2a787ba 100644
--- a/tests/test-hyperbolic-calculator.cpp
+++ b/tests/test-hyperbolic-calculator.cpp
@@ -24,7 +24,7 @@
 #include "route/routing-table-calculator.hpp"
 
 #include "adjacency-list.hpp"
-#include "lsa.hpp"
+//#include "lsa.hpp"
 #include "lsdb.hpp"
 #include "nlsr.hpp"
 #include "route/map.hpp"
@@ -68,7 +68,7 @@
     lsdb.installAdjLsa(adjA);
 
 
-    CoordinateLsa coordA(adjA.getOrigRouter(), 1, MAX_TIME, 16.23, anglesA);
+    CoordinateLsa coordA(adjA.getOriginRouter(), 1, MAX_TIME, 16.23, anglesA);
     lsdb.installCoordinateLsa(coordA);
 
     // Router B
@@ -82,7 +82,7 @@
     AdjLsa adjB(b.getName(), 1, MAX_TIME, 2, adjacencyListB);
     lsdb.installAdjLsa(adjB);
 
-    CoordinateLsa coordB(adjB.getOrigRouter(), 1, MAX_TIME, 16.59, anglesB);
+    CoordinateLsa coordB(adjB.getOriginRouter(), 1, MAX_TIME, 16.59, anglesB);
     lsdb.installCoordinateLsa(coordB);
 
     // Router C
@@ -96,7 +96,7 @@
     AdjLsa adjC(c.getName(), 1, MAX_TIME, 2, adjacencyListC);
     lsdb.installAdjLsa(adjC);
 
-    CoordinateLsa coordC(adjC.getOrigRouter(), 1, MAX_TIME, 14.11, anglesC);
+    CoordinateLsa coordC(adjC.getOriginRouter(), 1, MAX_TIME, 14.11, anglesC);
     lsdb.installCoordinateLsa(coordC);
 
     map.createFromAdjLsdb(lsdb.getAdjLsdb().begin(), lsdb.getAdjLsdb().end());
diff --git a/tests/test-link-state-calculator.cpp b/tests/test-link-state-calculator.cpp
index 2d8ee1b..f43c4f6 100644
--- a/tests/test-link-state-calculator.cpp
+++ b/tests/test-link-state-calculator.cpp
@@ -22,7 +22,7 @@
 #include "route/routing-table-calculator.hpp"
 
 #include "adjacency-list.hpp"
-#include "lsa.hpp"
+//#include "lsa.hpp"
 #include "lsdb.hpp"
 #include "nlsr.hpp"
 #include "test-common.hpp"
@@ -172,11 +172,11 @@
 BOOST_AUTO_TEST_CASE(Asymmetric)
 {
   // Asymmetric link cost between B and C
-  ndn::Name key = ndn::Name(ROUTER_B_NAME).append(std::to_string(Lsa::Type::ADJACENCY));
+  ndn::Name key = ndn::Name(ROUTER_B_NAME).append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
   AdjLsa* lsa = nlsr.m_lsdb.findAdjLsa(key);
   BOOST_REQUIRE(lsa != nullptr);
 
-  auto c = lsa->getAdl().findAdjacent(ROUTER_C_NAME);
+  auto c = lsa->m_adl.findAdjacent(ROUTER_C_NAME);
   BOOST_REQUIRE(c != conf.getAdjacencyList().end());
 
   double higherLinkCost = LINK_BC_COST + 1;
@@ -221,11 +221,11 @@
 BOOST_AUTO_TEST_CASE(NonAdjacentCost)
 {
   // Asymmetric link cost between B and C
-  ndn::Name key = ndn::Name(ROUTER_B_NAME).append(std::to_string(Lsa::Type::ADJACENCY));
+  ndn::Name key = ndn::Name(ROUTER_B_NAME).append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
   auto lsa = nlsr.m_lsdb.findAdjLsa(key);
   BOOST_REQUIRE(lsa != nullptr);
 
-  auto c = lsa->getAdl().findAdjacent(ROUTER_C_NAME);
+  auto c = lsa->m_adl.findAdjacent(ROUTER_C_NAME);
   BOOST_REQUIRE(c != conf.getAdjacencyList().end());
 
   // Break the link between B - C by setting it to a NON_ADJACENT_COST.
@@ -263,24 +263,24 @@
 BOOST_AUTO_TEST_CASE(AsymmetricZeroCostLink)
 {
   // Asymmetric and zero link cost between B - C, and B - A.
-  ndn::Name keyB = ndn::Name(ROUTER_B_NAME).append(std::to_string(Lsa::Type::ADJACENCY));
+  ndn::Name keyB = ndn::Name(ROUTER_B_NAME).append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
   auto lsaB = nlsr.m_lsdb.findAdjLsa(keyB);
   BOOST_REQUIRE(lsaB != nullptr);
 
-  auto c = lsaB->getAdl().findAdjacent(ROUTER_C_NAME);
+  auto c = lsaB->m_adl.findAdjacent(ROUTER_C_NAME);
   BOOST_REQUIRE(c != conf.getAdjacencyList().end());
   // Re-adjust link cost to 0 from B-C. However, this should not set B-C cost 0 because C-B
   // cost is greater that 0 i.e. 17
   c->setLinkCost(0);
 
-  auto a = lsaB->getAdl().findAdjacent(ROUTER_A_NAME);
+  auto a = lsaB->m_adl.findAdjacent(ROUTER_A_NAME);
   BOOST_REQUIRE(a != conf.getAdjacencyList().end());
 
-  ndn::Name keyA = ndn::Name(ROUTER_A_NAME).append(std::to_string(Lsa::Type::ADJACENCY));
+  ndn::Name keyA = ndn::Name(ROUTER_A_NAME).append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
   auto lsaA = nlsr.m_lsdb.findAdjLsa(keyA);
   BOOST_REQUIRE(lsaA != nullptr);
 
-  auto b = lsaA->getAdl().findAdjacent(ROUTER_B_NAME);
+  auto b = lsaA->m_adl.findAdjacent(ROUTER_B_NAME);
   BOOST_REQUIRE(b != conf.getAdjacencyList().end());
 
   // Re-adjust link cost to 0 from both the direction i.e B-A and A-B
diff --git a/tests/test-lsa-rule.cpp b/tests/test-lsa-rule.cpp
index dffe174..00c0ded 100644
--- a/tests/test-lsa-rule.cpp
+++ b/tests/test-lsa-rule.cpp
@@ -119,7 +119,7 @@
   lsaDataName.append(confParam.getRouterName());
 
   // Append LSA type
-  lsaDataName.append(std::to_string(Lsa::Type::NAME));
+  lsaDataName.append(boost::lexical_cast<std::string>(Lsa::Type::NAME));
 
   // This would be the sequence number of its own NameLsa
   lsaDataName.appendNumber(nlsr.m_lsdb.m_sequencingManager.getNameLsaSeq());
@@ -149,7 +149,7 @@
   lsaDataName.append(confParam.getRouterName());
 
   // Append LSA type
-  lsaDataName.append(std::to_string(Lsa::Type::NAME));
+  lsaDataName.append(boost::lexical_cast<std::string>(Lsa::Type::NAME));
 
   // This would be the sequence number of its own NameLsa
   lsaDataName.appendNumber(nlsr.m_lsdb.m_sequencingManager.getNameLsaSeq());
diff --git a/tests/test-lsa-segment-storage.cpp b/tests/test-lsa-segment-storage.cpp
index 2881d88..7862e45 100644
--- a/tests/test-lsa-segment-storage.cpp
+++ b/tests/test-lsa-segment-storage.cpp
@@ -26,7 +26,7 @@
 #include "test-common.hpp"
 #include "nlsr.hpp"
 #include "name-prefix-list.hpp"
-#include "lsa.hpp"
+// #include "lsa.hpp"
 
 namespace nlsr {
 namespace test {
@@ -68,9 +68,9 @@
       npl1.insert("name1-" + std::to_string(i));
     }
     NameLsa nameLsa("/ndn/other-site/%C1.Router/other-router", 12,
-                    ndn::time::system_clock::now() + ndn::time::seconds(LSA_REFRESH_TIME_DEFAULT), npl1);
-    segmentPublisher.publish(interestName, interestName,
-                             ndn::encoding::makeStringBlock(ndn::tlv::Content, nameLsa.serialize()),
+                    ndn::time::system_clock::now() + ndn::time::seconds(LSA_REFRESH_TIME_DEFAULT),
+                    npl1);
+    segmentPublisher.publish(interestName, interestName, nameLsa.wireEncode(),
                              ndn::time::seconds(LSA_REFRESH_TIME_DEFAULT));
   }
 
diff --git a/tests/test-lsa.cpp b/tests/test-lsa.cpp
index 20fc1c1..fb08473 100644
--- a/tests/test-lsa.cpp
+++ b/tests/test-lsa.cpp
@@ -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.
  *
@@ -19,43 +19,162 @@
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  **/
 
-#include "lsa.hpp"
+#include "lsa/name-lsa.hpp"
+#include "lsa/adj-lsa.hpp"
+#include "lsa/coordinate-lsa.hpp"
 #include "test-common.hpp"
 #include "adjacent.hpp"
 #include "name-prefix-list.hpp"
 
 #include <ndn-cxx/util/time.hpp>
-#include <sstream>
 
 namespace nlsr {
 namespace test {
 
+/*static void
+printBytes(const uint8_t* buf, size_t size)
+{
+  std::string hex = ndn::toHex(buf, size);
+
+  for (size_t i = 0; i < hex.size(); i++) {
+    if (i > 0 && i % 30 == 0)
+      std::cout << "\n  ";
+
+    std::cout << "0x" << hex[i];
+    std::cout << hex[++i];
+
+    if ((i + 1) != hex.size())
+      std::cout << ", ";
+  }
+  std::cout << "\n" << "};" << std::endl;
+}
+
+printBytes(wire.wire(), wire.size());*/
+
 BOOST_AUTO_TEST_SUITE(TestLsa)
 
+const uint8_t NAME_LSA1[] = {
+  0x89, 0x37, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0C, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x33, 0x34, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61,
+  0x6D, 0x65, 0x31, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61, 0x6D, 0x65, 0x32
+};
+
+const uint8_t NAME_LSA_EXTRA_NAME[] = {
+  0x89, 0x40, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0C, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x33, 0x34, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61,
+  0x6D, 0x65, 0x31, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61, 0x6D, 0x65, 0x32, 0x07, 0x07, 0x08,
+  0x05, 0x6E, 0x61, 0x6D, 0x65, 0x33
+};
+
+const uint8_t NAME_LSA_DIFF_SEQ[] = {
+  0x89, 0x40, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0E, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x33, 0x34, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61,
+  0x6D, 0x65, 0x31, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61, 0x6D, 0x65, 0x32, 0x07, 0x07, 0x08,
+  0x05, 0x6E, 0x61, 0x6D, 0x65, 0x33
+};
+
+const uint8_t NAME_LSA_DIFF_TS[] = {
+  0x89, 0x40, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0E, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x34, 0x34, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61,
+  0x6D, 0x65, 0x31, 0x07, 0x07, 0x08, 0x05, 0x6E, 0x61, 0x6D, 0x65, 0x32, 0x07, 0x07, 0x08,
+  0x05, 0x6E, 0x61, 0x6D, 0x65, 0x33
+};
+
 BOOST_AUTO_TEST_CASE(NameLsaBasic)
 {
   ndn::Name s1{"name1"};
   ndn::Name s2{"name2"};
   NamePrefixList npl1{s1, s2};
 
-  ndn::time::system_clock::TimePoint testTimePoint =  ndn::time::system_clock::now();
+  ndn::time::system_clock::TimePoint testTimePoint =
+    ndn::time::fromUnixTimestamp(ndn::time::milliseconds(1585196014943));
 
-  //3rd arg is seqNo. which will be a random number I just put in 12.
+  // 3rd argument is seqNo
   NameLsa nlsa1("router1", 12, testTimePoint, npl1);
   NameLsa nlsa2("router2", 12, testTimePoint, npl1);
 
   BOOST_CHECK_EQUAL(nlsa1.getType(), Lsa::Type::NAME);
-
   BOOST_CHECK(nlsa1.getExpirationTimePoint() == nlsa2.getExpirationTimePoint());
-
   BOOST_CHECK(nlsa1.getKey() != nlsa2.getKey());
+
+  auto wire = nlsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(NAME_LSA1, NAME_LSA1 + sizeof(NAME_LSA1),
+                                wire.begin(), wire.end());
+
+  nlsa1.addName("name3");
+  wire = nlsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(NAME_LSA_EXTRA_NAME,
+                                NAME_LSA_EXTRA_NAME + sizeof(NAME_LSA_EXTRA_NAME),
+                                wire.begin(), wire.end());
+
+  nlsa1.setSeqNo(14);
+  wire = nlsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(NAME_LSA_DIFF_SEQ, NAME_LSA_DIFF_SEQ + sizeof(NAME_LSA_DIFF_SEQ),
+                                wire.begin(), wire.end());
+
+  testTimePoint =
+    ndn::time::fromUnixTimestamp(ndn::time::milliseconds(1585196024993));
+  nlsa1.setExpirationTimePoint(testTimePoint);
+  wire = nlsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(NAME_LSA_DIFF_TS, NAME_LSA_DIFF_TS + sizeof(NAME_LSA_DIFF_TS),
+                                wire.begin(), wire.end());
+  // Not testing router name as not sure if that will ever change once set
 }
 
-BOOST_AUTO_TEST_CASE(AdjacentLsaConstructorAndGetters)
+const uint8_t ADJ_LSA1[] = {
+  0x83, 0x58, 0x80, 0x2D, 0x07, 0x13, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04, 0x73, 0x69,
+  0x74, 0x65, 0x08, 0x06, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x82, 0x01, 0x0C, 0x8B, 0x13,
+  0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36, 0x20, 0x30, 0x34, 0x3A, 0x31,
+  0x33, 0x3A, 0x33, 0x34, 0x84, 0x27, 0x07, 0x16, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04,
+  0x73, 0x69, 0x74, 0x65, 0x08, 0x09, 0x61, 0x64, 0x6A, 0x61, 0x63, 0x65, 0x6E, 0x63, 0x79,
+  0x8D, 0x03, 0x3A, 0x2F, 0x2F, 0x8C, 0x08, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t ADJ_LSA_EXTRA_NEIGHBOR[] = {
+  0x83, 0x80, 0x80, 0x2D, 0x07, 0x13, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04, 0x73, 0x69,
+  0x74, 0x65, 0x08, 0x06, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x82, 0x01, 0x0C, 0x8B, 0x13,
+  0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36, 0x20, 0x30, 0x34, 0x3A, 0x31,
+  0x33, 0x3A, 0x33, 0x34, 0x84, 0x27, 0x07, 0x16, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04,
+  0x73, 0x69, 0x74, 0x65, 0x08, 0x09, 0x61, 0x64, 0x6A, 0x61, 0x63, 0x65, 0x6E, 0x63, 0x79,
+  0x8D, 0x03, 0x3A, 0x2F, 0x2F, 0x8C, 0x08, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x84, 0x26, 0x07, 0x15, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x03, 0x65, 0x64, 0x75, 0x08,
+  0x09, 0x61, 0x64, 0x6A, 0x61, 0x63, 0x65, 0x6E, 0x63, 0x79, 0x8D, 0x03, 0x3A, 0x2F, 0x2F,
+  0x8C, 0x08, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t ADJ_LSA_DIFF_SEQ[] = {
+  0x83, 0x80, 0x80, 0x2D, 0x07, 0x13, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04, 0x73, 0x69,
+  0x74, 0x65, 0x08, 0x06, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x82, 0x01, 0x0E, 0x8B, 0x13,
+  0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36, 0x20, 0x30, 0x34, 0x3A, 0x31,
+  0x33, 0x3A, 0x33, 0x34, 0x84, 0x27, 0x07, 0x16, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04,
+  0x73, 0x69, 0x74, 0x65, 0x08, 0x09, 0x61, 0x64, 0x6A, 0x61, 0x63, 0x65, 0x6E, 0x63, 0x79,
+  0x8D, 0x03, 0x3A, 0x2F, 0x2F, 0x8C, 0x08, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x84, 0x26, 0x07, 0x15, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x03, 0x65, 0x64, 0x75, 0x08,
+  0x09, 0x61, 0x64, 0x6A, 0x61, 0x63, 0x65, 0x6E, 0x63, 0x79, 0x8D, 0x03, 0x3A, 0x2F, 0x2F,
+  0x8C, 0x08, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+const uint8_t ADJ_LSA_DIFF_TS[] = {
+  0x83, 0x80, 0x80, 0x2D, 0x07, 0x13, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04, 0x73, 0x69,
+  0x74, 0x65, 0x08, 0x06, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x82, 0x01, 0x0E, 0x8B, 0x13,
+  0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36, 0x20, 0x30, 0x34, 0x3A, 0x31,
+  0x33, 0x3A, 0x34, 0x34, 0x84, 0x27, 0x07, 0x16, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x04,
+  0x73, 0x69, 0x74, 0x65, 0x08, 0x09, 0x61, 0x64, 0x6A, 0x61, 0x63, 0x65, 0x6E, 0x63, 0x79,
+  0x8D, 0x03, 0x3A, 0x2F, 0x2F, 0x8C, 0x08, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x84, 0x26, 0x07, 0x15, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x03, 0x65, 0x64, 0x75, 0x08,
+  0x09, 0x61, 0x64, 0x6A, 0x61, 0x63, 0x65, 0x6E, 0x63, 0x79, 0x8D, 0x03, 0x3A, 0x2F, 0x2F,
+  0x8C, 0x08, 0x40, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+BOOST_AUTO_TEST_CASE(AdjLsaBasic)
 {
   ndn::Name routerName("/ndn/site/router");
   ndn::Name adjacencyName("/ndn/site/adjacency");
-  ndn::time::system_clock::TimePoint testTimePoint =  ndn::time::system_clock::now();
+  ndn::time::system_clock::TimePoint testTimePoint =
+    ndn::time::fromUnixTimestamp(ndn::time::milliseconds(1585196014943));
   uint32_t seqNo = 12;
 
   // An AdjLsa initialized with ACTIVE adjacencies should copy the adjacencies
@@ -68,7 +187,7 @@
                activeAdjacencies.size(), activeAdjacencies);
   BOOST_CHECK_EQUAL(alsa1.getAdl().size(), 1);
   BOOST_CHECK_EQUAL(alsa1.getType(), Lsa::Type::ADJACENCY);
-  BOOST_CHECK_EQUAL(alsa1.getLsSeqNo(), seqNo);
+  BOOST_CHECK_EQUAL(alsa1.getSeqNo(), seqNo);
   BOOST_CHECK_EQUAL(alsa1.getExpirationTimePoint(), testTimePoint);
   BOOST_CHECK_EQUAL(alsa1.getNoLink(), 1);
   BOOST_CHECK(alsa1.getAdl().isNeighbor(activeAdjacency.getName()));
@@ -90,12 +209,73 @@
   AdjLsa alsa3(routerName, seqNo, testTimePoint,
                activeAdjacencies.size(), activeAdjacencies);
   BOOST_CHECK(alsa1.isEqualContent(alsa3));
+
+  auto wire = alsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(ADJ_LSA1, ADJ_LSA1 + sizeof(ADJ_LSA1),
+                                wire.begin(), wire.end());
+
+  Adjacent activeAdjacency2("/ndn/edu/adjacency");
+  activeAdjacency2.setStatus(Adjacent::STATUS_ACTIVE);
+  alsa1.addAdjacent(activeAdjacency2);
+  wire = alsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(ADJ_LSA_EXTRA_NEIGHBOR,
+                                ADJ_LSA_EXTRA_NEIGHBOR + sizeof(ADJ_LSA_EXTRA_NEIGHBOR),
+                                wire.begin(), wire.end());
+
+  alsa1.setSeqNo(14);
+  wire = alsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(ADJ_LSA_DIFF_SEQ, ADJ_LSA_DIFF_SEQ + sizeof(ADJ_LSA_DIFF_SEQ),
+                                wire.begin(), wire.end());
+
+  testTimePoint =
+    ndn::time::fromUnixTimestamp(ndn::time::milliseconds(1585196024993));
+  alsa1.setExpirationTimePoint(testTimePoint);
+  wire = alsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(ADJ_LSA_DIFF_TS, ADJ_LSA_DIFF_TS + sizeof(ADJ_LSA_DIFF_TS),
+                                wire.begin(), wire.end());
 }
 
-BOOST_AUTO_TEST_CASE(CoordinateLsaConstructorAndGetters)
+const uint8_t COORDINATE_LSA1[] = {
+  0x85, 0x43, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0C, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x33, 0x34, 0x87, 0x08, 0x40, 0x04, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x88, 0x08, 0x40, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
+  0x08, 0x40, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t COORDINATE_LSA_DIFF_ANGLE[] = {
+  0x85, 0x39, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0C, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x33, 0x34, 0x87, 0x08, 0x40, 0x04, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x88, 0x08, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t COORDINATE_LSA_DIFF_RADIUS[] = {
+  0x85, 0x39, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0C, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x33, 0x34, 0x87, 0x08, 0x40, 0x02, 0x66, 0x66,
+  0x66, 0x66, 0x66, 0x66, 0x88, 0x08, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t COORDINATE_LSA_DIFF_SEQ[] = {
+  0x85, 0x39, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0E, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x33, 0x34, 0x87, 0x08, 0x40, 0x02, 0x66, 0x66,
+  0x66, 0x66, 0x66, 0x66, 0x88, 0x08, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+const uint8_t COORDINATE_LSA_DIFF_TS[] = {
+  0x85, 0x39, 0x80, 0x23, 0x07, 0x09, 0x08, 0x07, 0x72, 0x6F, 0x75, 0x74, 0x65, 0x72, 0x31,
+  0x82, 0x01, 0x0E, 0x8B, 0x13, 0x32, 0x30, 0x32, 0x30, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x36,
+  0x20, 0x30, 0x34, 0x3A, 0x31, 0x33, 0x3A, 0x34, 0x34, 0x87, 0x08, 0x40, 0x02, 0x66, 0x66,
+  0x66, 0x66, 0x66, 0x66, 0x88, 0x08, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+BOOST_AUTO_TEST_CASE(CoordinateLsaBasic)
 {
-  ndn::time::system_clock::TimePoint testTimePoint =  ndn::time::system_clock::now();
-  std::vector<double> angles1, angles2;
+  ndn::time::system_clock::TimePoint testTimePoint =
+    ndn::time::fromUnixTimestamp(ndn::time::milliseconds(1585196014943));
+  std::vector<double> angles1 {30.0}, angles2 {30.0};
   angles1.push_back(30.0);
   angles2.push_back(30.0);
   CoordinateLsa clsa1("router1", 12, testTimePoint, 2.5, angles1);
@@ -106,7 +286,38 @@
 
   BOOST_CHECK(clsa1.isEqualContent(clsa2));
 
-  BOOST_CHECK_EQUAL(clsa1.serialize(), clsa2.serialize());
+  BOOST_CHECK_EQUAL(clsa1.wireEncode(), clsa2.wireEncode());
+
+  auto wire = clsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(COORDINATE_LSA1, COORDINATE_LSA1 + sizeof(COORDINATE_LSA1),
+                                wire.begin(), wire.end());
+
+  std::vector<double> angles3{40.0};
+  clsa1.setCorTheta(angles3);
+  wire = clsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(COORDINATE_LSA_DIFF_ANGLE,
+                                COORDINATE_LSA_DIFF_ANGLE + sizeof(COORDINATE_LSA_DIFF_ANGLE),
+                                wire.begin(), wire.end());
+
+  clsa1.setCorRadius(2.3);
+  wire = clsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(COORDINATE_LSA_DIFF_RADIUS,
+                                COORDINATE_LSA_DIFF_RADIUS + sizeof(COORDINATE_LSA_DIFF_RADIUS),
+                                wire.begin(), wire.end());
+
+  clsa1.setSeqNo(14);
+  wire = clsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(COORDINATE_LSA_DIFF_SEQ,
+                                COORDINATE_LSA_DIFF_SEQ + sizeof(COORDINATE_LSA_DIFF_SEQ),
+                                wire.begin(), wire.end());
+
+  testTimePoint =
+    ndn::time::fromUnixTimestamp(ndn::time::milliseconds(1585196024993));
+  clsa1.setExpirationTimePoint(testTimePoint);
+  wire = clsa1.wireEncode();
+  BOOST_CHECK_EQUAL_COLLECTIONS(COORDINATE_LSA_DIFF_TS,
+                                COORDINATE_LSA_DIFF_TS + sizeof(COORDINATE_LSA_DIFF_TS),
+                                wire.begin(), wire.end());
 }
 
 BOOST_AUTO_TEST_CASE(IncrementAdjacentNumber)
@@ -121,7 +332,7 @@
   adjList.insert(adj1);
   adjList.insert(adj2);
 
-  ndn::time::system_clock::TimePoint testTimePoint = ndn::time::system_clock::now();
+  ndn::time::system_clock::TimePoint testTimePoint = ndn::time::system_clock::now() + ndn::time::seconds(3600);
   std::ostringstream ss;
   ss << testTimePoint;
 
@@ -130,19 +341,13 @@
   AdjLsa lsa("router1", 12, testTimePoint, adjList.size(), adjList);
 
   std::string EXPECTED_OUTPUT =
-    "LSA of type ADJACENCY:\n"
-    "-Origin Router: /router1\n"
-    "-Sequence Number: 12\n"
-    "-Expiration Point: " + TEST_TIME_POINT_STRING + "\n"
-    "-Adjacents:--Adjacent1:\n"
-    "---Adjacent Name: /adjacent1\n"
-    "---Connecting FaceUri: ://\n"
-    "---Link Cost: 10\n"
-    "--Adjacent2:\n"
-    "---Adjacent Name: /adjacent2\n"
-    "---Connecting FaceUri: ://\n"
-    "---Link Cost: 10\n"
-    "adj_lsa_end";
+    "    ADJACENCY LSA:\n"
+    "      Origin Router      : /router1\n"
+    "      Sequence Number    : 12\n"
+    "      Expires in         : 3599999 milliseconds\n"
+    "      Adjacents:\n"
+    "        Adjacent 0: (name=/adjacent1, uri=://, cost=10)\n"
+    "        Adjacent 1: (name=/adjacent2, uri=://, cost=10)\n";
 
   std::ostringstream os;
   os << lsa;
@@ -172,10 +377,7 @@
   ndn::time::system_clock::TimePoint testTimePoint = ndn::time::system_clock::now();
 
   AdjLsa adjlsa1("router1", 1, testTimePoint, adjList.size(), adjList);
-  AdjLsa adjlsa2;
-
-  BOOST_CHECK(adjlsa2.deserialize(adjlsa1.serialize()));
-
+  AdjLsa adjlsa2(adjlsa1.wireEncode());
   BOOST_CHECK(adjlsa1.isEqualContent(adjlsa2));
 
   //Name LSA
@@ -184,24 +386,16 @@
   NamePrefixList npl1{s1, s2};
 
   NameLsa nlsa1("router1", 1, testTimePoint, npl1);
-  NameLsa nlsa2;
-
-  BOOST_CHECK(nlsa2.deserialize(nlsa1.serialize()));
-
-  BOOST_CHECK_EQUAL(nlsa1.serialize(), nlsa2.serialize());
+  NameLsa nlsa2(nlsa1.wireEncode());
+  BOOST_CHECK_EQUAL(nlsa1.wireEncode(), nlsa2.wireEncode());
 
   //Coordinate LSA
   std::vector<double> angles = {30, 40.0};
   CoordinateLsa clsa1("router1", 12, testTimePoint, 2.5, angles);
-  CoordinateLsa clsa2;
-
-  BOOST_CHECK(clsa2.deserialize(clsa1.serialize()));
-
-  BOOST_CHECK_EQUAL(clsa1.serialize(), clsa2.serialize());
+  CoordinateLsa clsa2(clsa1.wireEncode());
+  BOOST_CHECK_EQUAL(clsa1.wireEncode(), clsa2.wireEncode());
 }
 
-BOOST_AUTO_TEST_SUITE(TestNameLsa)
-
 BOOST_AUTO_TEST_CASE(OperatorEquals)
 {
   NameLsa lsa1;
@@ -221,8 +415,6 @@
   BOOST_CHECK(lsa1.isEqualContent(lsa2));
 }
 
-BOOST_AUTO_TEST_SUITE_END() // TestNameLsa
-
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace test
diff --git a/tests/test-lsdb.cpp b/tests/test-lsdb.cpp
index 56e862b..9ed1f26 100644
--- a/tests/test-lsdb.cpp
+++ b/tests/test-lsdb.cpp
@@ -23,7 +23,7 @@
 
 #include "test-common.hpp"
 #include "nlsr.hpp"
-#include "lsa.hpp"
+#include "lsa/lsa.hpp"
 #include "name-prefix-list.hpp"
 
 #include <ndn-cxx/util/dummy-client-face.hpp>
@@ -175,12 +175,13 @@
   ndn::Name lsaKey("/ndn/site/%C1.Router/this-router/NAME");
 
   NameLsa* nameLsa = lsdb.findNameLsa(lsaKey);
-  uint64_t seqNo = nameLsa->getLsSeqNo();
+  BOOST_REQUIRE(nameLsa != nullptr);
+  uint64_t seqNo = nameLsa->getSeqNo();
 
   ndn::Name prefix("/ndn/edu/memphis/netlab/research/nlsr/test/prefix/");
 
   int nPrefixes = 0;
-  while (nameLsa->serialize().size() < ndn::MAX_NDN_PACKET_SIZE) {
+  while (nameLsa->wireEncode().size() < ndn::MAX_NDN_PACKET_SIZE) {
     nameLsa->addName(ndn::Name(prefix).appendNumber(++nPrefixes));
     break;
   }
@@ -218,17 +219,17 @@
   ndn::Name lsaKey("/ndn/site/%C1.Router/this-router/NAME");
 
   NameLsa* lsa = lsdb.findNameLsa(lsaKey);
-  uint64_t seqNo = lsa->getLsSeqNo();
+  uint64_t seqNo = lsa->getSeqNo();
 
   ndn::Name prefix("/ndn/edu/memphis/netlab/research/nlsr/test/prefix/");
 
   int nPrefixes = 0;
-  while (lsa->serialize().size() < ndn::MAX_NDN_PACKET_SIZE) {
+  while (lsa->wireEncode().size() < ndn::MAX_NDN_PACKET_SIZE) {
     lsa->addName(ndn::Name(prefix).appendNumber(++nPrefixes));
   }
   lsdb.installNameLsa(*lsa);
 
-  std::string expectedDataContent = lsa->serialize();
+  ndn::Block expectedDataContent = lsa->wireEncode();
 
   ndn::Name interestName("/localhop/ndn/nlsr/LSA/site/%C1.Router/this-router/NAME/");
   interestName.appendNumber(seqNo);
@@ -240,7 +241,7 @@
                                                   ndn::security::v2::getAcceptAllValidator());
   fetcher->onComplete.connect([&expectedDataContent] (ndn::ConstBufferPtr bufferPtr) {
                                 ndn::Block block(bufferPtr);
-                                BOOST_CHECK_EQUAL(expectedDataContent, readString(block));
+                                BOOST_CHECK_EQUAL(expectedDataContent, block);
                               });
 
   advanceClocks(ndn::time::milliseconds(1), 100);
@@ -264,13 +265,13 @@
   ndn::Name interestName("/localhop/ndn/nlsr/LSA/cs/%C1.Router/router1/NAME/");
   interestName.appendNumber(seqNo);
 
-  ndn::Block block = ndn::encoding::makeStringBlock(ndn::tlv::Content, lsa.serialize());
+  ndn::Block block = lsa.wireEncode();
   lsdb.afterFetchLsa(block.getBuffer(), interestName);
 
   NameLsa* foundLsa = lsdb.findNameLsa(lsa.getKey());
   BOOST_REQUIRE(foundLsa != nullptr);
 
-  BOOST_CHECK_EQUAL(foundLsa->serialize(), lsa.serialize());
+  BOOST_CHECK_EQUAL(foundLsa->wireEncode(), lsa.wireEncode());
 }
 
 BOOST_AUTO_TEST_CASE(LsdbRemoveAndExists)
diff --git a/tests/test-name-prefix-list.cpp b/tests/test-name-prefix-list.cpp
index 3bb93b7..687d6c3 100644
--- a/tests/test-name-prefix-list.cpp
+++ b/tests/test-name-prefix-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
  *
  * This file is part of NLSR (Named-data Link State Routing).
diff --git a/tests/test-nlsr.cpp b/tests/test-nlsr.cpp
index ab69692..ab5fd15 100644
--- a/tests/test-nlsr.cpp
+++ b/tests/test-nlsr.cpp
@@ -142,7 +142,7 @@
   Adjacent neighbor("/ndn/neighborA", ndn::FaceUri(faceUri), 10,
                     Adjacent::STATUS_INACTIVE, 0, 0);
 
-  BOOST_REQUIRE_EQUAL(conf.getAdjacencyList().insert(neighbor), 0);
+  BOOST_REQUIRE_EQUAL(conf.getAdjacencyList().insert(neighbor), true);
 
   this->advanceClocks(10_ms);
 
@@ -306,11 +306,11 @@
 
   // Make sure an adjacency LSA was built
   ndn::Name key = ndn::Name(conf.getRouterPrefix())
-    .append(std::to_string(Lsa::Type::ADJACENCY));
+    .append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
   AdjLsa* lsa = lsdb.findAdjLsa(key);
   BOOST_REQUIRE(lsa != nullptr);
 
-  uint32_t lastAdjLsaSeqNo = lsa->getLsSeqNo();
+  uint32_t lastAdjLsaSeqNo = lsa->getSeqNo();
   nlsr.m_lsdb.m_sequencingManager.setAdjLsaSeq(lastAdjLsaSeqNo);
 
   this->advanceClocks(1500_ms, 10);
@@ -345,7 +345,7 @@
   lsa = lsdb.findAdjLsa(key);
   BOOST_REQUIRE(lsa != nullptr);
 
-  BOOST_CHECK_EQUAL(lsa->getLsSeqNo(), lastAdjLsaSeqNo + 1);
+  BOOST_CHECK_EQUAL(lsa->getSeqNo(), lastAdjLsaSeqNo + 1);
 
   this->advanceClocks(15_s, 10);
 
@@ -381,7 +381,7 @@
   receiveHelloData(neighborAName, conf.getRouterPrefix());
   this->advanceClocks(1_s, 10);
 
-  ndn::Name lsaKey = ndn::Name(conf.getRouterPrefix()).append(std::to_string(Lsa::Type::ADJACENCY));
+  ndn::Name lsaKey = ndn::Name(conf.getRouterPrefix()).append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
 
   // Adjacency LSA should be built even though other router is INACTIVE
   AdjLsa* lsa = lsdb.findAdjLsa(lsaKey);
diff --git a/tests/test-sequencing-manager.cpp b/tests/test-sequencing-manager.cpp
index 6bbcb00..218952a 100644
--- a/tests/test-sequencing-manager.cpp
+++ b/tests/test-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.
  *
diff --git a/tests/test-statistics.cpp b/tests/test-statistics.cpp
index 0dbe274..cfd82b6 100644
--- a/tests/test-statistics.cpp
+++ b/tests/test-statistics.cpp
@@ -198,16 +198,16 @@
   uint32_t seqNo = 1;
 
   // Adjacency LSA
-  sendInterestAndCheckStats(interestPrefix, std::to_string(Lsa::Type::ADJACENCY), seqNo,
-                            Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
+  sendInterestAndCheckStats(interestPrefix, boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY),
+                            seqNo, Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
 
   // Coordinate LSA
-  sendInterestAndCheckStats(interestPrefix, std::to_string(Lsa::Type::COORDINATE), seqNo,
-                            Statistics::PacketType::SENT_COORD_LSA_INTEREST);
+  sendInterestAndCheckStats(interestPrefix, boost::lexical_cast<std::string>(Lsa::Type::COORDINATE),
+                            seqNo, Statistics::PacketType::SENT_COORD_LSA_INTEREST);
 
   // Name LSA
-  sendInterestAndCheckStats(interestPrefix, std::to_string(Lsa::Type::NAME), seqNo,
-                            Statistics::PacketType::SENT_NAME_LSA_INTEREST);
+  sendInterestAndCheckStats(interestPrefix, boost::lexical_cast<std::string>(Lsa::Type::NAME),
+                            seqNo, Statistics::PacketType::SENT_NAME_LSA_INTEREST);
 
   // 3 total lsa interests were sent
   BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::SENT_LSA_INTEREST), 3);
@@ -226,10 +226,10 @@
   lsdb.buildAndInstallOwnAdjLsa();
 
   ndn::Name adjLsaKey = conf.getRouterPrefix();
-  adjLsaKey.append(std::to_string(Lsa::Type::ADJACENCY));
+  adjLsaKey.append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY));
 
   AdjLsa* adjLsa = lsdb.findAdjLsa(adjLsaKey);
-  uint32_t seqNo = adjLsa->getLsSeqNo();
+  uint32_t seqNo = adjLsa->getSeqNo();
 
   Adjacent adjacency("adjacency");
   adjacency.setStatus(Adjacent::STATUS_ACTIVE);
@@ -242,26 +242,26 @@
 
   // Receive Adjacency LSA Interest
   receiveInterestAndCheckSentStats(interestPrefix,
-                                   std::to_string(Lsa::Type::ADJACENCY),
+                                   boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY),
                                    seqNo,
                                    Statistics::PacketType::RCV_ADJ_LSA_INTEREST,
                                    Statistics::PacketType::SENT_ADJ_LSA_DATA);
 
   // Name LSA
   ndn::Name nameLsaKey = conf.getRouterPrefix();
-  nameLsaKey.append(std::to_string(Lsa::Type::NAME));
+  nameLsaKey.append(boost::lexical_cast<std::string>(Lsa::Type::NAME));
 
   NameLsa* nameLsa = lsdb.findNameLsa(nameLsaKey);
   BOOST_ASSERT(nameLsa != nullptr);
 
-  seqNo = nameLsa->getLsSeqNo();
+  seqNo = nameLsa->getSeqNo();
 
   nameLsa->addName(ndn::Name("/ndn/name"));
   lsdb.installNameLsa(*nameLsa);
 
   // Receive Name LSA Interest
   receiveInterestAndCheckSentStats(interestPrefix,
-                                   std::to_string(Lsa::Type::NAME),
+                                   boost::lexical_cast<std::string>(Lsa::Type::NAME),
                                    seqNo,
                                    Statistics::PacketType::RCV_NAME_LSA_INTEREST,
                                    Statistics::PacketType::SENT_NAME_LSA_DATA);
@@ -269,16 +269,16 @@
   // // Coordinate LSA
   lsdb.buildAndInstallOwnCoordinateLsa();
   ndn::Name coorLsaKey = conf.getRouterPrefix();
-  coorLsaKey.append(std::to_string(Lsa::Type::COORDINATE));
+  coorLsaKey.append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE));
 
   CoordinateLsa* coorLsa = lsdb.findCoordinateLsa(coorLsaKey);
-  seqNo = coorLsa->getLsSeqNo();
+  seqNo = coorLsa->getSeqNo();
   coorLsa->setCorTheta({20.0, 30.0});
   lsdb.installCoordinateLsa(*coorLsa);
 
   // Receive Adjacency LSA Interest
   receiveInterestAndCheckSentStats(interestPrefix,
-                                   std::to_string(Lsa::Type::COORDINATE),
+                                   boost::lexical_cast<std::string>(Lsa::Type::COORDINATE),
                                    seqNo,
                                    Statistics::PacketType::RCV_COORD_LSA_INTEREST,
                                    Statistics::PacketType::SENT_COORD_LSA_DATA);
@@ -306,9 +306,7 @@
   AdjLsa aLsa(routerName, seqNo, MAX_TIME, 1, conf.getAdjacencyList());
   lsdb.installAdjLsa(aLsa);
 
-  ndn::Block block = ndn::encoding::makeStringBlock(ndn::tlv::Content, aLsa.serialize());
-
-  lsdb.afterFetchLsa(block.getBuffer(), adjInterest);
+  lsdb.afterFetchLsa(aLsa.wireEncode().getBuffer(), adjInterest);
   BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_ADJ_LSA_DATA), 1);
 
   // coordinate lsa
@@ -318,20 +316,16 @@
   CoordinateLsa cLsa(routerName, seqNo, MAX_TIME, 2.5, angles);
   lsdb.installCoordinateLsa(cLsa);
 
-  block = ndn::encoding::makeStringBlock(ndn::tlv::Content, cLsa.serialize());
-
-  lsdb.afterFetchLsa(block.getBuffer(), coordInterest);
+  lsdb.afterFetchLsa(cLsa.wireEncode().getBuffer(), coordInterest);
   BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_COORD_LSA_DATA), 1);
 
   // name lsa
   ndn::Name interestName("/localhop/ndn/nlsr/LSA/cs/%C1.Router/router1/NAME/");
   interestName.appendNumber(seqNo);
-  NameLsa nLsa(routerName, seqNo, MAX_TIME, conf.getNamePrefixList());
-  lsdb.installNameLsa(nLsa);
+  NameLsa nlsa(routerName, seqNo, MAX_TIME, conf.getNamePrefixList());
+  lsdb.installNameLsa(nlsa);
 
-  block = ndn::encoding::makeStringBlock(ndn::tlv::Content, nLsa.serialize());
-
-  lsdb.afterFetchLsa(block.getBuffer(), interestName);
+  lsdb.afterFetchLsa(nlsa.wireEncode().getBuffer(), interestName);
   BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_NAME_LSA_DATA), 1);
 
   // 3 lsa data types should be received
diff --git a/tests/tlv/test-adjacency-lsa.cpp b/tests/tlv/test-adjacency-lsa.cpp
deleted file mode 100644
index 531e1a4..0000000
--- a/tests/tlv/test-adjacency-lsa.cpp
+++ /dev/null
@@ -1,223 +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 "tlv/adjacency-lsa.hpp"
-
-#include "tests/boost-test.hpp"
-
-namespace nlsr {
-namespace tlv {
-namespace test {
-
-BOOST_AUTO_TEST_SUITE(TlvTestAdjacencyLsa)
-
-const uint8_t AdjacencyLsaWithAdjacenciesData[] =
-{
-  // Header
-  0x83, 0x3d,
-  // LsaInfo
-  0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
-  0x80, 0x8b, 0x02, 0x27, 0x10,
-  // Adjacency
-  0x84, 0x13, 0x07, 0x07, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x8d, 0x05, 0x74,
-  0x65, 0x73, 0x74, 0x31, 0x8c, 0x01, 0x80,
-  // Adjacency
-  0x84, 0x13, 0x07, 0x07, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x8d, 0x05, 0x74,
-  0x65, 0x73, 0x74, 0x32, 0x8c, 0x01, 0x80
-};
-
-const uint8_t AdjacencyLsaWithoutAdjacenciesData[] =
-{
-  // Header
-  0x83, 0x13,
-  // LsaInfo
-  0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
-  0x80, 0x8b, 0x02, 0x27, 0x10
-};
-
-BOOST_AUTO_TEST_CASE(AdjacencyLsaEncodeWithAdjacencies)
-{
-  AdjacencyLsa adjacencyLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  adjacencyLsa.setLsaInfo(lsaInfo);
-
-  Adjacency adjacency1;
-  adjacency1.setName("test1");
-  adjacency1.setUri("test1");
-  adjacency1.setCost(128);
-  adjacencyLsa.addAdjacency(adjacency1);
-
-  Adjacency adjacency2;
-  adjacency2.setName("test2");
-  adjacency2.setUri("test2");
-  adjacency2.setCost(128);
-  adjacencyLsa.addAdjacency(adjacency2);
-
-  const ndn::Block& wire = adjacencyLsa.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(AdjacencyLsaWithAdjacenciesData,
-                                  AdjacencyLsaWithAdjacenciesData +
-                                    sizeof(AdjacencyLsaWithAdjacenciesData),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(AdjacencyLsaDecodeWithAdjacencies)
-{
-  AdjacencyLsa adjacencyLsa;
-
-  adjacencyLsa.wireDecode(ndn::Block(AdjacencyLsaWithAdjacenciesData,
-                                      sizeof(AdjacencyLsaWithAdjacenciesData)));
-
-  LsaInfo lsaInfo = adjacencyLsa.getLsaInfo();
-  BOOST_CHECK_EQUAL(lsaInfo.getOriginRouter(), "test");
-  BOOST_CHECK_EQUAL(lsaInfo.getSequenceNumber(), 128);
-  BOOST_CHECK_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));
-
-  BOOST_CHECK_EQUAL(adjacencyLsa.hasAdjacencies(), true);
-  std::list<Adjacency> adjacencies = adjacencyLsa.getAdjacencies();
-  std::list<Adjacency>::const_iterator it = adjacencies.begin();
-  BOOST_CHECK_EQUAL(it->getName(), "test1");
-  BOOST_CHECK_EQUAL(it->getUri(), "test1");
-  BOOST_CHECK_EQUAL(it->getCost(), 128);
-
-  it++;
-  BOOST_CHECK_EQUAL(it->getName(), "test2");
-  BOOST_CHECK_EQUAL(it->getUri(), "test2");
-  BOOST_CHECK_EQUAL(it->getCost(), 128);
-}
-
-BOOST_AUTO_TEST_CASE(AdjacencyLsaEncodeWithoutAdjacencies)
-{
-  AdjacencyLsa adjacencyLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  adjacencyLsa.setLsaInfo(lsaInfo);
-
-  const ndn::Block& wire = adjacencyLsa.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(AdjacencyLsaWithoutAdjacenciesData,
-                                  AdjacencyLsaWithoutAdjacenciesData +
-                                    sizeof(AdjacencyLsaWithoutAdjacenciesData),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(AdjacencyLsaDecodeWithoutAdjacencies)
-{
-  AdjacencyLsa adjacencyLsa;
-
-  adjacencyLsa.wireDecode(ndn::Block(AdjacencyLsaWithoutAdjacenciesData,
-                                      sizeof(AdjacencyLsaWithoutAdjacenciesData)));
-
-  LsaInfo lsaInfo = adjacencyLsa.getLsaInfo();
-  BOOST_CHECK_EQUAL(lsaInfo.getOriginRouter(), "test");
-  BOOST_CHECK_EQUAL(lsaInfo.getSequenceNumber(), 128);
-  BOOST_CHECK_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));
-
-  BOOST_CHECK_EQUAL(adjacencyLsa.hasAdjacencies(), false);
-}
-
-
-BOOST_AUTO_TEST_CASE(AdjacencyLsaClear)
-{
-  AdjacencyLsa adjacencyLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  adjacencyLsa.setLsaInfo(lsaInfo);
-
-  Adjacency adjacency1;
-  adjacency1.setName("test1");
-  adjacency1.setUri("test1");
-  adjacency1.setCost(128);
-  adjacencyLsa.addAdjacency(adjacency1);
-  BOOST_CHECK_EQUAL(adjacencyLsa.getAdjacencies().size(), 1);
-
-  std::list<Adjacency> adjacencies = adjacencyLsa.getAdjacencies();
-  std::list<Adjacency>::const_iterator it = adjacencies.begin();
-  BOOST_CHECK_EQUAL(it->getName(), "test1");
-  BOOST_CHECK_EQUAL(it->getUri(), "test1");
-  BOOST_CHECK_EQUAL(it->getCost(), 128);
-
-  adjacencyLsa.clearAdjacencies();
-  BOOST_CHECK_EQUAL(adjacencyLsa.getAdjacencies().size(), 0);
-
-  Adjacency adjacency2;
-  adjacency2.setName("test2");
-  adjacency2.setUri("test2");
-  adjacency2.setCost(128);
-  adjacencyLsa.addAdjacency(adjacency2);
-  BOOST_CHECK_EQUAL(adjacencyLsa.getAdjacencies().size(), 1);
-
-  adjacencies = adjacencyLsa.getAdjacencies();
-  it = adjacencies.begin();
-  BOOST_CHECK_EQUAL(it->getName(), "test2");
-  BOOST_CHECK_EQUAL(it->getUri(), "test2");
-  BOOST_CHECK_EQUAL(it->getCost(), 128);
-}
-
-BOOST_AUTO_TEST_CASE(AdjacencyLsaOutputStream)
-{
-  AdjacencyLsa adjacencyLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  adjacencyLsa.setLsaInfo(lsaInfo);
-
-  Adjacency adjacency1;
-  adjacency1.setName("test1");
-  adjacency1.setUri("test1");
-  adjacency1.setCost(128);
-  adjacencyLsa.addAdjacency(adjacency1);
-
-  Adjacency adjacency2;
-  adjacency2.setName("test2");
-  adjacency2.setUri("test2");
-  adjacency2.setCost(128);
-  adjacencyLsa.addAdjacency(adjacency2);
-
-  std::ostringstream os;
-  os << adjacencyLsa;
-
-  BOOST_CHECK_EQUAL(os.str(), "AdjacencyLsa("
-                                "LsaInfo("
-                                  "OriginRouter: /test, "
-                                  "SequenceNumber: 128, "
-                                  "ExpirationPeriod: 10000 milliseconds), "
-                                "Adjacency(Name: /test1, Uri: test1, Cost: 128), "
-                                "Adjacency(Name: /test2, Uri: test2, Cost: 128))");
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace test
-} // namespace tlv
-} // namespace nlsr
diff --git a/tests/tlv/test-adjacency.cpp b/tests/tlv/test-adjacency.cpp
deleted file mode 100644
index 6e3b754..0000000
--- a/tests/tlv/test-adjacency.cpp
+++ /dev/null
@@ -1,91 +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 "tlv/adjacency.hpp"
-
-#include "tests/boost-test.hpp"
-
-namespace nlsr {
-namespace tlv {
-namespace test {
-
-BOOST_AUTO_TEST_SUITE(TlvTestAdjacency)
-
-const uint8_t AdjacencyData[] =
-{
-  // Header
-  0x84, 0x30,
-  // Name
-  0x07, 0x16, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x09, 0x61, 0x64, 0x6a, 0x61,
-  0x63, 0x65, 0x6e, 0x63, 0x79, 0x08, 0x03, 0x74, 0x6c, 0x76,
-  // Uri
-  0x8d, 0x13, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x61, 0x64, 0x6a, 0x61, 0x63, 0x65,
-  0x6e, 0x63, 0x79, 0x2f, 0x74, 0x6c, 0x76,
-  // Cost
-  0x8c, 0x01, 0x80
-};
-
-BOOST_AUTO_TEST_CASE(AdjacencyEncode)
-{
-  Adjacency adjacency;
-  adjacency.setName("/test/adjacency/tlv");
-  adjacency.setUri("/test/adjacency/tlv");
-  adjacency.setCost(128);
-
-  const ndn::Block& wire = adjacency.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(AdjacencyData,
-                                  AdjacencyData + sizeof(AdjacencyData),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(AdjacencyDecode)
-{
-  Adjacency adjacency;
-
-  adjacency.wireDecode(ndn::Block(AdjacencyData, sizeof(AdjacencyData)));
-
-  ndn::Name name("/test/adjacency/tlv");
-  BOOST_REQUIRE_EQUAL(adjacency.getName(), name);
-  BOOST_REQUIRE_EQUAL(adjacency.getUri(), "/test/adjacency/tlv");
-  BOOST_REQUIRE_EQUAL(adjacency.getCost(), 128);
-}
-
-BOOST_AUTO_TEST_CASE(AdjacencyOutputStream)
-{
-  Adjacency adjacency;
-  adjacency.setName("/test/adjacency/tlv");
-  adjacency.setUri("/test/adjacency/tlv");
-  adjacency.setCost(128);
-
-  std::ostringstream os;
-  os << adjacency;
-
-  BOOST_CHECK_EQUAL(os.str(), "Adjacency(Name: /test/adjacency/tlv, "
-                              "Uri: /test/adjacency/tlv, "
-                              "Cost: 128)");
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace test
-} // namespace tlv
-} // namespace nlsr
diff --git a/tests/tlv/test-coordinate-lsa.cpp b/tests/tlv/test-coordinate-lsa.cpp
deleted file mode 100644
index 225c708..0000000
--- a/tests/tlv/test-coordinate-lsa.cpp
+++ /dev/null
@@ -1,126 +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 "tlv/coordinate-lsa.hpp"
-
-#include "tests/boost-test.hpp"
-
-namespace nlsr {
-namespace tlv {
-namespace test {
-
-BOOST_AUTO_TEST_SUITE(TlvTestCoordinateLsa)
-
-const uint8_t CoordinateLsaData[] =
-{
-  // Header
-  0x85, 0x27,
-  // LsaInfo
-  0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
-  0x80, 0x8b, 0x02, 0x27, 0x10,
-  // HyperbolicRadius
-  0x87, 0x08, 0x3f, 0xfa, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
-  // HyperbolicAngle
-  0x88, 0x08, 0x3f, 0xfc, 0x7a, 0xe1, 0x47, 0xae, 0x14, 0x7b
-
-};
-
-BOOST_AUTO_TEST_CASE(CoordinateLsaEncode)
-{
-  CoordinateLsa coordinateLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  coordinateLsa.setLsaInfo(lsaInfo);
-
-  coordinateLsa.setHyperbolicRadius(1.65);
-  std::vector<double> angles;
-  angles.push_back(1.78);
-  coordinateLsa.setHyperbolicAngle(angles);
-
-  const ndn::Block& wire = coordinateLsa.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(CoordinateLsaData,
-                                  CoordinateLsaData + sizeof(CoordinateLsaData),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(CoordinateLsaDecode)
-{
-  CoordinateLsa coordinateLsa;
-
-  coordinateLsa.wireDecode(ndn::Block(CoordinateLsaData, sizeof(CoordinateLsaData)));
-
-  BOOST_REQUIRE_EQUAL(coordinateLsa.getLsaInfo().getOriginRouter(), "test");
-  BOOST_REQUIRE_EQUAL(coordinateLsa.getLsaInfo().getSequenceNumber(), 128);
-  BOOST_REQUIRE_EQUAL(coordinateLsa.getLsaInfo().getExpirationPeriod(),
-                      ndn::time::milliseconds(10000));
-  BOOST_REQUIRE_EQUAL(coordinateLsa.getHyperbolicRadius(), 1.65);
-  std::vector<double> angles = {1.78};
-  BOOST_REQUIRE(coordinateLsa.getHyperbolicAngle() == angles);
-}
-
-BOOST_AUTO_TEST_CASE(CoordinateLsaOutputStream)
-{
-  CoordinateLsa coordinateLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  coordinateLsa.setLsaInfo(lsaInfo);
-
-  coordinateLsa.setHyperbolicRadius(1.65);
-  std::vector<double> angles = {1.78};
-  coordinateLsa.setHyperbolicAngle(angles);
-
-  std::ostringstream os;
-  os << coordinateLsa;
-
-  BOOST_CHECK_EQUAL(os.str(), "CoordinateLsa("
-                                "LsaInfo(OriginRouter: /test, "
-                                        "SequenceNumber: 128, "
-                                        "ExpirationPeriod: 10000 milliseconds), "
-                                "HyperbolicRadius: 1.65, "
-                                "HyperbolicAngles: 1.78)");
-
-  angles.push_back(3.21);
-  coordinateLsa.setHyperbolicAngle(angles);
-
-  std::ostringstream os2;
-  os2 << coordinateLsa;
-
-  BOOST_CHECK_EQUAL(os2.str(), "CoordinateLsa("
-                                "LsaInfo(OriginRouter: /test, "
-                                        "SequenceNumber: 128, "
-                                        "ExpirationPeriod: 10000 milliseconds), "
-                                "HyperbolicRadius: 1.65, "
-                                "HyperbolicAngles: 1.78, 3.21)");
-}
-
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace test
-} // namespace tlv
-} // namespace nlsr
diff --git a/tests/tlv/test-destination.cpp b/tests/tlv/test-destination.cpp
index 8e2d177..adc153e 100644
--- a/tests/tlv/test-destination.cpp
+++ b/tests/tlv/test-destination.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/tests/tlv/test-lsa-info.cpp b/tests/tlv/test-lsa-info.cpp
deleted file mode 100644
index 46157a5..0000000
--- a/tests/tlv/test-lsa-info.cpp
+++ /dev/null
@@ -1,144 +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 "tlv/lsa-info.hpp"
-
-#include "tests/boost-test.hpp"
-#include "tests/mocks/lsa.hpp"
-
-namespace nlsr {
-namespace tlv {
-namespace test {
-
-BOOST_AUTO_TEST_SUITE(TlvTestLsaInfo)
-
-const uint8_t LsaInfoData[] =
-{
-  // Header
-  0x80, 0x21,
-  // OriginRouter
-  0x81, 0x18, 0x07, 0x16, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x03, 0x6c, 0x73,
-  0x61, 0x08, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x08, 0x03, 0x74, 0x6c, 0x76,
-  // SequenceNumber
-  0x82, 0x01, 0x80,
-  // ExpirationPeriod
-  0x8b, 0x02, 0x27, 0x10
-};
-
-const uint8_t LsaInfoDataInfiniteExpirationPeriod[] =
-{
-  // Header
-  0x80, 0x1d,
-  // OriginRouter
-  0x81, 0x18, 0x07, 0x16, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x03, 0x6c, 0x73,
-  0x61, 0x08, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x08, 0x03, 0x74, 0x6c, 0x76,
-  // SequenceNumber
-  0x82, 0x1, 0x80
-};
-
-BOOST_AUTO_TEST_CASE(LsaInfoEncode)
-{
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("/test/lsa/info/tlv");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-
-  const ndn::Block& wire = lsaInfo.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(LsaInfoData,
-                                  LsaInfoData + sizeof(LsaInfoData),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(LsaInfoDecode)
-{
-  LsaInfo lsaInfo;
-
-  lsaInfo.wireDecode(ndn::Block(LsaInfoData, sizeof(LsaInfoData)));
-
-  ndn::Name originRouter("/test/lsa/info/tlv");
-  BOOST_REQUIRE_EQUAL(lsaInfo.getOriginRouter(), originRouter);
-  BOOST_REQUIRE_EQUAL(lsaInfo.getSequenceNumber(), 128);
-  BOOST_REQUIRE_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));
-  BOOST_REQUIRE_EQUAL(lsaInfo.hasInfiniteExpirationPeriod(), false);
-}
-
-BOOST_AUTO_TEST_CASE(LsaInfoInfiniteExpirationPeriodEncode)
-{
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("/test/lsa/info/tlv");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(LsaInfo::INFINITE_EXPIRATION_PERIOD);
-
-  const ndn::Block& wire = lsaInfo.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(LsaInfoDataInfiniteExpirationPeriod,
-                                  LsaInfoDataInfiniteExpirationPeriod +
-                                    sizeof(LsaInfoDataInfiniteExpirationPeriod),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(LsaInfoInfiniteExpirationPeriodDecode)
-{
-  LsaInfo lsaInfo;
-
-  lsaInfo.wireDecode(ndn::Block(LsaInfoDataInfiniteExpirationPeriod,
-                                sizeof(LsaInfoDataInfiniteExpirationPeriod)));
-
-  ndn::Name originRouter("/test/lsa/info/tlv");
-  BOOST_REQUIRE_EQUAL(lsaInfo.getOriginRouter(), originRouter);
-  BOOST_REQUIRE_EQUAL(lsaInfo.getSequenceNumber(), 128);
-  BOOST_REQUIRE_EQUAL(lsaInfo.getExpirationPeriod(), LsaInfo::INFINITE_EXPIRATION_PERIOD);
-  BOOST_REQUIRE_EQUAL(lsaInfo.hasInfiniteExpirationPeriod(), true);
-}
-
-BOOST_AUTO_TEST_CASE(LsaInfoOutputStream)
-{
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("/test/lsa/info/tlv");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-
-  std::ostringstream os;
-  os << lsaInfo;
-
-  BOOST_CHECK_EQUAL(os.str(), "LsaInfo(OriginRouter: /test/lsa/info/tlv, SequenceNumber: 128, "
-                              "ExpirationPeriod: 10000 milliseconds)");
-}
-
-BOOST_AUTO_TEST_CASE(LsaInfoMake)
-{
-  nlsr::test::MockLsa lsa;
-  lsa.setOrigRouter("/test/lsa/info/tlv");
-  lsa.setLsSeqNo(128);
-  lsa.setExpirationTimePoint(ndn::time::system_clock::now());
-
-  std::shared_ptr<LsaInfo> lsaInfo = makeLsaInfo(lsa);
-  BOOST_CHECK_EQUAL(lsaInfo->getOriginRouter(), lsa.getOrigRouter());
-  BOOST_CHECK_EQUAL(lsaInfo->getSequenceNumber(), lsa.getLsSeqNo());
-  BOOST_CHECK_LE(lsaInfo->getExpirationPeriod(), ndn::time::milliseconds(0));
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace test
-} // namespace tlv
-} // namespace nlsr
diff --git a/tests/tlv/test-name-lsa.cpp b/tests/tlv/test-name-lsa.cpp
deleted file mode 100644
index 885d225..0000000
--- a/tests/tlv/test-name-lsa.cpp
+++ /dev/null
@@ -1,182 +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 "tlv/name-lsa.hpp"
-
-#include "tests/boost-test.hpp"
-
-namespace nlsr {
-namespace tlv {
-namespace test {
-
-BOOST_AUTO_TEST_SUITE(TlvTestNameLsa)
-
-const uint8_t NameLsaWithNamesData[] =
-{
-  // Header
-  0x89, 0x25,
-  // LsaInfo
-  0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
-  0x80, 0x8b, 0x02, 0x27, 0x10,
-  // Name
-  0x07, 0x07, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31,
-  // Name
-  0x07, 0x07, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32
-};
-
-const uint8_t NameLsaWithoutNamesData[] =
-{
-  // Header
-  0x89, 0x13,
-  // LsaInfo
-  0x80, 0x11, 0x81, 0x08, 0x07, 0x06, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x82, 0x01,
-  0x80, 0x8b, 0x02, 0x27, 0x10,
-};
-
-BOOST_AUTO_TEST_CASE(NameLsaEncodeWithNames)
-{
-  NameLsa nameLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  nameLsa.setLsaInfo(lsaInfo);
-
-  nameLsa.addName("test1");
-  nameLsa.addName("test2");
-
-  const ndn::Block& wire = nameLsa.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(NameLsaWithNamesData,
-                                  NameLsaWithNamesData + sizeof(NameLsaWithNamesData),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(NameLsaDecodeWithNames)
-{
-  NameLsa nameLsa;
-
-  nameLsa.wireDecode(ndn::Block(NameLsaWithNamesData, sizeof(NameLsaWithNamesData)));
-
-  LsaInfo lsaInfo = nameLsa.getLsaInfo();
-  BOOST_CHECK_EQUAL(lsaInfo.getOriginRouter(), "test");
-  BOOST_CHECK_EQUAL(lsaInfo.getSequenceNumber(), 128);
-  BOOST_CHECK_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));
-
-  BOOST_CHECK_EQUAL(nameLsa.hasNames(), true);
-  std::list<ndn::Name> names = nameLsa.getNames();
-  std::list<ndn::Name>::const_iterator it = names.begin();
-  BOOST_CHECK_EQUAL(*it, "test1");
-
-  it++;
-  BOOST_CHECK_EQUAL(*it, "test2");
-}
-
-BOOST_AUTO_TEST_CASE(NameLsaEncodeWithoutNames)
-{
-  NameLsa nameLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  nameLsa.setLsaInfo(lsaInfo);
-
-  const ndn::Block& wire = nameLsa.wireEncode();
-
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(NameLsaWithoutNamesData,
-                                  NameLsaWithoutNamesData + sizeof(NameLsaWithoutNamesData),
-                                  wire.begin(), wire.end());
-}
-
-BOOST_AUTO_TEST_CASE(NameLsaDecodeWithoutNames)
-{
-  NameLsa nameLsa;
-
-  nameLsa.wireDecode(ndn::Block(NameLsaWithoutNamesData, sizeof(NameLsaWithoutNamesData)));
-
-  LsaInfo lsaInfo = nameLsa.getLsaInfo();
-  BOOST_CHECK_EQUAL(lsaInfo.getOriginRouter(), "test");
-  BOOST_CHECK_EQUAL(lsaInfo.getSequenceNumber(), 128);
-  BOOST_CHECK_EQUAL(lsaInfo.getExpirationPeriod(), ndn::time::milliseconds(10000));
-
-  BOOST_CHECK_EQUAL(nameLsa.hasNames(), false);
-}
-
-BOOST_AUTO_TEST_CASE(NameLsaClear)
-{
-  NameLsa nameLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  nameLsa.setLsaInfo(lsaInfo);
-
-  nameLsa.addName("test1");
-  BOOST_CHECK_EQUAL(nameLsa.getNames().size(), 1);
-
-  std::list<ndn::Name> names = nameLsa.getNames();
-  std::list<ndn::Name>::const_iterator it = names.begin();
-  BOOST_CHECK_EQUAL(*it, "test1");
-
-  nameLsa.clearNames();
-  BOOST_CHECK_EQUAL(nameLsa.getNames().size(), 0);
-
-  nameLsa.addName("test2");
-  BOOST_CHECK_EQUAL(nameLsa.getNames().size(), 1);
-
-  names = nameLsa.getNames();
-  it = names.begin();
-  BOOST_CHECK_EQUAL(*it, "test2");
-}
-
-BOOST_AUTO_TEST_CASE(AdjacencyLsaOutputStream)
-{
-  NameLsa nameLsa;
-
-  LsaInfo lsaInfo;
-  lsaInfo.setOriginRouter("test");
-  lsaInfo.setSequenceNumber(128);
-  lsaInfo.setExpirationPeriod(ndn::time::milliseconds(10000));
-  nameLsa.setLsaInfo(lsaInfo);
-
-  nameLsa.addName("test1");
-  nameLsa.addName("test2");
-
-  std::ostringstream os;
-  os << nameLsa;
-
-  BOOST_CHECK_EQUAL(os.str(), "NameLsa("
-                                "LsaInfo("
-                                  "OriginRouter: /test, "
-                                  "SequenceNumber: 128, "
-                                  "ExpirationPeriod: 10000 milliseconds), "
-                                "Name: /test1, "
-                                "Name: /test2)");
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace test
-} // namespace tlv
-} // namespace nlsr
diff --git a/tests/tlv/test-nexthops.cpp b/tests/tlv/test-nexthops.cpp
index 12a479e..f5b4d29 100644
--- a/tests/tlv/test-nexthops.cpp
+++ b/tests/tlv/test-nexthops.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/tests/tlv/test-routing-table-entry.cpp b/tests/tlv/test-routing-table-entry.cpp
index 378dfd9..338945b 100644
--- a/tests/tlv/test-routing-table-entry.cpp
+++ b/tests/tlv/test-routing-table-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,
  *                           Arizona Board of Regents.
  *
diff --git a/tests/tlv/test-routing-table.cpp b/tests/tlv/test-routing-table.cpp
index ba8cef6..70c25c9 100644
--- a/tests/tlv/test-routing-table.cpp
+++ b/tests/tlv/test-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,
  *                           Arizona Board of Regents.
  *
@@ -107,7 +107,6 @@
 BOOST_AUTO_TEST_CASE(RoutingTableDecode2)
 {
   RoutingTableStatus rtStatus;
-
   rtStatus.wireDecode(ndn::Block(RoutingTableData2, sizeof(RoutingTableData2)));
 
   BOOST_CHECK_EQUAL(rtStatus.hasRoutingTable(), false);
diff --git a/tests/update/test-nfd-rib-command-processor.cpp b/tests/update/test-nfd-rib-command-processor.cpp
index 514fa1c..47f02c5 100644
--- a/tests/update/test-nfd-rib-command-processor.cpp
+++ b/tests/update/test-nfd-rib-command-processor.cpp
@@ -66,7 +66,7 @@
     ndn::Name lsaInterestName = conf.getLsaPrefix();
     lsaInterestName.append(conf.getSiteName());
     lsaInterestName.append(conf.getRouterName());
-    lsaInterestName.append(std::to_string(Lsa::Type::NAME));
+    lsaInterestName.append(boost::lexical_cast<std::string>(Lsa::Type::NAME));
     lsaInterestName.appendNumber(nlsr.m_lsdb.m_sequencingManager.getNameLsaSeq());
 
     face.receive(ndn::Interest(lsaInterestName).setCanBePrefix(true));
diff --git a/tests/update/test-prefix-update-processor.cpp b/tests/update/test-prefix-update-processor.cpp
index 711935f..ca887d1 100644
--- a/tests/update/test-prefix-update-processor.cpp
+++ b/tests/update/test-prefix-update-processor.cpp
@@ -102,7 +102,7 @@
     ndn::Name lsaInterestName = conf.getLsaPrefix();
     lsaInterestName.append(conf.getSiteName());
     lsaInterestName.append(conf.getRouterName());
-    lsaInterestName.append(std::to_string(Lsa::Type::NAME));
+    lsaInterestName.append(boost::lexical_cast<std::string>(Lsa::Type::NAME));
 
     lsaInterestName.appendNumber(nlsr.m_lsdb.m_sequencingManager.getNameLsaSeq());
 
diff --git a/tools/nlsrc.cpp b/tools/nlsrc.cpp
index f4e5965..a943b85 100644
--- a/tools/nlsrc.cpp
+++ b/tools/nlsrc.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.
  *
@@ -252,22 +252,22 @@
 void
 Nlsrc::fetchAdjacencyLsas()
 {
-  fetchFromLsdb<nlsr::tlv::AdjacencyLsa>(nlsr::dataset::ADJACENCY_COMPONENT,
-                                         std::bind(&Nlsrc::recordAdjacencyLsa, this, _1));
+  fetchFromLsdb<nlsr::AdjLsa>(nlsr::dataset::ADJACENCY_COMPONENT,
+                              std::bind(&Nlsrc::recordLsa, this, _1));
 }
 
 void
 Nlsrc::fetchCoordinateLsas()
 {
-  fetchFromLsdb<nlsr::tlv::CoordinateLsa>(nlsr::dataset::COORDINATE_COMPONENT,
-                                          std::bind(&Nlsrc::recordCoordinateLsa, this, _1));
+  fetchFromLsdb<nlsr::CoordinateLsa>(nlsr::dataset::COORDINATE_COMPONENT,
+                                     std::bind(&Nlsrc::recordLsa, this, _1));
 }
 
 void
 Nlsrc::fetchNameLsas()
 {
-  fetchFromLsdb<nlsr::tlv::NameLsa>(nlsr::dataset::NAME_COMPONENT,
-                                    std::bind(&Nlsrc::recordNameLsa, this, _1));
+  fetchFromLsdb<nlsr::NameLsa>(nlsr::dataset::NAME_COMPONENT,
+                               std::bind(&Nlsrc::recordLsa, this, _1));
 }
 
 void
@@ -340,66 +340,36 @@
             << ", error: " << error << ")"  << std::endl;
 }
 
-std::string
-Nlsrc::getLsaInfoString(const nlsr::tlv::LsaInfo& info)
-{
-  std::ostringstream os;
-  os << "      info=" << info;
-
-  return os.str();
-}
-
 void
-Nlsrc::recordAdjacencyLsa(const nlsr::tlv::AdjacencyLsa& lsa)
+Nlsrc::recordLsa(const nlsr::Lsa& lsa)
 {
-  Router& router = getRouterLsdb(lsa.getLsaInfo());
+  const auto& pair = m_routers.emplace(lsa.getOriginRouter(), Router());
+  Router& router = pair.first->second;
 
   std::ostringstream os;
-  os << "    AdjacencyLsa:" << std::endl;
 
-  os << getLsaInfoString(lsa.getLsaInfo()) << std::endl;
-
-  for (const auto& adjacency : lsa.getAdjacencies()) {
-    os << "      adjacency=" << adjacency << std::endl;
+  switch (lsa.getType()) {
+    case nlsr::Lsa::Type::ADJACENCY: {
+      const nlsr::AdjLsa& adjLsa = static_cast<const nlsr::AdjLsa&>(lsa);
+      os << adjLsa;
+      router.adjacencyLsaString = os.str();
+      break;
+    }
+    case nlsr::Lsa::Type::COORDINATE: {
+      const nlsr::CoordinateLsa& coorLsa = static_cast<const nlsr::CoordinateLsa&>(lsa);
+      os << coorLsa;
+      router.coordinateLsaString = os.str();
+      break;
+    }
+    case nlsr::Lsa::Type::NAME: {
+      const nlsr::NameLsa& nameLsa = static_cast<const nlsr::NameLsa&>(lsa);
+      os << nameLsa;
+      router.nameLsaString = os.str();
+      break;
+    }
+    default:
+      break;
   }
-
-  router.adjacencyLsaString = os.str();
-}
-
-void
-Nlsrc::recordCoordinateLsa(const nlsr::tlv::CoordinateLsa& lsa)
-{
-  Router& router = getRouterLsdb(lsa.getLsaInfo());
-
-  std::ostringstream os;
-  os << "    Coordinate LSA:" << std::endl;
-
-  os << getLsaInfoString(lsa.getLsaInfo()) << std::endl;
-
-  int i = 0;
-  for (auto const& value: lsa.getHyperbolicAngle()) {
-    os << "    Hyp Angle " << i++ << ": "<< value << " ";
-  }
-  os << "\n   radius=" << lsa.getHyperbolicRadius() << std::endl;
-
-  router.coordinateLsaString = os.str();
-}
-
-void
-Nlsrc::recordNameLsa(const nlsr::tlv::NameLsa& lsa)
-{
-  Router& router = getRouterLsdb(lsa.getLsaInfo());
-
-  std::ostringstream os;
-  os << "    Name LSA:" << std::endl;
-
-  os << getLsaInfoString(lsa.getLsaInfo()) << std::endl;
-
-  for (const auto& name : lsa.getNames()) {
-    os << "      name=" << name << std::endl;
-  }
-
-  router.nameLsaString = os.str();
 }
 
 void
@@ -469,15 +439,19 @@
   printRT();
 }
 
-Nlsrc::Router&
-Nlsrc::getRouterLsdb(const nlsr::tlv::LsaInfo& info)
+std::string
+Nlsrc::getLsaInfo(const nlsr::Lsa& lsa)
 {
-  const ndn::Name& originRouterName = info.getOriginRouter();
+  auto duration = ndn::time::duration_cast<ndn::time::seconds>(lsa.getExpirationTimePoint() -
+                                                               ndn::time::system_clock::now());
+  std::ostringstream os;
+  os << "     LsaInfo("
+     << "OriginRouter: " << lsa.getOriginRouter() << ", "
+     << "SequenceNumber: " << lsa.getSeqNo() << ", "
+     << "ExpirationPeriod: " << duration;
+     os << ")\n\n";
 
-  const auto& pair =
-    m_routers.insert(std::make_pair(originRouterName, Router()));
-
-  return pair.first->second;
+  return os.str();
 }
 
 } // namespace nlsrc
diff --git a/tools/nlsrc.hpp b/tools/nlsrc.hpp
index e05891c..aab636c 100644
--- a/tools/nlsrc.hpp
+++ b/tools/nlsrc.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.
  *
@@ -19,12 +19,11 @@
  * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  **/
 
-#include "tlv/adjacency-lsa.hpp"
-#include "tlv/coordinate-lsa.hpp"
-#include "tlv/name-lsa.hpp"
+#include "lsa/adj-lsa.hpp"
+#include "lsa/coordinate-lsa.hpp"
+#include "lsa/name-lsa.hpp"
 #include "tlv/routing-table-status.hpp"
 
-
 #include <boost/noncopyable.hpp>
 #include <ndn-cxx/face.hpp>
 #include <ndn-cxx/security/key-chain.hpp>
@@ -120,18 +119,8 @@
   void
   onTimeout(uint32_t errorCode, const std::string& error);
 
-private:
-  std::string
-  getLsaInfoString(const nlsr::tlv::LsaInfo& info);
-
   void
-  recordAdjacencyLsa(const nlsr::tlv::AdjacencyLsa& lsa);
-
-  void
-  recordCoordinateLsa(const nlsr::tlv::CoordinateLsa& lsa);
-
-  void
-  recordNameLsa(const nlsr::tlv::NameLsa& lsa);
+  recordLsa(const nlsr::Lsa& lsa);
 
   void
   recordRtable(const nlsr::tlv::RoutingTableStatus& rts);
@@ -145,6 +134,9 @@
   void
   printAll();
 
+  std::string
+  getLsaInfo(const nlsr::Lsa& lsa);
+
 public:
   const char* programName;
 
@@ -160,11 +152,7 @@
     std::string nameLsaString;
   };
 
-  Router&
-  getRouterLsdb(const nlsr::tlv::LsaInfo& info);
-
-  typedef std::map<const ndn::Name, Router> RouterMap;
-  RouterMap m_routers;
+  std::map<ndn::Name, Router> m_routers;
 
 private:
   ndn::KeyChain m_keyChain;
@@ -184,7 +172,6 @@
   static const uint32_t ERROR_CODE_TIMEOUT;
   static const uint32_t RESPONSE_CODE_SUCCESS;
   static const uint32_t RESPONSE_CODE_SAVE_OR_DELETE;
-
 };
 
 } // namespace nlsrc