Added unit tests for ONOS-1451: Separate Event Key space per instance

* Added an unit test mechanism to give a collection of topology events
  to the TopologyManager, let the TopologyManger process the events,
  and deliver the result topology events to the listeners.

* Added an unit test mechanism to collect the delivered events from the
  TopologyManager

* Added an unit test for processing a Mastership Event, and collecting
  the expected event(s)

* Added an unit test for processing a Switch Event, and collecting
  the expected event(s)

* Added an unit test for processing a misordered Switch Event, and collecting
  the expected event(s)

* Added an unit test for processing a Switch Event with a Mastership Event
  from another ONOS instace, and collecting the expected event(s)

* Added an unit test for processing a Switch Event with a Mastership
  switchover between two ONOS instances, and collecting the expected event(s)

* Added unit tests for method TopologyManager.addMastershipEvent(),
  and for method TopologyManager.removeMastershipEvent()

* Minor cleanup

Change-Id: I1768209bb33ba62d7bb6bdffd4fd0fcc24bcbe6a
diff --git a/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
index c99768b..9856366 100644
--- a/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
+++ b/src/test/java/net/onrc/onos/core/topology/TopologyManagerTest.java
@@ -6,7 +6,9 @@
 import net.onrc.onos.core.datagrid.IEventChannel;
 import net.onrc.onos.core.datagrid.IEventChannelListener;
 import net.onrc.onos.core.registry.IControllerRegistryService;
+import net.onrc.onos.core.registry.RegistryException;
 import net.onrc.onos.core.util.Dpid;
+import net.onrc.onos.core.util.EventEntry;
 import net.onrc.onos.core.util.OnosInstanceId;
 import net.onrc.onos.core.util.PortNumber;
 import net.onrc.onos.core.util.SwitchPort;
@@ -18,6 +20,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -26,11 +29,15 @@
 import static org.easymock.EasyMock.eq;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
 import static org.easymock.EasyMock.verify;
 import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
@@ -45,6 +52,9 @@
  */
 public class TopologyManagerTest extends UnitTest {
     private TopologyManager theTopologyManager;
+    private TopologyManager.EventHandler theEventHandler;
+    private TopologyListenerTest theTopologyListener =
+        new TopologyListenerTest();
     private final String eventChannelName = "onos.topology";
     private IEventChannel<byte[], TopologyEvent> eventChannel;
     private IDatagridService datagridService;
@@ -52,8 +62,31 @@
     private IControllerRegistryService registryService;
     private CopyOnWriteArrayList<ITopologyListener> topologyListeners;
     private Collection<TopologyEvent> allTopologyEvents;
-    private OnosInstanceId onosInstanceId =
-        new OnosInstanceId("ONOS-Test-Instance-ID");
+    private static final OnosInstanceId ONOS_INSTANCE_ID_1 =
+        new OnosInstanceId("ONOS-Instance-ID-1");
+    private static final OnosInstanceId ONOS_INSTANCE_ID_2 =
+        new OnosInstanceId("ONOS-Instance-ID-2");
+    private static final Dpid DPID_1 = new Dpid(1);
+    private static final Dpid DPID_2 = new Dpid(2);
+
+    /**
+     * Topology events listener.
+     */
+    private class TopologyListenerTest implements ITopologyListener {
+        private TopologyEvents topologyEvents;
+
+        @Override
+        public void topologyEvents(TopologyEvents events) {
+            this.topologyEvents = events;
+        }
+
+        /**
+         * Clears the Topology Listener state.
+         */
+        public void clear() {
+            this.topologyEvents = null;
+        }
+    }
 
     @SuppressWarnings("unchecked")
     @Before
@@ -111,17 +144,30 @@
                 anyObject(LinkEvent.class)))
                 .andReturn(true).anyTimes();
 
-        expect(registryService.getOnosInstanceId()).andReturn(onosInstanceId).anyTimes();
-
-        replay(datagridService);
-        replay(registryService);
-        replay(dataStoreService);
+        // Setup the Registry Service
+        expect(registryService.getOnosInstanceId()).andReturn(ONOS_INSTANCE_ID_1).anyTimes();
+        try {
+            expect(registryService.getControllerForSwitch(DPID_1.value())).
+                andReturn(ONOS_INSTANCE_ID_1.toString()).anyTimes();
+            expect(registryService.getControllerForSwitch(DPID_2.value())).
+                andReturn(ONOS_INSTANCE_ID_2.toString()).anyTimes();
+        } catch (RegistryException ex) {
+            throw new IllegalStateException(ex);
+        }
 
         allTopologyEvents = new CopyOnWriteArrayList<>();
         expect(eventChannel.getAllEntries())
             .andReturn(allTopologyEvents).anyTimes();
+
+        replay(datagridService);
+        replay(registryService);
+        replay(dataStoreService);
+        // replay(eventChannel);
     }
 
