diff --git a/protocols/ospf/ctl/src/test/java/org/onosproject/ospf/controller/area/OspfAreaImplTest.java b/protocols/ospf/ctl/src/test/java/org/onosproject/ospf/controller/area/OspfAreaImplTest.java
new file mode 100755
index 0000000..f7b40fa
--- /dev/null
+++ b/protocols/ospf/ctl/src/test/java/org/onosproject/ospf/controller/area/OspfAreaImplTest.java
@@ -0,0 +1,722 @@
+/*
+ * 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 org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.ospf.controller.OspfArea;
+import org.onosproject.ospf.controller.OspfAreaAddressRange;
+import org.onosproject.ospf.controller.OspfInterface;
+import org.onosproject.ospf.controller.OspfNbr;
+import org.onosproject.ospf.controller.OspfNeighborState;
+import org.onosproject.ospf.controller.TopologyForDeviceAndLink;
+import org.onosproject.ospf.controller.impl.Controller;
+import org.onosproject.ospf.controller.impl.OspfInterfaceChannelHandler;
+import org.onosproject.ospf.controller.impl.OspfNbrImpl;
+import org.onosproject.ospf.controller.impl.TopologyForDeviceAndLinkImpl;
+import org.onosproject.ospf.controller.lsdb.LsaWrapperImpl;
+import org.onosproject.ospf.protocol.lsa.LsaHeader;
+import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
+import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
+import org.onosproject.ospf.protocol.util.OspfInterfaceState;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+
+/**
+ * Unit test class for OspfAreaImpl.
+ */
+public class OspfAreaImplTest {
+
+    private OspfAreaImpl ospfArea;
+    private int result;
+    private OspfInterfaceImpl ospfInterface;
+    private HashMap<String, OspfNbr> ospfNbrList;
+    private List<OspfInterface> ospfInterfaces;
+    private OspfInterfaceImpl ospfInterface1;
+    private OspfInterfaceImpl ospfInterface2;
+    private OspfInterfaceImpl ospfInterface3;
+    private OspfInterfaceImpl ospfInterface4;
+    private OspfInterfaceImpl ospfInterface5;
+    private OspfInterfaceImpl ospfInterface6;
+    private NetworkLsa networkLsa;
+    private OspfNbrImpl ospfNbr;
+    private RouterLsa routerLsa;
+    private List<OspfAreaAddressRange> ospfAreaAddressRanges;
+    private LsaHeader lsaHeader;
+    private TopologyForDeviceAndLink topologyForDeviceAndLink;
+
+    @Before
+    public void setUp() throws Exception {
+        ospfArea = new OspfAreaImpl();
+        topologyForDeviceAndLink = new TopologyForDeviceAndLinkImpl();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        ospfArea = null;
+        ospfInterface = null;
+        ospfNbrList = null;
+        ospfInterfaces = null;
+        ospfAreaAddressRanges = null;
+        lsaHeader = null;
+        routerLsa = null;
+        ospfNbr = null;
+        networkLsa = null;
+        ospfInterface1 = null;
+        ospfInterface2 = null;
+        ospfInterface3 = null;
+        ospfInterface4 = null;
+        ospfInterface5 = null;
+        ospfInterface6 = null;
+
+    }
+
+    /**
+     * Tests equals() method.
+     */
+    @Test
+    public void testEquals() throws Exception {
+        ospfArea = new OspfAreaImpl();
+        ospfInterface = new OspfInterfaceImpl();
+        ospfArea.setTransitCapability(true);
+        ospfArea.setExternalRoutingCapability(true);
+        ospfArea.setStubCost(100);
+        ospfArea.initializeDb();
+        ospfArea.setAddressRanges(ospfAreaAddressRanges);
+        assertThat(ospfArea.equals(ospfArea), is(true));
+        ospfArea = EasyMock.createMock(OspfAreaImpl.class);
+        assertThat(ospfArea.equals(ospfArea), is(true));
+        OspfArea ospfArea = new OspfAreaImpl();
+        assertThat(ospfArea.equals(ospfArea), is(true));
+    }
+
+    /**
+     * Tests hashCode() method.
+     */
+    @Test
+    public void testHashCode() throws Exception {
+        result = ospfArea.hashCode();
+        assertThat(result, is(notNullValue()));
+    }
+
+    /**
+     * Tests routerId() getter method.
+     */
+    @Test
+    public void testGetRouterId() throws Exception {
+        ospfArea.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        assertThat(ospfArea.routerId(), is(Ip4Address.valueOf("1.1.1.1")));
+    }
+
+    /**
+     * Tests routerId() setter method.
+     */
+    @Test
+    public void testSetRouterId() throws Exception {
+        ospfArea.setRouterId(Ip4Address.valueOf("1.1.1.1"));
+        assertThat(ospfArea.routerId(), is(Ip4Address.valueOf("1.1.1.1")));
+    }
+
+    /**
+     * Tests isOpaqueEnabled() getter method.
+     */
+    @Test
+    public void testSetisOpaqueEnabled() throws Exception {
+        ospfArea.setIsOpaqueEnabled(true);
+        assertThat(ospfArea.isOpaqueEnabled(), is(true));
+    }
+
+    /**
+     * Tests isOpaqueEnabled() setter method.
+     */
+    @Test
+    public void testIsOpaqueEnabled() throws Exception {
+        ospfArea.setIsOpaqueEnabled(true);
+        assertThat(ospfArea.isOpaqueEnabled(), is(true));
+    }
+
+    /**
+     * Tests initializeDb() method.
+     */
+    @Test
+    public void testInitializeDb() throws Exception {
+        ospfArea.initializeDb();
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests refreshArea() method.
+     */
+    @Test
+    public void testRefreshArea() throws Exception {
+
+        ospfInterface = new OspfInterfaceImpl();
+        ospfInterface.setState(OspfInterfaceState.DR);
+        ospfNbrList = new HashMap();
+        ospfNbrList.put("1.1.1.1", new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                                   Ip4Address.valueOf("1.1.1.1"),
+                                                   Ip4Address.valueOf("2.2.2.2"), 2,
+                                                   new OspfInterfaceChannelHandler(new Controller(),
+                                                                                   new OspfAreaImpl(),
+                                                                                   new OspfInterfaceImpl()),
+                                                   topologyForDeviceAndLink));
+        ospfNbrList.put("2.2.2.2", new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                                   Ip4Address.valueOf("1.1.1.1"),
+                                                   Ip4Address.valueOf("2.2.2.2"), 2,
+                                                   new OspfInterfaceChannelHandler(new Controller(),
+                                                                                   new OspfAreaImpl(),
+                                                                                   new OspfInterfaceImpl())
+                , topologyForDeviceAndLink));
+        ospfNbrList.put("3.3.3.3", new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                                   Ip4Address.valueOf("1.1.1.1"),
+                                                   Ip4Address.valueOf("2.2.2.2"), 2,
+                                                   new OspfInterfaceChannelHandler(new Controller(),
+                                                                                   new OspfAreaImpl(),
+                                                                                   new OspfInterfaceImpl())
+                , topologyForDeviceAndLink));
+        ospfNbrList.put("4.4.4.4", new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                                   Ip4Address.valueOf("1.1.1.1"),
+                                                   Ip4Address.valueOf("2.2.2.2"), 2,
+                                                   new OspfInterfaceChannelHandler(new Controller(),
+                                                                                   new OspfAreaImpl(),
+                                                                                   new OspfInterfaceImpl())
+                , topologyForDeviceAndLink));
+
+        ospfInterface.setListOfNeighbors(ospfNbrList);
+        ospfInterface.setIpAddress(Ip4Address.valueOf("10.10.10.10"));
+        ospfInterface.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfInterfaces.add(ospfInterface1);
+        ospfInterface2 = new OspfInterfaceImpl();
+        ospfInterface2.setIpAddress(Ip4Address.valueOf("2.2.2.2"));
+        ospfInterfaces.add(ospfInterface2);
+        ospfInterface3 = new OspfInterfaceImpl();
+        ospfInterface3.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterfaces.add(ospfInterface3);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        ospfArea.setRouterId(Ip4Address.valueOf("111.111.111.111"));
+        networkLsa = ospfArea.buildNetworkLsa(Ip4Address.valueOf("1.1.1.1"),
+                                              Ip4Address.valueOf("255.255.255.255"));
+        ospfArea.refreshArea(ospfInterface);
+        assertThat(ospfNbrList.size(), is(4));
+        assertThat(networkLsa, is(notNullValue()));
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests buildNetworkLsa() method.
+     */
+    @Test
+    public void testBuildNetworkLsa() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfInterfaces.add(ospfInterface1);
+        ospfInterface2 = new OspfInterfaceImpl();
+        ospfInterface2.setIpAddress(Ip4Address.valueOf("2.2.2.2"));
+        ospfInterfaces.add(ospfInterface2);
+        ospfInterface3 = new OspfInterfaceImpl();
+        ospfInterface3.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterfaces.add(ospfInterface3);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        ospfArea.setRouterId(Ip4Address.valueOf("111.111.111.111"));
+        networkLsa = ospfArea.buildNetworkLsa(Ip4Address.valueOf("1.1.1.1"),
+                                              Ip4Address.valueOf("255.255.255.255"));
+        assertThat(ospfInterfaces.size(), is(3));
+        assertThat(networkLsa, is(notNullValue()));
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests buildNetworkLsa() method.
+     */
+    @Test
+    public void testBuildNetworkLsa1() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfInterface1.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface1.setState(OspfInterfaceState.POINT2POINT);
+        ospfNbr = new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                  Ip4Address.valueOf("1.1.1.1"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(),
+                                                                  new OspfAreaImpl(),
+                                                                  new OspfInterfaceImpl())
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfInterface1.addNeighbouringRouter(ospfNbr);
+        ospfInterfaces.add(ospfInterface1);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        ospfArea.setRouterId(Ip4Address.valueOf("111.111.111.111"));
+        networkLsa = ospfArea.buildNetworkLsa(Ip4Address.valueOf("1.1.1.1"),
+                                              Ip4Address.valueOf("255.255.255.255"));
+        assertThat(ospfInterfaces.size(), is(1));
+        assertThat(networkLsa, is(notNullValue()));
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests buildRouterLsa() method.
+     */
+    @Test
+    public void testBuildRouterLsa() throws Exception {
+        ospfNbrList = new HashMap();
+        ospfNbr = new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                  Ip4Address.valueOf("1.1.1.1"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(),
+                                                                  new OspfAreaImpl(),
+                                                                  new OspfInterfaceImpl())
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfInterface1.setState(OspfInterfaceState.DOWN);
+        ospfInterface1.addNeighbouringRouter(ospfNbr);
+        ospfInterfaces.add(ospfInterface1);
+        ospfInterface2 = new OspfInterfaceImpl();
+        ospfInterface2.setState(OspfInterfaceState.LOOPBACK);
+        ospfInterface2.setIpAddress(Ip4Address.valueOf("2.2.2.2"));
+        ospfInterface2.addNeighbouringRouter(ospfNbr);
+        ospfInterfaces.add(ospfInterface2);
+        ospfInterface3 = new OspfInterfaceImpl();
+        ospfInterface3.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterface3.setState(OspfInterfaceState.POINT2POINT);
+        ospfInterface3.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface3.addNeighbouringRouter(ospfNbr);
+        ospfInterface3.setListOfNeighbors(ospfNbrList);
+        ospfInterfaces.add(ospfInterface3);
+        ospfInterface4 = new OspfInterfaceImpl();
+        ospfInterface4.setState(OspfInterfaceState.WAITING);
+        ospfInterface4.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterface4.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterfaces.add(ospfInterface4);
+        ospfInterface5 = new OspfInterfaceImpl();
+        ospfInterface5.setState(OspfInterfaceState.DR);
+        ospfInterface5.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterfaces.add(ospfInterface5);
+        ospfInterface6 = new OspfInterfaceImpl();
+        ospfInterface6.setState(OspfInterfaceState.BDR);
+        ospfInterface6.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterface6.setDr(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterfaces.add(ospfInterface6);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        ospfArea.setRouterId(Ip4Address.valueOf("111.111.111.111"));
+        assertThat(ospfInterfaces.size(), is(6));
+        routerLsa = ospfArea.buildRouterLsa(ospfInterface1);
+        assertThat(routerLsa, is(notNullValue()));
+        routerLsa = ospfArea.buildRouterLsa(ospfInterface2);
+        assertThat(routerLsa, is(notNullValue()));
+        routerLsa = ospfArea.buildRouterLsa(ospfInterface3);
+        assertThat(routerLsa, is(notNullValue()));
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests buildRouterLsa() method.
+     */
+    @Test
+    public void testBuildRouterLsa1() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfInterface1.setIpNetworkMask(Ip4Address.valueOf("255.255.255.255"));
+        ospfInterface1.setState(OspfInterfaceState.POINT2POINT);
+        ospfNbr = new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                  Ip4Address.valueOf("1.1.1.1"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(),
+                                                                  new OspfAreaImpl(),
+                                                                  new OspfInterfaceImpl())
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfInterface1.addNeighbouringRouter(ospfNbr);
+        ospfInterfaces.add(ospfInterface1);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        ospfArea.setRouterId(Ip4Address.valueOf("111.111.111.111"));
+        routerLsa = ospfArea.buildRouterLsa(ospfInterface1);
+        assertThat(routerLsa, is(notNullValue()));
+    }
+
+    /**
+     * Tests areaId() getter method.
+     */
+    @Test
+    public void testGetAreaId() throws Exception {
+        ospfArea.setAreaId(Ip4Address.valueOf("1.1.1.1"));
+        assertThat(ospfArea.areaId(), is(Ip4Address.valueOf("1.1.1.1")));
+    }
+
+    /**
+     * Tests areaId() setter method.
+     */
+    @Test
+    public void testSetAreaId() throws Exception {
+        ospfArea.setAreaId(Ip4Address.valueOf("1.1.1.1"));
+        assertThat(ospfArea.areaId(), is(Ip4Address.valueOf("1.1.1.1")));
+    }
+
+    /**
+     * Tests addressRanges() getter method.
+     */
+    @Test
+    public void testGetAddressRanges() throws Exception {
+        ospfAreaAddressRanges = new ArrayList();
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfArea.setAddressRanges(ospfAreaAddressRanges);
+        assertThat(ospfArea.addressRanges().size(), is(4));
+    }
+
+    /**
+     * Tests addressRanges() setter method.
+     */
+    @Test
+    public void testSetAddressRanges() throws Exception {
+        ospfAreaAddressRanges = new ArrayList();
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfAreaAddressRanges.add(new OspfAreaAddressRangeImpl());
+        ospfArea.setAddressRanges(ospfAreaAddressRanges);
+        assertThat(ospfArea.addressRanges().size(), is(4));
+    }
+
+    /**
+     * Tests isTransitCapability() getter method.
+     */
+    @Test
+    public void testIsTransitCapability() throws Exception {
+        ospfArea.setTransitCapability(true);
+        assertThat(ospfArea.isTransitCapability(), is(true));
+    }
+
+    /**
+     * Tests isTransitCapability() setter method.
+     */
+    @Test
+    public void testSetTransitCapability() throws Exception {
+        ospfArea.setTransitCapability(true);
+        assertThat(ospfArea.isTransitCapability(), is(true));
+    }
+
+    /**
+     * Tests isExternalRoutingCapability() getter method.
+     */
+    @Test
+    public void testIsExternalRoutingCapability() throws Exception {
+        ospfArea.setExternalRoutingCapability(true);
+        assertThat(ospfArea.isExternalRoutingCapability(), is(true));
+    }
+
+    /**
+     * Tests isExternalRoutingCapability() setter method.
+     */
+    @Test
+    public void testSetExternalRoutingCapability() throws Exception {
+        ospfArea.setExternalRoutingCapability(true);
+        assertThat(ospfArea.isExternalRoutingCapability(), is(true));
+    }
+
+    /**
+     * Tests stubCost() getter method.
+     */
+    @Test
+    public void testGetStubCost() throws Exception {
+        ospfArea.setStubCost(100);
+        assertThat(ospfArea.stubCost(), is(100));
+    }
+
+    /**
+     * Tests stubCost() setter method.
+     */
+    @Test
+    public void testSetStubCost() throws Exception {
+        ospfArea.setStubCost(100);
+        assertThat(ospfArea.stubCost(), is(100));
+    }
+
+    /**
+     * Tests getInterfacesLst() getter method.
+     */
+    @Test
+    public void testGetInterfacesLst() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfInterfaces.add(ospfInterface1);
+        ospfInterface2 = new OspfInterfaceImpl();
+        ospfInterface2.setIpAddress(Ip4Address.valueOf("2.2.2.2"));
+        ospfInterfaces.add(ospfInterface2);
+        ospfInterface3 = new OspfInterfaceImpl();
+        ospfInterface3.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterfaces.add(ospfInterface3);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        assertThat(ospfInterfaces.size(), is(3));
+        assertThat(ospfArea.getInterfacesLst(), is(notNullValue()));
+    }
+
+    /**
+     * Tests setInterfacesLst() setter method.
+     */
+    @Test
+    public void testSetInterfacesLst() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfInterfaces.add(ospfInterface1);
+        ospfInterface2 = new OspfInterfaceImpl();
+        ospfInterface2.setIpAddress(Ip4Address.valueOf("2.2.2.2"));
+        ospfInterfaces.add(ospfInterface2);
+        ospfInterface3 = new OspfInterfaceImpl();
+        ospfInterface3.setIpAddress(Ip4Address.valueOf("3.3.3.3"));
+        ospfInterfaces.add(ospfInterface3);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        assertThat(ospfInterfaces.size(), is(3));
+        assertThat(ospfArea.getInterfacesLst(), is(notNullValue()));
+    }
+
+    /**
+     * Tests noNeighborInLsaExchangeProcess() method.
+     */
+    @Test
+    public void testNoNeighborInLsaExchangeProcess() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfNbr = new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                  Ip4Address.valueOf("1.1.1.1"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(),
+                                                                  new OspfAreaImpl(),
+                                                                  new OspfInterfaceImpl())
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.EXCHANGE.EXCHANGE);
+        ospfInterface1.addNeighbouringRouter(ospfNbr);
+        ospfInterfaces.add(ospfInterface1);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        assertThat(ospfArea.noNeighborInLsaExchangeProcess(), is(false));
+    }
+
+    /**
+     * Tests getLsaHeaders() method.
+     */
+    @Test
+    public void testGetLsaHeaders() throws Exception {
+        assertThat(ospfArea.getLsaHeaders(true, true).size(), is(0));
+    }
+
+    /**
+     * Tests getLsa() method.
+     */
+    @Test
+    public void testGetLsa() throws Exception {
+        assertThat(ospfArea.getLsa(1, "1.1.1.1", "1.1.1.1"), is(nullValue()));
+        assertThat(ospfArea.getLsa(10, "1.1.1.1", "1.1.1.1"), is(nullValue()));
+    }
+
+    /**
+     * Tests lsaLookup() method.
+     */
+    @Test
+    public void testLsaLookup() throws Exception {
+        assertThat(ospfArea.lsaLookup(new RouterLsa()), is(nullValue()));
+    }
+
+    /**
+     * Tests isNewerOrSameLsa() method.
+     */
+    @Test
+    public void testIsNewerOrSameLsa() throws Exception {
+        assertThat(ospfArea.isNewerOrSameLsa(new RouterLsa(), new RouterLsa()), is("same"));
+    }
+
+    /**
+     * Tests addLsa() method.
+     */
+    @Test
+    public void testAddLsa() throws Exception {
+        ospfArea.addLsa(new RouterLsa(), new OspfInterfaceImpl());
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests addLsa() method.
+     */
+    @Test
+    public void testAddLsa1() throws Exception {
+        ospfArea.addLsa(new RouterLsa(), false, new OspfInterfaceImpl());
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests addLsaToMaxAgeBin() method.
+     */
+    @Test
+    public void testAddLsaToMaxAgeBin() throws Exception {
+        ospfArea.addLsaToMaxAgeBin("111", new LsaWrapperImpl());
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests setDbRouterSequenceNumber() method.
+     */
+    @Test
+    public void testSetDbRouterSequenceNumber() throws Exception {
+        ospfArea.setDbRouterSequenceNumber(123456);
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests deleteLsa() method.
+     */
+    @Test
+    public void testDeleteLsa() throws Exception {
+        ospfArea.deleteLsa(new LsaHeader());
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests removeLsaFromBin() method.
+     */
+    @Test
+    public void testRemoveLsaFromBin() throws Exception {
+        ospfArea.removeLsaFromBin(new LsaWrapperImpl());
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests to string method.
+     */
+    @Test
+    public void testToString() throws Exception {
+        assertThat(ospfArea.toString(), is(notNullValue()));
+    }
+
+    /**
+     * Tests getNeighborsInFullState() method.
+     */
+    @Test
+    public void testGetNeighborsinFullState() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfNbr = new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                  Ip4Address.valueOf("1.1.1.1"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(),
+                                                                  new OspfAreaImpl(),
+                                                                  new OspfInterfaceImpl())
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfInterface1.addNeighbouringRouter(ospfNbr);
+        ospfInterfaces.add(ospfInterface1);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        assertThat(ospfArea.getNeighborsInFullState(ospfInterface1).size(), is(1));
+    }
+
+    /**
+     * Tests getLsaKey() method.
+     */
+    @Test
+    public void testGetLsaKey() throws Exception {
+        lsaHeader = new LsaHeader();
+        lsaHeader.setAdvertisingRouter(Ip4Address.valueOf("1.1.1.1"));
+        assertThat(ospfArea.getLsaKey(lsaHeader), is(notNullValue()));
+    }
+
+    /**
+     * Tests addToOtherNeighborLsaTxList() method.
+     */
+    @Test
+    public void testAddToOtherNeighborLsaTxList() throws Exception {
+        ospfInterfaces = new ArrayList();
+        ospfInterface1 = new OspfInterfaceImpl();
+        ospfInterface1.setIpAddress(Ip4Address.valueOf("1.1.1.1"));
+        ospfNbr = new OspfNbrImpl(new OspfAreaImpl(), new OspfInterfaceImpl(),
+                                  Ip4Address.valueOf("1.1.1.1"),
+                                  Ip4Address.valueOf("2.2.2.2"), 2,
+                                  new OspfInterfaceChannelHandler(new Controller(),
+                                                                  new OspfAreaImpl(),
+                                                                  new OspfInterfaceImpl())
+                , topologyForDeviceAndLink);
+        ospfNbr.setState(OspfNeighborState.FULL);
+        ospfInterface1.addNeighbouringRouter(ospfNbr);
+        ospfInterfaces.add(ospfInterface1);
+        ospfArea.setInterfacesLst(ospfInterfaces);
+        lsaHeader = new LsaHeader();
+        lsaHeader.setAdvertisingRouter(Ip4Address.valueOf("1.1.1.1"));
+        ospfArea.addToOtherNeighborLsaTxList(lsaHeader);
+        assertThat(ospfArea, is(notNullValue()));
+    }
+
+    /**
+     * Tests options() getter method.
+     */
+    @Test
+    public void testGetOptions() throws Exception {
+        ospfArea.setOptions(2);
+        assertThat(ospfArea.options(), is(2));
+    }
+
+    /**
+     * Tests options() setter method.
+     */
+    @Test
+    public void testSetOptions() throws Exception {
+        ospfArea.setOptions(2);
+        assertThat(ospfArea.options(), is(2));
+    }
+
+    /**
+     * Tests isOpaqueEnabled() method.
+     */
+    @Test
+    public void testGetOpaqueEnabledOptions() throws Exception {
+        ospfArea.setIsOpaqueEnabled(true);
+        assertThat(ospfArea.isOpaqueEnabled(), is(true));
+    }
+
+    /**
+     * Tests database()  method.
+     */
+    @Test
+    public void testGetDatabase() throws Exception {
+        assertThat(ospfArea.database(), is(notNullValue()));
+    }
+
+    /**
+     * Tests opaqueEnabledOptions()  method.
+     */
+    @Test
+    public void testOpaqueEnabledOptionsa() throws Exception {
+        assertThat(ospfArea.opaqueEnabledOptions(), is(66));
+    }
+}
\ No newline at end of file
