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();
+    }
 }