+    /**
+     * Setup the Topology Manager.
+     */
     private void setupTopologyManager() {
         // Create a TopologyManager object for testing
         topologyListeners = new CopyOnWriteArrayList<>();
@@ -138,7 +184,33 @@
     }
 
     /**
-     * Test the Switch Mastership updated event.
+     * Setup the Topology Manager with the Event Handler.
+     */
+    private void setupTopologyManagerWithEventHandler() {
+        // Create a TopologyManager object for testing
+        topologyListeners = new CopyOnWriteArrayList<>();
+        topologyListeners.add(theTopologyListener);
+        theTopologyManager = new TopologyManager(registryService,
+                                                 topologyListeners);
+        // Allocate the Event Handler, so we can have direct access to it
+        theEventHandler = theTopologyManager.new EventHandler();
+        TestUtils.setField(theTopologyManager, "eventHandler",
+                           theEventHandler);
+
+        // Replace the data store with a mocked object
+        TestUtils.setField(theTopologyManager, "datastore", dataStoreService);
+
+        replay(eventChannel);
+        //
+        // NOTE: Uncomment-out the line below if the startup() method needs
+        // to be called for some of the unit tests. For now it is commented-out
+        // to avoid any side effects of starting the eventHandler thread.
+        //
+        // theTopologyManager.startup(datagridService);
+    }
+
+    /**
+     * Test the Switch Mastership Updated Event.
      */
     @Test
     public void testPutSwitchMastershipEvent() {
@@ -151,10 +223,9 @@
         setupTopologyManager();
 
         // Generate a new Switch Mastership event
-        Dpid dpid = new Dpid(100L);
         Role role = Role.MASTER;
         MastershipEvent mastershipEvent =
-            new MastershipEvent(dpid, this.onosInstanceId, role);
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
 
         // Call the topologyManager function for adding the event
         theTopologyManager.putSwitchMastershipEvent(mastershipEvent);
@@ -164,7 +235,7 @@
     }
 
     /**
-     * Test the Switch Mastership removed event.
+     * Test the Switch Mastership Removed Event.
      */
     @Test
     public void testRemoveSwitchMastershipEvent() {
@@ -175,11 +246,10 @@
 
         setupTopologyManager();
 
-        // Generate a new Switch Mastership event
-        Dpid dpid = new Dpid(100L);
+        // Generate a new Switch Mastership Event
         Role role = Role.MASTER;
         MastershipEvent mastershipEvent =
-            new MastershipEvent(dpid, this.onosInstanceId, role);
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
 
         // Call the topologyManager function for removing the event
         theTopologyManager.removeSwitchMastershipEvent(mastershipEvent);
@@ -196,26 +266,25 @@
         // Mock the eventChannel functions first
         eventChannel.addEntry(anyObject(byte[].class),
                               anyObject(TopologyEvent.class));
-        EasyMock.expectLastCall().times(3, 3);  // (1 switch + 1 port), 1 port
+        EasyMock.expectLastCall().times(3, 3);  // (1 Switch + 1 Port), 1 Port
         replay(eventChannel);
 
         setupTopologyManager();
 
-        // mockSwitch has one port
-        Dpid swDpid = new Dpid(100L);
+        // Mock Switch has one Port
         PortNumber portNumber = PortNumber.uint32(1);
 
         // Generate a new Switch Event along with a Port Event
-        SwitchEvent switchEvent = new SwitchEvent(swDpid);
+        SwitchEvent switchEvent = new SwitchEvent(DPID_1);
 
         Collection<PortEvent> portEvents = new ArrayList<PortEvent>();
-        portEvents.add(new PortEvent(swDpid, portNumber));
+        portEvents.add(new PortEvent(DPID_1, portNumber));
 
-        // Call the topologyManager function for adding a switch
+        // Call the topologyManager function for adding a Switch
         theTopologyManager.putSwitchDiscoveryEvent(switchEvent, portEvents);
 
         for (PortEvent portEvent : portEvents) {
-            // Call the topologyManager function for adding a port
+            // Call the topologyManager function for adding a Port
             theTopologyManager.putPortDiscoveryEvent(portEvent);
         }
 
@@ -225,31 +294,30 @@
     }
 
     /**
-     * Test the switch and port removed functions.
+     * Test the Switch and Port removed functions.
      */
     @Test
     public void testRemoveSwitchAndPortDiscoveryEvent() {
         // Mock the eventChannel functions first
         eventChannel.removeEntry(anyObject(byte[].class));
-        EasyMock.expectLastCall().times(2, 2);          // 1 switch, 1 port
+        EasyMock.expectLastCall().times(2, 2);          // 1 Switch, 1 Port
         replay(eventChannel);
 
         setupTopologyManager();
 
-        Dpid swDpid = new Dpid(100L);
         PortNumber portNumber = PortNumber.uint32(1);
 
         // Generate a Port Event
         Collection<PortEvent> portEvents = new ArrayList<PortEvent>();
-        portEvents.add(new PortEvent(swDpid, portNumber));
+        portEvents.add(new PortEvent(DPID_1, portNumber));
 
-        // Call the topologyManager function for removing a port
+        // Call the topologyManager function for removing a Port
         for (PortEvent portEvent : portEvents) {
             theTopologyManager.removePortDiscoveryEvent(portEvent);
         }
 
-        // Call the topologyManager function for removing a switch
-        SwitchEvent switchEvent = new SwitchEvent(swDpid);
+        // Call the topologyManager function for removing a Switch
+        SwitchEvent switchEvent = new SwitchEvent(DPID_1);
         theTopologyManager.removeSwitchDiscoveryEvent(switchEvent);
 
         // Verify the function calls
@@ -258,44 +326,40 @@
     }
 
     /**
-     * Test the link discovered function.
+     * Test the Link discovered function.
      */
     @Test
     public void testPutLinkDiscoveryEvent() {
         // Mock the eventChannel functions first
         eventChannel.addEntry(anyObject(byte[].class),
                               anyObject(TopologyEvent.class));
-        EasyMock.expectLastCall().times(5, 5);  // (2 switch + 2 port + 1 link)
+        EasyMock.expectLastCall().times(5, 5);  // (2 Switch + 2 Port + 1 Link)
         replay(eventChannel);
 
         setupTopologyManager();
 
-        // Assign the switch and port IDs
-        Dpid swDpid1 = new Dpid(100L);
+        // Generate the Switch and Port Events
         PortNumber portNumber1 = PortNumber.uint32(1);
-        Dpid swDpid2 = new Dpid(200L);
-        PortNumber portNumber2 = PortNumber.uint32(2);
-
-        // Generate the switch and port events
-        SwitchEvent switchEvent1 = new SwitchEvent(swDpid1);
+        SwitchEvent switchEvent1 = new SwitchEvent(DPID_1);
         Collection<PortEvent> portEvents1 = new ArrayList<PortEvent>();
-        portEvents1.add(new PortEvent(swDpid1, portNumber1));
+        portEvents1.add(new PortEvent(DPID_1, portNumber1));
 
-        // Call the topologyManager function for adding a switch
+        // Call the topologyManager function for adding a Switch
         theTopologyManager.putSwitchDiscoveryEvent(switchEvent1, portEvents1);
 
         // Generate the Switch and Port Events
-        SwitchEvent switchEvent2 = new SwitchEvent(swDpid2);
+        PortNumber portNumber2 = PortNumber.uint32(2);
+        SwitchEvent switchEvent2 = new SwitchEvent(DPID_2);
         Collection<PortEvent> portEvents2 = new ArrayList<PortEvent>();
-        portEvents2.add(new PortEvent(swDpid2, portNumber2));
+        portEvents2.add(new PortEvent(DPID_2, portNumber2));
 
-        // Call the topologyManager function for adding a switch
+        // Call the topologyManager function for adding a Switch
         theTopologyManager.putSwitchDiscoveryEvent(switchEvent2, portEvents2);
 
         // Create the Link Event
         LinkEvent linkEvent =
-            new LinkEvent(new SwitchPort(swDpid1, portNumber1),
-                          new SwitchPort(swDpid2, portNumber2));
+            new LinkEvent(new SwitchPort(DPID_1, portNumber1),
+                          new SwitchPort(DPID_2, portNumber2));
         theTopologyManager.putLinkDiscoveryEvent(linkEvent);
 
         // Verify the function calls
@@ -303,43 +367,39 @@
     }
 
     /**
-     * Test the link removed function.
+     * Test the Link removed function.
      */
     @Test
     public void testRemoveLinkDiscoveryEvent() {
         // Mock the eventChannel functions first
         eventChannel.removeEntry(anyObject(byte[].class));
-        EasyMock.expectLastCall().times(1, 1);          // (1 link)
+        EasyMock.expectLastCall().times(1, 1);          // (1 Link)
         replay(eventChannel);
 
         setupTopologyManager();
 
-        // Assign the switch and port IDs
-        Dpid swDpid1 = new Dpid(100L);
-        PortNumber portNumber1 = PortNumber.uint32(1);
-        Dpid swDpid2 = new Dpid(200L);
-        PortNumber portNumber2 = PortNumber.uint32(2);
-
         // Generate the Switch and Port Events
-        SwitchEvent switchEvent1 = new SwitchEvent(swDpid1);
+        PortNumber portNumber1 = PortNumber.uint32(1);
+        SwitchEvent switchEvent1 = new SwitchEvent(DPID_1);
         Collection<PortEvent> portEvents1 = new ArrayList<PortEvent>();
-        portEvents1.add(new PortEvent(swDpid1, portNumber1));
+        portEvents1.add(new PortEvent(DPID_1, portNumber1));
 
-        // Call the topologyManager function for adding a switch
+        // Call the topologyManager function for adding a Switch
         theTopologyManager.putSwitchDiscoveryEvent(switchEvent1, portEvents1);
 
-        // Generate the Switch and port Events
-        SwitchEvent switchEvent2 = new SwitchEvent(swDpid2);
+        // Generate the Switch and Port Events
+        PortNumber portNumber2 = PortNumber.uint32(2);
+        SwitchEvent switchEvent2 = new SwitchEvent(DPID_2);
         Collection<PortEvent> portEvents2 = new ArrayList<PortEvent>();
-        portEvents2.add(new PortEvent(swDpid2, portNumber2));
+        portEvents2.add(new PortEvent(DPID_2, portNumber2));
 
-        // Call the topologyManager function for adding a switch
+        // Call the topologyManager function for adding a Switch
         theTopologyManager.putSwitchDiscoveryEvent(switchEvent2, portEvents2);
 
-        // Remove the link
+        // Remove the Link
         LinkEvent linkEventRemove =
-            new LinkEvent(new SwitchPort(swDpid1, portNumber1),
-                          new SwitchPort(swDpid2, portNumber2));
+            new LinkEvent(new SwitchPort(DPID_1, portNumber1),
+                          new SwitchPort(DPID_2, portNumber2));
         theTopologyManager.removeLinkDiscoveryEvent(linkEventRemove);
 
         // Verify the function calls
@@ -347,30 +407,28 @@
     }
 
     /**
-     * Test the host discovered function.
+     * Test the Host discovered function.
      */
     @Test
     public void testPutHostDiscoveryEvent() {
         // Mock the eventChannel functions first
         eventChannel.addEntry(anyObject(byte[].class),
                               anyObject(TopologyEvent.class));
-        EasyMock.expectLastCall().times(1, 1);          // 1 host
+        EasyMock.expectLastCall().times(1, 1);          // 1 Host
         replay(eventChannel);
 
         setupTopologyManager();
 
-        Dpid swDpid = new Dpid(100L);
-        PortNumber portNumber = PortNumber.uint32(1);
-
         // Generate a new Host Event
+        PortNumber portNumber = PortNumber.uint32(1);
         MACAddress hostMac = MACAddress.valueOf("00:AA:11:BB:33:CC");
-        SwitchPort sp = new SwitchPort(swDpid, portNumber);
+        SwitchPort sp = new SwitchPort(DPID_1, portNumber);
         List<SwitchPort> spLists = new ArrayList<SwitchPort>();
         spLists.add(sp);
         HostEvent hostEvent = new HostEvent(hostMac);
         hostEvent.setAttachmentPoints(spLists);
 
-        // Call the topologyManager function for adding a host
+        // Call the topologyManager function for adding a Host
         theTopologyManager.putHostDiscoveryEvent(hostEvent);
 
         // Verify the function calls
@@ -378,29 +436,27 @@
     }
 
     /**
-     * Test the host removed function.
+     * Test the Host removed function.
      */
     @Test
     public void testRemoveHostDiscoveryEvent() {
         // Mock the eventChannel functions first
         eventChannel.removeEntry(anyObject(byte[].class));
-        EasyMock.expectLastCall().times(1, 1);          // 1 host
+        EasyMock.expectLastCall().times(1, 1);          // 1 Host
         replay(eventChannel);
 
         setupTopologyManager();
 
-        Dpid swDpid = new Dpid(100L);
-        PortNumber portNumber = PortNumber.uint32(1);
-
         // Generate a new Host Event
+        PortNumber portNumber = PortNumber.uint32(1);
         MACAddress hostMac = MACAddress.valueOf("00:AA:11:BB:33:CC");
-        SwitchPort sp = new SwitchPort(swDpid, portNumber);
+        SwitchPort sp = new SwitchPort(DPID_1, portNumber);
         List<SwitchPort> spLists = new ArrayList<SwitchPort>();
         spLists.add(sp);
         HostEvent hostEvent = new HostEvent(hostMac);
         hostEvent.setAttachmentPoints(spLists);
 
-        // Call the topologyManager function for removing a host
+        // Call the topologyManager function for removing a Host
         theTopologyManager.removeHostDiscoveryEvent(hostEvent);
 
         // Verify the function calls
@@ -408,14 +464,75 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests adding of a Switch Mastership event and the topology replica
+     * transformation.
+     */
+    @Test
+    public void testAddMastershipEvent() {
+        setupTopologyManager();
+
+        // Prepare the event
+        Role role = Role.MASTER;
+        MastershipEvent mastershipEvent =
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
+        // Add the event
+        TestUtils.callMethod(theTopologyManager, "addMastershipEvent",
+                             MastershipEvent.class, mastershipEvent);
+
+        //
+        // NOTE: The topology itself doesn't contain the Mastership Events,
+        // hence we don't check the topology.
+        //
+
+        // Check the events to be fired
+        List<MastershipEvent> apiAddedMastershipEvents
+            = TestUtils.getField(theTopologyManager,
+                                 "apiAddedMastershipEvents");
+        assertThat(apiAddedMastershipEvents, hasItem(mastershipEvent));
+    }
+
+    /**
+     * Tests removing of a Switch Mastership event and the topology replica
+     * transformation.
+     */
+    @Test
+    public void testRemoveMastershipEvent() {
+        setupTopologyManager();
+
+        // Prepare the event
+        Role role = Role.MASTER;
+        MastershipEvent mastershipEvent =
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
+        // Add the event
+        TestUtils.callMethod(theTopologyManager, "addMastershipEvent",
+                             MastershipEvent.class, mastershipEvent);
+
+        // Check the events to be fired
+        List<MastershipEvent> apiAddedMastershipEvents
+            = TestUtils.getField(theTopologyManager,
+                                 "apiAddedMastershipEvents");
+        assertThat(apiAddedMastershipEvents, hasItem(mastershipEvent));
+
+        // Remove the event
+        TestUtils.callMethod(theTopologyManager, "removeMastershipEvent",
+                             MastershipEvent.class,
+                             new MastershipEvent(mastershipEvent));
+
+        // Check the events to be fired
+        List<MastershipEvent> apiRemovedMastershipEvents
+            = TestUtils.getField(theTopologyManager,
+                                 "apiRemovedMastershipEvents");
+        assertThat(apiRemovedMastershipEvents, hasItem(mastershipEvent));
+    }
+
+    /**
+     * Tests adding of a Switch and the topology replica transformation.
      */
     @Test
     public void testAddSwitch() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         TestUtils.callMethod(theTopologyManager, "addSwitch",
@@ -424,7 +541,7 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
@@ -436,18 +553,17 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests adding of a Port and the topology replica transformation.
      */
     @Test
     public void testAddPort() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumber = PortNumber.uint32(2);
-        PortEvent port = new PortEvent(dpid, portNumber);
+        PortEvent port = new PortEvent(DPID_1, portNumber);
         port.createStringAttribute("fuzz", "buzz");
 
         TestUtils.callMethod(theTopologyManager, "addSwitch",
@@ -458,12 +574,12 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPort = new SwitchPort(dpid, portNumber);
+        final SwitchPort switchPort = new SwitchPort(DPID_1, portNumber);
         PortEvent portInTopo = topology.getPortEvent(switchPort);
         assertEquals(port, portInTopo);
         assertTrue(portInTopo.isFrozen());
@@ -476,18 +592,18 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests removing of a Port followed by removing of a Switch,
+     * and the topology replica transformation.
      */
     @Test
     public void testRemovePortThenSwitch() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumber = PortNumber.uint32(2);
-        PortEvent port = new PortEvent(dpid, portNumber);
+        PortEvent port = new PortEvent(DPID_1, portNumber);
         port.createStringAttribute("fuzz", "buzz");
 
         TestUtils.callMethod(theTopologyManager, "addSwitch",
@@ -498,12 +614,12 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPort = new SwitchPort(dpid, portNumber);
+        final SwitchPort switchPort = new SwitchPort(DPID_1, portNumber);
         PortEvent portInTopo = topology.getPortEvent(switchPort);
         assertEquals(port, portInTopo);
         assertTrue(portInTopo.isFrozen());
@@ -526,18 +642,18 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests removing of a Switch without removing of a Port,
+     * and the topology replica transformation.
      */
     @Test
     public void testRemoveSwitchWithoutPortRemoval() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumber = PortNumber.uint32(2);
-        PortEvent port = new PortEvent(dpid, portNumber);
+        PortEvent port = new PortEvent(DPID_1, portNumber);
         port.createStringAttribute("fuzz", "buzz");
 
         TestUtils.callMethod(theTopologyManager, "addSwitch",
@@ -548,12 +664,12 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPort = new SwitchPort(dpid, portNumber);
+        final SwitchPort switchPort = new SwitchPort(DPID_1, portNumber);
         PortEvent portInTopo = topology.getPortEvent(switchPort);
         assertEquals(port, portInTopo);
         assertTrue(portInTopo.isFrozen());
@@ -577,22 +693,21 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests adding of a Link and the topology replica transformation.
      */
     @Test
     public void testAddLink() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumberA = PortNumber.uint32(2);
-        PortEvent portA = new PortEvent(dpid, portNumberA);
+        PortEvent portA = new PortEvent(DPID_1, portNumberA);
         portA.createStringAttribute("fuzz", "buzz");
 
         final PortNumber portNumberB = PortNumber.uint32(3);
-        PortEvent portB = new PortEvent(dpid, portNumberB);
+        PortEvent portB = new PortEvent(DPID_1, portNumberB);
         portB.createStringAttribute("fizz", "buz");
 
         LinkEvent linkA = new LinkEvent(portA.getSwitchPort(),
@@ -618,18 +733,18 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPortA = new SwitchPort(dpid, portNumberA);
+        final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA);
         PortEvent portAInTopo = topology.getPortEvent(switchPortA);
         assertEquals(portA, portAInTopo);
         assertTrue(portAInTopo.isFrozen());
         assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
 
-        final SwitchPort switchPortB = new SwitchPort(dpid, portNumberB);
+        final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB);
         PortEvent portBInTopo = topology.getPortEvent(switchPortB);
         assertEquals(portB, portBInTopo);
         assertTrue(portBInTopo.isFrozen());
@@ -654,26 +769,26 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests removing of a Link without removing of a Host, and the topology
+     * replica transformation.
      */
     @Test
     public void testAddLinkKickingOffHost() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumberA = PortNumber.uint32(2);
-        PortEvent portA = new PortEvent(dpid, portNumberA);
+        PortEvent portA = new PortEvent(DPID_1, portNumberA);
         portA.createStringAttribute("fuzz", "buzz");
 
         final PortNumber portNumberB = PortNumber.uint32(3);
-        PortEvent portB = new PortEvent(dpid, portNumberB);
+        PortEvent portB = new PortEvent(DPID_1, portNumberB);
         portB.createStringAttribute("fizz", "buz");
 
         final PortNumber portNumberC = PortNumber.uint32(4);
-        PortEvent portC = new PortEvent(dpid, portNumberC);
+        PortEvent portC = new PortEvent(DPID_1, portNumberC);
         portC.createStringAttribute("fizz", "buz");
 
         final MACAddress macA = MACAddress.valueOf(666L);
@@ -720,18 +835,18 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPortA = new SwitchPort(dpid, portNumberA);
+        final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA);
         PortEvent portAInTopo = topology.getPortEvent(switchPortA);
         assertEquals(portA, portAInTopo);
         assertTrue(portAInTopo.isFrozen());
         assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
 
-        final SwitchPort switchPortB = new SwitchPort(dpid, portNumberB);
+        final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB);
         PortEvent portBInTopo = topology.getPortEvent(switchPortB);
         assertEquals(portB, portBInTopo);
         assertTrue(portBInTopo.isFrozen());
@@ -773,22 +888,21 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests removing of a Link and the topology replica transformation.
      */
     @Test
     public void testRemoveLink() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumberA = PortNumber.uint32(2);
-        PortEvent portA = new PortEvent(dpid, portNumberA);
+        PortEvent portA = new PortEvent(DPID_1, portNumberA);
         portA.createStringAttribute("fuzz", "buzz");
 
         final PortNumber portNumberB = PortNumber.uint32(3);
-        PortEvent portB = new PortEvent(dpid, portNumberB);
+        PortEvent portB = new PortEvent(DPID_1, portNumberB);
         portB.createStringAttribute("fizz", "buz");
 
         LinkEvent linkA = new LinkEvent(portA.getSwitchPort(),
@@ -814,18 +928,18 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPortA = new SwitchPort(dpid, portNumberA);
+        final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA);
         PortEvent portAInTopo = topology.getPortEvent(switchPortA);
         assertEquals(portA, portAInTopo);
         assertTrue(portAInTopo.isFrozen());
         assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
 
-        final SwitchPort switchPortB = new SwitchPort(dpid, portNumberB);
+        final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB);
         PortEvent portBInTopo = topology.getPortEvent(switchPortB);
         assertEquals(portB, portBInTopo);
         assertTrue(portBInTopo.isFrozen());
@@ -867,26 +981,26 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests adding of a Host without adding of a Link, and the topology
+     * replica transformation.
      */
     @Test
     public void testAddHostIgnoredByLink() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumberA = PortNumber.uint32(2);
-        PortEvent portA = new PortEvent(dpid, portNumberA);
+        PortEvent portA = new PortEvent(DPID_1, portNumberA);
         portA.createStringAttribute("fuzz", "buzz");
 
         final PortNumber portNumberB = PortNumber.uint32(3);
-        PortEvent portB = new PortEvent(dpid, portNumberB);
+        PortEvent portB = new PortEvent(DPID_1, portNumberB);
         portB.createStringAttribute("fizz", "buz");
 
         final PortNumber portNumberC = PortNumber.uint32(4);
-        PortEvent portC = new PortEvent(dpid, portNumberC);
+        PortEvent portC = new PortEvent(DPID_1, portNumberC);
         portC.createStringAttribute("fizz", "buz");
 
         LinkEvent linkA = new LinkEvent(portA.getSwitchPort(),
@@ -936,18 +1050,18 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPortA = new SwitchPort(dpid, portNumberA);
+        final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA);
         PortEvent portAInTopo = topology.getPortEvent(switchPortA);
         assertEquals(portA, portAInTopo);
         assertTrue(portAInTopo.isFrozen());
         assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
 
-        final SwitchPort switchPortB = new SwitchPort(dpid, portNumberB);
+        final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB);
         PortEvent portBInTopo = topology.getPortEvent(switchPortB);
         assertEquals(portB, portBInTopo);
         assertTrue(portBInTopo.isFrozen());
