@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 = IPv4Address.of(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, null, null, null,
                           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));
}