diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java
new file mode 100755
index 0000000..2c33ed5
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/area/OspfAreaImpl.java
@@ -0,0 +1,803 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ospf.controller.area;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.controller.LsaWrapper;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.OspfAreaAddressRange;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfLsa;
+import org.onosproject.ospf.controller.OspfLsaType;
+import org.onosproject.ospf.controller.OspfLsdb;
+import org.onosproject.ospf.controller.OspfNbr;
+import org.onosproject.ospf.controller.OspfNeighborState;
+import org.onosproject.ospf.controller.impl.OspfNbrImpl;
+import org.onosproject.ospf.controller.lsdb.OspfLsdbImpl;
+import org.onosproject.ospf.protocol.lsa.LsaHeader;
+import org.onosproject.ospf.protocol.lsa.subtypes.OspfLsaLink;
+import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
+import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
+import org.onosproject.ospf.protocol.util.ChecksumCalculator;
+import org.onosproject.ospf.protocol.util.OspfInterfaceState;
+import org.onosproject.ospf.protocol.util.OspfParameters;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Representation an OSPF area and related information.
+ */
+public class OspfAreaImpl implements OspfArea {
+    private static final Logger log = LoggerFactory.getLogger(OspfAreaImpl.class);
+    /**
+     * Address ranges in order to aggregate routing information at area.
+     * boundaries. Each address range is specified by an [address,mask] pair and
+     * a status indication of either Advertise or DoNotAdvertise
+     */
+    private List<OspfAreaAddressRange> addressRanges;
+    /**
+     * This parameter indicates whether the area can carry data traffic that.
+     * neither originates nor terminates in the area itself.
+     */
+    private boolean transitCapability;
+    /**
+     * Whether AS-external-LSAs will be flooded into/throughout the area.
+     */
+    private boolean externalRoutingCapability;
+    /**
+     * Indicates the cost of the default summary-LSA.
+     */
+    private int stubCost;
+    /**
+     * Represents a list of all router's interfaces associated with this area.
+     */
+    private List<OspfInterface> interfacesLst;
+    /**
+     * The LS Database for this area. It includes router-LSAs, network-LSAs and.
+     * summary-LSAs. AS-external-LSAs are hold in the OSPF class itself.
+     */
+    private OspfLsdbImpl database;
+    /**
+     * A 32-bit number identifying the area.
+     */
+    private Ip4Address areaId;
+    /**
+     * Router ID.
+     */
+    private Ip4Address routerId;
+    /**
+     * Represents Options like external, opaque capabilities.
+     */
+    private int options;
+    /**
+     * Represents Opaque Enable or not.
+     */
+    private boolean isOpaqueEnable;
+
+    /**
+     * Creates an instance of area implementation.
+     */
+    public OspfAreaImpl() {
+        database = new OspfLsdbImpl(this);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        OspfAreaImpl that = (OspfAreaImpl) o;
+        return Objects.equal(areaId, that.areaId) &&
+                Objects.equal(routerId, that.routerId) &&
+                Objects.equal(addressRanges.size(), that.addressRanges.size()) &&
+                Objects.equal(transitCapability, that.transitCapability) &&
+                Objects.equal(externalRoutingCapability, that.externalRoutingCapability) &&
+                Objects.equal(stubCost, that.stubCost) &&
+                Objects.equal(interfacesLst.size(), that.interfacesLst.size()) &&
+                Objects.equal(database, that.database);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(areaId, routerId, addressRanges, transitCapability, externalRoutingCapability,
+                                stubCost, interfacesLst, database);
+    }
+
+    /**
+     * Gets the router id.
+     *
+     * @return router id
+     */
+    public Ip4Address routerId() {
+        return routerId;
+    }
+
+    /**
+     * Sets the router id.
+     *
+     * @param routerId router id
+     */
+    @JsonProperty("routerId")
+    public void setRouterId(Ip4Address routerId) {
+        this.routerId = routerId;
+    }
+
+    /**
+     * Sets opaque enabled to true or false.
+     *
+     * @param isOpaqueEnable true if opaque enabled else false
+     */
+    @JsonProperty("isOpaqueEnable")
+    public void setIsOpaqueEnabled(boolean isOpaqueEnable) {
+        this.isOpaqueEnable = isOpaqueEnable;
+    }
+
+    /**
+     * Gets is opaque enabled or not.
+     *
+     * @return true if opaque enabled else false
+     */
+    public boolean isOpaqueEnabled() {
+        return this.isOpaqueEnable;
+    }
+
+    /**
+     * Initializes link state database.
+     */
+    public void initializeDb() {
+
+        database.initializeDb();
+    }
+
+    /**
+     * Refreshes the OSPF area information .
+     * Gets called as soon as the interface is down or neighbor full Router LSA is updated.
+     *
+     * @param ospfInterface OSPF interface instance
+     */
+    @Override
+    public void refreshArea(OspfInterface ospfInterface) {
+        OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
+        log.debug("Inside refreshArea...!!!");
+        //If interface state is DR build network LSA.
+        if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
+            if (ospfInterface.listOfNeighbors().size() > 0) {
+                //Get the NetworkLsa
+                NetworkLsa networkLsa = null;
+                try {
+                    networkLsa = buildNetworkLsa(ospfInterface.ipAddress(), ospfInterface.ipNetworkMask());
+                } catch (Exception e) {
+                    log.debug("Error while building NetworkLsa {}", e.getMessage());
+                }
+                //Add the NetworkLsa to lsdb
+                database.addLsa(networkLsa, true, ospfInterface);
+                addToOtherNeighborLsaTxList(networkLsa);
+            } else {
+                log.debug("No Neighbors hence not creating  NetworkLSA...!!!");
+            }
+        }
+        //Get the router LSA
+        RouterLsa routerLsa = null;
+        try {
+            routerLsa = buildRouterLsa(ospfInterface);
+        } catch (Exception e) {
+            log.debug("Error while building RouterLsa {}", e.getMessage());
+        }
+        //Add the RouterLSA to lsdb
+        database.addLsa(routerLsa, true, ospfInterface);
+        addToOtherNeighborLsaTxList(routerLsa);
+    }
+
+    /**
+     * Builds a network LSA.
+     *
+     * @param interfaceIp interface IP address
+     * @param mask        interface network mask
+     * @return NetworkLsa instance
+     * @throws Exception might throws exception
+     */
+    public NetworkLsa buildNetworkLsa(Ip4Address interfaceIp, Ip4Address mask) throws Exception {
+        // generate the Router-LSA for this Area.
+        NetworkLsa networkLsa = new NetworkLsa();
+        networkLsa.setAdvertisingRouter(routerId);
+        networkLsa.setLinkStateId(interfaceIp.toString());
+        networkLsa.setLsType(OspfLsaType.NETWORK.value());
+        networkLsa.setAge(1);
+        networkLsa.setOptions(2);
+        networkLsa.setNetworkMask(mask);
+        //Adding our own router.
+        networkLsa.addAttachedRouter(routerId());
+        Iterator iter = interfacesLst.iterator();
+        OspfInterfaceImpl ospfInterface = null;
+        while (iter.hasNext()) {
+            ospfInterface = (OspfInterfaceImpl) iter.next();
+            if (ospfInterface.ipAddress().equals(interfaceIp)) {
+                break;
+            }
+        }
+        if (ospfInterface != null) {
+            List<OspfNbr> neighborsInFullState = getNeighborsInFullState(ospfInterface);
+            if (neighborsInFullState != null) {
+                for (OspfNbr ospfnbr : neighborsInFullState) {
+                    networkLsa.addAttachedRouter(ospfnbr.neighborId());
+                    log.debug("Adding attached neighbor:: {}", ospfnbr.neighborId());
+                }
+            }
+        }
+        networkLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.NETWORK));
+        //Find the byte length and add it in lsa object
+        ChecksumCalculator checksum = new ChecksumCalculator();
+        byte[] lsaBytes = networkLsa.asBytes();
+        networkLsa.setLsPacketLen(lsaBytes.length);
+        //Convert lsa object to byte again to reflect the packet length which we added.
+        lsaBytes = networkLsa.asBytes();
+        //find the checksum
+        byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
+                                                               OspfUtil.LSAPACKET_CHECKSUM_POS1,
+                                                               OspfUtil.LSAPACKET_CHECKSUM_POS2);
+        int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
+        networkLsa.setLsCheckSum(checkSumVal);
+        return networkLsa;
+    }
+
+    /**
+     * Builds Router LSA.
+     *
+     * @param ospfInterface Interface instance
+     * @return routerLsa Router LSA instance
+     * @throws Exception might throws exception
+     */
+    public RouterLsa buildRouterLsa(OspfInterface ospfInterface) throws Exception {
+        // generate the Router-LSA for this Area.
+        RouterLsa routerLsa = new RouterLsa();
+        routerLsa.setAdvertisingRouter(routerId);
+        routerLsa.setLinkStateId(routerId.toString());
+        routerLsa.setLsType(OspfLsaType.ROUTER.value());
+        routerLsa.setAge(1);
+        routerLsa.setOptions(options);
+        routerLsa.setAreaBorderRouter(false);
+        routerLsa.setAsBoundaryRouter(false);
+        routerLsa.setVirtualEndPoint(false);
+        buildLinkForRouterLsa(routerLsa, ospfInterface);
+        routerLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.ROUTER));
+        //Find the byte length and add it in lsa object
+        ChecksumCalculator checksum = new ChecksumCalculator();
+        byte[] lsaBytes = routerLsa.asBytes();
+        routerLsa.setLsPacketLen(lsaBytes.length);
+        //Convert lsa object to byte again to reflect the packet length whic we added.
+        lsaBytes = routerLsa.asBytes();
+        //find the checksum
+        byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
+                                                               OspfUtil.LSAPACKET_CHECKSUM_POS1,
+                                                               OspfUtil.LSAPACKET_CHECKSUM_POS2);
+        int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
+        routerLsa.setLsCheckSum(checkSumVal);
+        return routerLsa;
+    }
+
+    /**
+     * Builds LSA link for router LSA.
+     *
+     * @param routerLsa     router LSA instance
+     * @param ospfInterface interface instance
+     */
+    private void buildLinkForRouterLsa(RouterLsa routerLsa, OspfInterface ospfInterface) {
+        OspfInterfaceImpl nextInterface;
+        Iterator interfaces = interfacesLst.iterator();
+        while (interfaces.hasNext()) {
+            nextInterface = (OspfInterfaceImpl) interfaces.next();
+            if (nextInterface.state() == OspfInterfaceState.DOWN) {
+                continue;
+            } else if (nextInterface.state() == OspfInterfaceState.LOOPBACK) {
+                OspfLsaLink link = new OspfLsaLink();
+                link.setLinkData("-1");
+                link.setLinkId(nextInterface.ipAddress().toString());
+                link.setLinkType(3);
+                link.setMetric(0);
+                link.setTos(0);
+                routerLsa.addRouterLink(link);
+                routerLsa.incrementLinkNo();
+            } else if (nextInterface.state() == OspfInterfaceState.POINT2POINT) {
+                // adding all neighbour routers
+                List<OspfNbr> neighborsInFullState = getNeighborsInFullState(nextInterface);
+                if (neighborsInFullState != null) {
+                    log.debug("Adding OspfLsaLink ::neighborsInFullState {}, InterfaceIP: {}",
+                              neighborsInFullState.size(), nextInterface.ipAddress());
+                    for (OspfNbr ospfnbr : neighborsInFullState) {
+                        OspfLsaLink link = new OspfLsaLink();
+                        link.setLinkData(nextInterface.ipAddress().toString());
+                        link.setLinkId(ospfnbr.neighborId().toString());
+                        link.setLinkType(1);
+                        link.setMetric(0);
+                        link.setTos(0);
+                        routerLsa.addRouterLink(link);
+                        routerLsa.incrementLinkNo();
+                        log.debug("Added OspfLsaLink :: {}, neighborIP: {}, routerLinks: {}",
+                                  ospfnbr.neighborId(), ospfnbr.neighborIpAddr(), routerLsa.noLink());
+                    }
+                }
+                // adding the self address
+                OspfLsaLink link = new OspfLsaLink();
+                link.setLinkData(nextInterface.ipNetworkMask().toString());
+                link.setLinkId(nextInterface.ipAddress().toString());
+                link.setLinkType(3);
+                link.setMetric(0);
+                link.setTos(0);
+                routerLsa.addRouterLink(link);
+                routerLsa.incrementLinkNo();
+            } else {
+                buildLinkForRouterLsaBroadcast(routerLsa, nextInterface);
+            }
+        }
+    }
+
+    /**
+     * Builds LSA link for router LSA.
+     *
+     * @param routerLsa     router LSA instance
+     * @param ospfInterface interface instance
+     */
+    private void buildLinkForRouterLsaBroadcast(RouterLsa routerLsa, OspfInterface ospfInterface) {
+        OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
+        if (ospfInterfaceImpl.state() == OspfInterfaceState.WAITING) {
+            OspfLsaLink link = new OspfLsaLink();
+            link.setLinkData(ospfInterface.ipNetworkMask().toString());
+            //Link id should be set to ip network number
+            link.setLinkId(ospfInterface.ipAddress().toString());
+            link.setLinkType(3);
+            link.setMetric(0);
+            link.setTos(0);
+            routerLsa.addRouterLink(link);
+            routerLsa.incrementLinkNo();
+        } else if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
+            OspfLsaLink link = new OspfLsaLink();
+            link.setLinkData(ospfInterface.ipAddress().toString());
+            link.setLinkId(ospfInterface.ipAddress().toString());
+            link.setLinkType(2);
+            link.setMetric(0);
+            link.setTos(0);
+            routerLsa.addRouterLink(link);
+            routerLsa.incrementLinkNo();
+        } else if (ospfInterfaceImpl.state() == OspfInterfaceState.BDR ||
+                ospfInterfaceImpl.state() == OspfInterfaceState.DROTHER) {
+            OspfLsaLink link = new OspfLsaLink();
+            link.setLinkData(ospfInterface.ipAddress().toString());
+            link.setLinkId(ospfInterface.dr().toString());
+            link.setLinkType(2);
+            link.setMetric(0);
+            link.setTos(0);
+            routerLsa.addRouterLink(link);
+            routerLsa.incrementLinkNo();
+        }
+    }
+
+    /**
+     * Gets the area id.
+     *
+     * @return area id
+     */
+    public Ip4Address areaId() {
+        return areaId;
+    }
+
+    /**
+     * Sets the area id.
+     *
+     * @param areaId area id
+     */
+    @JsonProperty("areaId")
+    public void setAreaId(Ip4Address areaId) {
+        this.areaId = areaId;
+    }
+
+    /**
+     * Gets address range.
+     *
+     * @return list of area address ranges
+     */
+    public List<OspfAreaAddressRange> addressRanges() {
+        return addressRanges;
+    }
+
+    /**
+     * Sets the area address ranges.
+     *
+     * @param addressRanges list of area address range
+     */
+    @JsonProperty("addressRange")
+    public void setAddressRanges(List<OspfAreaAddressRange> addressRanges) {
+        this.addressRanges = addressRanges;
+    }
+
+    /**
+     * Gets is transit capable or not.
+     *
+     * @return true if transit capable, else false
+     */
+    public boolean isTransitCapability() {
+        return transitCapability;
+    }
+
+    /**
+     * Sets transit capability.
+     *
+     * @param transitCapability true if transit capable, else false
+     */
+    @JsonProperty("transitCapability")
+    public void setTransitCapability(boolean transitCapability) {
+        this.transitCapability = transitCapability;
+    }
+
+    /**
+     * Gets external routing capability.
+     *
+     * @return true if external routing capable, else false
+     */
+    public boolean isExternalRoutingCapability() {
+        return externalRoutingCapability;
+    }
+
+    /**
+     * Sets external routing capability.
+     *
+     * @param externalRoutingCapability true if external routing capable, else false
+     */
+    @JsonProperty("externalRoutingCapability")
+    public void setExternalRoutingCapability(boolean externalRoutingCapability) {
+        this.externalRoutingCapability = externalRoutingCapability;
+    }
+
+    /**
+     * Gets the stub cost.
+     *
+     * @return stub cost
+     */
+    public int stubCost() {
+        return stubCost;
+    }
+
+    /**
+     * Sets the stub cost.
+     *
+     * @param stubCost stub cost
+     */
+    @JsonProperty("stubCost")
+    public void setStubCost(int stubCost) {
+        this.stubCost = stubCost;
+    }
+
+    /**
+     * Gets the list of interfaces in this area.
+     *
+     * @return list of interfaces
+     */
+    public List<OspfInterface> getInterfacesLst() {
+        return interfacesLst;
+    }
+
+    /**
+     * Sets the list of interfaces attached to the area.
+     *
+     * @param interfacesLst list of OspfInterface instances
+     */
+    @JsonProperty("interface")
+    public void setInterfacesLst(List<OspfInterface> interfacesLst) {
+        this.interfacesLst = interfacesLst;
+    }
+
+    /**
+     * Checks all neighbors belonging to this area whether they are in state EXCHANGE or LOADING.
+     * Return false if there is at least one, else return true. This Method is used by
+     * "processReceivedLsa()" in the neighbor class.
+     *
+     * @return boolean indicating that there is no Neighbor in Database Exchange
+     */
+    public boolean noNeighborInLsaExchangeProcess() {
+        OspfInterfaceImpl nextInterface;
+        OspfNeighborState nextNeighborState;
+        Iterator interfaces = interfacesLst.iterator();
+        while (interfaces.hasNext()) {
+            nextInterface = (OspfInterfaceImpl) interfaces.next();
+            Iterator neighbors = nextInterface.listOfNeighbors().values().iterator();
+            while (neighbors.hasNext()) {
+                nextNeighborState = ((OspfNbrImpl) neighbors.next()).getState();
+                if (nextNeighborState == OspfNeighborState.EXCHANGE ||
+                        nextNeighborState == OspfNeighborState.LOADING) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Gets header of all types of LSAs.
+     *
+     * @param excludeMaxAgeLsa need to include(true) or exclude(false) maxage lsa's
+     * @param isOpaquecapable  need to include(true) or exclude(false) Type 10 Opaque lsa's
+     * @return list of lsa header in the lsdb
+     */
+    public List getLsaHeaders(boolean excludeMaxAgeLsa, boolean isOpaquecapable) {
+        return database.getAllLsaHeaders(excludeMaxAgeLsa, isOpaquecapable);
+    }
+
+    /**
+     * Gets the LSA from LSDB based on the input.
+     *
+     * @param lsType            type of lsa to form the key
+     * @param linkStateID       link state id to form the key
+     * @param advertisingRouter advertising router to form the key
+     * @return lsa wrapper instance which contains the Lsa
+     * @throws Exception might throws exception
+     */
+    public LsaWrapper getLsa(int lsType, String linkStateID, String advertisingRouter) throws Exception {
+        String lsaKey = lsType + "-" + linkStateID + "-" + advertisingRouter;
+        if (lsType == OspfParameters.LINK_LOCAL_OPAQUE_LSA || lsType == OspfParameters.AREA_LOCAL_OPAQUE_LSA ||
+                lsType == OspfParameters.AS_OPAQUE_LSA) {
+            byte[] linkStateAsBytes = InetAddress.getByName(linkStateID).getAddress();
+            int opaqueType = linkStateAsBytes[0];
+            int opaqueId = OspfUtil.byteToInteger(Arrays.copyOfRange(linkStateAsBytes, 1,
+                                                                     linkStateAsBytes.length));
+            lsaKey = lsType + "-" + opaqueType + opaqueId + "-" + advertisingRouter;
+        }
+        return database.findLsa(lsType, lsaKey);
+    }
+
+
+    /**
+     * Checks whether an instance of the given LSA exists in the database belonging to this area.
+     * If so return true else false.
+     *
+     * @param lookupLsa ospf LSA instance to lookup
+     * @return LSA wrapper instance which contains the Lsa
+     */
+    public LsaWrapper lsaLookup(OspfLsa lookupLsa) {
+        return database.lsaLookup((LsaHeader) lookupLsa);
+    }
+
+    /**
+     * Checks whether an instance of the given LSA exists in the database belonging to this area.
+     * If so return true else false.
+     *
+     * @param lsa1 OSPF LSA instance to compare
+     * @param lsa2 OSPF LSA instance to compare
+     * @return "same" if both instances are same, "latest" if lsa1 is latest, or "old" if lsa1 is old
+     */
+    public String isNewerOrSameLsa(OspfLsa lsa1, OspfLsa lsa2) {
+        return database.isNewerOrSameLsa((LsaHeader) lsa1, (LsaHeader) lsa2);
+    }
+
+    /**
+     * Methods gets called from ChannelHandler to add the received LSA to LSDB.
+     *
+     * @param ospfLsa       OSPF LSA instance
+     * @param ospfInterface OSPF interface instance
+     */
+    public void addLsa(OspfLsa ospfLsa, OspfInterface ospfInterface) throws Exception {
+        //second param is false as lsa from network
+        database.addLsa((LsaHeader) ospfLsa, false, ospfInterface);
+    }
+
+    /**
+     * Methods gets called from ChannelHandler to add the received LSA to LSDB.
+     *
+     * @param ospfLsa          OSPF LSA instance
+     * @param isSelfOriginated true if the LSA is self originated. Else false
+     * @param ospfInterface    OSPF interface instance
+     */
+    public void addLsa(OspfLsa ospfLsa, boolean isSelfOriginated, OspfInterface ospfInterface)
+            throws Exception {
+        database.addLsa((LsaHeader) ospfLsa, isSelfOriginated, ospfInterface);
+    }
+
+    /**
+     * Adds the LSA to maxAge bin.
+     *
+     * @param key     key to add it to LSDB
+     * @param wrapper LSA wrapper instance
+     */
+    public void addLsaToMaxAgeBin(String key, LsaWrapper wrapper) {
+        database.addLsaToMaxAgeBin(key, wrapper);
+    }
+
+    /**
+     * Sets router sequence number for router LSA.
+     *
+     * @param newSequenceNumber sequence number
+     */
+    public void setDbRouterSequenceNumber(long newSequenceNumber) {
+        database.setRouterLsaSeqNo(newSequenceNumber);
+    }
+
+    /**
+     * Methods gets called from ChannelHandler to delete the LSA.
+     *
+     * @param ospfLsa the LSA instance to delete
+     */
+    public void deleteLsa(LsaHeader ospfLsa) {
+        database.deleteLsa(ospfLsa);
+    }
+
+    /**
+     * Removes LSA from bin.
+     *
+     * @param lsaWrapper the LSA wrapper instance to delete
+     */
+    public void removeLsaFromBin(LsaWrapper lsaWrapper) {
+        database.removeLsaFromBin(lsaWrapper);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("areaID", areaId)
+                .add("stubCost", stubCost)
+                .add("addressRanges", addressRanges)
+                .add("interfacesLst", interfacesLst)
+                .add("transitCapability", transitCapability)
+                .add("externalRoutingCapability", externalRoutingCapability)
+                .toString();
+    }
+
+    /**
+     * Checks all Neighbors belonging to this Area whether they are in state lesser than the EXCHANGE.
+     * <p>
+     * Creates list of such neighbors
+     * <p>
+     * Returns list of neighbors who satisfy the conditions
+     *
+     * @param ospfInterface OSPF interface instance
+     * @return List of interfaces having state lesser than exchange
+     */
+    public List<OspfNbr> getNeighborsInFullState(OspfInterface ospfInterface) {
+
+        List<OspfNbr> listEligibleNeighbors = null;
+        OspfNbrImpl ospfNeighbor = null;
+        OspfNeighborState nextNeighborState;
+        Iterator nbrInterface = ospfInterface.listOfNeighbors().values().iterator();
+        while (nbrInterface.hasNext()) {
+            ospfNeighbor = (OspfNbrImpl) nbrInterface.next();
+            nextNeighborState = ospfNeighbor.getState();
+            if (nextNeighborState.getValue() == OspfNeighborState.FULL.getValue()) {
+                if (listEligibleNeighbors == null) {
+                    listEligibleNeighbors = new ArrayList<OspfNbr>();
+                    listEligibleNeighbors.add(ospfNeighbor);
+                } else {
+                    listEligibleNeighbors.add(ospfNeighbor);
+                }
+            }
+        }
+        return listEligibleNeighbors;
+    }
+
+    /**
+     * Gets the LSDB LSA key from LSA header.
+     *
+     * @param lsaHeader LSA header instance
+     * @return key LSA key
+     */
+    public String getLsaKey(LsaHeader lsaHeader) {
+        return database.getLsaKey(lsaHeader);
+    }
+
+    /**
+     * Adds the received LSA in other neighbors tx list.
+     *
+     * @param recLsa LSA Header instance
+     */
+    public void addToOtherNeighborLsaTxList(LsaHeader recLsa) {
+        //Add the received LSA in other neighbors retransmission list.
+        log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList");
+        List<OspfInterface> ospfInterfaces = getInterfacesLst();
+        for (OspfInterface ospfInterfaceFromArea : ospfInterfaces) {
+            Map neighbors = ospfInterfaceFromArea.listOfNeighbors();
+            for (Object neighborIP : neighbors.keySet()) {
+                OspfNbrImpl nbr = (OspfNbrImpl) neighbors.get(neighborIP);
+                if (nbr.getState().getValue() < OspfNeighborState.EXCHANGE.getValue()) {
+                    continue;
+                }
+                String key = database.getLsaKey(recLsa);
+                if (nbr.getState() == OspfNeighborState.EXCHANGE || nbr.getState() == OspfNeighborState.LOADING) {
+                    if (nbr.getLsReqList().containsKey(key)) {
+                        LsaWrapper lsWrapper = lsaLookup(recLsa);
+                        if (lsWrapper != null) {
+                            LsaHeader ownLSA = (LsaHeader) lsWrapper.ospfLsa();
+                            String status = isNewerOrSameLsa(recLsa, ownLSA);
+                            if (status.equals("old")) {
+                                continue;
+                            } else if (status.equals("same")) {
+                                log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
+                                                  "Removing lsa from reTxtList {}", key);
+                                nbr.getLsReqList().remove(key);
+                                continue;
+                            } else {
+                                log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
+                                                  "Removing lsa from reTxtList {}", key);
+                                nbr.getLsReqList().remove(key);
+                            }
+                        }
+                    }
+                }
+                if (recLsa.advertisingRouter().equals((String) neighborIP)) {
+                    continue;
+                }
+                if ((recLsa.lsType() == OspfParameters.LINK_LOCAL_OPAQUE_LSA ||
+                        recLsa.lsType() == OspfParameters.AREA_LOCAL_OPAQUE_LSA)) {
+                    if (nbr.isOpaqueCapable()) {
+                        log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
+                                  recLsa);
+                        nbr.getReTxList().put(key, recLsa);
+                    }
+                } else {
+                    log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
+                              recLsa);
+                    nbr.getReTxList().put(key, recLsa);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the options value.
+     *
+     * @return options value
+     */
+    public int options() {
+        return options;
+    }
+
+    /**
+     * Sets the options value.
+     *
+     * @param options options value
+     */
+    public void setOptions(int options) {
+        this.options = options;
+    }
+
+    /**
+     * Gets the opaque enabled options value.
+     *
+     * @return opaque enabled options value
+     */
+    public int opaqueEnabledOptions() {
+        return Integer.parseInt(OspfParameters.OPAQUE_ENABLED_OPTION_VALUE, 2);
+    }
+
+    /**
+     * Gets the lsdb instance for this area.
+     *
+     * @return lsdb instance
+     */
+    public OspfLsdb database() {
+        return database;
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfNbrImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfNbrImpl.java
new file mode 100755
index 0000000..0d284bf
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/impl/OspfNbrImpl.java
@@ -0,0 +1,1871 @@
+/*
+* Copyright 2016 Open Networking Laboratory
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.onosproject.ospf.controller.impl;
+
+import org.jboss.netty.channel.Channel;
+import org.onlab.packet.Ip4Address;
+import org.onlab.util.Bandwidth;
+import org.onosproject.ospf.controller.DeviceInformation;
+import org.onosproject.ospf.controller.LinkInformation;
+import org.onosproject.ospf.controller.LsaWrapper;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.OspfDeviceTed;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfLinkTed;
+import org.onosproject.ospf.controller.OspfLsa;
+import org.onosproject.ospf.controller.OspfLsaType;
+import org.onosproject.ospf.controller.OspfLsdb;
+import org.onosproject.ospf.controller.OspfNbr;
+import org.onosproject.ospf.controller.OspfNeighborState;
+import org.onosproject.ospf.controller.OspfRouter;
+import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
+import org.onosproject.ospf.controller.area.OspfAreaImpl;
+import org.onosproject.ospf.controller.area.OspfInterfaceImpl;
+import org.onosproject.ospf.controller.lsdb.LsaWrapperImpl;
+import org.onosproject.ospf.controller.util.OspfInterfaceType;
+import org.onosproject.ospf.protocol.lsa.LsaHeader;
+import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
+import org.onosproject.ospf.protocol.lsa.types.OpaqueLsa10;
+import org.onosproject.ospf.protocol.lsa.types.TopLevelTlv;
+import org.onosproject.ospf.protocol.ospfpacket.OspfMessage;
+import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
+import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
+import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;
+import org.onosproject.ospf.protocol.util.ChecksumCalculator;
+import org.onosproject.ospf.protocol.util.OspfInterfaceState;
+import org.onosproject.ospf.protocol.util.OspfPacketType;
+import org.onosproject.ospf.protocol.util.OspfParameters;
+import org.onosproject.ospf.protocol.util.OspfUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Represents an OSPF neighbor.
+ * The first thing an OSPF router must do is find its neighbors and form adjacency.
+ * Each neighbor that the router finds will be represented by this class.
+ */
+public class OspfNbrImpl implements OspfNbr {
+    private static final Logger log = LoggerFactory.getLogger(OspfNbrImpl.class);
+    private OspfNeighborState state;
+    private InternalRxmtDdPacket rxmtDdPacketTask;
+    private InternalInactivityTimeCheck inActivityTimeCheckTask;
+    private InternalFloodingTask floodingTask;
+    private InternalRxmtLsrPacket rxmtLsrPacketTask;
+    private ScheduledExecutorService exServiceRxmtLsr;
+    private ScheduledExecutorService exServiceFlooding;
+    private ScheduledExecutorService exServiceRxmtDDPacket;
+    private ScheduledExecutorService exServiceInActivity;
+
+    private boolean floodingTimerScheduled = false;
+    private boolean rxmtLsrTimerScheduled = false;
+    private boolean rxmtDdPacketTimerScheduled = false;
+    private boolean inActivityTimerScheduled = false;
+
+    /**
+     * When the two neighbors are exchanging databases, they form a master/slave relationship.
+     * The master sends the first Database Description Packet
+     */
+    private int isMaster;
+
+    /**
+     * The DD Sequence Number of the DD packet that is currently being sent to the neighbor.
+     */
+    private long ddSeqNum;
+
+    /**
+     * Another data structure for keeping information of the last received DD packet.
+     */
+    private DdPacket lastDdPacket;
+
+    /**
+     * Another data structure for keeping information of the last Sent DD packet.
+     */
+    private DdPacket lastSentDdPacket;
+
+    /**
+     * Another data structure for keeping information of the last Sent LSrequest packet.
+     */
+    private LsRequest lastSentLsrPacket;
+
+    /**
+     * The router ID of the Neighbor Router.
+     */
+    private Ip4Address neighborId;
+
+    /**
+     * The IP address of the neighboring router's interface to the attached network.
+     */
+    private Ip4Address neighborIpAddr;
+
+    /**
+     * The neighbor's IDEA of the designated router.
+     */
+    private Ip4Address neighborDr;
+
+    /**
+     * The neighbor's IDEA of the backup designated router.
+     */
+    private Ip4Address neighborBdr;
+
+    private int routerPriority;
+    private int routerDeadInterval;
+
+    /**
+     * The list of LSAs that have to be flooded.
+     */
+    private Map<String, OspfLsa> reTxList = new LinkedHashMap();
+
+    /**
+     * The list of LSAs that have been flooded but not yet acknowledged on this adjacency.
+     */
+    private Map<String, OspfLsa> pendingReTxList = new LinkedHashMap();
+
+    /**
+     * List of LSAs which are failed to received ACK.
+     */
+    private Map failedTxList = new HashMap();
+
+    /**
+     * The complete list of LSAs that make up the area link-state database, at the moment the.
+     * neighbor goes into Database Exchange state (EXCHANGE).
+     */
+    private List<LsaHeader> ddSummaryList = new CopyOnWriteArrayList();
+
+    /**
+     * LSA Request List from Neighbor.
+     */
+    private Hashtable lsReqList = new Hashtable();
+
+    /**
+     * The optional OSPF capabilities supported by the neighbor.
+     */
+    private int options;
+    private boolean isOpaqueCapable;
+
+    /**
+     * A link to the OSPF-Interface this Neighbor belongs to.
+     */
+    private OspfInterface ospfInterface;
+
+    /**
+     * A link to the OSPF-Area this Neighbor Data Structure belongs to.
+     */
+    private OspfArea ospfArea;
+    private OspfInterfaceChannelHandler handler;
+    private List<TopLevelTlv> topLevelTlvs = new ArrayList<>();
+    private List<DeviceInformation> deviceInformationList = new ArrayList<>();
+
+    private TopologyForDeviceAndLink topologyForDeviceAndLink;
+
+    /**
+     * Creates an instance of Neighbor.
+     *
+     * @param paramOspfArea                  OSPF Area instance
+     * @param paramOspfInterface             OSPF interface instance
+     * @param ipAddr                         IP address
+     * @param routerId                       router id
+     * @param options                        options
+     * @param handler                        channel handler instance
+     * @param topologyForDeviceAndLinkCommon topology for device and link instance
+     */
+    public OspfNbrImpl(OspfArea paramOspfArea, OspfInterface paramOspfInterface,
+                       Ip4Address ipAddr, Ip4Address routerId, int options,
+                       OspfInterfaceChannelHandler handler, TopologyForDeviceAndLink topologyForDeviceAndLinkCommon) {
+        this.ospfArea = paramOspfArea;
+        this.ospfInterface = paramOspfInterface;
+        state = OspfNeighborState.DOWN;
+        isMaster = OspfUtil.NOT_MASTER;
+        ddSeqNum = OspfUtil.createRandomNumber();
+        neighborIpAddr = ipAddr;
+        neighborId = routerId;
+        this.options = options;
+        lastDdPacket = new DdPacket();
+        routerDeadInterval = paramOspfInterface.routerDeadIntervalTime();
+        this.handler = handler;
+        this.topologyForDeviceAndLink = topologyForDeviceAndLinkCommon;
+    }
+
+    /**
+     * Gets the IP address of this neighbor.
+     *
+     * @return the IP address of this neighbor
+     */
+    public Ip4Address neighborIpAddr() {
+        return neighborIpAddr;
+    }
+
+    /**
+     * Gets the neighbor is opaque enabled or not.
+     *
+     * @return true if the neighbor is opaque enabled else false.
+     */
+    public boolean isOpaqueCapable() {
+        return isOpaqueCapable;
+    }
+
+    /**
+     * Sets the neighbor is opaque enabled or not.
+     *
+     * @param isOpaqueCapable true if the neighbor is opaque enabledelse false
+     */
+    public void setIsOpaqueCapable(boolean isOpaqueCapable) {
+        this.isOpaqueCapable = isOpaqueCapable;
+    }
+
+    /**
+     * Have seen a Neighbor, but the Neighbor doesn't know about me.
+     *
+     * @param ospfHello Hello Packet instance
+     * @param channel   netty channel instance
+     */
+    public void oneWayReceived(OspfMessage ospfHello, Channel channel) {
+        log.debug("OSPFNbr::oneWayReceived...!!!");
+        stopInactivityTimeCheck();
+        startInactivityTimeCheck();
+
+        if (state == OspfNeighborState.ATTEMPT) {
+            state = OspfNeighborState.INIT;
+        } else if (state == OspfNeighborState.DOWN) {
+            state = OspfNeighborState.INIT;
+        }
+
+        if (state.getValue() >= OspfNeighborState.TWOWAY.getValue()) {
+            state = OspfNeighborState.INIT;
+            failedTxList.clear();
+            ddSummaryList.clear();
+            lsReqList.clear();
+        }
+    }
+
+    /**
+     * Called when a DD OSPFMessage is received while state was INIT.
+     *
+     * @param ospfMessage ospf message instance
+     * @param channel     netty channel instance
+     * @throws Exception might throws exception
+     */
+    public void twoWayReceived(OspfMessage ospfMessage, Channel channel) throws Exception {
+        log.debug("OSPFNbr::twoWayReceived...!!!");
+        stopInactivityTimeCheck();
+        startInactivityTimeCheck();
+        startFloodingTimer(channel);
+
+        OspfPacketHeader packet = (OspfPacketHeader) ospfMessage;
+        if (state.getValue() <= OspfNeighborState.TWOWAY.getValue()) {
+            if (formAdjacencyOrNot()) {
+                state = OspfNeighborState.EXSTART;
+
+                ddSeqNum++;
+                DdPacket ddPacket = new DdPacket();
+                // seting OSPF Header
+                ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+                ddPacket.setOspftype(OspfPacketType.DD.value());
+                ddPacket.setRouterId(ospfArea.routerId());
+                ddPacket.setAreaId(ospfArea.areaId());
+                ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+                ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+                boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+                if (isOpaqueEnabled) {
+                    ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+                } else {
+                    ddPacket.setOptions(ospfArea.options());
+                }
+                ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
+                ddPacket.setIsMore(OspfUtil.MORE_SET);
+                ddPacket.setIsMaster(OspfUtil.IS_MASTER);
+                ddPacket.setImtu(ospfInterface.mtu());
+                ddPacket.setSequenceNo(ddSeqNum);
+
+                setLastSentDdPacket(ddPacket);
+                rxmtDdPacketTask = new InternalRxmtDdPacket(channel);
+                startRxMtDdTimer(channel);
+                //setting destination ip
+                ddPacket.setDestinationIp(packet.sourceIp());
+                channel.write(ddPacket);
+            } else {
+                state = OspfNeighborState.TWOWAY;
+            }
+        }
+    }
+
+    /**
+     * Checks whether to form adjacency or not.
+     *
+     * @return true indicates form adjacency, else false
+     */
+    private boolean formAdjacencyOrNot() {
+        boolean formAdjacency = false;
+
+        if (ospfInterface.interfaceType() == OspfInterfaceType.POINT_TO_POINT.value()) {
+            formAdjacency = true;
+        } else if (ospfInterface.interfaceType() == OspfInterfaceType.BROADCAST.value()) {
+            if (ospfInterface.ipAddress().equals(this.neighborDr) ||
+                    ospfInterface.ipAddress().equals(this.neighborBdr)) {
+                formAdjacency = true;
+            } else if (neighborBdr.equals(neighborIpAddr) ||
+                    neighborDr.equals(neighborIpAddr)) {
+                formAdjacency = true;
+            }
+        }
+
+        log.debug("FormAdjacencyOrNot - neighborDR: {}, neighborBDR: {}, neighborIPAddr: {}, formAdjacencyOrNot {}",
+                  neighborDr, neighborBdr, neighborIpAddr, formAdjacency);
+
+        return formAdjacency;
+    }
+
+    /**
+     * At this point Master/Slave relationship is definitely established.
+     * DD sequence numbers have been exchanged.
+     * This is the begin of sending/receiving of DD OSPFMessages.
+     *
+     * @param ospfMessage      OSPF message instance
+     * @param neighborIsMaster neighbor is master or slave
+     * @param payload          contains the LSAs to add in Dd Packet
+     * @param ch               netty channel instance
+     * @throws Exception might throws exception
+     */
+    public void negotiationDone(OspfMessage ospfMessage,
+                                boolean neighborIsMaster, List payload, Channel ch) throws Exception {
+        stopRxMtDdTimer();
+        OspfPacketHeader packet = (OspfPacketHeader) ospfMessage;
+        DdPacket ddPacketForCheck = (DdPacket) packet;
+        if (ddPacketForCheck.isOpaqueCapable()) {
+            OspfLsdb database = ospfArea.database();
+            List opaqueLsas = database.getAllLsaHeaders(true, true);
+            Iterator iterator = opaqueLsas.iterator();
+            while (iterator.hasNext()) {
+                OspfLsa ospfLsa = (OspfLsa) iterator.next();
+                if (ospfLsa.getOspfLsaType() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA) {
+                    OpaqueLsa10 opaqueLsa10 = (OpaqueLsa10) ospfLsa;
+                    topLevelTlvs = opaqueLsa10.topLevelValues();
+                }
+            }
+        }
+        if (state == OspfNeighborState.EXSTART) {
+            state = OspfNeighborState.EXCHANGE;
+            boolean excludeMaxAgeLsa = true;
+            //list of contents of area wise LSA
+            ddSummaryList = (CopyOnWriteArrayList) ospfArea.getLsaHeaders(excludeMaxAgeLsa, isOpaqueCapable);
+
+            if (neighborIsMaster) {
+                processLsas(payload);
+                // ...construct new DD Packet...
+                DdPacket ddPacket = new DdPacket();
+                // setting OSPF Header
+                ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+                ddPacket.setOspftype(OspfPacketType.DD.value());
+                ddPacket.setRouterId(ospfArea.routerId());
+                ddPacket.setAreaId(ospfArea.areaId());
+                ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+                ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+                boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+                if (isOpaqueEnabled && isOpaqueCapable) {
+                    ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+                } else {
+                    ddPacket.setOptions(ospfArea.options());
+                }
+                ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
+                ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
+                ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
+                ddPacket.setImtu(ospfInterface.mtu());
+                ddPacket.setSequenceNo(ddSeqNum);
+                //setting the destination
+                ddPacket.setDestinationIp(packet.sourceIp());
+                setLastSentDdPacket(ddPacket);
+                getIsMoreBit();
+
+                ch.write(lastSentDdPacket());
+            } else {
+                // process LSA Vector's List, Add it to LSRequestList.
+                processLsas(payload);
+                DdPacket ddPacket = new DdPacket();
+                // setting OSPF Header
+                ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+                ddPacket.setOspftype(OspfPacketType.DD.value());
+                ddPacket.setRouterId(ospfArea.routerId());
+                ddPacket.setAreaId(ospfArea.areaId());
+                ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+                ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+                boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+                if (isOpaqueEnabled && isOpaqueCapable) {
+                    ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+                } else {
+                    ddPacket.setOptions(ospfArea.options());
+                }
+                ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
+                ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
+                ddPacket.setIsMaster(OspfUtil.IS_MASTER);
+                ddPacket.setImtu(ospfInterface.mtu());
+                ddPacket.setSequenceNo(ddSeqNum);
+                setLastSentDdPacket(ddPacket);
+                getIsMoreBit();
+                ddPacket.setDestinationIp(packet.sourceIp());
+                ch.write(lastSentDdPacket());
+                startRxMtDdTimer(ch);
+            }
+        }
+    }
+
+    /**
+     * Process the LSA Headers received in the last received Database Description OSPFMessage.
+     *
+     * @param ddPayload LSA headers to process
+     * @throws Exception might throws exception
+     */
+    public void processLsas(List ddPayload) throws Exception {
+        log.debug("OSPFNbr::processLsas...!!!");
+        OspfLsa nextLsa;
+        Iterator lsas = ddPayload.iterator();
+        while (lsas.hasNext()) {
+            nextLsa = (OspfLsa) lsas.next();
+            // check LSA Type.
+            if (((nextLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
+                    (nextLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
+                    (nextLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
+                // unknown lsType found!
+                seqNumMismatch("LS Type found was unknown.");
+                return;
+            }
+
+            if ((nextLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
+                    !ospfArea.isExternalRoutingCapability()) {
+                // LSA is external and the Area has no external lsa capability
+                seqNumMismatch("External LSA found although area is stub.");
+                return;
+            }
+
+            LsaWrapper lsaHasInstance = ospfArea.lsaLookup(nextLsa);
+            if (lsaHasInstance == null) {
+                lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
+            } else {
+                String isNew = ((OspfAreaImpl) ospfArea).isNewerOrSameLsa(nextLsa,
+                                                                          lsaHasInstance.ospfLsa());
+                if (isNew.equals("latest")) {
+                    lsReqList.put(((OspfAreaImpl) ospfArea).getLsaKey((LsaHeader) nextLsa), nextLsa);
+                }
+            }
+        }
+    }
+
+    /**
+     * Handles sequence number mis match event.
+     *
+     * @param reason a string represents the mismatch reason
+     * @return OSPF message instance
+     * @throws Exception might throws exception
+     */
+    public OspfMessage seqNumMismatch(String reason) throws Exception {
+        log.debug("OSPFNbr::seqNumMismatch...{} ", reason);
+        stopRxMtDdTimer();
+
+        if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
+           /* if (state == OspfNeighborState.FULL) {
+                ospfArea.refreshArea(ospfInterface);
+            }*/
+
+            state = OspfNeighborState.EXSTART;
+            lsReqList.clear();
+            ddSummaryList.clear();
+            //increment the dd sequence number
+            ddSeqNum++;
+
+            DdPacket ddPacket = new DdPacket();
+            // seting OSPF Header
+            ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+            ddPacket.setOspftype(OspfPacketType.DD.value());
+            ddPacket.setRouterId(ospfArea.routerId());
+            ddPacket.setAreaId(ospfArea.areaId());
+            ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+            ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+            ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+            ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+            boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+            if (isOpaqueEnabled) {
+                ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+            } else {
+                ddPacket.setOptions(ospfArea.options());
+            }
+            ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
+            ddPacket.setIsMore(OspfUtil.MORE_SET);
+            ddPacket.setIsMaster(OspfUtil.IS_MASTER);
+            ddPacket.setImtu(ospfInterface.mtu());
+            ddPacket.setSequenceNo(ddSeqNum);
+
+            setLastSentDdPacket(ddPacket);
+            //setting destination ip
+            ddPacket.setDestinationIp(neighborIpAddr());
+            setLastSentDdPacket(ddPacket);
+
+            return ddPacket;
+        }
+
+        return null;
+    }
+
+    /**
+     * Called if a LS Request has been received for an LSA which is not contained in the database.
+     * This indicates an error in the Database Exchange process.
+     * Actions to be performed are the same as in seqNumMismatch.
+     * In addition, stop the possibly activated re transmission timer.
+     *
+     * @param ch netty channel instance
+     */
+    public void badLSReq(Channel ch) throws Exception {
+        log.debug("OSPFNbr::badLSReq...!!!");
+
+        if (state.getValue() >= OspfNeighborState.EXCHANGE.getValue()) {
+            if (state == OspfNeighborState.FULL) {
+                ospfArea.refreshArea(ospfInterface);
+            }
+
+            stopRxMtDdTimer();
+            state = OspfNeighborState.EXSTART;
+
+            lsReqList.clear();
+            ddSummaryList.clear();
+            reTxList.clear();
+            //increment the dd sequence number
+            isMaster = OspfUtil.IS_MASTER;
+            ddSeqNum++;
+            DdPacket ddPacket = new DdPacket();
+            // seting OSPF Header
+            ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+            ddPacket.setOspftype(OspfPacketType.DD.value());
+            ddPacket.setRouterId(ospfArea.routerId());
+            ddPacket.setAreaId(ospfArea.areaId());
+            ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+            ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+            ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+            ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+
+            // setting DD Body
+            boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+            if (isOpaqueEnabled && this.isOpaqueCapable) {
+                ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+            } else {
+                ddPacket.setOptions(ospfArea.options());
+            }
+            ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
+            ddPacket.setIsMore(OspfUtil.MORE_SET);
+            ddPacket.setIsMaster(OspfUtil.IS_MASTER);
+            ddPacket.setImtu(ospfInterface.mtu());
+            ddPacket.setSequenceNo(ddSeqNum);
+
+            rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
+            startRxMtDdTimer(ch);
+
+            //setting destination ip
+            ddPacket.setDestinationIp(neighborIpAddr());
+            setLastSentDdPacket(ddPacket);
+            ch.write(ddPacket);
+        }
+    }
+
+    /**
+     * Called if state is EXCHANGE. This method is executed every time a DD Packets arrives.
+     * When the last Packet arrives, it transfers the state into LOADING or FULL
+     *
+     * @param neighborIsMaster true if neighbor is master else false
+     * @param dataDescPkt      DdPacket instance
+     * @param ch               netty channel instance
+     * @throws Exception might throws exception
+     */
+    public void processDdPacket(boolean neighborIsMaster, DdPacket dataDescPkt,
+                                Channel ch) throws Exception {
+        log.debug("OSPFNbr::neighborIsMaster.{}", neighborIsMaster);
+
+        if (!neighborIsMaster) {
+            stopRxMtDdTimer();
+            ddSeqNum++;
+            processLsas(dataDescPkt.getLsaHeaderList());
+            if ((ddSummaryList.isEmpty()) &&
+                    (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
+                log.debug(
+                        "OSPFNbr::ddSummaryList is empty and dataDescPkt.isMore is zero..!!!");
+                // generate the neighbor event ExchangeDone.
+                exchangeDone(dataDescPkt, ch);
+            } else {
+                log.debug("OSPFNbr::ddSummaryList is present...!!!");
+                // send a new Database Description Packet to the slave.
+                DdPacket ddPacket = new DdPacket();
+                // seting OSPF Header
+                ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+                ddPacket.setOspftype(OspfPacketType.DD.value());
+                ddPacket.setRouterId(ospfArea.routerId());
+                ddPacket.setAreaId(ospfArea.areaId());
+                ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+                ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+                // setting DD Body
+                boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+                if (isOpaqueEnabled && isOpaqueCapable) {
+                    ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+                } else {
+                    ddPacket.setOptions(ospfArea.options());
+                }
+                ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
+                ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
+                ddPacket.setIsMaster(OspfUtil.IS_MASTER);
+                ddPacket.setImtu(ospfInterface.mtu());
+                ddPacket.setSequenceNo(ddSeqNum);
+
+                setLastSentDdPacket(ddPacket);
+                getIsMoreBit();
+                //Set the destination IP Address
+                ddPacket.setDestinationIp(dataDescPkt.sourceIp());
+                ch.write(lastSentDdPacket());
+
+                startRxMtDdTimer(ch);
+            }
+        } else {
+            log.debug("OSPFNbr::neighborIsMaster is master...!!!");
+            ddSeqNum = dataDescPkt.sequenceNo();
+            processLsas(dataDescPkt.getLsaHeaderList());
+
+            DdPacket ddPacket = new DdPacket();
+            // seting OSPF Header
+            ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+            ddPacket.setOspftype(OspfPacketType.DD.value());
+            ddPacket.setRouterId(ospfArea.routerId());
+            ddPacket.setAreaId(ospfArea.areaId());
+            ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+            ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+            ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+            ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+            // setting DD Body
+            boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+            if (isOpaqueEnabled && this.isOpaqueCapable) {
+                ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+            } else {
+                ddPacket.setOptions(ospfArea.options());
+            }
+            ddPacket.setIsInitialize(OspfUtil.INITIALIZE_NOTSET);
+            ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
+            ddPacket.setIsMaster(OspfUtil.NOT_MASTER);
+            ddPacket.setImtu(ospfInterface.mtu());
+            ddPacket.setSequenceNo(ddSeqNum);
+            setLastSentDdPacket(ddPacket);
+            getIsMoreBit();
+
+            if ((ddPacket.isMore() == OspfUtil.MORE_NOTSET) &&
+                    (dataDescPkt.isMore() == OspfUtil.MORE_NOTSET)) {
+                // generate the neighbor event ExchangeDone.
+                exchangeDone(dataDescPkt, ch);
+            }
+
+            ddPacket.setDestinationIp(dataDescPkt.sourceIp());
+            ch.write(ddPacket);
+        }
+    }
+
+    /**
+     * Sets the more bit in stored, last sent DdPacket.
+     */
+    private void getIsMoreBit() {
+        DdPacket ddPacket = lastSentDdPacket();
+        int count = ddSummaryList.size();
+
+        if (!ddSummaryList.isEmpty()) {
+            Iterator itr = ddSummaryList.iterator();
+            int currentLength = OspfUtil.DD_HEADER_LENGTH;
+            int maxSize = ospfInterface.mtu() - OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
+            while (itr.hasNext()) {
+                if ((currentLength + OspfUtil.LSA_HEADER_LENGTH) > maxSize) {
+                    break;
+                }
+
+                LsaHeader lsaHeader = (LsaHeader) itr.next();
+                ddPacket.addLsaHeader(lsaHeader);
+                currentLength = currentLength + OspfUtil.LSA_HEADER_LENGTH;
+                ddSummaryList.remove(lsaHeader);
+                count--;
+            }
+
+            if (count > 0) {
+                ddPacket.setIsMore(OspfUtil.MORE_SET);
+            } else {
+                ddPacket.setIsMore(OspfUtil.MORE_NOTSET);
+            }
+        }
+
+        setLastSentDdPacket(ddPacket);
+    }
+
+    /**
+     * At this point, the router has sent and received an entire sequence of DD packets.
+     * Now it must be determined whether the new state is FULL, or LS Request packets
+     * have to be send.
+     *
+     * @param message OSPF message instance
+     * @param ch      netty channel handler
+     */
+    public void exchangeDone(OspfMessage message, Channel ch) {
+        log.debug("OSPFNbr::exchangeDone...!!!");
+        stopRxMtDdTimer();
+
+        OspfPacketHeader header = (OspfPacketHeader) message;
+
+        if (state == OspfNeighborState.EXCHANGE) {
+            if (lsReqList.isEmpty()) {
+                state = OspfNeighborState.FULL;
+                //handler.addDeviceInformation(this);
+                //handler.addLinkInformation(this, topLevelTlvs);
+            } else {
+                state = OspfNeighborState.LOADING;
+                LsRequest lsRequest = buildLsRequest();
+                //Setting the destination address
+                lsRequest.setDestinationIp(header.sourceIp());
+                ch.write(lsRequest);
+
+                setLastSentLsrPacket(lsRequest);
+                startRxMtLsrTimer(ch);
+            }
+        }
+    }
+
+    /**
+     * Builds LS Request.
+     *
+     * @return ls request instance
+     */
+    private LsRequest buildLsRequest() {
+        //send link state request packet to neighbor
+        //for recent lsa's which are not received in exchange state
+        LsRequest lsRequest = new LsRequest();
+        lsRequest.setOspfVer(OspfUtil.OSPF_VERSION);
+        lsRequest.setOspftype(OspfPacketType.LSREQUEST.value());
+        lsRequest.setRouterId(ospfArea.routerId());
+        lsRequest.setAreaId(ospfArea.areaId());
+        lsRequest.setAuthType(OspfUtil.NOT_ASSIGNED);
+        lsRequest.setAuthentication(OspfUtil.NOT_ASSIGNED);
+        lsRequest.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+        lsRequest.setChecksum(OspfUtil.NOT_ASSIGNED);
+
+        Set lsaKeys = lsReqList.keySet();
+        Iterator itr = lsaKeys.iterator();
+
+        int currentLength = OspfUtil.OSPF_HEADER_LENGTH;
+        int maxSize = ospfInterface.mtu() -
+                OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
+
+        while (itr.hasNext()) {
+            if ((currentLength + OspfUtil.LSREQUEST_LENGTH) >= maxSize) {
+                break;
+            }
+            LsRequestPacket lsRequestPacket = new LsRequestPacket();
+
+            String key = ((String) itr.next());
+            String[] lsaKey = key.split("-");
+            OspfLsa lsa = (OspfLsa) lsReqList.get(key);
+
+            lsRequestPacket.setLsType(Integer.valueOf(lsaKey[0]));
+            lsRequestPacket.setOwnRouterId(lsaKey[2]);
+
+            if (((lsa.getOspfLsaType().value() == OspfLsaType.AREA_LOCAL_OPAQUE_LSA.value()) ||
+                    (lsa.getOspfLsaType().value() == OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
+                    (lsa.getOspfLsaType().value() == OspfLsaType.AS_OPAQUE_LSA.value())) {
+                OpaqueLsaHeader header = (OpaqueLsaHeader) lsa;
+                byte[] opaqueIdBytes = OspfUtil.convertToTwoBytes(header.opaqueId());
+                lsRequestPacket.setLinkStateId(header.opaqueType() + "." + "0" + "." + opaqueIdBytes[0]
+                                                       + "." + opaqueIdBytes[1]);
+            } else {
+                lsRequestPacket.setLinkStateId(lsaKey[1]);
+            }
+
+            lsRequest.addLinkStateRequests(lsRequestPacket);
+            currentLength = currentLength + OspfUtil.LSREQUEST_LENGTH;
+        }
+
+        return lsRequest;
+    }
+
+    /**
+     * Determines whether an adjacency should be established/maintained with the neighbor or not.
+     *
+     * @param ch netty channel instance
+     */
+    public void adjOk(Channel ch) {
+        log.debug("OSPFNbr::adjOk...!!!");
+        if (ospfInterface.interfaceType() != OspfInterfaceType.POINT_TO_POINT.value()) {
+            if (state == OspfNeighborState.TWOWAY) {
+                if (formAdjacencyOrNot()) {
+                    state = OspfNeighborState.EXSTART;
+                    //check for sequence number in lsdb
+                    ddSeqNum++;
+
+                    DdPacket ddPacket = new DdPacket();
+                    // seting OSPF Header
+                    ddPacket.setOspfVer(OspfUtil.OSPF_VERSION);
+                    ddPacket.setOspftype(OspfPacketType.DD.value());
+                    ddPacket.setRouterId(ospfArea.routerId());
+                    ddPacket.setAreaId(ospfArea.areaId());
+                    ddPacket.setAuthType(OspfUtil.NOT_ASSIGNED);
+                    ddPacket.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                    ddPacket.setOspfPacLength(OspfUtil.NOT_ASSIGNED);
+                    ddPacket.setChecksum(OspfUtil.NOT_ASSIGNED);
+
+                    // setting DD Body
+                    boolean isOpaqueEnabled = ospfArea.isOpaqueEnabled();
+                    if (isOpaqueEnabled && this.isOpaqueCapable) {
+                        ddPacket.setOptions(ospfArea.opaqueEnabledOptions());
+                    } else {
+                        ddPacket.setOptions(ospfArea.options());
+                    }
+                    ddPacket.setIsInitialize(OspfUtil.INITIALIZE_SET);
+                    ddPacket.setIsMore(OspfUtil.MORE_SET);
+                    ddPacket.setIsMaster(OspfUtil.IS_MASTER);
+                    ddPacket.setImtu(ospfInterface.mtu());
+                    ddPacket.setSequenceNo(ddSeqNum);
+                    rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
+                    startRxMtDdTimer(ch);
+                    //setting destination ip
+                    ddPacket.setDestinationIp(neighborIpAddr());
+                    setLastSentDdPacket(ddPacket);
+                    ch.write(ddPacket);
+                }
+            } else if (state.getValue() >= OspfNeighborState.EXSTART.getValue()) {
+                if (!formAdjacencyOrNot()) {
+                    state = OspfNeighborState.TWOWAY;
+                    lsReqList.clear();
+                    ddSummaryList.clear();
+                    reTxList.clear();
+                }
+            }
+        }
+    }
+
+    /**
+     * LS Update Packet has been received while state was EXCHANGE or LOADING.
+     * Examine the received LSAs, check whether they were requested or not and process
+     * them accordingly. Therefore use method "processReceivedLsa" for further treatment.
+     *
+     * @param lsUpdPkt LS Update Packet received while Neighbor state was EXCHANGE or
+     *                 LOADING
+     * @param ch       netty channel instance
+     * @throws Exception might throws exception
+     */
+    public void processLsUpdate(LsUpdate lsUpdPkt, Channel ch) throws Exception {
+        stopRxMtLsrTimer();
+        log.debug("OSPFNbr::processLsUpdate...!!!");
+
+        List lsaList = lsUpdPkt.getLsaList();
+        if (!lsaList.isEmpty()) {
+            Iterator itr = lsaList.iterator();
+
+            while (itr.hasNext()) {
+                LsaHeader lsaHeader = (LsaHeader) itr.next();
+                String key = ((OspfAreaImpl) ospfArea).getLsaKey(lsaHeader);
+
+                if (lsReqList.containsKey(key)) {
+                    boolean removeIt;
+                    removeIt = processReceivedLsa(lsaHeader, false, ch,
+                                                  lsUpdPkt.sourceIp());
+                    if (removeIt) {
+                        lsReqList.remove(key);
+                    }
+                } else {
+                    // LSA was received via Flooding
+                    processReceivedLsa(lsaHeader, true, ch,
+                                       lsUpdPkt.sourceIp());
+                }
+            }
+
+            if (lsReqList.isEmpty() && (state == OspfNeighborState.LOADING)) {
+                // loading complete
+                loadingDone();
+            } else {
+                stopRxMtLsrTimer();
+                LsRequest lsRequest = buildLsRequest();
+                lsRequest.setDestinationIp(lsUpdPkt.sourceIp());
+                setLastSentLsrPacket(lsRequest);
+
+                startRxMtLsrTimer(ch);
+            }
+        }
+    }
+
+    /***
+     * Method gets called when no more ls request list and moving to FULL State.
+     *
+     * @throws Exception might throws exception
+     */
+    public void loadingDone() throws Exception {
+        stopRxMtLsrTimer();
+        stopRxMtDdTimer();
+        log.debug("OSPFNbr::loadingDone...!!!");
+        state = OspfNeighborState.FULL;
+        ospfArea.refreshArea(ospfInterface);
+    }
+
+    /**
+     * Adds device and link.
+     *
+     * @param topologyForDeviceAndLink topology for device and link instance
+     */
+    private void callDeviceAndLinkAdding(TopologyForDeviceAndLink topologyForDeviceAndLink) {
+        Map<String, DeviceInformation> deviceInformationMap = topologyForDeviceAndLink.deviceInformationMap();
+        Map<String, LinkInformation> linkInformationMap = topologyForDeviceAndLink.linkInformationMap();
+        OspfRouter ospfRouter = new OspfRouterImpl();
+        log.debug("Device Information in list format along with size {}", deviceInformationMap.size());
+        for (String key : deviceInformationMap.keySet()) {
+            DeviceInformation value = deviceInformationMap.get(key);
+            ospfRouter.setRouterIp(value.routerId());
+            ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
+            ospfRouter.setNeighborRouterId(value.deviceId());
+            OspfDeviceTed ospfDeviceTed = new OspfDeviceTedImpl();
+            List<Ip4Address> ip4Addresses = value.interfaceId();
+            ospfDeviceTed.setIpv4RouterIds(ip4Addresses);
+            ospfRouter.setDeviceTed(ospfDeviceTed);
+            ospfRouter.setOpaque(ospfArea.isOpaqueEnabled());
+            if (value.isDr()) {
+                ospfRouter.setDr(value.isDr());
+            } else {
+                ospfRouter.setDr(false);
+            }
+            int size = value.interfaceId().size();
+            for (int i = 0; i < size; i++) {
+                ospfRouter.setInterfaceId(value.interfaceId().get(i));
+            }
+            if (value.isAlreadyCreated()) {
+                removeDeviceDetails(value.routerId());
+                OspfRouter ospfRouter1 = new OspfRouterImpl();
+                ospfRouter1.setRouterIp(value.routerId());
+                ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
+                ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
+                ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
+                topologyForDeviceAndLink.removeLinks(value.routerId());
+                handler.removeDeviceInformation(ospfRouter1);
+            }
+            handler.addDeviceInformation(ospfRouter);
+        }
+        for (Map.Entry<String, LinkInformation> entry : linkInformationMap.entrySet()) {
+            String key = entry.getKey();
+            LinkInformation value = entry.getValue();
+            OspfRouter ospfRouterForLink = new OspfRouterImpl();
+            ospfRouterForLink.setInterfaceId(value.interfaceIp());
+            ospfRouterForLink.setAreaIdOfInterface(ospfArea.areaId());
+            ospfRouterForLink.setOpaque(ospfArea.isOpaqueEnabled());
+            OspfLinkTed ospfLinkTed =
+                    topologyForDeviceAndLink.getOspfLinkTedHashMap(value.linkDestinationId().toString());
+            if (ospfLinkTed == null) {
+                ospfLinkTed = new OspfLinkTedImpl();
+                ospfLinkTed.setMaximumLink(Bandwidth.bps(0));
+                ospfLinkTed.setMaxReserved(Bandwidth.bps(0));
+                ospfLinkTed.setTeMetric(0);
+            }
+
+            if (!value.isLinkSrcIdNotRouterId()) {
+                ospfRouterForLink.setRouterIp(value.linkSourceId());
+                ospfRouterForLink.setNeighborRouterId(value.linkDestinationId());
+                try {
+                    handler.addLinkInformation(ospfRouterForLink, ospfLinkTed);
+                    log.debug("LinkId, LinkSrc , LinkDest , LinkInterface values are : "
+                                      + value.linkId() + " , " + value.linkSourceId() + "  , "
+                                      + value.linkDestinationId() + " , "
+                                      + value.interfaceIp());
+                } catch (Exception e) {
+                    log.debug("Got Exception : {}", e.getMessage());
+                }
+            }
+        }
+    }
+
+    // RFC 2328 Section 13 - partly as flooding procedure
+
+    /**
+     * Processes the received Lsa.
+     *
+     * @param recLsa              received Lsa
+     * @param receivedViaFlooding received via flooding or not
+     * @param ch                  channel instance
+     * @param sourceIp            source of this Lsa
+     * @return true to remove it from lsReqList else false
+     * @throws Exception might throws exception
+     */
+    public boolean processReceivedLsa(LsaHeader recLsa,
+                                      boolean receivedViaFlooding, Channel ch, Ip4Address sourceIp)
+            throws Exception {
+        log.debug("OSPFNbr::processReceivedLsa(recLsa, recievedViaFlooding, ch)...!!!");
+
+        //Validate the lsa checksum RFC 2328 13 (1)
+        ChecksumCalculator checkSum = new ChecksumCalculator();
+        if (!checkSum.isValidLsaCheckSum(recLsa,
+                                         recLsa.getOspfLsaType().value(),
+                                         OspfUtil.LSAPACKET_CHECKSUM_POS1,
+                                         OspfUtil.LSAPACKET_CHECKSUM_POS2)) {
+            log.debug("Checksum mismatch. Received LSA packet type {} ",
+                      recLsa.lsType());
+
+            return true;
+        }
+
+        //If LSA type is unknown discard the lsa RFC 2328 13(2)
+        if (((recLsa.getOspfLsaType().value() > OspfLsaType.EXTERNAL_LSA.value()) &&
+                (recLsa.getOspfLsaType().value() < OspfLsaType.LINK_LOCAL_OPAQUE_LSA.value())) ||
+                (recLsa.getOspfLsaType().value() > OspfLsaType.AS_OPAQUE_LSA.value())) {
+            return true;
+        }
+
+        //If LSA type is external & the area is configured as stub area discard the lsa RFC 2328 13(3)
+        if ((recLsa.getOspfLsaType() == OspfLsaType.EXTERNAL_LSA) &&
+                (!ospfArea.isExternalRoutingCapability())) // to determine how to store options
+        {
+            return true;
+        }
+
+        //if lsa age is equal to maxage && instance is not in lsdb && none of neighbors are in exchange
+        // or loading state
+        // Acknowledge the receipt by sending LSAck to the sender. 2328 13(4)
+        if ((recLsa.age() == OspfParameters.MAXAGE) &&
+                (ospfArea.lsaLookup(recLsa) == null) &&
+                ospfArea.noNeighborInLsaExchangeProcess()) {
+            // RFC 2328 Section 13. (4)
+            // Because the LSA was not yet requested, it is treated as a flooded LSA and thus
+            // acknowledged.
+            directAcknowledge(recLsa, ch, sourceIp);
+            return true;
+        }
+
+        String key = ((OspfAreaImpl) ospfArea).getLsaKey(recLsa);
+        LsaWrapper lsWrapper = ospfArea.lsaLookup(recLsa);
+        String status = isNullorLatest(lsWrapper, recLsa);
+        //Section 13 (5)
+        if (status.equals("isNullorLatest")) {
+
+            if (recLsa.lsType() == OspfLsaType.ROUTER.value() && recLsa.advertisingRouter().equals(
+                    ospfArea.routerId())) {
+                if (recLsa.lsSequenceNo() > ((LsaWrapperImpl) lsWrapper).lsaHeader().lsSequenceNo()) {
+                    ospfArea.setDbRouterSequenceNumber(recLsa.lsSequenceNo() + 1);
+                    processSelfOriginatedLsa();
+                }
+
+                if (recLsa.age() == OspfParameters.MAXAGE) {
+                    ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
+                    //remove from db & bin, add the lsa to MaxAge bin.
+                    ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
+                            lsWrapper).lsaHeader()), lsWrapper);
+                    ospfArea.removeLsaFromBin(lsWrapper);
+                }
+
+                return true;
+            } else if (recLsa.lsType() == OspfLsaType.NETWORK.value() && isLinkStateMatchesOwnRouterId(
+                    recLsa.linkStateId())) {
+                // if we are not DR or if origination router ID not equal to our router ID //either
+                // DR state changed or our router ID was changed
+                //set LSAge = MaxAge
+                //flood the LSA
+                if (((OspfInterfaceImpl) ospfInterface).state() != OspfInterfaceState.DR ||
+                        !recLsa.advertisingRouter().equals(
+                                ospfArea.routerId())) {
+                    if (lsWrapper != null) {
+                        ((LsaWrapperImpl) lsWrapper).lsaHeader().setAge(OspfParameters.MAXAGE);
+                        //remove from bin, add the lsa to MaxAge bin.
+                        ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
+                                lsWrapper).lsaHeader()), lsWrapper);
+                        ospfArea.removeLsaFromBin(lsWrapper);
+                    } else {
+                        recLsa.setAge(OspfParameters.MAXAGE);
+                        ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
+                    }
+                }
+
+                return true;
+            } else {
+                if (recLsa.age() == OspfParameters.MAXAGE) {
+                    ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
+                    //remove from db & bin, add the lsa to MaxAge bin.
+                    if (lsWrapper != null) {
+                        lsWrapper.setLsaAgeReceived(OspfParameters.MAXAGE);
+                        ospfArea.addLsaToMaxAgeBin(((OspfAreaImpl) ospfArea).getLsaKey(((LsaWrapperImpl)
+                                lsWrapper).lsaHeader()), lsWrapper);
+                        ospfArea.removeLsaFromBin(lsWrapper);
+                    } else {
+                        ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
+                    }
+
+                    return true;
+                } else {
+                    ospfArea.addLsa(recLsa, ospfInterface);
+                    log.debug("Inside addLsaMethod");
+                    topologyForDeviceAndLink.addLocalDevice(recLsa, ospfInterface, ospfArea);
+                    callDeviceAndLinkAdding(topologyForDeviceAndLink);
+                    log.debug("Adding to lsdb interface State {}", ((OspfInterfaceImpl) ospfInterface).state().value());
+                    // should not send any acknowledge if flooded out on receiving interface
+                    if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
+                        if (neighborDr.equals(sourceIp)) {
+                            log.debug("Adding for delayed ack {}", recLsa);
+                            ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
+                        }
+                    } else {
+                        log.debug("Adding for delayed ack {}", recLsa);
+                        ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
+                    }
+
+                    if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.DR.value() ||
+                            ((OspfInterfaceImpl) ospfInterface).state().value() ==
+                                    OspfInterfaceState.POINT2POINT.value()) {
+                        ((OspfAreaImpl) ospfArea).addToOtherNeighborLsaTxList(recLsa);
+                    }
+                }
+
+            }
+        }
+        // RFC 2328 Section 13  (6)
+        if (lsReqList.contains(key)) {
+            badLSReq(ch);
+        }
+        if (status.equals("same")) { //13 (7)
+            if (pendingReTxList.containsKey(key)) {
+                pendingReTxList.remove(key);
+                if (((OspfInterfaceImpl) ospfInterface).state().value() == OspfInterfaceState.BDR.value()) {
+                    if (neighborDr.equals(recLsa.advertisingRouter())) {
+                        ((OspfInterfaceImpl) ospfInterface).addLsaHeaderForDelayAck(recLsa);
+                    }
+                }
+            } else {
+                directAcknowledge(recLsa, ch, sourceIp);
+                return true;
+            }
+        } else if (status.equals("old")) { // section 13 - point 8
+            if ((recLsa.lsSequenceNo() == OspfParameters.MAXSEQUENCENUMBER) &&
+                    (recLsa.age() == OspfParameters.MAXAGE)) {
+                // section 13 - point 8
+                // simple discard the received LSA -
+                return true;
+            } else {
+                // respond back with the same LSA
+                //Using flood LSA to sent the LSUpdate back to advertising router
+                int diff = Math.abs(lsWrapper.lsaAgeReceived() - recLsa.age());
+                if (diff > OspfParameters.MINLSARRIVAL) {
+                    sendLsa(((LsaWrapperImpl) lsWrapper).lsaHeader(), sourceIp, ch);
+                }
+            }
+        }
+        callDeviceAndLinkAdding(topologyForDeviceAndLink);
+        return true;
+    }
+
+    /**
+     * Checks Link State ID is equal to one of the router's own IP interface addresses.
+     *
+     * @param linkStateId link state id
+     * @return true if link state matches or false
+     */
+    private boolean isLinkStateMatchesOwnRouterId(String linkStateId) {
+        boolean isLinkStateMatches = false;
+        List<OspfInterface> interfaceLst = ospfArea.getInterfacesLst();
+        for (OspfInterface ospfInterface : interfaceLst) {
+            if (ospfInterface.ipAddress().toString().equals(linkStateId)) {
+                isLinkStateMatches = true;
+                break;
+            }
+        }
+
+        return isLinkStateMatches;
+    }
+
+    /**
+     * RFC 2328 Section 13 (5).
+     *
+     * @param lsWrapper ls wrapper instance
+     * @param recLsa    received LSA instance
+     * @return returns a string status
+     */
+    public String isNullorLatest(LsaWrapper lsWrapper, LsaHeader recLsa) {
+
+
+        if (lsWrapper != null) {
+            LsaHeader ownLsa = (LsaHeader) lsWrapper.ospfLsa();
+            String status = ospfArea.isNewerOrSameLsa(recLsa, ownLsa);
+
+            if (status.equals("latest")) {
+                return "isNullorLatest";
+            } else {
+                return status;
+            }
+        } else {
+            return "isNullorLatest";
+        }
+    }
+
+    /**
+     * RFC 2328 section 13.4
+     * Processing self-originated LSAs.
+     *
+     * @throws Exception might throws exception
+     */
+    public void processSelfOriginatedLsa() throws Exception {
+        ospfArea.refreshArea(ospfInterface);
+    }
+
+    /**
+     * Sends the LSA to destination address.
+     *
+     * @param lsa         LSA instance to sent
+     * @param destination destination IP address
+     * @param ch          netty channel instance
+     */
+    public void sendLsa(LsaHeader lsa, Ip4Address destination, Channel ch) {
+        if (lsa == null) {
+            return;
+        }
+
+        LsUpdate responseLsUpdate = new LsUpdate();
+        // seting OSPF Header
+        responseLsUpdate.setOspfVer(OspfUtil.OSPF_VERSION);
+        responseLsUpdate.setOspftype(OspfPacketType.LSUPDATE.value());
+        responseLsUpdate.setRouterId(ospfArea.routerId());
+        responseLsUpdate.setAreaId(ospfArea.areaId());
+        responseLsUpdate.setAuthType(OspfUtil.NOT_ASSIGNED);
+        responseLsUpdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
+        responseLsUpdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+        responseLsUpdate.setChecksum(OspfUtil.NOT_ASSIGNED);
+        responseLsUpdate.setNumberOfLsa(1);
+        responseLsUpdate.addLsa(lsa);
+
+        //setting the destination.
+        responseLsUpdate.setDestinationIp(destination);
+        ch.write(responseLsUpdate);
+    }
+
+    /**
+     * Sends a direct Acknowledgment for a particular LSA to the Neighbor.
+     *
+     * @param ackLsa   LSA instance
+     * @param ch       netty channel instance
+     * @param sourceIp source IP address
+     */
+    public void directAcknowledge(LsaHeader ackLsa, Channel ch, Ip4Address sourceIp) {
+        log.debug("OSPFNbr::directAcknowledge...!!!");
+
+        LsAcknowledge ackContent = new LsAcknowledge();
+        // seting OSPF Header
+        ackContent.setOspfVer(OspfUtil.OSPF_VERSION);
+        ackContent.setOspftype(OspfPacketType.LSAACK.value());
+        ackContent.setRouterId(ospfArea.routerId());
+        ackContent.setAreaId(ospfArea.areaId());
+        ackContent.setAuthType(OspfUtil.NOT_ASSIGNED);
+        ackContent.setAuthentication(OspfUtil.NOT_ASSIGNED);
+        ackContent.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+        ackContent.setChecksum(OspfUtil.NOT_ASSIGNED);
+        ackContent.addLinkStateHeader(ackLsa);
+        //setting the destination IP
+        ackContent.setDestinationIp(sourceIp);
+        ch.write(ackContent);
+    }
+
+    /**
+     * Called when neighbor is down.
+     *
+     * @throws Exception might throws exception
+     */
+    public void neighborDown() throws Exception {
+        log.debug("Neighbor Down {} and NeighborId {}", neighborIpAddr,
+                  neighborId);
+        stopInactivityTimeCheck();
+        stopRxMtDdTimer();
+        stopRxMtLsrTimer();
+
+        if (floodingTimerScheduled) {
+            stopFloodingTimer();
+            floodingTimerScheduled = false;
+        }
+
+        state = OspfNeighborState.DOWN;
+        ospfArea.refreshArea(ospfInterface);
+        lsReqList.clear();
+        ddSummaryList.clear();
+        if (neighborIpAddr.equals(neighborBdr) ||
+                neighborIpAddr.equals(neighborDr)) {
+            handler.neighborChange();
+        }
+        log.debug("Neighbor Went Down : "
+                          + this.neighborIpAddr + " , " + this.neighborId);
+        removeDeviceDetails(this.neighborId);
+        OspfRouter ospfRouter = new OspfRouterImpl();
+        ospfRouter.setRouterIp(this.neighborId());
+        ospfRouter.setInterfaceId(ospfInterface.ipAddress());
+        ospfRouter.setAreaIdOfInterface(ospfArea.areaId());
+        ospfRouter.setDeviceTed(new OspfDeviceTedImpl());
+        handler.removeDeviceInformation(ospfRouter);
+        removeDeviceDetails(this.neighborIpAddr);
+        OspfRouter ospfRouter1 = new OspfRouterImpl();
+        ospfRouter1.setRouterIp(this.neighborIpAddr);
+        ospfRouter1.setInterfaceId(ospfInterface.ipAddress());
+        ospfRouter1.setAreaIdOfInterface(ospfArea.areaId());
+        ospfRouter1.setDeviceTed(new OspfDeviceTedImpl());
+        handler.removeDeviceInformation(ospfRouter1);
+        handler.removeLinkInformation(this);
+        callDeviceAndLinkAdding(topologyForDeviceAndLink);
+    }
+
+    /**
+     * Removes device details.
+     *
+     * @param routerId router id
+     */
+    private void removeDeviceDetails(Ip4Address routerId) {
+        String key = "device:" + routerId;
+        topologyForDeviceAndLink.removeDeviceInformationMap(key);
+        topologyForDeviceAndLink.removeLinks(routerId);
+    }
+
+    /**
+     * Starts the inactivity timer.
+     */
+    private void startInactivityTimeCheck() {
+        if (!inActivityTimerScheduled) {
+            log.debug("OSPFNbr::startInactivityTimeCheck");
+            inActivityTimeCheckTask = new InternalInactivityTimeCheck();
+            exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
+            exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, routerDeadInterval,
+                                                    routerDeadInterval, TimeUnit.SECONDS);
+            inActivityTimerScheduled = true;
+        }
+    }
+
+    /**
+     * Stops the inactivity timer.
+     */
+    private void stopInactivityTimeCheck() {
+        if (inActivityTimerScheduled) {
+            log.debug("OSPFNbr::stopInactivityTimeCheck ");
+            exServiceInActivity.shutdown();
+            inActivityTimerScheduled = false;
+        }
+    }
+
+    /**
+     * Starts the flooding timer.
+     *
+     * @param channel channel instance
+     */
+    public void startFloodingTimer(Channel channel) {
+
+        if (!floodingTimerScheduled) {
+            log.debug("OSPFNbr::startFloodingTimer");
+            floodingTask = new InternalFloodingTask(channel);
+            exServiceFlooding = Executors.newSingleThreadScheduledExecutor();
+            //Run every 5 seconds.
+            exServiceFlooding.scheduleAtFixedRate(floodingTask, OspfParameters.START_NOW,
+                                                  OspfParameters.MINLSINTERVAL, TimeUnit.SECONDS);
+            floodingTimerScheduled = true;
+        }
+    }
+
+    /**
+     * Stops the flooding timer.
+     */
+    private void stopFloodingTimer() {
+        if (floodingTimerScheduled) {
+            log.debug("OSPFNbr::stopFloodingTimer ");
+            exServiceFlooding.shutdown();
+            floodingTimerScheduled = false;
+        }
+    }
+
+    /**
+     * Starts the Dd Retransmission executor task.
+     *
+     * @param ch netty channel instance
+     */
+    private void startRxMtDdTimer(Channel ch) {
+        if (!rxmtDdPacketTimerScheduled) {
+            long retransmitInterval = ospfInterface.reTransmitInterval();
+            rxmtDdPacketTask = new InternalRxmtDdPacket(ch);
+            exServiceRxmtDDPacket = Executors.newSingleThreadScheduledExecutor();
+            exServiceRxmtDDPacket.scheduleAtFixedRate(rxmtDdPacketTask, retransmitInterval,
+                                                      retransmitInterval, TimeUnit.SECONDS);
+            rxmtDdPacketTimerScheduled = true;
+        }
+    }
+
+    /**
+     * Stops the Dd Retransmission executor task.
+     */
+    private void stopRxMtDdTimer() {
+        if (rxmtDdPacketTimerScheduled) {
+            exServiceRxmtDDPacket.shutdown();
+            rxmtDdPacketTimerScheduled = false;
+        }
+    }
+
+    /**
+     * Starts Ls request retransmission executor task.
+     *
+     * @param ch Netty channel instance
+     */
+    private void startRxMtLsrTimer(Channel ch) {
+        if (!rxmtLsrTimerScheduled) {
+            log.debug("OSPFNbr::startRxMtLsrTimer...!!!");
+            long retransmitIntrvl = ospfInterface.reTransmitInterval();
+            rxmtLsrPacketTask = new InternalRxmtLsrPacket(ch);
+            exServiceRxmtLsr = Executors.newSingleThreadScheduledExecutor();
+            exServiceRxmtLsr.scheduleAtFixedRate(rxmtLsrPacketTask, retransmitIntrvl,
+                                                 retransmitIntrvl, TimeUnit.SECONDS);
+            rxmtLsrTimerScheduled = true;
+        }
+    }
+
+    /**
+     * Stops Ls request retransmission executor task.
+     */
+    private void stopRxMtLsrTimer() {
+        if (rxmtLsrTimerScheduled) {
+            exServiceRxmtLsr.shutdown();
+            rxmtLsrTimerScheduled = false;
+        }
+    }
+
+    /**
+     * Gets the last sent DdPacket.
+     *
+     * @return DdPacket instance
+     */
+    public DdPacket lastDdPacket() {
+        return lastDdPacket;
+    }
+
+    /**
+     * Sets the last sent DdPacket.
+     *
+     * @param lastDdPacket DdPacket instance
+     */
+    public void setLastDdPacket(DdPacket lastDdPacket) {
+        this.lastDdPacket = lastDdPacket;
+    }
+
+    /**
+     * Gets neighbor id.
+     *
+     * @return neighbor id
+     */
+    public Ip4Address neighborId() {
+        return neighborId;
+    }
+
+    /**
+     * Sets the neighbor id.
+     *
+     * @param neighborId neighbor id
+     */
+    public void setNeighborId(Ip4Address neighborId) {
+        this.neighborId = neighborId;
+    }
+
+    /**
+     * Gets the neighbor DR address.
+     *
+     * @return neighbor DR address
+     */
+    public Ip4Address neighborDr() {
+        return neighborDr;
+    }
+
+    /**
+     * Sets the neighbor DR address.
+     *
+     * @param neighborDr neighbor DR address
+     */
+    public void setNeighborDr(Ip4Address neighborDr) {
+        this.neighborDr = neighborDr;
+    }
+
+    /**
+     * Gets the neighbor BDR address.
+     *
+     * @return neighbor BDR address
+     */
+    public Ip4Address neighborBdr() {
+        return neighborBdr;
+    }
+
+    /**
+     * Sets the neighbor BDR address.
+     *
+     * @param neighborBdr neighbor BDR address
+     */
+    public void setNeighborBdr(Ip4Address neighborBdr) {
+        this.neighborBdr = neighborBdr;
+    }
+
+    /**
+     * Gets router priority.
+     *
+     * @return router priority
+     */
+    public int routerPriority() {
+        return routerPriority;
+    }
+
+    /**
+     * Sets router priority.
+     *
+     * @param routerPriority router priority
+     */
+    public void setRouterPriority(int routerPriority) {
+        this.routerPriority = routerPriority;
+    }
+
+    /**
+     * Gets the options value.
+     *
+     * @return options value
+     */
+    public int options() {
+        return options;
+    }
+
+    /**
+     * Sets the options value.
+     *
+     * @param options options value
+     */
+    public void setOptions(int options) {
+        this.options = options;
+    }
+
+    /**
+     * Gets the DD sequence number.
+     *
+     * @return DD sequence number
+     */
+    public long ddSeqNum() {
+        return ddSeqNum;
+    }
+
+    /**
+     * Sets the DD sequence number.
+     *
+     * @param ddSeqNum DD sequence number
+     */
+    public void setDdSeqNum(long ddSeqNum) {
+        this.ddSeqNum = ddSeqNum;
+    }
+
+    /**
+     * Gets neighbor is master or not.
+     *
+     * @return true if neighbor is master else false
+     */
+    public int isMaster() {
+        return isMaster;
+    }
+
+    /**
+     * Gets the last sent DD Packet.
+     *
+     * @return last sent DD Packet
+     */
+    public DdPacket lastSentDdPacket() {
+        return lastSentDdPacket;
+    }
+
+    /**
+     * Sets the last sent DD Packet.
+     *
+     * @param lastSentDdPacket last sent DD Packet
+     */
+    public void setLastSentDdPacket(DdPacket lastSentDdPacket) {
+        this.lastSentDdPacket = lastSentDdPacket;
+    }
+
+    /**
+     * Gets the last sent Ls Request Packet.
+     *
+     * @return last sent Ls Request Packet
+     */
+    public LsRequest getLastSentLsrPacket() {
+        return lastSentLsrPacket;
+    }
+
+    /**
+     * Sets the last sent Ls Request Packet.
+     *
+     * @param lastSentLsrPacket last sent Ls Request Packet
+     */
+    public void setLastSentLsrPacket(LsRequest lastSentLsrPacket) {
+        this.lastSentLsrPacket = lastSentLsrPacket;
+    }
+
+    /**
+     * Gets the neighbors state.
+     *
+     * @return neighbors state
+     */
+    public OspfNeighborState getState() {
+        return state;
+    }
+
+    /**
+     * Sets the neighbors state.
+     *
+     * @param state neighbors state
+     */
+    public void setState(OspfNeighborState state) {
+        this.state = state;
+    }
+
+    /**
+     * Sets neighbor is master or not.
+     *
+     * @param isMaster neighbor is master or not
+     */
+    public void setIsMaster(int isMaster) {
+        this.isMaster = isMaster;
+    }
+
+    /**
+     * Gets the ls request list.
+     *
+     * @return ls request list
+     */
+    public Hashtable getLsReqList() {
+        return lsReqList;
+    }
+
+    /**
+     * Gets the reTxList instance.
+     *
+     * @return reTxList instance
+     */
+    public Map getReTxList() {
+        return reTxList;
+    }
+
+    /**
+     * Gets the pending re transmit list.
+     *
+     * @return pendingReTxList instance
+     */
+    public Map<String, OspfLsa> getPendingReTxList() {
+        return pendingReTxList;
+    }
+
+
+    /**
+     * Represents a Task which will do an inactivity time check.
+     */
+    private class InternalInactivityTimeCheck implements Runnable {
+        /**
+         * Constructor.
+         */
+        InternalInactivityTimeCheck() {
+        }
+
+        @Override
+        public void run() {
+            try {
+                log.debug("Neighbor Not Heard till the past router dead interval .");
+                neighborDown();
+            } catch (Exception e) {
+                log.debug("Exception at inactivity time check...!!!");
+            }
+        }
+    }
+
+    /**
+     * Task which re transmits DdPacket every configured time interval.
+     */
+    private class InternalRxmtDdPacket implements Runnable {
+        Channel ch;
+
+        /**
+         * Creates an instance or Re transmit DD packet timer.
+         *
+         * @param ch netty channel instance
+         */
+        InternalRxmtDdPacket(Channel ch) {
+            this.ch = ch;
+        }
+
+        @Override
+        public void run() {
+            if ((ch != null) && ch.isConnected()) {
+                DdPacket ddPacket = lastSentDdPacket();
+                ch.write(ddPacket);
+                log.debug("Re-Transmit DD Packet .");
+            } else {
+                log.debug(
+                        "Re-Transmit DD Packet failed. Channel not connected..");
+            }
+        }
+    }
+
+    /**
+     * Task which re transmits Ls request Packet every configured time interval.
+     */
+    private class InternalRxmtLsrPacket implements Runnable {
+        Channel ch;
+
+        /**
+         * Creates an instance or Re transmit LS Request packet timer.
+         *
+         * @param ch netty channel instance
+         */
+        InternalRxmtLsrPacket(Channel ch) {
+            this.ch = ch;
+        }
+
+        @Override
+        public void run() {
+            if ((ch != null) && ch.isConnected()) {
+                LsRequest lsrPacket = getLastSentLsrPacket();
+                ch.write(lsrPacket);
+                log.debug("Re-Transmit LSRequest Packet .");
+            } else {
+                log.debug(
+                        "Re-Transmit LSRequest failed. Channel not connected..");
+            }
+        }
+    }
+
+    /**
+     * Task which transmits Ls update Packet based on the re transmit list.
+     * every configured time interval.
+     */
+    private class InternalFloodingTask implements Runnable {
+        Channel channel;
+
+        /**
+         * Creates an instance or Flooding task.
+         *
+         * @param ch netty channel instance
+         */
+        InternalFloodingTask(Channel ch) {
+            this.channel = ch;
+        }
+
+        @Override
+        public void run() {
+            if ((channel != null) && channel.isConnected()) {
+
+                if ((pendingReTxList != null) && (pendingReTxList.size() > 0)) {
+                    List<LsUpdate> lsUpdateList = buildLsUpdate(pendingReTxList);
+
+                    for (LsUpdate lsupdate : lsUpdateList) {
+                        //Pending for acknowledge directly sent it to neighbor
+                        lsupdate.setDestinationIp(neighborIpAddr);
+                        channel.write(lsupdate);
+                    }
+                }
+
+                if ((reTxList != null) && (reTxList.size() > 0)) {
+                    List<LsUpdate> lsUpdateList = buildLsUpdate(reTxList);
+
+                    for (LsUpdate lsupdate : lsUpdateList) {
+                        //set the destination
+                        if ((((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DR) ||
+                                (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.POINT2POINT)) {
+                            lsupdate.setDestinationIp(OspfUtil.ALL_SPF_ROUTERS);
+                        } else if (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.DROTHER ||
+                                (((OspfInterfaceImpl) ospfInterface).state() == OspfInterfaceState.BDR)) {
+                            lsupdate.setDestinationIp(neighborDr);
+                        }
+                        channel.write(lsupdate);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Builds the LsUpdate for flooding.
+         *
+         * @param txList list contains LSAs
+         * @return list of LsUpdate instances
+         */
+        private List buildLsUpdate(Map<String, OspfLsa> txList) {
+            List<LsUpdate> lsUpdateList = new ArrayList<>();
+            ListIterator itr = new ArrayList(txList.keySet()).listIterator();
+            while (itr.hasNext()) {
+                LsUpdate lsupdate = new LsUpdate();
+                // seting OSPF Header
+                lsupdate.setOspfVer(OspfUtil.OSPF_VERSION);
+                lsupdate.setOspftype(OspfPacketType.LSUPDATE.value());
+                lsupdate.setRouterId(ospfArea.routerId());
+                lsupdate.setAreaId(ospfArea.areaId());
+                lsupdate.setAuthType(OspfUtil.NOT_ASSIGNED);
+                lsupdate.setAuthentication(OspfUtil.NOT_ASSIGNED);
+                lsupdate.setOspfPacLength(OspfUtil.NOT_ASSIGNED); // to calculate packet length
+                lsupdate.setChecksum(OspfUtil.NOT_ASSIGNED);
+
+                //limit to mtu
+                int currentLength = OspfUtil.OSPF_HEADER_LENGTH + OspfUtil.FOUR_BYTES;
+                int maxSize = ospfInterface.mtu() -
+                        OspfUtil.LSA_HEADER_LENGTH; // subtract a normal IP header.
+
+                int noLsa = 0;
+                while (itr.hasNext()) {
+
+                    String key = (String) itr.next();
+                    OspfLsa lsa = txList.get(key);
+                    if ((lsa.age() + OspfParameters.INFTRA_NS_DELAY) >= OspfParameters.MAXAGE) {
+                        ((LsaHeader) lsa.lsaHeader()).setAge(OspfParameters.MAXAGE);
+                    } else {
+                        ((LsaHeader) lsa.lsaHeader()).setAge(lsa.age() + OspfParameters.INFTRA_NS_DELAY);
+                    }
+
+                    if ((currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen()) >= maxSize) {
+                        itr.previous();
+                        break;
+                    }
+                    log.debug("FloodingTimer::LSA Type::{}, Header: {}, LSA: {}", lsa.getOspfLsaType(),
+                              lsa.lsaHeader(), lsa);
+
+                    if (lsa != null) {
+                        lsupdate.addLsa(lsa);
+                        noLsa++;
+                        currentLength = currentLength + ((LsaHeader) lsa.lsaHeader()).lsPacketLen();
+                    }
+                    log.debug("FloodingTimer::Removing key {}", key);
+                    if (txList.equals(reTxList)) {
+                        reTxList.remove(key);
+                        pendingReTxList.put(key, lsa);
+                    }
+                }
+                //set number of lsa's
+                lsupdate.setNumberOfLsa(noLsa);
+                lsUpdateList.add(lsupdate);
+            }
+            return lsUpdateList;
+        }
+    }
+}
\ No newline at end of file
diff --git a/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/OspfLsdbImpl.java b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/OspfLsdbImpl.java
new file mode 100755
index 0000000..2c30155
--- /dev/null
+++ b/protocols/ospf/ctl/src/main/java/org/onosproject/ospf/controller/lsdb/OspfLsdbImpl.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.ospf.controller.lsdb;
+
+import com.google.common.base.Objects;
+import org.onosproject.ospf.controller.LsaBin;
+import org.onosproject.ospf.controller.LsaWrapper;
+import org.onosproject.ospf.controller.LsdbAge;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfLsaType;
+import org.onosproject.ospf.controller.OspfLsdb;
+import org.onosproject.ospf.controller.area.OspfAreaImpl;
+import org.onosproject.ospf.protocol.lsa.LsaHeader;
+import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
+import org.onosproject.ospf.protocol.util.OspfParameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Represents the Link State Database.
+ */
+public class OspfLsdbImpl implements OspfLsdb {
+    private static final Logger log = LoggerFactory.getLogger(OspfLsdbImpl.class);
+    private Map routerLsas = new HashMap();
+    private Map networkLsas = new HashMap();
+    private Map summaryLsas = new HashMap();
+    private Map asbrSummaryLSAs = new HashMap();
+    private Map opaque9Lsas = new HashMap();
+    private Map opaque10Lsas = new HashMap();
+    private Map opaque11Lsas = new HashMap();
+    private Map externalLsas = new HashMap();
+    private long routerLsaSeqNo = OspfParameters.STARTLSSEQUENCENUM;
+    private long networkLsaSeqNo = OspfParameters.STARTLSSEQUENCENUM;
+    private LsdbAge lsdbAge = null;
+    private OspfArea ospfArea = null;
+
+
+    /**
+     * Creates an instance of OSPF LSDB.
+     *
+     * @param ospfArea area instance
+     */
+    public OspfLsdbImpl(OspfArea ospfArea) {
+        this.ospfArea = ospfArea;
+        lsdbAge = new LsdbAgeImpl(ospfArea);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        OspfLsdbImpl that = (OspfLsdbImpl) o;
+        return Objects.equal(routerLsas.size(), that.routerLsas.size()) &&
+                Objects.equal(networkLsas.size(), that.networkLsas.size()) &&
+                Objects.equal(summaryLsas.size(), that.summaryLsas.size()) &&
+                Objects.equal(asbrSummaryLSAs.size(), that.asbrSummaryLSAs.size()) &&
+                Objects.equal(lsdbAge, that.lsdbAge) &&
+                Objects.equal(routerLsaSeqNo, that.routerLsaSeqNo) &&
+                Objects.equal(networkLsaSeqNo, that.networkLsaSeqNo);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(routerLsas, networkLsas, summaryLsas, asbrSummaryLSAs, lsdbAge,
+                                routerLsaSeqNo, networkLsaSeqNo);
+    }
+
+    /**
+     * Initializes the link state database.
+     */
+    public void initializeDb() {
+        lsdbAge.startDbAging();
+    }
+
+    /**
+     * Returns all LSA Headers (Router and Summary) in a Vector.
+     *
+     * @param excludeMaxAgeLsa exclude the max age LSAs
+     * @param isOpaqueCapable  is opaque capable or not
+     * @return List of LSA headers
+     */
+    public List getAllLsaHeaders(boolean excludeMaxAgeLsa, boolean isOpaqueCapable) {
+        List summList = new CopyOnWriteArrayList();
+        addLsaToHeaderList(summList, excludeMaxAgeLsa, routerLsas);
+        addLsaToHeaderList(summList, excludeMaxAgeLsa, networkLsas);
+        addLsaToHeaderList(summList, excludeMaxAgeLsa, summaryLsas);
+        addLsaToHeaderList(summList, excludeMaxAgeLsa, asbrSummaryLSAs);
+        addLsaToHeaderList(summList, excludeMaxAgeLsa, externalLsas);
+        if (isOpaqueCapable) {
+            addLsaToHeaderList(summList, excludeMaxAgeLsa, opaque9Lsas);
+            addLsaToHeaderList(summList, excludeMaxAgeLsa, opaque10Lsas);
+            addLsaToHeaderList(summList, excludeMaxAgeLsa, opaque11Lsas);
+        }
+
+        return summList;
+    }
+
+    /**
+     * Adds the LSAs to summary list.
+     *
+     * @param summList         summary list
+     * @param excludeMaxAgeLsa exclude max age LSA
+     * @param lsaMap           map of LSA
+     */
+    private void addLsaToHeaderList(List summList, boolean excludeMaxAgeLsa, Map lsaMap) {
+        Iterator slotVals = lsaMap.values().iterator();
+        while (slotVals.hasNext()) {
+            LsaWrapper wrapper = (LsaWrapper) slotVals.next();
+            if (excludeMaxAgeLsa) {
+                //if current age of lsa is max age or lsa present in Max Age bin
+                if (wrapper.currentAge() != OspfParameters.MAXAGE &&
+                        lsdbAge.getMaxAgeBin().ospfLsa(((OspfAreaImpl)
+                                ospfArea).getLsaKey(((LsaWrapperImpl) wrapper).lsaHeader())) == null) {
+                    addToList(wrapper, summList);
+                }
+            } else {
+                addToList(wrapper, summList);
+            }
+        }
+    }
+
+    /**
+     * Adds the LSWrapper to summary list.
+     *
+     * @param wrapper  LSA wrapper instance
+     * @param summList LSA summary list
+     */
+    private void addToList(LsaWrapper wrapper, List summList) {
+        LsaHeader header = (LsaHeader) wrapper.ospfLsa();
+        //set the current age
+        header.setAge(wrapper.currentAge());
+        summList.add(header);
+    }
+
+    /**
+     * Gets the LSDB LSA key from Lsa Header.
+     *
+     * @param lsaHeader LSA header instance
+     * @return key
+     */
+    public String getLsaKey(LsaHeader lsaHeader) {
+        String lsaKey = "";
+        switch (lsaHeader.lsType()) {
+            case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
+            case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
+            case OspfParameters.AS_OPAQUE_LSA:
+                OpaqueLsaHeader header = (OpaqueLsaHeader) lsaHeader;
+                lsaKey = lsaHeader.lsType() + "-" + header.opaqueType() + header.opaqueId() + "-" +
+                        lsaHeader.advertisingRouter();
+                break;
+            case OspfParameters.ROUTER:
+            case OspfParameters.NETWORK:
+            case OspfParameters.ASBR_SUMMARY:
+            case OspfParameters.SUMMARY:
+            case OspfParameters.EXTERNAL_LSA:
+                lsaKey = lsaHeader.lsType() + "-" + lsaHeader.linkStateId() + "-" +
+                        lsaHeader.advertisingRouter();
+                break;
+            default:
+                log.debug("Unknown LSA type..!!!");
+                break;
+        }
+
+        return lsaKey;
+    }
+
+    /**
+     * Gets wrapper instance in LSDB.
+     *
+     * @param lsaHeader LSA header instance.
+     * @return LSA Wrapper instance.
+     */
+    public LsaWrapper lsaLookup(LsaHeader lsaHeader) {
+
+        return findLsa(lsaHeader.lsType(), getLsaKey(lsaHeader));
+    }
+
+    /**
+     * Finds the LSA from appropriate maps.
+     *
+     * @param lsType type of LSA
+     * @param lsaKey key
+     * @return LSA wrapper object
+     */
+    public LsaWrapper findLsa(int lsType, String lsaKey) {
+        LsaWrapper lsaWrapper = null;
+
+        switch (lsType) {
+            case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
+                lsaWrapper = (LsaWrapper) opaque9Lsas.get(lsaKey);
+                break;
+            case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
+                lsaWrapper = (LsaWrapper) opaque10Lsas.get(lsaKey);
+                break;
+            case OspfParameters.AS_OPAQUE_LSA:
+                lsaWrapper = (LsaWrapper) opaque11Lsas.get(lsaKey);
+                break;
+            case OspfParameters.ROUTER:
+                lsaWrapper = (LsaWrapper) routerLsas.get(lsaKey);
+                break;
+            case OspfParameters.NETWORK:
+                lsaWrapper = (LsaWrapper) networkLsas.get(lsaKey);
+                break;
+            case OspfParameters.ASBR_SUMMARY:
+                lsaWrapper = (LsaWrapper) asbrSummaryLSAs.get(lsaKey);
+                break;
+            case OspfParameters.SUMMARY:
+                lsaWrapper = (LsaWrapper) summaryLsas.get(lsaKey);
+                break;
+            case OspfParameters.EXTERNAL_LSA:
+                lsaWrapper = (LsaWrapper) externalLsas.get(lsaKey);
+                break;
+            default:
+                log.debug("Unknown LSA type..!!!");
+                break;
+        }
+
+        //set the current age
+        if (lsaWrapper != null) {
+            //set the current age
+            ((LsaWrapperImpl) lsaWrapper).lsaHeader().setAge(lsaWrapper.currentAge());
+            ((LsaHeader) lsaWrapper.ospfLsa()).setAge(lsaWrapper.currentAge());
+        }
+
+        return lsaWrapper;
+    }
+
+
+    /**
+     * Installs a new self-originated LSA if possible.
+     * Return true if installing was successful else false.
+     *
+     * @param newLsa           LSA header instance
+     * @param isSelfOriginated is self originated or not
+     * @param ospfInterface    OSPF interface instance
+     * @return true if successfully added
+     */
+    public boolean addLsa(LsaHeader newLsa, boolean isSelfOriginated, OspfInterface ospfInterface) {
+
+        LsaWrapperImpl lsaWrapper = new LsaWrapperImpl();
+        lsaWrapper.setLsaType(newLsa.getOspfLsaType());
+        lsaWrapper.setOspfLsa(newLsa);
+        lsaWrapper.setLsaHeader(newLsa);
+        lsaWrapper.setLsaAgeReceived(newLsa.age());
+        lsaWrapper.setAgeCounterWhenReceived(lsdbAge.getAgeCounter());
+        lsaWrapper.setIsSelfOriginated(isSelfOriginated);
+        lsaWrapper.setIsSelfOriginated(isSelfOriginated);
+        lsaWrapper.setOspfInterface(ospfInterface);
+        lsaWrapper.setLsdbAge(lsdbAge);
+        addLsa(lsaWrapper);
+
+        log.debug("Added LSA In LSDB: {}", newLsa);
+
+        return true;
+    }
+
+    /**
+     * Installs a new self-originated LSA if possible.
+     * Return true if installing was successful else false.
+     * Adding LSA In cases
+     * 1) New Self Originated LSA based on change in topology
+     * 2) New Self Originated LSA because of LSRefresh
+     * 2) New LSA received via Link State Update Packet
+     *
+     * @param newLsa LSA wrapper instance
+     * @return true if added successfully
+     */
+    private boolean addLsa(LsaWrapper newLsa) {
+        // adding an LSA - verify if it's old or new
+        // verify min failed
+        // to verify if it's a new LSA or updating the old LSA .
+        // fetch the LSA Type
+        // verify if the LSA age is ! Max Age
+        // a) it is  received during the flooding process (Section 13)
+        // b) it is originated by the router itself (Section 12.4)
+        // start aging .
+        String key = getLsaKey(((LsaWrapperImpl) newLsa).lsaHeader());
+        //Remove the lsa from bin if exist. we will be adding it in new bin based on the current age.
+        removeLsaFromBin(lsaLookup(((LsaWrapperImpl) newLsa).lsaHeader()));
+
+        switch (((LsaWrapperImpl) newLsa).lsaHeader().lsType()) {
+
+            case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
+                opaque9Lsas.put(key, newLsa);
+                break;
+            case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
+                opaque10Lsas.put(key, newLsa);
+                break;
+            case OspfParameters.AS_OPAQUE_LSA:
+                opaque11Lsas.put(key, newLsa);
+                break;
+            case OspfParameters.ROUTER:
+                routerLsas.put(key, newLsa);
+                break;
+            case OspfParameters.NETWORK:
+                networkLsas.put(key, newLsa);
+                break;
+            case OspfParameters.ASBR_SUMMARY:
+                asbrSummaryLSAs.put(key, newLsa);
+                break;
+            case OspfParameters.SUMMARY:
+                summaryLsas.put(key, newLsa);
+                break;
+            case OspfParameters.EXTERNAL_LSA:
+                externalLsas.put(key, newLsa);
+                break;
+            default:
+                log.debug("Unknown LSA type to add..!!!");
+                break;
+        }
+        //add it to bin
+        Integer binNumber = lsdbAge.age2Bin(((LsaWrapperImpl) newLsa).lsaHeader().age());
+        LsaBin lsaBin = lsdbAge.getLsaBin(binNumber);
+        if (lsaBin != null) {
+            //remove from existing
+            newLsa.setBinNumber(binNumber);
+            lsaBin.addOspfLsa(key, newLsa);
+            lsdbAge.addLsaBin(binNumber, lsaBin);
+            log.debug("Added Type {} LSA to LSDB and LSABin[{}], Age of LSA {}", newLsa.lsaType(),
+                      binNumber, ((LsaWrapperImpl) newLsa).lsaHeader().age());
+        }
+
+        return false;
+    }
+
+    /**
+     * Adds the LSA to maxAge bin.
+     *
+     * @param key     key
+     * @param wrapper LSA wrapper instance
+     */
+    public void addLsaToMaxAgeBin(String key, Object wrapper) {
+        lsdbAge.addLsaToMaxAgeBin(key, (LsaWrapper) wrapper);
+    }
+
+    /**
+     * Removes LSA from Bin.
+     *
+     * @param lsaWrapper LSA wrapper instance
+     */
+    public void removeLsaFromBin(Object lsaWrapper) {
+        if (lsaWrapper != null) {
+            lsdbAge.removeLsaFromBin((LsaWrapper) lsaWrapper);
+        }
+    }
+
+    /**
+     * RFC 2328 - Section 13.1.  Determining which LSA is newer.
+     *
+     * @param lsa1 LSA instance
+     * @param lsa2 LSA instance
+     * @return string status
+     */
+    public String isNewerOrSameLsa(LsaHeader lsa1, LsaHeader lsa2) {
+        if (lsa1.lsSequenceNo() > lsa2.lsSequenceNo()) {
+            return "latest";
+        } else if (lsa1.lsSequenceNo() < lsa2.lsSequenceNo()) {
+            return "old";
+        } else if (lsa1.lsSequenceNo() == lsa2.lsSequenceNo()) {
+            if (lsa1.lsCheckSum() > lsa2.lsCheckSum()) {
+                return "latest";
+            } else if (lsa1.lsCheckSum() < lsa2.lsCheckSum()) {
+                return "old";
+            } else if (lsa1.lsCheckSum() == lsa2.lsCheckSum()) {
+                if (lsa1.age() == lsa2.age()) {
+                    return "same";
+                } else if (lsa1.age() == OspfParameters.MAXAGE) {
+                    return "latest";
+                } else if (lsa2.age() == OspfParameters.MAXAGE) {
+                    return "old";
+                } else if (OspfParameters.MAXAGEDIFF == (lsa1.age() - lsa2.age())) {
+                    if (lsa1.age() < lsa2.age()) {
+                        return "latest";
+                    } else {
+                        return "old";
+                    }
+                } else {
+                    return "same";
+                }
+            }
+        }
+
+        return "";
+    }
+
+    /**
+     * Gets the sequence number.
+     *
+     * @param lsaType type of LSA
+     * @return sequence number
+     */
+    public long getLsSequenceNumber(OspfLsaType lsaType) {
+        switch (lsaType) {
+            case ROUTER:
+                return routerLsaSeqNo++;
+            case NETWORK:
+                return networkLsaSeqNo++;
+            default:
+                return OspfParameters.STARTLSSEQUENCENUM;
+        }
+    }
+
+    /**
+     * Deletes the given LSA.
+     *
+     * @param lsaHeader LSA header instance
+     */
+    public void deleteLsa(LsaHeader lsaHeader) {
+
+        String lsaKey = getLsaKey(lsaHeader);
+        switch (lsaHeader.lsType()) {
+            case OspfParameters.LINK_LOCAL_OPAQUE_LSA:
+                opaque9Lsas.remove(lsaKey);
+                break;
+            case OspfParameters.AREA_LOCAL_OPAQUE_LSA:
+                opaque10Lsas.remove(lsaKey);
+                break;
+            case OspfParameters.AS_OPAQUE_LSA:
+                opaque11Lsas.remove(lsaKey);
+                break;
+            case OspfParameters.ROUTER:
+                routerLsas.remove(lsaKey);
+                break;
+            case OspfParameters.NETWORK:
+                networkLsas.remove(lsaKey);
+                break;
+            case OspfParameters.ASBR_SUMMARY:
+                asbrSummaryLSAs.remove(lsaKey);
+                break;
+            case OspfParameters.SUMMARY:
+                summaryLsas.remove(lsaKey);
+                break;
+            case OspfParameters.EXTERNAL_LSA:
+                externalLsas.remove(lsaKey);
+                break;
+            default:
+                log.debug("Unknown LSA type to delete..!!!");
+                break;
+        }
+    }
+
+    /**
+     * Sets sequence number.
+     *
+     * @param routerLsaSeqNo sequence number
+     */
+    public void setRouterLsaSeqNo(long routerLsaSeqNo) {
+        this.routerLsaSeqNo = routerLsaSeqNo;
+    }
+
+    /**
+     * Sets sequence number.
+     *
+     * @param networkLsaSeqNo sequence number
+     */
+    public void setNetworkLsaSeqNo(long networkLsaSeqNo) {
+        this.networkLsaSeqNo = networkLsaSeqNo;
+    }
+}
\ No newline at end of file
