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
