@Test
public void testAttachmentPointFlapping() throws Exception {

	Calendar c = Calendar.getInstance();
	ITopologyService mockTopology = createMock(ITopologyService.class);
	expect(mockTopology.isAttachmentPointPort(DatapathId.of(anyLong()),
			OFPort.of(anyShort()))).andReturn(true).anyTimes();
	expect(mockTopology.isBroadcastDomainPort(DatapathId.of(anyLong()),
			OFPort.of(anyShort()))).
			andReturn(false).anyTimes();
	expect(mockTopology.isInSameBroadcastDomain(DatapathId.of(anyLong()), OFPort.of(anyShort()),
			DatapathId.of(anyLong()), OFPort.of(anyShort()))).andReturn(false).anyTimes();
	expect(mockTopology.getOpenflowDomainId(DatapathId.of(anyLong()))).
	andReturn(DatapathId.of(1L)).anyTimes();
	expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(1L), OFPort.of(1))).
	andReturn(true).anyTimes();
	expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
	andReturn(false).anyTimes();
	expect(mockTopology.isConsistent(DatapathId.of(1L), OFPort.of(1), DatapathId.of(10L), OFPort.of(1))).
	andReturn(false).anyTimes();
	expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(1), DatapathId.of(10L), OFPort.of(1))).
	andReturn(false).anyTimes();
	expect(mockTopology.isConsistent(DatapathId.of(10L), OFPort.of(1), DatapathId.of(1L), OFPort.of(1))).
	andReturn(false).anyTimes();
	expect(mockTopology.isConsistent(DatapathId.of(5L), OFPort.of(1), DatapathId.of(1L), OFPort.of(1))).
	andReturn(false).anyTimes();
	expect(mockTopology.isConsistent(DatapathId.of(10L), OFPort.of(1), DatapathId.of(5L), OFPort.of(1))).
	andReturn(false).anyTimes();
	Date topologyUpdateTime = new Date();
	expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
	anyTimes();
	replay(mockTopology);
	deviceManager.topology = mockTopology;
	/* All w/same activeSince stamp, c.getTime() */
	Entity entity1 = new Entity(MacAddress.of(1L), VlanVid.ZERO, IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(1L), OFPort.of(1), c.getTime());
	Entity entity1a = new Entity(MacAddress.of(1L), VlanVid.ZERO, IPv4Address.of(1), IPv6Address.NONE, DatapathId.of(1L), OFPort.of(1), c.getTime());
	Entity entity2 = new Entity(MacAddress.of(1L), VlanVid.ZERO, IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(5L), OFPort.of(1), c.getTime());
	Entity entity3 = new Entity(MacAddress.of(1L), VlanVid.ZERO, IPv4Address.NONE, IPv6Address.NONE, DatapathId.of(10L), OFPort.of(1), c.getTime());
	entity1.setLastSeenTimestamp(c.getTime()); /* same as activeSince */
	c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/2);
	entity1a.setLastSeenTimestamp(c.getTime()); /* halfway timed out for entity1 */
	c.add(Calendar.MILLISECOND, 1);
	entity2.setLastSeenTimestamp(c.getTime()); /* small increment; still below entity1 timeout */
	c.add(Calendar.MILLISECOND, 1);
	entity3.setLastSeenTimestamp(c.getTime()); /* small increment; still below entity1 timeout */
	IDevice d;
	d = deviceManager.learnDeviceByEntity(entity1);
	d = deviceManager.learnDeviceByEntity(entity1a);
	d = deviceManager.learnDeviceByEntity(entity2);
	d = deviceManager.learnDeviceByEntity(entity3);
	// all entities are active, so entity3 should win
	assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)) },
			d.getAttachmentPoints());
	assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)),},
			d.getAttachmentPoints(true));
	c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT/4);
	entity1.setLastSeenTimestamp(c.getTime()); /* entity1 now is 3/4 the way to a timeout, but still is active */
	d = deviceManager.learnDeviceByEntity(entity1); /* we're going back to an old AP here within its active window (the "flapping") */
	// all are still active; entity3 should still win
	assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)) },
			d.getAttachmentPoints());
	assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(10L), OFPort.of(1)),
			new SwitchPort(DatapathId.of(5L), OFPort.of(1),
					ErrorStatus.DUPLICATE_DEVICE),
					new SwitchPort(DatapathId.of(1L), OFPort.of(1),
							ErrorStatus.DUPLICATE_DEVICE) },
							d.getAttachmentPoints(true));
	c.add(Calendar.MILLISECOND, Entity.ACTIVITY_TIMEOUT+2000);
	entity1.setLastSeenTimestamp(c.getTime()); /* now "relearn" entity1 for a time beyond all others' timeouts; thus entity1 should be the only remaining AP */
	d = deviceManager.learnDeviceByEntity(entity1);
	assertEquals(entity1.getActiveSince(), entity1.getLastSeenTimestamp());
	// entity1 should now be the only active entity
	assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) },
			d.getAttachmentPoints());
	assertArrayEquals(new SwitchPort[] { new SwitchPort(DatapathId.of(1L), OFPort.of(1)) },
			d.getAttachmentPoints(true));
}