@@ -992,26 +1106,26 @@
     }
 
     /**
-     * Test to confirm topology replica transformation.
+     * Tests adding and moving of a Host, and the topology replica
+     * transformation.
      */
     @Test
     public void testAddHostMove() {
         setupTopologyManager();
 
-        final Dpid dpid = new Dpid(1);
-        SwitchEvent sw = new SwitchEvent(dpid);
+        SwitchEvent sw = new SwitchEvent(DPID_1);
         sw.createStringAttribute("foo", "bar");
 
         final PortNumber portNumberA = PortNumber.uint32(2);
-        PortEvent portA = new PortEvent(dpid, portNumberA);
+        PortEvent portA = new PortEvent(DPID_1, portNumberA);
         portA.createStringAttribute("fuzz", "buzz");
 
         final PortNumber portNumberB = PortNumber.uint32(3);
-        PortEvent portB = new PortEvent(dpid, portNumberB);
+        PortEvent portB = new PortEvent(DPID_1, portNumberB);
         portB.createStringAttribute("fizz", "buz");
 
         final PortNumber portNumberC = PortNumber.uint32(4);
-        PortEvent portC = new PortEvent(dpid, portNumberC);
+        PortEvent portC = new PortEvent(DPID_1, portNumberC);
         portC.createStringAttribute("fizz", "buz");
 
         TestUtils.callMethod(theTopologyManager, "addSwitch",
@@ -1023,7 +1137,7 @@
         TestUtils.callMethod(theTopologyManager, "addPort",
                              PortEvent.class, portC);
 
-        // Add hostA attached to a port which already has a link
+        // Add hostA attached to a Port which already has a Link
         final MACAddress macA = MACAddress.valueOf(666L);
         HostEvent hostA = new HostEvent(macA);
         hostA.addAttachmentPoint(portA.getSwitchPort());
@@ -1037,18 +1151,18 @@
         // Check the topology structure
         TopologyInternal topology =
             (TopologyInternal) theTopologyManager.getTopology();
-        SwitchEvent swInTopo = topology.getSwitchEvent(dpid);
+        SwitchEvent swInTopo = topology.getSwitchEvent(DPID_1);
         assertEquals(sw, swInTopo);
         assertTrue(swInTopo.isFrozen());
         assertEquals("bar", swInTopo.getStringAttribute("foo"));
 
-        final SwitchPort switchPortA = new SwitchPort(dpid, portNumberA);
+        final SwitchPort switchPortA = new SwitchPort(DPID_1, portNumberA);
         PortEvent portAInTopo = topology.getPortEvent(switchPortA);
         assertEquals(portA, portAInTopo);
         assertTrue(portAInTopo.isFrozen());
         assertEquals("buzz", portAInTopo.getStringAttribute("fuzz"));
 
-        final SwitchPort switchPortB = new SwitchPort(dpid, portNumberB);
+        final SwitchPort switchPortB = new SwitchPort(DPID_1, portNumberB);
         PortEvent portBInTopo = topology.getPortEvent(switchPortB);
         assertEquals(portB, portBInTopo);
         assertTrue(portBInTopo.isFrozen());
@@ -1066,7 +1180,7 @@
         assertThat(apiAddedHostEvents, hasItem(hostA));
 
 
-        // Clear the events before moving the host
+        // Clear the events before moving the Host
         apiAddedHostEvents.clear();
 
         HostEvent hostAmoved = new HostEvent(macA);
@@ -1091,4 +1205,350 @@
             = TestUtils.getField(theTopologyManager, "apiRemovedHostEvents");
         assertThat(apiRemovedHostEvents, not(hasItem(hostA)));
     }
+
+    /**
+     * Tests processing of a Switch Mastership Event and the delivery of the
+     * topology events.
+     */
+    @Test
+    public void testProcessMastershipEvent() {
+        List<EventEntry<TopologyEvent>> events = new LinkedList<>();
+        EventEntry<TopologyEvent> eventEntry;
+        TopologyEvent topologyEvent;
+
+        setupTopologyManagerWithEventHandler();
+
+        // Prepare the Mastership Event
+        Role role = Role.MASTER;
+        MastershipEvent mastershipEvent =
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
+        topologyEvent = new TopologyEvent(mastershipEvent, ONOS_INSTANCE_ID_1);
+
+        // Add the Mastership Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologyEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events
+        TopologyEvents topologyEvents = theTopologyListener.topologyEvents;
+        assertNotNull(topologyEvents);
+        assertThat(topologyEvents.getAddedMastershipEvents(),
+                   hasItem(mastershipEvent));
+        theTopologyListener.clear();
+    }
+
+    /**
+     * Tests processing of a Switch Event, and the delivery of the topology
+     * events.
+     *
+     * We test the following scenario:
+     * - Switch Mastership Event is processed along with a Switch Event - both
+     *   events should be delivered.
+     */
+    @Test
+    public void testProcessSwitchEvent() {
+        TopologyEvents topologyEvents;
+        List<EventEntry<TopologyEvent>> events = new LinkedList<>();
+        EventEntry<TopologyEvent> eventEntry;
+        TopologyEvent topologyMastershipEvent;
+        TopologyEvent topologySwitchEvent;
+
+        setupTopologyManagerWithEventHandler();
+
+        // Prepare the Mastership Event
+        Role role = Role.MASTER;
+        MastershipEvent mastershipEvent =
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
+        topologyMastershipEvent = new TopologyEvent(mastershipEvent,
+                                                    ONOS_INSTANCE_ID_1);
+
+        // Prepare the Switch Event
+        SwitchEvent switchEvent = new SwitchEvent(DPID_1);
+        topologySwitchEvent = new TopologyEvent(switchEvent,
+                                                ONOS_INSTANCE_ID_1);
+
+        // Add the Mastership Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologyMastershipEvent);
+        events.add(eventEntry);
+
+        // Add the Switch Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologySwitchEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNotNull(topologyEvents);
+        assertThat(topologyEvents.getAddedMastershipEvents(),
+                   hasItem(mastershipEvent));
+        assertThat(topologyEvents.getAddedSwitchEvents(),
+                   hasItem(switchEvent));
+        theTopologyListener.clear();
+    }
+
+    /**
+     * Tests processing of a misordered Switch Event, and the delivery of the
+     * topology events.
+     *
+     * We test the following scenario:
+     * - Only a Switch Event is processed first, later followed by a Switch
+     *   Mastership Event - the Switch Event should be delivered after the
+     *   Switch Mastership Event is processed.
+     */
+    @Test
+    public void testProcessMisorderedSwitchEvent() {
+        TopologyEvents topologyEvents;
+        List<EventEntry<TopologyEvent>> events = new LinkedList<>();
+        EventEntry<TopologyEvent> eventEntry;
+        TopologyEvent topologyMastershipEvent;
+        TopologyEvent topologySwitchEvent;
+
+        setupTopologyManagerWithEventHandler();
+
+        // Prepare the Mastership Event
+        Role role = Role.MASTER;
+        MastershipEvent mastershipEvent =
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
+        topologyMastershipEvent = new TopologyEvent(mastershipEvent,
+                                                    ONOS_INSTANCE_ID_1);
+
+        // Prepare the Switch Event
+        SwitchEvent switchEvent = new SwitchEvent(DPID_1);
+        topologySwitchEvent = new TopologyEvent(switchEvent,
+                                                ONOS_INSTANCE_ID_1);
+
+        // Add the Switch Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologySwitchEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events: no events should be fired
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNull(topologyEvents);
+        theTopologyListener.clear();
+        events.clear();
+
+        // Add the Mastership Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologyMastershipEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events: both events should be fired
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNotNull(topologyEvents);
+        assertThat(topologyEvents.getAddedMastershipEvents(),
+                   hasItem(mastershipEvent));
+        assertThat(topologyEvents.getAddedSwitchEvents(),
+                   hasItem(switchEvent));
+        theTopologyListener.clear();
+    }
+
+    /**
+     * Tests processing of a Switch Event with Mastership Event from
+     * another ONOS instance, and the delivery of the topology events.
+     *
+     * We test the following scenario:
+     * - Only a Switch Event is processed first, later followed by a Switch
+     *   Mastership Event from another ONOS instance - only the Switch
+     *   Mastership Event should be delivered.
+     */
+    @Test
+    public void testProcessSwitchEventNoMastership() {
+        TopologyEvents topologyEvents;
+        List<EventEntry<TopologyEvent>> events = new LinkedList<>();
+        EventEntry<TopologyEvent> eventEntry;
+        TopologyEvent topologyMastershipEvent;
+        TopologyEvent topologySwitchEvent;
+
+        setupTopologyManagerWithEventHandler();
+
+        // Prepare the Mastership Event
+        Role role = Role.MASTER;
+        MastershipEvent mastershipEvent =
+            new MastershipEvent(DPID_2, ONOS_INSTANCE_ID_2, role);
+        topologyMastershipEvent = new TopologyEvent(mastershipEvent,
+                                                    ONOS_INSTANCE_ID_2);
+
+        // Prepare the Switch Event
+        // NOTE: The originator (ONOS_INSTANCE_ID_1) is NOT the Master
+        SwitchEvent switchEvent = new SwitchEvent(DPID_2);
+        topologySwitchEvent = new TopologyEvent(switchEvent,
+                                                ONOS_INSTANCE_ID_1);
+
+        // Add the Switch Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologySwitchEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events: no events should be fired
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNull(topologyEvents);
+        theTopologyListener.clear();
+        events.clear();
+
+        // Add the Mastership Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologyMastershipEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events: only the Mastership event should be fired
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNotNull(topologyEvents);
+        assertThat(topologyEvents.getAddedMastershipEvents(),
+                   hasItem(mastershipEvent));
+        assertThat(topologyEvents.getAddedSwitchEvents(), is(empty()));
+        theTopologyListener.clear();
+    }
+
+    /**
+     * Tests processing of Switch Events with Mastership switchover between
+     * two ONOS instance, and the delivery of the topology events.
+     *
+     * We test the following scenario:
+     * - Initially, a Mastership Event and a Switch Event from one ONOS
+     *   instance are processed - both events should be delivered.
+     * - Later, a Mastership Event and a Switch event from another ONOS
+     *   instances are processed - both events should be delivered.
+     * - Finally, a REMOVE Switch Event is received from the first ONOS
+     *   instance - no event should be delivered.
+     */
+    @Test
+    public void testProcessSwitchMastershipSwitchover() {
+        TopologyEvents topologyEvents;
+        List<EventEntry<TopologyEvent>> events = new LinkedList<>();
+        EventEntry<TopologyEvent> eventEntry;
+        TopologyEvent topologyMastershipEvent;
+        TopologyEvent topologySwitchEvent;
+
+        setupTopologyManagerWithEventHandler();
+
+        // Prepare the Mastership Event from the first ONOS instance
+        Role role = Role.MASTER;
+        MastershipEvent mastershipEvent =
+            new MastershipEvent(DPID_1, ONOS_INSTANCE_ID_1, role);
+        topologyMastershipEvent = new TopologyEvent(mastershipEvent,
+                                                    ONOS_INSTANCE_ID_1);
+
+        // Prepare the Switch Event from the first ONOS instance
+        SwitchEvent switchEvent = new SwitchEvent(DPID_1);
+        topologySwitchEvent = new TopologyEvent(switchEvent,
+                                                ONOS_INSTANCE_ID_1);
+
+        // Add the Mastership Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologyMastershipEvent);
+        events.add(eventEntry);
+
+        // Add the Switch Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologySwitchEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events: both events should be fired
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNotNull(topologyEvents);
+        assertThat(topologyEvents.getAddedMastershipEvents(),
+                   hasItem(mastershipEvent));
+        assertThat(topologyEvents.getAddedSwitchEvents(),
+                   hasItem(switchEvent));
+        theTopologyListener.clear();
+        events.clear();
+
+        //
+        // Update the Registry Service, so the second ONOS instance is the
+        // Master.
+        //
+        reset(registryService);
+        try {
+            expect(registryService.getControllerForSwitch(DPID_1.value())).
+                andReturn(ONOS_INSTANCE_ID_2.toString()).anyTimes();
+        } catch (RegistryException ex) {
+            throw new IllegalStateException(ex);
+        }
+        replay(registryService);
+
+        // Prepare the Mastership Event from the second ONOS instance
+        role = Role.MASTER;
+        mastershipEvent = new MastershipEvent(DPID_1,
+                                              ONOS_INSTANCE_ID_2, role);
+        topologyMastershipEvent = new TopologyEvent(mastershipEvent,
+                                                    ONOS_INSTANCE_ID_2);
+
+        // Prepare the Switch Event from second ONOS instance
+        switchEvent = new SwitchEvent(DPID_1);
+        topologySwitchEvent = new TopologyEvent(switchEvent,
+                                                ONOS_INSTANCE_ID_2);
+
+        // Add the Mastership Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologyMastershipEvent);
+        events.add(eventEntry);
+
+        // Add the Switch Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                                   topologySwitchEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events: both events should be fired
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNotNull(topologyEvents);
+        assertThat(topologyEvents.getAddedMastershipEvents(),
+                   hasItem(mastershipEvent));
+        assertThat(topologyEvents.getAddedSwitchEvents(),
+                   hasItem(switchEvent));
+        theTopologyListener.clear();
+        events.clear();
+
+        // Prepare the REMOVE Switch Event from first ONOS instance
+        switchEvent = new SwitchEvent(DPID_1);
+        topologySwitchEvent = new TopologyEvent(switchEvent,
+                                                ONOS_INSTANCE_ID_1);
+        // Add the Switch Event
+        eventEntry = new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
+                                                   topologySwitchEvent);
+        events.add(eventEntry);
+
+        // Process the events
+        TestUtils.callMethod(theEventHandler, "processEvents",
+                             List.class, events);
+
+        // Check the fired events: no events should be fired
+        topologyEvents = theTopologyListener.topologyEvents;
+        assertNull(topologyEvents);
+        theTopologyListener.clear();
+        events.clear();
+    }
 }