diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
index f1eb3e991aa1a8b005085d1cb46cbf74c306ffc7..5b32a31c85f32ef5e187775ad71e115b3eafc57f 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
@@ -17,10 +17,10 @@
 
 package net.floodlightcontroller.devicemanager.internal;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.TreeSet;
 
 import org.openflow.util.HexString;
@@ -28,6 +28,7 @@ import org.openflow.util.HexString;
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IEntityClass;
 import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.floodlightcontroller.topology.ITopologyService;
 
 /**
  * Concrete implementation of {@link IDevice}
@@ -35,7 +36,8 @@ import net.floodlightcontroller.devicemanager.SwitchPort;
  */
 public class Device implements IDevice {
     protected Long deviceKey;
-    
+    protected DeviceManagerImpl deviceManager;
+
     protected Entity[] entities;
     protected IEntityClass[] entityClasses;
     
@@ -47,13 +49,16 @@ public class Device implements IDevice {
     
     /**
      * Create a device from a set of entities
+     * @param deviceManager the device manager for this device
      * @param deviceKey the unique identifier for this device object
      * @param entity the initial entity for the device
      * @param entityClasses the entity classes associated with the entity
      */
-    public Device(Long deviceKey,
+    public Device(DeviceManagerImpl deviceManager,
+                  Long deviceKey,
                   Entity entity, 
                   Collection<IEntityClass> entityClasses) {
+        this.deviceManager = deviceManager;
         this.deviceKey = deviceKey;
         this.entities = new Entity[] {entity};
         this.macAddressString = 
@@ -64,17 +69,20 @@ public class Device implements IDevice {
     }
 
     /**
-     * Construct a new device with the given key and containing the provided
-     * entities and entity classes
+     * Construct a new device consisting of the entities from the old device
+     * plus an additional entity
      * @param device the old device object
-     * @param entities the entities for the device
+     * @param newEntity the entity to add
      * @param entityClasses the entity classes associated with the entities
      */
     public Device(Device device,
-                  Collection<Entity> entities,
+                  Entity newEntity,
                   Collection<IEntityClass> entityClasses) {
-        this.deviceKey = device.getDeviceKey();
-        this.entities = entities.toArray(new Entity[entities.size()]);
+        this.deviceManager = device.deviceManager;
+        this.deviceKey = device.deviceKey;
+        this.entities = Arrays.<Entity>copyOf(device.entities, 
+                                              device.entities.length + 1);
+        this.entities[this.entities.length - 1] = newEntity;
         Arrays.sort(this.entities);
 
         this.macAddressString = 
@@ -162,8 +170,31 @@ public class Device implements IDevice {
             }
         }
 
-        HashSet<SwitchPort> vals = new HashSet<SwitchPort>();
-        for (Entity e : entities) {
+        // Find the most recent attachment point for each cluster
+        // XXX - TODO suppress flapping
+        Entity[] clentities = Arrays.<Entity>copyOf(entities, entities.length);
+        Arrays.sort(clentities, deviceManager.clusterIdComparator);
+        
+        ITopologyService topology = deviceManager.topology;
+        long prevCluster = 0;
+        int clEntIndex = -1;
+        for (int i = 0; i < clentities.length; i++) {
+            if (clentities[i].switchDPID == null) continue;
+            long curCluster = 
+                    topology.getSwitchClusterId(clentities[i].switchDPID);
+            if (prevCluster != curCluster)
+                clEntIndex += 1;
+            clentities[clEntIndex] = clentities[i];
+            prevCluster = curCluster;
+        }
+
+        if (clEntIndex < 0) {
+            return new SwitchPort[0];
+        }
+        
+        ArrayList<SwitchPort> vals = new ArrayList<SwitchPort>(clEntIndex + 1);
+        for (int i = 0; i <= clEntIndex; i++) {
+            Entity e = clentities[i];
             if (e.getSwitchDPID() != null &&
                 e.getSwitchPort() != null) {
                 SwitchPort sp = new SwitchPort(e.getSwitchDPID(), 
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index f8dd1eda3081f0aaeb3874735f64182b4cdf5d84..99a589db0522bbbbaf5710fb850088eb5a9c3619 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -198,6 +199,11 @@ public class DeviceManagerImpl implements
         }        
     }
     
+    /**
+     * Comparator for sorting by cluster ID
+     */
+    public Comparator<Entity> clusterIdComparator;
+    
     // *********************
     // IDeviceManagerService
     // *********************
@@ -353,8 +359,6 @@ public class DeviceManagerImpl implements
     @Override
     public void setEntityClassifier(IEntityClassifier classifier) {
         entityClassifier = classifier;
-        primaryIndex = new DeviceUniqueIndex(classifier.getKeyFields());
-        secondaryIndexMap = new HashMap<EnumSet<DeviceField>, DeviceIndex>();
     }
     
     @Override
@@ -511,10 +515,46 @@ public class DeviceManagerImpl implements
     public void startUp(FloodlightModuleContext fmc) {
         if (entityClassifier == null)
             setEntityClassifier(new DefaultEntityClassifier());
+        
+        primaryIndex = new DeviceUniqueIndex(entityClassifier.getKeyFields());
+        secondaryIndexMap = new HashMap<EnumSet<DeviceField>, DeviceIndex>();
+        
         deviceMap = new ConcurrentHashMap<Long, Device>();
         classStateMap = 
                 new ConcurrentHashMap<IEntityClass, ClassState>();
-        
+        clusterIdComparator = new Comparator<Entity>() {
+            @Override
+            public int compare(Entity e1, Entity e2) {
+                int r = 0;
+
+                Long swdpid1 = e1.getSwitchDPID();
+                Long swdpid2 = e2.getSwitchDPID();
+                if (swdpid1 == null)
+                    r = swdpid2 == null ? 0 : -1;
+                else if (swdpid2 == null)
+                    r = 1;
+                else {
+                    Long d1ClusterId = 
+                            topology.getSwitchClusterId(swdpid1);
+                    Long d2ClusterId = 
+                            topology.getSwitchClusterId(swdpid2);
+                    r = d1ClusterId.compareTo(d2ClusterId);
+                }
+                if (r != 0) return r;
+                
+                Date e1t = e1.getLastSeenTimestamp();
+                Date e2t = e2.getLastSeenTimestamp();
+                if (e1t == null)
+                    r = e2t == null ? 0 : -1;
+                else if (e2t == null)
+                    r = 1;
+                else
+                    r = e1t.compareTo(e2t);
+
+                return r;
+            }
+        };
+
         if (topology != null) {
             // Register to get updates from topology
             topology.addListener(this);
@@ -807,13 +847,12 @@ public class DeviceManagerImpl implements
                 }
             }
             if (deviceKey != null) {
-                // If the primary or secondary index contains the entity, 
-                // update the entity timestamp, then use resulting device 
-                // key to look up the device in the device map, and
-                // use the referenced Device below.
+                // If the primary or secondary index contains the entity
+                // use resulting device key to look up the device in the 
+                // device map, and use the referenced Device below.
                 device = deviceMap.get(deviceKey);
                 if (device == null)
-                    continue;
+                    throw new IllegalStateException("Corrupted device index");
             } else {
                 // If the secondary index does not contain the entity, 
                 // create a new Device object containing the entity, and 
@@ -821,11 +860,12 @@ public class DeviceManagerImpl implements
                 synchronized (deviceKeyLock) {
                     deviceKey = Long.valueOf(deviceKeyCounter++);
                 }
-                device = new Device(deviceKey, entity, classes);
+                device = new Device(this, deviceKey, entity, classes);
                 
                 // Add the new device to the primary map with a simple put
                 deviceMap.put(deviceKey, device);
                 
+                // update indices
                 if (!updateIndices(device, deviceKey)) {
                     if (deleteQueue == null)
                         deleteQueue = new ArrayList<Long>();
@@ -835,6 +875,7 @@ public class DeviceManagerImpl implements
                 
                 updateSecondaryIndices(entity, classes, deviceKey);
                 
+                // generate new device update
                 deviceUpdates = 
                         updateUpdates(deviceUpdates,
                                       new DeviceUpdate(device, true, null));
@@ -856,62 +897,20 @@ public class DeviceManagerImpl implements
                 // field (including updating the entity caches), preserving the 
                 // old timestamp of the entity.
 
-                Entity[] entities = device.getEntities();
-                ArrayList<Entity> newEntities = null;
-                ArrayList<Entity> removedEntities = null;
-                EnumSet<DeviceField> changedFields = 
-                        findChangedFields(device, entity);
-                
-                // iterate backwards since we want indices for removed entities
-                // to update in reverse order
-                for (int i = entities.length - 1; i >= 0; i--) {
-                    // XXX - TODO Handle port channels                    
-                    // XXX - TODO Handle broadcast domains
-                    // XXX - TODO Prevent flapping of entities
-                    // XXX - TODO Handle unique indices
-
-                    Long edpid = entities[i].getSwitchDPID();
-                    Long cdpid = entity.getSwitchDPID();
-                    
-                    // Remove attachment points in the same cluster 
-                    if (edpid != null && cdpid != null &&
-                        topology != null && 
-                        topology.inSameCluster(edpid, cdpid)) {
-                        // XXX - TODO don't delete entities; we should just
-                        // filter out the attachment points on read
-                        removedEntities = 
-                                updateEntityList(removedEntities, entities[i]);
-
-                        changedFields.add(DeviceField.SWITCH);
-                        
-                        Entity shim = makeShimEntity(entity, entities[i], 
-                                                     device.getEntityClasses());
-                        newEntities = updateEntityList(newEntities, shim);
-                        continue;
-                    }
-                    
-                    newEntities = updateEntityList(newEntities, entities[i]);
-                }
-                newEntities = updateEntityList(newEntities, entity);
-                removeEntities(removedEntities, device.getEntityClasses());
+                // XXX - TODO Prevent flapping of entities
                 
                 Device newDevice = new Device(device,
-                                              newEntities, classes);
-
-                updateSecondaryIndices(entity, 
-                                       newDevice.getEntityClasses(), 
-                                       deviceKey);
-                for (Entity e : newEntities) {
-                    updateSecondaryIndices(e, 
-                                           newDevice.getEntityClasses(), 
-                                           deviceKey);                    
-                }
+                                              entity, classes);
                 
+                // generate updates
+                EnumSet<DeviceField> changedFields = 
+                        findChangedFields(device, entity);
                 deviceUpdates = 
                         updateUpdates(deviceUpdates,
                                       new DeviceUpdate(device, false, 
                                                        changedFields));
                 
+                // update the device map with a replace call
                 boolean res = deviceMap.replace(deviceKey, device, newDevice);
                 // If replace returns false, restart the process from the 
                 // beginning (this implies another thread concurrently 
@@ -921,9 +920,13 @@ public class DeviceManagerImpl implements
                 
                 device = newDevice;
                 
+                // update indices
                 if (!updateIndices(device, deviceKey)) {
                     continue;
                 }
+                updateSecondaryIndices(entity, 
+                                       device.getEntityClasses(), 
+                                       deviceKey);
                 break;
             }
         }
@@ -1007,72 +1010,7 @@ public class DeviceManagerImpl implements
             }
         }
     }
-    
-    /**
-     * If there's information that would be lost about a device because
-     * we're removing an old entity, construct a "shim" entity to provide
-     * that information
-     * @param newentity the entity being added
-     * @param rementity the entity that's being removed
-     * @param classes the entity classes
-     * @return the entity, or null if no entity needed
-     */
-    private Entity makeShimEntity(Entity newentity, Entity rementity,
-                                  IEntityClass[] classes) {
-        Set<DeviceField> nonkey = null;
-    
-        for (IEntityClass clazz : classes) {
-            if (nonkey == null)
-                nonkey = EnumSet.complementOf(clazz.getKeyFields());
-            else
-                nonkey.removeAll(clazz.getKeyFields());
-        }
 
-        Integer ipv4Address = null;
-        Short vlan = null;
-
-        for (DeviceField f : nonkey) {
-            switch (f) {
-                case IPV4:
-                    if (rementity.getIpv4Address() != null &&
-                        !rementity.getIpv4Address()
-                        .equals(newentity.getIpv4Address()))
-                        ipv4Address = rementity.getIpv4Address();
-                    break;
-                case VLAN:
-                    if (rementity.getVlan() != null &&
-                        !rementity.getVlan()
-                        .equals(newentity.getVlan()))
-                        vlan = rementity.getVlan();
-                    break;
-                case MAC:
-                case PORT:
-                case SWITCH:
-                    break;
-                default:
-                    logger.warn("Unexpected device field {}", f);
-            }
-        }
-        
-        Entity shim = null;        
-        if (ipv4Address != null || vlan != null) {
-            shim = new Entity(rementity.getMacAddress(), vlan, 
-                              ipv4Address, null, null, 
-                              rementity.getLastSeenTimestamp());
-        }
-        return shim;
-    }
-    
-    private ArrayList<Entity> updateEntityList(ArrayList<Entity> list,
-                                               Entity entity) {
-        if (entity == null) return list;
-        if (list == null)
-            list = new ArrayList<Entity>();
-        list.add(entity);
-        
-        return list;
-    }
-    
     private LinkedList<DeviceUpdate> 
         updateUpdates(LinkedList<DeviceUpdate> list, DeviceUpdate update) {
         if (update == null) return list;
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index 8ea54363236fd5a90aa089d3ad29a7d218eeb138..784b74fe0611d5004a500b53150f9c92c7da61c0 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -18,6 +18,7 @@
 package net.floodlightcontroller.devicemanager.internal;
 
 import java.util.Arrays;
+import java.util.Calendar;
 import java.util.Collection;
 import java.util.Date;
 import java.util.EnumSet;
@@ -29,6 +30,7 @@ import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.reset;
 import static org.easymock.EasyMock.verify;
 import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.anyLong;
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
@@ -157,6 +159,11 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         deviceManager.addListener(mockListener);
         deviceManager.setEntityClassifier(new TestEntityClassifier());
         
+        ITopologyService mockTopology = createMock(ITopologyService.class);
+        expect(mockTopology.getSwitchClusterId(anyLong())).
+            andReturn(1L).anyTimes();
+        deviceManager.topology = mockTopology;
+
         Entity entity1 = new Entity(1L, null, null, 1L, 1, new Date());
         Entity entity2 = new Entity(1L, null, null, 10L, 1, new Date());
         Entity entity3 = new Entity(1L, null, 1, 10L, 1, new Date());
@@ -164,9 +171,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         Entity entity5 = new Entity(2L, (short)4, 1, 5L, 2, new Date());
         Entity entity6 = new Entity(2L, (short)4, 1, 50L, 3, new Date());
 
-        
         mockListener.deviceAdded(isA(IDevice.class));
-        replay(mockListener);
+        replay(mockListener, mockTopology);
         
         Device d1 = deviceManager.learnDeviceByEntity(entity1);        
         assertSame(d1, deviceManager.learnDeviceByEntity(entity1)); 
@@ -257,30 +263,27 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         deviceManager.addListener(mockListener);
 
         ITopologyService mockTopology = createMock(ITopologyService.class);
-        expect(mockTopology.inSameCluster(1L, 2L)).andReturn(true).anyTimes();
-        expect(mockTopology.inSameCluster(2L, 1L)).andReturn(true).anyTimes();
-
-        expect(mockTopology.inSameCluster(3L, 4L)).andReturn(true).anyTimes();
-        expect(mockTopology.inSameCluster(4L, 3L)).andReturn(true).anyTimes();
-        
-        expect(mockTopology.inSameCluster(1L, 3L)).andReturn(false).anyTimes();
-        expect(mockTopology.inSameCluster(3L, 1L)).andReturn(false).anyTimes();
-        expect(mockTopology.inSameCluster(1L, 4L)).andReturn(false).anyTimes();
-        expect(mockTopology.inSameCluster(4L, 1L)).andReturn(false).anyTimes();
-
-        expect(mockTopology.inSameCluster(2L, 3L)).andReturn(false).anyTimes();
-        expect(mockTopology.inSameCluster(3L, 2L)).andReturn(false).anyTimes();
-        expect(mockTopology.inSameCluster(2L, 4L)).andReturn(false).anyTimes();
-        expect(mockTopology.inSameCluster(4L, 2L)).andReturn(false).anyTimes();
+        expect(mockTopology.getSwitchClusterId(1L)).
+        andReturn(1L).anyTimes();
+        expect(mockTopology.getSwitchClusterId(2L)).
+        andReturn(1L).anyTimes();
+        expect(mockTopology.getSwitchClusterId(3L)).
+        andReturn(3L).anyTimes();
+        expect(mockTopology.getSwitchClusterId(4L)).
+        andReturn(3L).anyTimes();
         
         replay(mockTopology);
         
         deviceManager.topology = mockTopology;
         
-        Entity entity1 = new Entity(1L, null, 1, 1L, 1, new Date());
-        Entity entity2 = new Entity(1L, null, null, 2L, 1, new Date());
-        Entity entity3 = new Entity(1L, null, null, 3L, 1, new Date());
-        Entity entity4 = new Entity(1L, null, null, 4L, 1, new Date());
+        Calendar c = Calendar.getInstance();
+        Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
+        c.add(1,Calendar.SECOND);
+        Entity entity2 = new Entity(1L, null, null, 2L, 1, c.getTime());
+        c.add(1,Calendar.SECOND);
+        Entity entity3 = new Entity(1L, null, null, 3L, 1, c.getTime());
+        c.add(1,Calendar.SECOND);
+        Entity entity4 = new Entity(1L, null, null, 4L, 1, c.getTime());
         
         IDevice d;
         SwitchPort[] aps;
@@ -316,8 +319,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         d = deviceManager.learnDeviceByEntity(entity3);
         assertEquals(1, deviceManager.getAllDevices().size());
         aps = d.getAttachmentPoints(); 
-        assertArrayEquals(new SwitchPort[] { new SwitchPort(3L, 1),
-                                             new SwitchPort(2L, 1) }, aps);
+        assertArrayEquals(new SwitchPort[] { new SwitchPort(2L, 1),
+                                             new SwitchPort(3L, 1) }, aps);
         ips = d.getIPv4Addresses();
         assertArrayEquals(new Integer[] { 1 }, ips);
         verify(mockListener);
@@ -339,7 +342,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
     @Test
     public void testPacketIn() throws Exception {
         deviceManager.addIndex(true, true, EnumSet.of(DeviceField.IPV4));
-        byte[] dataLayerSource = ((Ethernet)this.testPacket).getSourceMACAddress();
+        byte[] dataLayerSource = 
+                ((Ethernet)this.testPacket).getSourceMACAddress();
 
         // Mock up our expected behavior
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
@@ -356,7 +360,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         // build our expected Device
         Integer ipaddr = IPv4.toIPv4Address("192.168.1.1");
         Device device = 
-                new Device(new Long(deviceManager.deviceKeyCounter),
+                new Device(deviceManager,
+                           new Long(deviceManager.deviceKeyCounter),
                            new Entity(Ethernet.toLong(dataLayerSource),
                                       (short)5,
                                       ipaddr,
@@ -392,7 +397,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         assertEquals(device, result);
         
         device = 
-                new Device(new Long(deviceManager.deviceKeyCounter),
+                new Device(device,
                            new Entity(Ethernet.toLong(dataLayerSource),
                                       (short)5,
                                       ipaddr,
@@ -406,7 +411,8 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         expect(mockSwitch.getStringId()).
             andReturn("00:00:00:00:00:00:00:02").anyTimes();
         expect(mockTopology.isInternal(2L, (short)2)).andReturn(false);
-        expect(mockTopology.inSameCluster(1L, 2L)).andReturn(true);
+        expect(mockTopology.getSwitchClusterId(1L)).andReturn(1L).anyTimes();
+        expect(mockTopology.getSwitchClusterId(2L)).andReturn(1L).anyTimes();
         
         // Start recording the replay on the mocks
         replay(mockSwitch, mockTopology);
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
index d2fbf581b9d056fbf442406f6a89f9199f6723ea..aacef4e102d6fcf4f1b58a26585890bfdf0256ab 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
@@ -1,6 +1,10 @@
 package net.floodlightcontroller.devicemanager.test;
 
+import java.util.Collections;
+import java.util.Set;
+
 import net.floodlightcontroller.devicemanager.IDevice;
+import net.floodlightcontroller.devicemanager.IDeviceManagerAware;
 import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl;
 import net.floodlightcontroller.devicemanager.internal.Entity;
 
@@ -16,17 +20,43 @@ public class MockDeviceManager extends DeviceManagerImpl {
      * @param ipv4Address the IP (can be null)
      * @param switchDPID the attachment point switch DPID (can be null)
      * @param switchPort the attachment point switch port (can be null)
+     * @param processUpdates if false, will not send updates.  Note that this 
+     * method is not thread safe if this is false
      * @return the device, either new or not
      */
     public IDevice learnEntity(long macAddress, Short vlan, 
                                Integer ipv4Address, Long switchDPID, 
-                               Integer switchPort) {
+                               Integer switchPort,
+                               boolean processUpdates) {
+        Set<IDeviceManagerAware> listeners = deviceListeners;
+        if (!processUpdates) {
+            deviceListeners = Collections.<IDeviceManagerAware>emptySet();
+        }
+        
         if (vlan != null && vlan.shortValue() <= 0)
             vlan = null;
         if (ipv4Address != null && ipv4Address == 0)
             ipv4Address = null;
-        return learnDeviceByEntity(new Entity(macAddress, vlan, 
-                                              ipv4Address, switchDPID, 
-                                              switchPort, null));
+        IDevice res =  learnDeviceByEntity(new Entity(macAddress, vlan, 
+                                                      ipv4Address, switchDPID, 
+                                                      switchPort, null));
+        deviceListeners = listeners;
+        return res;
+    }
+    
+    /**
+     * Learn a device using the given characteristics. 
+     * @param macAddress the MAC
+     * @param vlan the VLAN (can be null)
+     * @param ipv4Address the IP (can be null)
+     * @param switchDPID the attachment point switch DPID (can be null)
+     * @param switchPort the attachment point switch port (can be null)
+     * @return the device, either new or not
+     */
+    public IDevice learnEntity(long macAddress, Short vlan, 
+                               Integer ipv4Address, Long switchDPID, 
+                               Integer switchPort) {
+        return learnEntity(macAddress, vlan, ipv4Address, 
+                           switchDPID, switchPort, true);
     }
 }
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index 9b96785b98ceb828423a0ccbcb7d906467a6e284..7e4278eaa0ce6a8671fdf311513c8875e2ac7489 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -33,13 +33,13 @@ import java.util.Map;
 import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.internal.Device;
-import net.floodlightcontroller.devicemanager.internal.Entity;
+import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
 import net.floodlightcontroller.counter.CounterStore;
+import net.floodlightcontroller.counter.ICounterStoreService;
+import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceManagerService;
-import net.floodlightcontroller.linkdiscovery.SwitchPortTuple;
 import net.floodlightcontroller.packet.Data;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPacket;
@@ -69,12 +69,12 @@ import org.openflow.protocol.action.OFActionOutput;
 public class ForwardingTest extends FloodlightTestCase {
     protected MockFloodlightProvider mockFloodlightProvider;
     protected FloodlightContext cntx;
-    protected IDeviceManagerService deviceManager;
+    protected MockDeviceManager deviceManager;
     protected IRoutingService routingEngine;
     protected Forwarding forwarding;
     protected ITopologyService topology;
     protected IOFSwitch sw1, sw2;
-    protected Device srcDevice, dstDevice1, dstDevice2;
+    protected IDevice srcDevice, dstDevice1, dstDevice2;
     protected OFPacketIn packetIn;
     protected OFPacketOut packetOut;
     protected IPacket testPacket;
@@ -90,15 +90,23 @@ public class ForwardingTest extends FloodlightTestCase {
         cntx = new FloodlightContext();
         mockFloodlightProvider = getMockFloodlightProvider();
         forwarding = getForwarding();
-        deviceManager = createMock(IDeviceManagerService.class);
+        deviceManager = new MockDeviceManager();
         routingEngine = createMock(IRoutingService.class);
         topology = createMock(ITopologyService.class);
-        forwarding.setFloodlightProvider(mockFloodlightProvider);
-        forwarding.setDeviceManager(deviceManager);
-        forwarding.setRoutingEngine(routingEngine);
-        forwarding.setTopology(topology);
-        forwarding.setCounterStore(new CounterStore());
 
+        FloodlightModuleContext fmc = new FloodlightModuleContext();
+        fmc.addService(IFloodlightProviderService.class, 
+                       mockFloodlightProvider);
+        fmc.addService(ITopologyService.class, topology);
+        fmc.addService(IRoutingService.class, routingEngine);
+        fmc.addService(ICounterStoreService.class, new CounterStore());
+        fmc.addService(IDeviceManagerService.class, deviceManager);
+
+        forwarding.init(fmc);
+        deviceManager.init(fmc);
+        deviceManager.startUp(fmc);
+        forwarding.startUp(fmc);
+        
         // Mock switches
         sw1 = EasyMock.createNiceMock(IOFSwitch.class);
         expect(sw1.getId()).andReturn(1L).anyTimes();
@@ -157,29 +165,14 @@ public class ForwardingTest extends FloodlightTestCase {
                     getDestinationAddress();
 
         currentDate = new Date();
-        Entity e = new Entity(Ethernet.toLong(dataLayerSource),
-                              null,
-                              networkSource,
-                              1L,
-                              1,
-                              currentDate);
-        srcDevice = new Device(0L, e, DefaultEntityClassifier.entityClasses);
-
-        e = new Entity(Ethernet.toLong(dataLayerDest),
-                       null,
-                       networkDest,
-                       2L,
-                       3,
-                       currentDate);
-        dstDevice1 = new Device(1L, e, DefaultEntityClassifier.entityClasses);
-
-        e = new Entity(Ethernet.toLong(dataLayerDest),
-                       null,
-                       networkDest,
-                       1L,
-                       3,
-                       currentDate);
-        dstDevice2 = new Device(2L, e, DefaultEntityClassifier.entityClasses);
+        srcDevice = 
+                deviceManager.learnEntity(Ethernet.toLong(dataLayerSource), 
+                                          null, networkSource,
+                                          1L, 1);
+        dstDevice1 = 
+                deviceManager.learnEntity(Ethernet.toLong(dataLayerDest), 
+                                          null, networkDest,
+                                          2L, 3);
         
         // Mock Packet-in
         testPacketSerialized = testPacket.serialize();
@@ -277,9 +270,9 @@ public class ForwardingTest extends FloodlightTestCase {
         expectLastCall().anyTimes(); 
 
         // Reset mocks, trigger the packet in, and validate results
-        replay(sw1, sw2, deviceManager, routingEngine, topology);
+        replay(sw1, sw2, routingEngine, topology);
         forwarding.receive(sw1, this.packetIn, cntx);
-        verify(sw1, sw2,deviceManager, routingEngine);
+        verify(sw1, sw2, routingEngine);
         
         assertTrue(wc1.hasCaptured());  // wc1 should get packetout + flowmod.
         assertTrue(wc2.hasCaptured());  // wc2 should be a flowmod.
@@ -301,6 +294,26 @@ public class ForwardingTest extends FloodlightTestCase {
     @Test
     public void testForwardSingleSwitchPath() throws Exception {        
         // Set destination as local and Mock route
+        byte[] dataLayerSource = ((Ethernet)testPacket).getSourceMACAddress();
+        byte[] dataLayerDest = 
+                ((Ethernet)testPacket).getDestinationMACAddress();
+        int networkSource =
+                ((IPv4)((Ethernet)testPacket).getPayload()).
+                    getSourceAddress();
+        int networkDest = 
+                ((IPv4)((Ethernet)testPacket).getPayload()).
+                    getDestinationAddress();
+        deviceManager.startUp(null);
+        
+        srcDevice = 
+                deviceManager.learnEntity(Ethernet.toLong(dataLayerSource), 
+                                          null, networkSource,
+                                          1L, 1);
+        dstDevice2 = 
+                deviceManager.learnEntity(Ethernet.toLong(dataLayerDest), 
+                                          null, networkDest,
+                                          1L, 3);
+        
         IDeviceManagerService.fcStore.
             put(cntx, 
                 IDeviceManagerService.CONTEXT_DST_DEVICE, 
@@ -331,9 +344,9 @@ public class ForwardingTest extends FloodlightTestCase {
         sw1.write(packetOut, cntx);
 
         // Reset mocks, trigger the packet in, and validate results
-        replay(sw1, sw2, deviceManager, routingEngine, topology);
+        replay(sw1, sw2, routingEngine, topology);
         forwarding.receive(sw1, this.packetIn, cntx);
-        verify(sw1, sw2, deviceManager, routingEngine);
+        verify(sw1, sw2, routingEngine);
     }
 
     @Test
@@ -344,9 +357,9 @@ public class ForwardingTest extends FloodlightTestCase {
                 
         // Reset mocks, trigger the packet in, and validate results
         expect(topology.isIncomingBroadcastAllowedOnSwitchPort(1L, (short)1)).andReturn(true).anyTimes();
-        replay(sw1, sw2, deviceManager, routingEngine, topology);
+        replay(sw1, sw2, routingEngine, topology);
         forwarding.receive(sw1, this.packetIn, cntx);
-        verify(sw1, sw2,deviceManager, routingEngine);
+        verify(sw1, sw2, routingEngine);
     }
 
 }