diff --git a/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java b/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java
index 65504f2..1c6349e 100644
--- a/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/edgeservice/impl/EdgeManagerTest.java
@@ -15,47 +15,80 @@
  */
 package org.onosproject.net.edgeservice.impl;
 
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.event.Event;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultPort;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
 import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceServiceAdapter;
 import org.onosproject.net.edge.EdgePortEvent;
 import org.onosproject.net.edge.EdgePortListener;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.packet.OutboundPacket;
 import org.onosproject.net.packet.PacketServiceAdapter;
 import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyEvent;
 import org.onosproject.net.topology.TopologyListener;
 import org.onosproject.net.topology.TopologyServiceAdapter;
 
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.*;
+import static org.onosproject.net.device.DeviceEvent.Type.*;
+import static org.onosproject.net.edge.EdgePortEvent.Type.EDGE_PORT_ADDED;
+import static org.onosproject.net.edge.EdgePortEvent.Type.EDGE_PORT_REMOVED;
+import static org.onosproject.net.link.LinkEvent.Type.LINK_ADDED;
+import static org.onosproject.net.link.LinkEvent.Type.LINK_REMOVED;
+import static org.onosproject.net.topology.TopologyEvent.Type.TOPOLOGY_CHANGED;
 
 /**
- * Test of the edge port manager.
+ * Test of the edge port manager. Each device has ports '0' through 'numPorts - 1'
+ * as specified by the variable 'numPorts'.
  */
 public class EdgeManagerTest {
 
     private EdgeManager mgr;
-    private final EdgePortListener testListener = new TestListener();
-
+    private int totalPorts = 10;
+    private boolean alwaysReturnPorts = false;
+    private final Set<ConnectPoint> infrastructurePorts = Sets.newConcurrentHashSet();
+    private List<EdgePortEvent> events = Lists.newArrayList();
+    private final Map<DeviceId, Device> devices = Maps.newConcurrentMap();
+    private Set<OutboundPacket> packets = Sets.newConcurrentHashSet();
+    private final EdgePortListener testListener = new TestListener(events);
+    private TestTopologyManager testTopologyManager;
 
     @Before
     public void setUp() {
         mgr = new EdgeManager();
         mgr.eventDispatcher = new TestEventDispatcher();
-        mgr.topologyService = new TestTopologyManager();
-        mgr.deviceService = new TestDeviceManager();
+        testTopologyManager = new TestTopologyManager(infrastructurePorts);
+        mgr.topologyService = testTopologyManager;
+        mgr.deviceService = new TestDeviceManager(devices);
         mgr.packetService = new TestPacketManager();
         mgr.activate();
         mgr.addListener(testListener);
+
     }
 
+
     @After
     public void tearDown() {
         mgr.removeListener(testListener);
@@ -63,14 +96,347 @@
     }
 
     @Test
-    public void basics() {
+    public void testBasics() {
+        //Setup
+        int numDevices = 20;
+        int numPorts = 4;
+        defaultPopulator(numDevices, numPorts);
+
+        assertEquals("Unexpected number of ports", numDevices * numPorts, infrastructurePorts.size());
+
         assertFalse("no ports expected", mgr.getEdgePoints().iterator().hasNext());
+
+        assertFalse("Expected isEdge to return false",
+                mgr.isEdgePoint(NetTestTools.connectPoint(Integer.toString(1), 1)));
+
+        removeInfraPort(NetTestTools.connectPoint(Integer.toString(1), 1));
+        assertTrue("Expected isEdge to return false",
+                mgr.isEdgePoint(NetTestTools.connectPoint(Integer.toString(1), 1)));
+    }
+
+    @Test
+    public void testLinkUpdates() {
+        //Setup
+        ConnectPoint testPoint, referencePoint;
+
+        //Testing link removal
+        List<Event> eventsToAdd = Lists.newArrayList();
+        eventsToAdd.add(new LinkEvent(LINK_REMOVED, NetTestTools.link("a", 1, "b", 2)));
+        TopologyEvent event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+
+        assertTrue("The list contained an unexpected number of events", events.size() == 2);
+        assertTrue("The first element is of the wrong type.",
+                events.get(0).type() == EDGE_PORT_ADDED);
+        assertTrue("The second element is of the wrong type.",
+                events.get(1).type() == EDGE_PORT_ADDED);
+
+        testPoint = events.get(0).subject();
+        referencePoint = NetTestTools.connectPoint("a", 1);
+        assertTrue("The port numbers of the first element are incorrect",
+                testPoint.port().toLong() == referencePoint.port().toLong());
+        assertTrue("The device id of the first element is incorrect.",
+                testPoint.deviceId().equals(referencePoint.deviceId()));
+
+        testPoint = events.get(1).subject();
+        referencePoint = NetTestTools.connectPoint("b", 2);
+        assertTrue("The port numbers of the second element are incorrect",
+                testPoint.port().toLong() == referencePoint.port().toLong());
+        assertTrue("The device id of the second element is incorrect.",
+                testPoint.deviceId().equals(referencePoint.deviceId()));
+
+        //Rebroadcast event to ensure it results in no additional events
+        testTopologyManager.listener.event(event);
+        assertTrue("The list contained an unexpected number of events", events.size() == 2);
+
+        //Testing link adding when links to remove exist
+        eventsToAdd.clear();
+        events.clear();
+        eventsToAdd.add(new LinkEvent(LINK_ADDED, NetTestTools.link("a", 1, "b", 2)));
+        event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+
+        assertTrue("The list contained an unexpected number of events", events.size() == 2);
+        assertTrue("The first element is of the wrong type.",
+                events.get(0).type() == EDGE_PORT_REMOVED);
+        assertTrue("The second element is of the wrong type.",
+                events.get(1).type() == EDGE_PORT_REMOVED);
+
+        testPoint = events.get(0).subject();
+        referencePoint = NetTestTools.connectPoint("a", 1);
+        assertTrue("The port numbers of the first element are incorrect",
+                testPoint.port().toLong() == referencePoint.port().toLong());
+        assertTrue("The device id of the first element is incorrect.",
+                testPoint.deviceId().equals(referencePoint.deviceId()));
+
+        testPoint = events.get(1).subject();
+        referencePoint = NetTestTools.connectPoint("b", 2);
+        assertTrue("The port numbers of the second element are incorrect",
+                testPoint.port().toLong() == referencePoint.port().toLong());
+        assertTrue("The device id of the second element is incorrect.",
+                testPoint.deviceId().equals(referencePoint.deviceId()));
+
+        //Apparent duplicate of previous method tests removal when the elements have already been removed
+        eventsToAdd.clear();
+        events.clear();
+        eventsToAdd.add(new LinkEvent(LINK_ADDED, NetTestTools.link("a", 1, "b", 2)));
+        event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+
+        assertTrue("The list should contain no events, the removed elements don't exist.", events.size() == 0);
+    }
+
+    @Test
+    public void testDeviceUpdates() {
+        //Setup
+
+        Device referenceDevice;
+        TopologyEvent event;
+        List<Event> eventsToAdd = Lists.newArrayList();
+        int numDevices = 10;
+        int numInfraPorts = 5;
+        totalPorts = 10;
+        defaultPopulator(numDevices, numInfraPorts);
+
+        //Test response to device added events
+        referenceDevice = NetTestTools.device("1");
+        eventsToAdd.add(new DeviceEvent(DEVICE_ADDED, referenceDevice,
+                new DefaultPort(referenceDevice, PortNumber.portNumber(1), true)));
+        event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+
+        //Check that ports were populated correctly
+        assertTrue("Unexpected number of new ports added",
+                mgr.deviceService.getPorts(NetTestTools.did("1")).size() == 10);
+
+        //Check that of the ten ports the half that are infrastructure ports aren't added
+        assertEquals("Unexpected number of new edge ports added", (totalPorts - numInfraPorts), events.size());
+
+        for (int index = 0; index < numInfraPorts; index++) {
+            assertTrue("Unexpected type of event", events.get(index).type() == EDGE_PORT_ADDED);
+        }
+        //Names here are irrelevant, the first 5 ports are populated as infrastructure, 6-10 are edge
+        for (int index = 0; index < events.size(); index++) {
+            assertEquals("Port added had unexpected port number.",
+                    events.get(index).subject().port(),
+                    NetTestTools.connectPoint("a", index + numInfraPorts + 1).port());
+        }
+        events.clear();
+
+        //Repost the event to test repeated posts
+        testTopologyManager.listener.event(event);
+        assertEquals("The redundant notification should not have created additional notifications.",
+                0, events.size());
+        //Calculate the size of the returned iterable of edge points.
+        Iterable<ConnectPoint> pts = mgr.getEdgePoints();
+        Iterator pointIterator = pts.iterator();
+        int count = 0;
+        for (; pointIterator.hasNext(); count++) {
+            pointIterator.next();
+        }
+        assertEquals("Unexpected number of edge points", totalPorts - numInfraPorts, count);
+        //Testing device removal
+        events.clear();
+        eventsToAdd.clear();
+        eventsToAdd.add(new DeviceEvent(DEVICE_REMOVED, referenceDevice,
+                new DefaultPort(referenceDevice, PortNumber.portNumber(1), true)));
+        event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+
+        assertEquals("There should be five new events from removal of edge points",
+                totalPorts - numInfraPorts, events.size());
+        for (int index = 0; index < events.size(); index++) {
+            //Assert that the correct port numbers were removed in the correct order
+            assertEquals("Port removed had unexpected port number.",
+                    events.get(index).subject().port(),
+                    (NetTestTools.connectPoint("a", index + numInfraPorts + 1).port()));
+            //Assert that the events are of the correct type
+            assertEquals("Unexpected type of event", events.get(index).type(), EDGE_PORT_REMOVED);
+        }
+        events.clear();
+        //Rebroadcast event to check that it triggers no new behavior
+        testTopologyManager.listener.event(event);
+        assertEquals("Rebroadcast of removal event should not produce additional events",
+                0, events.size());
+
+        //Testing device status change, changed from unavailable to available
+        events.clear();
+        eventsToAdd.clear();
+        //Make sure that the devicemanager shows the device as available.
+        addDevice(referenceDevice, "1", 5);
+        devices.put(referenceDevice.id(), referenceDevice);
+
+        eventsToAdd.add(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, referenceDevice));
+        event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+        //An earlier setup set half of the reference device ports to infrastructure
+        assertEquals("An unexpected number of events were generated.", totalPorts - numInfraPorts, events.size());
+        for (int i = 0; i < 5; i++) {
+            assertEquals("The event was not of the right type", events.get(i).type(), EDGE_PORT_ADDED);
+        }
+        events.clear();
+        testTopologyManager.listener.event(event);
+        assertEquals("No events should have been generated for a set of existing ports.", 0, events.size());
+
+        //Test removal when state changes when the device becomes unavailable
+
+        //Ensure that the deviceManager shows the device as unavailable
+        removeDevice(referenceDevice);
+        /*This variable copies the behavior of the topology by returning ports attached to an unavailable device
+        //this behavior is necessary for the following event to execute properly, if these statements are removed
+        no events will be generated since no ports will be provided in getPorts() to EdgeManager.
+        */
+        alwaysReturnPorts = true;
+        testTopologyManager.listener.event(event);
+        alwaysReturnPorts = false;
+        assertEquals("An unexpected number of events were created.", totalPorts - numInfraPorts, events.size());
+        for (int i = 0; i < 5; i++) {
+            EdgePortEvent edgeEvent = events.get(i);
+            assertEquals("The event is of an unexpected type.",
+                    EdgePortEvent.Type.EDGE_PORT_REMOVED, edgeEvent.type());
+            assertEquals("The event pertains to an unexpected port", PortNumber.portNumber(i + numInfraPorts + 1),
+                    edgeEvent.subject().port());
+        }
+    }
+
+    @Test
+    public void testInternalCache() {
+        List<Event> eventsToAdd = Lists.newArrayList();
+        int numDevices = 10;
+        //Number of infrastructure ports per device
+        int numPorts = 5;
+        //Total ports per device when requesting all devices
+        totalPorts = 10;
+        defaultPopulator(numDevices, numPorts);
+        for (int i = 0; i < numDevices; i++) {
+            Device newDevice = NetTestTools.device(Integer.toString(i));
+            devices.put(newDevice.id(), newDevice);
+            eventsToAdd.add(new DeviceEvent(DEVICE_ADDED, newDevice));
+        }
+        TopologyEvent event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+
+        //Check all ports have correct designations
+        ConnectPoint testPoint;
+        for (int deviceNum = 0; deviceNum < numDevices; deviceNum++) {
+            for (int portNum = 1; portNum <= totalPorts; portNum++) {
+                testPoint = NetTestTools.connectPoint(Integer.toString(deviceNum), portNum);
+                if (portNum <= numPorts) {
+                    assertFalse("This should not be an edge point", mgr.isEdgePoint(testPoint));
+                } else {
+                    assertTrue("This should be an edge point", mgr.isEdgePoint(testPoint));
+                }
+            }
+        }
+        int count = 0;
+        for (ConnectPoint ignored : mgr.getEdgePoints()) {
+            count++;
+        }
+        assertEquals("There are an unexpeceted number of edge points returned.",
+                (totalPorts - numPorts) * numDevices, count);
+        for (int deviceNumber = 0; deviceNumber < numDevices; deviceNumber++) {
+            count = 0;
+            for (ConnectPoint ignored : mgr.getEdgePoints(NetTestTools.did("1"))) {
+                count++;
+            }
+            assertEquals("This element has an unexpected number of edge points.", (totalPorts - numPorts), count);
+        }
+    }
+
+
+    @Test
+    public void testEmit() {
+        byte[] arr = new byte[10];
+        Device referenceDevice;
+        TopologyEvent event;
+        List<Event> eventsToAdd = Lists.newArrayList();
+        int numDevices = 10;
+        int numInfraPorts = 5;
+        totalPorts = 10;
+        defaultPopulator(numDevices, numInfraPorts);
+        for (byte byteIndex = 0; byteIndex < arr.length; byteIndex++) {
+            arr[byteIndex] = byteIndex;
+        }
+        for (int i = 0; i < numDevices; i++) {
+            referenceDevice = NetTestTools.device(Integer.toString(i));
+            eventsToAdd.add(new DeviceEvent(DEVICE_ADDED, referenceDevice,
+                    new DefaultPort(referenceDevice, PortNumber.portNumber(1), true)));
+        }
+        event = new TopologyEvent(TOPOLOGY_CHANGED, null, eventsToAdd);
+        testTopologyManager.listener.event(event);
+
+        mgr.emitPacket(ByteBuffer.wrap(arr), Optional.<TrafficTreatment>empty());
+
+        assertEquals("There were an unexpected number of emitted packets",
+                (totalPorts - numInfraPorts) * numDevices, packets.size());
+        Iterator<OutboundPacket> packetIter = packets.iterator();
+        OutboundPacket packet;
+        while (packetIter.hasNext()) {
+            packet = packetIter.next();
+            assertEquals("The packet had an incorrect payload.", arr, packet.data().array());
+        }
+        //Start testing emission to a specific device
+        packets.clear();
+        mgr.emitPacket(NetTestTools.did(Integer.toString(1)), ByteBuffer.wrap(arr), Optional.<TrafficTreatment>empty());
+
+        assertEquals("Unexpected number of outbound packets were emitted.",
+                totalPorts - numInfraPorts, packets.size());
+        packetIter = packets.iterator();
+        while (packetIter.hasNext()) {
+            packet = packetIter.next();
+            assertEquals("The packet had an incorrect payload", arr, packet.data().array());
+        }
+    }
+
+
+    /**
+     * @param numDevices    the number of devices to populate.
+     * @param numInfraPorts the number of ports to be set as infrastructure on each device, numbered base 0, ports 0
+     *                      through numInfraPorts - 1
+     */
+    private void defaultPopulator(int numDevices, int numInfraPorts) {
+        for (int device = 0; device < numDevices; device++) {
+            String str = Integer.toString(device);
+            Device deviceToAdd = NetTestTools.device(str);
+            devices.put(deviceToAdd.id(), deviceToAdd);
+            for (int port = 1; port <= numInfraPorts; port++) {
+                infrastructurePorts.add(NetTestTools.connectPoint(str, port));
+            }
+        }
+    }
+
+    /**
+     * Adds the specified device with the specified number of edge ports so long as it is less than the total ports.
+     *
+     * @param device        The device to be added
+     * @param deviceName    The name given to generate the devices DID
+     * @param numInfraPorts The number of ports to be added numbered 1 ... numInfraPorts
+     */
+    private void addDevice(Device device, String deviceName, int numInfraPorts) {
+        if (!devices.keySet().contains(device.id())) {
+            devices.put(device.id(), device);
+            for (int i = 1; i <= numInfraPorts && i <= totalPorts; i++) {
+                infrastructurePorts.add(NetTestTools.connectPoint(deviceName, i));
+            }
+        }
+    }
+
+    private void removeDevice(Device device) {
+        devices.remove(device.id());
+    }
+
+    private void removeInfraPort(ConnectPoint port) {
+        infrastructurePorts.remove(port);
     }
 
     private class TestTopologyManager extends TopologyServiceAdapter {
         private TopologyListener listener;
         private Set<ConnectPoint> infrastructurePorts;
 
+        public TestTopologyManager(Set<ConnectPoint> infrastructurePorts) {
+            this.infrastructurePorts = infrastructurePorts;
+        }
+
         @Override
         public boolean isInfrastructure(Topology topology, ConnectPoint connectPoint) {
             return infrastructurePorts.contains(connectPoint);
@@ -89,12 +455,16 @@
 
     private class TestDeviceManager extends DeviceServiceAdapter {
 
-        private Set<Device> devices;
+        private Map<DeviceId, Device> devices;
+
+        public TestDeviceManager(Map<DeviceId, Device> devices) {
+            this.devices = devices;
+        }
 
         @Override
         public boolean isAvailable(DeviceId deviceId) {
-            for (Device device : devices) {
-                if (device.id().equals(deviceId)) {
+            for (DeviceId id : devices.keySet()) {
+                if (id.equals(deviceId)) {
                     return true;
                 }
             }
@@ -103,22 +473,38 @@
 
         @Override
         public List<Port> getPorts(DeviceId deviceId) {
-            return super.getPorts(deviceId);
+            List<Port> ports = new ArrayList<>();
+            Device device = devices.get(deviceId);
+            if (device == null && !alwaysReturnPorts) {
+                return ports;
+            }
+            for (int portNum = 1; portNum <= totalPorts; portNum++) {
+                //String is generated using 'of:' + the passed name, this creates a
+                ports.add(new DefaultPort(device, PortNumber.portNumber(portNum), true));
+            }
+            return ports;
         }
 
         @Override
         public Iterable<Device> getAvailableDevices() {
-            return devices;
+            return devices.values();
         }
     }
 
     private class TestPacketManager extends PacketServiceAdapter {
+        @Override
+        public void emit(OutboundPacket packet) {
+            packets.add(packet);
+        }
     }
 
-
     private class TestListener implements EdgePortListener {
         private List<EdgePortEvent> events;
 
+        public TestListener(List<EdgePortEvent> events) {
+            this.events = events;
+        }
+
         @Override
         public void event(EdgePortEvent event) {
             events.add(event);
