diff --git a/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
new file mode 100644
index 0000000..87b48b2
--- /dev/null
+++ b/src/test/java/net/onrc/onos/ofcontroller/linkdiscovery/internal/LinkDiscoveryManagerTest.java
@@ -0,0 +1,432 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    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 net.onrc.onos.ofcontroller.linkdiscovery.internal;
+
+import static org.easymock.EasyMock.*;
+
+import java.util.Collections;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IFloodlightProviderService.Role;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.test.MockThreadPoolService;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.restserver.RestApiServer;
+import net.floodlightcontroller.routing.IRoutingService;
+import net.floodlightcontroller.routing.Link;
+import net.floodlightcontroller.storage.IStorageSourceService;
+import net.floodlightcontroller.storage.memory.MemoryStorageSource;
+import net.floodlightcontroller.test.FloodlightTestCase;
+import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.topology.NodePortTuple;
+import net.floodlightcontroller.topology.TopologyManager;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
+import net.onrc.onos.ofcontroller.linkdiscovery.LinkInfo;
+import net.onrc.onos.ofcontroller.linkdiscovery.internal.LinkDiscoveryManager;
+
+/**
+ *
+ * @author David Erickson (daviderickson@cs.stanford.edu)
+ */
+public class LinkDiscoveryManagerTest extends FloodlightTestCase {
+
+    private TestLinkDiscoveryManager ldm;
+    protected static Logger log = LoggerFactory.getLogger(LinkDiscoveryManagerTest.class);
+    
+    public class TestLinkDiscoveryManager extends LinkDiscoveryManager {
+        public boolean isSendLLDPsCalled = false;
+        public boolean isClearLinksCalled = false;
+
+        @Override
+        protected void discoverOnAllPorts() {
+            isSendLLDPsCalled = true;
+            super.discoverOnAllPorts();
+        }
+
+        public void reset() {
+            isSendLLDPsCalled = false;
+            isClearLinksCalled = false;
+        }
+
+        @Override
+        protected void clearAllLinks() {
+            isClearLinksCalled = true;
+            super.clearAllLinks();
+        }
+    }
+    
+    public LinkDiscoveryManager getTopology() {
+        return ldm;
+    }
+
+    public IOFSwitch createMockSwitch(Long id) {
+        IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
+        expect(mockSwitch.getId()).andReturn(id).anyTimes();
+        return mockSwitch;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        FloodlightModuleContext cntx = new FloodlightModuleContext();
+        ldm = new TestLinkDiscoveryManager();
+        TopologyManager routingEngine = new TopologyManager();
+        ldm.linkDiscoveryAware = new ArrayList<ILinkDiscoveryListener>();
+        MockThreadPoolService tp = new MockThreadPoolService();
+        RestApiServer restApi = new RestApiServer();
+        cntx.addService(IRestApiService.class, restApi);
+        cntx.addService(IThreadPoolService.class, tp);
+        cntx.addService(IRoutingService.class, routingEngine);
+        cntx.addService(ILinkDiscoveryService.class, ldm);
+        cntx.addService(ITopologyService.class, ldm);
+        cntx.addService(IStorageSourceService.class, new MemoryStorageSource());
+        cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
+        restApi.init(cntx);
+        tp.init(cntx);
+        routingEngine.init(cntx);
+        ldm.init(cntx);
+        restApi.startUp(cntx);
+        tp.startUp(cntx);
+        routingEngine.startUp(cntx);
+        ldm.startUp(cntx);
+
+        IOFSwitch sw1 = createMockSwitch(1L);
+        IOFSwitch sw2 = createMockSwitch(2L);
+        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
+        switches.put(1L, sw1);
+        switches.put(2L, sw2);
+        getMockFloodlightProvider().setSwitches(switches);
+        replay(sw1, sw2);
+    }
+
+    @Test
+    public void testAddOrUpdateLink() throws Exception {
+        LinkDiscoveryManager topology = getTopology();
+
+        Link lt = new Link(1L, 2, 2L, 1);
+        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+                                     System.currentTimeMillis(), null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+
+
+        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+
+        // check invariants hold
+        assertNotNull(topology.switchLinks.get(lt.getSrc()));
+        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+        assertNotNull(topology.portLinks.get(srcNpt));
+        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+        assertNotNull(topology.portLinks.get(dstNpt));
+        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+        assertTrue(topology.links.containsKey(lt));
+    }
+
+    @Test
+    public void testDeleteLink() throws Exception {
+        LinkDiscoveryManager topology = getTopology();
+
+        Link lt = new Link(1L, 2, 2L, 1);
+        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+                                     System.currentTimeMillis(), null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+        topology.deleteLinks(Collections.singletonList(lt), "Test");
+
+        // check invariants hold
+        assertNull(topology.switchLinks.get(lt.getSrc()));
+        assertNull(topology.switchLinks.get(lt.getDst()));
+        assertNull(topology.portLinks.get(lt.getSrc()));
+        assertNull(topology.portLinks.get(lt.getDst()));
+        assertTrue(topology.links.isEmpty());
+    }
+
+    @Test
+    public void testAddOrUpdateLinkToSelf() throws Exception {
+        LinkDiscoveryManager topology = getTopology();
+
+        Link lt = new Link(1L, 2, 2L, 3);
+        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+        NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+
+        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+                                     System.currentTimeMillis(), null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+
+        // check invariants hold
+        assertNotNull(topology.switchLinks.get(lt.getSrc()));
+        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+        assertNotNull(topology.portLinks.get(srcNpt));
+        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+        assertNotNull(topology.portLinks.get(dstNpt));
+        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+        assertTrue(topology.links.containsKey(lt));
+    }
+
+    @Test
+    public void testDeleteLinkToSelf() throws Exception {
+        LinkDiscoveryManager topology = getTopology();
+
+        Link lt = new Link(1L, 2, 1L, 3);
+        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+        NodePortTuple dstNpt = new NodePortTuple(2L, 3);
+
+        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+                                     System.currentTimeMillis(), null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+        topology.deleteLinks(Collections.singletonList(lt), "Test to self");
+
+        // check invariants hold
+        assertNull(topology.switchLinks.get(lt.getSrc()));
+        assertNull(topology.switchLinks.get(lt.getDst()));
+        assertNull(topology.portLinks.get(srcNpt));
+        assertNull(topology.portLinks.get(dstNpt));
+        assertTrue(topology.links.isEmpty());
+    }
+
+    @Test
+    public void testRemovedSwitch() {
+        LinkDiscoveryManager topology = getTopology();
+
+        Link lt = new Link(1L, 2, 2L, 1);
+        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+                                     System.currentTimeMillis(), null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+
+        IOFSwitch sw1 = getMockFloodlightProvider().getSwitches().get(1L);
+        IOFSwitch sw2 = getMockFloodlightProvider().getSwitches().get(2L);
+        // Mock up our expected behavior
+        topology.removedSwitch(sw1);
+        verify(sw1, sw2);
+
+        // check invariants hold
+        assertNull(topology.switchLinks.get(lt.getSrc()));
+        assertNull(topology.switchLinks.get(lt.getDst()));
+        assertNull(topology.portLinks.get(srcNpt));
+        assertNull(topology.portLinks.get(dstNpt));
+        assertTrue(topology.links.isEmpty());
+    }
+
+    @Test
+    public void testRemovedSwitchSelf() {
+        LinkDiscoveryManager topology = getTopology();
+        IOFSwitch sw1 = createMockSwitch(1L);
+        replay(sw1);
+        Link lt = new Link(1L, 2, 1L, 3);
+        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+                                     System.currentTimeMillis(), null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+
+        // Mock up our expected behavior
+        topology.removedSwitch(sw1);
+
+        verify(sw1);
+        // check invariants hold
+        assertNull(topology.switchLinks.get(lt.getSrc()));
+        assertNull(topology.portLinks.get(lt.getSrc()));
+        assertNull(topology.portLinks.get(lt.getDst()));
+        assertTrue(topology.links.isEmpty());
+    }
+
+    @Test
+    public void testAddUpdateLinks() throws Exception {
+        LinkDiscoveryManager topology = getTopology();
+
+        Link lt = new Link(1L, 1, 2L, 1);
+        NodePortTuple srcNpt = new NodePortTuple(1L, 1);
+        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+        
+        LinkInfo info;
+
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            System.currentTimeMillis() - 40000, null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+
+        // check invariants hold
+        assertNotNull(topology.switchLinks.get(lt.getSrc()));
+        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+        assertNotNull(topology.portLinks.get(srcNpt));
+        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+        assertNotNull(topology.portLinks.get(dstNpt));
+        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+        assertTrue(topology.links.containsKey(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+        topology.timeoutLinks();
+
+
+        info = new LinkInfo(System.currentTimeMillis(),/* firstseen */
+                            null,/* unicast */
+                            System.currentTimeMillis(), 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+        // Add a link info based on info that woudld be obtained from unicast LLDP
+        // Setting the unicast LLDP reception time to be 40 seconds old, so we can use
+        // this to test timeout after this test.  Although the info is initialized
+        // with LT_OPENFLOW_LINK, the link property should be changed to LT_NON_OPENFLOW
+        // by the addOrUpdateLink method.
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            System.currentTimeMillis() - 40000, null, 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+        // Expect to timeout the unicast Valid Time, but not the multicast Valid time
+        // So the link type should go back to non-openflow link.
+        topology.timeoutLinks();
+        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+        // Set the multicastValidTime to be old and see if that also times out.
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            null, System.currentTimeMillis() - 40000, 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        topology.timeoutLinks();
+        assertTrue(topology.links.get(lt) == null);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+
+        // Test again only with multicast LLDP
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            null, System.currentTimeMillis() - 40000, 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        assertTrue(topology.links.get(lt).getUnicastValidTime() == null);
+        assertTrue(topology.links.get(lt).getMulticastValidTime() != null);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+        // Call timeout and check if link is no longer present.
+        topology.timeoutLinks();
+        assertTrue(topology.links.get(lt) == null);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt) == null ||
+                topology.portBroadcastDomainLinks.get(srcNpt).contains(lt) == false);
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt) == null ||
+                topology.portBroadcastDomainLinks.get(dstNpt).contains(lt) == false);
+
+        // Start clean and see if loops are also added.
+        lt = new Link(1L, 1, 1L, 2);
+        srcNpt = new NodePortTuple(1L, 1);
+        dstNpt = new NodePortTuple(1L, 2);
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            null, System.currentTimeMillis() - 40000, 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+        // Start clean and see if loops are also added.
+        lt = new Link(1L, 1, 1L, 3);
+        srcNpt = new NodePortTuple(1L, 1);
+        dstNpt = new NodePortTuple(1L, 3);
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            null, System.currentTimeMillis() - 40000, 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+        // Start clean and see if loops are also added.
+        lt = new Link(1L, 4, 1L, 5);
+        srcNpt = new NodePortTuple(1L, 4);
+        dstNpt = new NodePortTuple(1L, 5);
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            null, System.currentTimeMillis() - 40000, 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+
+
+        // Start clean and see if loops are also added.
+        lt = new Link(1L, 3, 1L, 5);
+        srcNpt = new NodePortTuple(1L, 3);
+        dstNpt = new NodePortTuple(1L, 5);
+        info = new LinkInfo(System.currentTimeMillis() - 40000,
+                            null, System.currentTimeMillis() - 40000, 0, 0);
+        topology.addOrUpdateLink(lt, info);
+        assertTrue(topology.portBroadcastDomainLinks.get(srcNpt).contains(lt));
+        assertTrue(topology.portBroadcastDomainLinks.get(dstNpt).contains(lt));
+    }
+
+    @Test
+    public void testHARoleChange() throws Exception {
+        LinkDiscoveryManager topology = getTopology();
+        IOFSwitch sw1 = createMockSwitch(1L);
+        IOFSwitch sw2 = createMockSwitch(2L);
+        replay(sw1, sw2);
+        Link lt = new Link(1L, 2, 2L, 1);
+        NodePortTuple srcNpt = new NodePortTuple(1L, 2);
+        NodePortTuple dstNpt = new NodePortTuple(2L, 1);
+        LinkInfo info = new LinkInfo(System.currentTimeMillis(),
+                                     System.currentTimeMillis(), null,
+                                     0, 0);
+        topology.addOrUpdateLink(lt, info);
+
+        // check invariants hold
+        assertNotNull(topology.switchLinks.get(lt.getSrc()));
+        assertTrue(topology.switchLinks.get(lt.getSrc()).contains(lt));
+        assertNotNull(topology.portLinks.get(srcNpt));
+        assertTrue(topology.portLinks.get(srcNpt).contains(lt));
+        assertNotNull(topology.portLinks.get(dstNpt));
+        assertTrue(topology.portLinks.get(dstNpt).contains(lt));
+        assertTrue(topology.links.containsKey(lt));
+        
+        // check that it clears from memory
+        getMockFloodlightProvider().dispatchRoleChanged(null, Role.SLAVE);
+        assertTrue(topology.switchLinks.isEmpty());
+        getMockFloodlightProvider().dispatchRoleChanged(Role.SLAVE, Role.MASTER);
+        // check that lldps were sent
+        assertTrue(ldm.isSendLLDPsCalled);
+        assertTrue(ldm.isClearLinksCalled);
+        ldm.reset();
+    }
+}
