diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c6c9c7329f3ea95204c744a4bd8ec16a2340ad19
--- /dev/null
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java
@@ -0,0 +1,167 @@
+/**
+*    Copyright 2012 Big Switch Networks, Inc. 
+* 
+*    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.floodlightcontroller.devicemanager.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Iterator;
+
+import org.junit.Test;
+import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
+import junit.framework.TestCase;
+
+/**
+ * 
+ * @author gregor
+ *
+ */
+public class DeviceUniqueIndexTest extends TestCase {
+    protected Entity e1a;
+    protected Entity e1b;
+    protected Device d1;
+    protected Entity e2;
+    protected Entity e2alt;
+    protected Entity e3;
+    protected Entity e4;
+    
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        e1a = new Entity(1L, (short)1, 1, 1L, 1, new Date());
+        e1b = new Entity(1L, (short)2, 1, 1L, 1, new Date());
+        List<Entity> d1Entities = new ArrayList<Entity>(2);
+        d1Entities.add(e1a);
+        d1Entities.add(e1b);
+        d1 = new Device(null, Long.valueOf(1), d1Entities, null);
+        
+        // e2 and e2 alt match in MAC and VLAN
+        e2 = new Entity(2L, (short)2, 2, 2L, 2, new Date());
+        e2alt = new Entity(2, (short)2, null, null, null, null);
+        
+        // IP is null
+        e3 = new Entity(3L, (short)3, null, 3L, 3, new Date());
+        
+        // IP and switch and port are null
+        e4 = new Entity(4L, (short)4, null, null, null, new Date());
+    }
+    
+    /*
+     * Checks that the iterator it returns the elements in the Set expected
+     * Doesn't check how often an element is returned as long it's at least
+     * once
+     */
+    protected void verifyIterator(Set<Long> expected, Iterator<Long> it) {
+        HashSet<Long> actual = new HashSet<Long>();
+        while (it.hasNext()) {
+            actual.add(it.next());
+        }
+        assertEquals(expected, actual);
+    }
+    
+    @Test
+    public void testDeviceUniqueIndex() {
+        DeviceUniqueIndex idx1 = new DeviceUniqueIndex(
+                                             EnumSet.of(DeviceField.MAC, 
+                                                        DeviceField.VLAN));
+        
+        idx1.updateIndex(d1, d1.getDeviceKey());
+        idx1.updateIndex(e2, 2L);
+        
+        //-------------
+        // Test findByEntity lookups
+        assertEquals(Long.valueOf(1L), idx1.findByEntity(e1a));
+        assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b));
+        assertEquals(Long.valueOf(2L), idx1.findByEntity(e2));
+        // we didn't add e2alt but since they key fields are the same we 
+        // should find it 
+        assertEquals(Long.valueOf(2L), idx1.findByEntity(e2alt));
+        assertEquals(null, idx1.findByEntity(e3));
+        assertEquals(null, idx1.findByEntity(e4));
+        
+        //-------------
+        // Test getAll()
+        HashSet<Long> expectedKeys = new HashSet<Long>();
+        expectedKeys.add(1L);
+        expectedKeys.add(2L);
+        verifyIterator(expectedKeys, idx1.getAll());
+        
+                
+        //-------------
+        // Test queryByEntity()
+        verifyIterator(Collections.<Long>singleton(1L), 
+                       idx1.queryByEntity(e1a));
+        verifyIterator(Collections.<Long>singleton(1L), 
+                       idx1.queryByEntity(e1b));
+        verifyIterator(Collections.<Long>singleton(2L), 
+                       idx1.queryByEntity(e2));
+        verifyIterator(Collections.<Long>singleton(2L),
+                       idx1.queryByEntity(e2alt));
+        assertEquals(false, idx1.queryByEntity(e3).hasNext());
+        assertEquals(false, idx1.queryByEntity(e3).hasNext());
+        
+        
+        //-------------
+        // Test removal
+        idx1.removeEntity(e1a, 42L); // No-op. e1a isn't mapped to this key
+        assertEquals(Long.valueOf(1L), idx1.findByEntity(e1a));
+        idx1.removeEntity(e1a, 1L); 
+        assertEquals(null, idx1.findByEntity(e1a));
+        assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b));
+        assertEquals(Long.valueOf(2L), idx1.findByEntity(e2));
+        idx1.removeEntity(e2);  
+        assertEquals(null, idx1.findByEntity(e2));
+        assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b));
+        
+        
+        //-------------
+        // Test null keys
+        DeviceUniqueIndex idx2 = new DeviceUniqueIndex(
+                                             EnumSet.of(DeviceField.IPV4,
+                                                        DeviceField.SWITCH));
+        // only one key field is null
+        idx2.updateIndex(e3, 3L);
+        assertEquals(Long.valueOf(3L), idx2.findByEntity(e3));
+        e3.ipv4Address = 3;
+        assertEquals(null, idx2.findByEntity(e3));
+        // all key fields are null
+        idx2.updateIndex(e4, 4L);
+        assertEquals(null, idx2.findByEntity(e4));
+        Device d4 = new Device(null, 4L, Collections.<Entity>singleton(e4), null);
+        idx2.updateIndex(d4, 4L);
+        assertEquals(null, idx2.findByEntity(e4));
+        
+        
+
+        //-------------
+        // entity already exists with different deviceKey
+        DeviceUniqueIndex idx3 = new DeviceUniqueIndex(
+                                             EnumSet.of(DeviceField.MAC, 
+                                                        DeviceField.VLAN));
+        idx3.updateIndex(e1a, 42L);
+        assertEquals(false, idx3.updateIndex(d1, 1L));
+        // TODO: shouldn't this fail as well so that the behavior
+        // is consistent?
+        idx3.updateIndex(e1a, 1L);
+        // anyways. We can now add d1 ;-)
+        assertEquals(true, idx3.updateIndex(d1, 1L));
+    }
+}