diff --git a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
index b12eaae..4788641 100644
--- a/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
+++ b/src/main/java/net/onrc/onos/core/topology/TopologyManager.java
@@ -29,22 +29,21 @@
 
 /**
  * The "NB" read-only Network Map.
- *
+ * <p/>
  * - Maintain Invariant/Relationships between Topology Objects.
- *
+ * <p/>
  * TODO To be synchronized based on TopologyEvent Notification.
- *
+ * <p/>
  * TODO TBD: Caller is expected to maintain parent/child calling order. Parent
  * Object must exist before adding sub component(Add Switch -> Port).
- *
+ * <p/>
  * TODO TBD: This class may delay the requested change to handle event
  * re-ordering. e.g.) Link Add came in, but Switch was not there.
- *
  */
 public class TopologyManager implements NetworkGraphDiscoveryInterface {
 
     private static final Logger log = LoggerFactory
-	    .getLogger(TopologyManager.class);
+            .getLogger(TopologyManager.class);
 
     private IEventChannel<byte[], TopologyEvent> eventChannel;
     public static final String EVENT_CHANNEL_NAME = "onos.topology";
@@ -60,11 +59,11 @@
     // NOTE: Switch Events are not affected by the event reordering.
     //
     private Map<ByteBuffer, PortEvent> reorderedAddedPortEvents =
-	new HashMap<ByteBuffer, PortEvent>();
+            new HashMap<ByteBuffer, PortEvent>();
     private Map<ByteBuffer, LinkEvent> reorderedAddedLinkEvents =
-	new HashMap<ByteBuffer, LinkEvent>();
+            new HashMap<ByteBuffer, LinkEvent>();
     private Map<ByteBuffer, DeviceEvent> reorderedAddedDeviceEvents =
-	new HashMap<ByteBuffer, DeviceEvent>();
+            new HashMap<ByteBuffer, DeviceEvent>();
 
     //
     // Local state for keeping track of locally discovered events so we can
@@ -77,11 +76,11 @@
     //    and Device events.
     //
     private Map<Long, Map<ByteBuffer, PortEvent>> discoveredAddedPortEvents =
-	new HashMap<>();
+            new HashMap<>();
     private Map<Long, Map<ByteBuffer, LinkEvent>> discoveredAddedLinkEvents =
-	new HashMap<>();
+            new HashMap<>();
     private Map<Long, Map<ByteBuffer, DeviceEvent>> discoveredAddedDeviceEvents =
-	new HashMap<>();
+            new HashMap<>();
 
     //
     // Local state for keeping track of the application event notifications
@@ -98,15 +97,15 @@
     /**
      * Constructor.
      *
-     * @param registryService the Registry Service to use.
+     * @param registryService       the Registry Service to use.
      * @param networkGraphListeners the collection of Network Graph Listeners
-     * to use.
+     *                              to use.
      */
     public TopologyManager(IControllerRegistryService registryService,
-			   CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners) {
-	datastore = new NetworkGraphDatastore();
-	this.registryService = registryService;
-	this.networkGraphListeners = networkGraphListeners;
+                           CopyOnWriteArrayList<INetworkGraphListener> networkGraphListeners) {
+        datastore = new NetworkGraphDatastore();
+        this.registryService = registryService;
+        this.networkGraphListeners = networkGraphListeners;
     }
 
     /**
@@ -115,247 +114,246 @@
      * @return the Network Graph.
      */
     NetworkGraph getNetworkGraph() {
-	return networkGraph;
+        return networkGraph;
     }
 
     /**
      * Event handler class.
      */
     private class EventHandler extends Thread implements
-	IEventChannelListener<byte[], TopologyEvent> {
-	private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
-	    new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
+            IEventChannelListener<byte[], TopologyEvent> {
+        private BlockingQueue<EventEntry<TopologyEvent>> topologyEvents =
+                new LinkedBlockingQueue<EventEntry<TopologyEvent>>();
 
-	/**
-	 * Startup processing.
-	 */
-	private void startup() {
-	    //
-	    // TODO: Read all state from the database:
-	    //
-	    // Collection<EventEntry<TopologyEvent>> collection =
-	    //    readWholeTopologyFromDB();
-	    //
-	    // For now, as a shortcut we read it from the datagrid
-	    //
-	    Collection<TopologyEvent> topologyEvents =
-		eventChannel.getAllEntries();
-	    Collection<EventEntry<TopologyEvent>> collection =
-		new LinkedList<EventEntry<TopologyEvent>>();
+        /**
+         * Startup processing.
+         */
+        private void startup() {
+            //
+            // TODO: Read all state from the database:
+            //
+            // Collection<EventEntry<TopologyEvent>> collection =
+            //    readWholeTopologyFromDB();
+            //
+            // For now, as a shortcut we read it from the datagrid
+            //
+            Collection<TopologyEvent> topologyEvents =
+                    eventChannel.getAllEntries();
+            Collection<EventEntry<TopologyEvent>> collection =
+                    new LinkedList<EventEntry<TopologyEvent>>();
 
-	    for (TopologyEvent topologyEvent : topologyEvents) {
-		EventEntry<TopologyEvent> eventEntry =
-		    new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
-						  topologyEvent);
-		collection.add(eventEntry);
-	    }
-	    processEvents(collection);
-	}
+            for (TopologyEvent topologyEvent : topologyEvents) {
+                EventEntry<TopologyEvent> eventEntry =
+                        new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                                topologyEvent);
+                collection.add(eventEntry);
+            }
+            processEvents(collection);
+        }
 
-	/**
-	 * Run the thread.
-	 */
-	@Override
-	public void run() {
-	    Collection<EventEntry<TopologyEvent>> collection =
-		new LinkedList<EventEntry<TopologyEvent>>();
+        /**
+         * Run the thread.
+         */
+        @Override
+        public void run() {
+            Collection<EventEntry<TopologyEvent>> collection =
+                    new LinkedList<EventEntry<TopologyEvent>>();
 
-	    this.setName("TopologyManager.EventHandler " + this.getId());
-	    startup();
+            this.setName("TopologyManager.EventHandler " + this.getId());
+            startup();
 
-	    //
-	    // The main loop
-	    //
-	    try {
-		while (true) {
-		    EventEntry<TopologyEvent> eventEntry = topologyEvents.take();
-		    collection.add(eventEntry);
-		    topologyEvents.drainTo(collection);
+            //
+            // The main loop
+            //
+            try {
+                while (true) {
+                    EventEntry<TopologyEvent> eventEntry = topologyEvents.take();
+                    collection.add(eventEntry);
+                    topologyEvents.drainTo(collection);
 
-		    processEvents(collection);
-		    collection.clear();
-		}
-	    } catch (Exception exception) {
-		log.debug("Exception processing Topology Events: ", exception);
-	    }
-	}
+                    processEvents(collection);
+                    collection.clear();
+                }
+            } catch (Exception exception) {
+                log.debug("Exception processing Topology Events: ", exception);
+            }
+        }
 
-	/**
-	 * Process all topology events.
-	 *
-	 * @param events the events to process.
-	 */
-	private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
-	    // Local state for computing the final set of events
-	    Map<ByteBuffer, SwitchEvent> addedSwitchEvents = new HashMap<>();
-	    Map<ByteBuffer, SwitchEvent> removedSwitchEvents = new HashMap<>();
-	    Map<ByteBuffer, PortEvent> addedPortEvents = new HashMap<>();
-	    Map<ByteBuffer, PortEvent> removedPortEvents = new HashMap<>();
-	    Map<ByteBuffer, LinkEvent> addedLinkEvents = new HashMap<>();
-	    Map<ByteBuffer, LinkEvent> removedLinkEvents = new HashMap<>();
-	    Map<ByteBuffer, DeviceEvent> addedDeviceEvents = new HashMap<>();
-	    Map<ByteBuffer, DeviceEvent> removedDeviceEvents = new HashMap<>();
+        /**
+         * Process all topology events.
+         *
+         * @param events the events to process.
+         */
+        private void processEvents(Collection<EventEntry<TopologyEvent>> events) {
+            // Local state for computing the final set of events
+            Map<ByteBuffer, SwitchEvent> addedSwitchEvents = new HashMap<>();
+            Map<ByteBuffer, SwitchEvent> removedSwitchEvents = new HashMap<>();
+            Map<ByteBuffer, PortEvent> addedPortEvents = new HashMap<>();
+            Map<ByteBuffer, PortEvent> removedPortEvents = new HashMap<>();
+            Map<ByteBuffer, LinkEvent> addedLinkEvents = new HashMap<>();
+            Map<ByteBuffer, LinkEvent> removedLinkEvents = new HashMap<>();
+            Map<ByteBuffer, DeviceEvent> addedDeviceEvents = new HashMap<>();
+            Map<ByteBuffer, DeviceEvent> removedDeviceEvents = new HashMap<>();
 
-	    //
-	    // Classify and suppress matching events
-	    //
-	    for (EventEntry<TopologyEvent> event : events) {
-		TopologyEvent topologyEvent = event.eventData();
-		SwitchEvent switchEvent = topologyEvent.switchEvent;
-		PortEvent portEvent = topologyEvent.portEvent;
-		LinkEvent linkEvent = topologyEvent.linkEvent;
-		DeviceEvent deviceEvent = topologyEvent.deviceEvent;
+            //
+            // Classify and suppress matching events
+            //
+            for (EventEntry<TopologyEvent> event : events) {
+                TopologyEvent topologyEvent = event.eventData();
+                SwitchEvent switchEvent = topologyEvent.switchEvent;
+                PortEvent portEvent = topologyEvent.portEvent;
+                LinkEvent linkEvent = topologyEvent.linkEvent;
+                DeviceEvent deviceEvent = topologyEvent.deviceEvent;
 
-		//
-		// Extract the events
-		//
-		switch (event.eventType()) {
-		case ENTRY_ADD:
-		    log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
-		    if (switchEvent != null) {
-			ByteBuffer id = switchEvent.getIDasByteBuffer();
-			addedSwitchEvents.put(id, switchEvent);
-			removedSwitchEvents.remove(id);
-			// Switch Events are not affected by event reordering
-		    }
-		    if (portEvent != null) {
-			ByteBuffer id = portEvent.getIDasByteBuffer();
-			addedPortEvents.put(id, portEvent);
-			removedPortEvents.remove(id);
-			reorderedAddedPortEvents.remove(id);
-		    }
-		    if (linkEvent != null) {
-			ByteBuffer id = linkEvent.getIDasByteBuffer();
-			addedLinkEvents.put(id, linkEvent);
-			removedLinkEvents.remove(id);
-			reorderedAddedLinkEvents.remove(id);
-		    }
-		    if (deviceEvent != null) {
-			ByteBuffer id = deviceEvent.getIDasByteBuffer();
-			addedDeviceEvents.put(id, deviceEvent);
-			removedDeviceEvents.remove(id);
-			reorderedAddedDeviceEvents.remove(id);
-		    }
-		    break;
-		case ENTRY_REMOVE:
-		    log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
-		    if (switchEvent != null) {
-			ByteBuffer id = switchEvent.getIDasByteBuffer();
-			addedSwitchEvents.remove(id);
-			removedSwitchEvents.put(id, switchEvent);
-			// Switch Events are not affected by event reordering
-		    }
-		    if (portEvent != null) {
-			ByteBuffer id = portEvent.getIDasByteBuffer();
-			addedPortEvents.remove(id);
-			removedPortEvents.put(id, portEvent);
-			reorderedAddedPortEvents.remove(id);
-		    }
-		    if (linkEvent != null) {
-			ByteBuffer id = linkEvent.getIDasByteBuffer();
-			addedLinkEvents.remove(id);
-			removedLinkEvents.put(id, linkEvent);
-			reorderedAddedLinkEvents.remove(id);
-		    }
-		    if (deviceEvent != null) {
-			ByteBuffer id = deviceEvent.getIDasByteBuffer();
-			addedDeviceEvents.remove(id);
-			removedDeviceEvents.put(id, deviceEvent);
-			reorderedAddedDeviceEvents.remove(id);
-		    }
-		    break;
-		}
-	    }
+                //
+                // Extract the events
+                //
+                switch (event.eventType()) {
+                    case ENTRY_ADD:
+                        log.debug("Topology event ENTRY_ADD: {}", topologyEvent);
+                        if (switchEvent != null) {
+                            ByteBuffer id = switchEvent.getIDasByteBuffer();
+                            addedSwitchEvents.put(id, switchEvent);
+                            removedSwitchEvents.remove(id);
+                            // Switch Events are not affected by event reordering
+                        }
+                        if (portEvent != null) {
+                            ByteBuffer id = portEvent.getIDasByteBuffer();
+                            addedPortEvents.put(id, portEvent);
+                            removedPortEvents.remove(id);
+                            reorderedAddedPortEvents.remove(id);
+                        }
+                        if (linkEvent != null) {
+                            ByteBuffer id = linkEvent.getIDasByteBuffer();
+                            addedLinkEvents.put(id, linkEvent);
+                            removedLinkEvents.remove(id);
+                            reorderedAddedLinkEvents.remove(id);
+                        }
+                        if (deviceEvent != null) {
+                            ByteBuffer id = deviceEvent.getIDasByteBuffer();
+                            addedDeviceEvents.put(id, deviceEvent);
+                            removedDeviceEvents.remove(id);
+                            reorderedAddedDeviceEvents.remove(id);
+                        }
+                        break;
+                    case ENTRY_REMOVE:
+                        log.debug("Topology event ENTRY_REMOVE: {}", topologyEvent);
+                        if (switchEvent != null) {
+                            ByteBuffer id = switchEvent.getIDasByteBuffer();
+                            addedSwitchEvents.remove(id);
+                            removedSwitchEvents.put(id, switchEvent);
+                            // Switch Events are not affected by event reordering
+                        }
+                        if (portEvent != null) {
+                            ByteBuffer id = portEvent.getIDasByteBuffer();
+                            addedPortEvents.remove(id);
+                            removedPortEvents.put(id, portEvent);
+                            reorderedAddedPortEvents.remove(id);
+                        }
+                        if (linkEvent != null) {
+                            ByteBuffer id = linkEvent.getIDasByteBuffer();
+                            addedLinkEvents.remove(id);
+                            removedLinkEvents.put(id, linkEvent);
+                            reorderedAddedLinkEvents.remove(id);
+                        }
+                        if (deviceEvent != null) {
+                            ByteBuffer id = deviceEvent.getIDasByteBuffer();
+                            addedDeviceEvents.remove(id);
+                            removedDeviceEvents.put(id, deviceEvent);
+                            reorderedAddedDeviceEvents.remove(id);
+                        }
+                        break;
+                }
+            }
 
-	    //
-	    // Lock the Network Graph while it is modified
-	    //
-	    networkGraph.acquireWriteLock();
+            //
+            // Lock the Network Graph while it is modified
+            //
+            networkGraph.acquireWriteLock();
 
-	    try {
-    	    	//
-		// Apply the classified events.
-		//
-		// Apply the "add" events in the proper order:
-		//   switch, port, link, device
-		//
-    	    	for (SwitchEvent switchEvent : addedSwitchEvents.values())
-    	    	    addSwitch(switchEvent);
-    	    	for (PortEvent portEvent : addedPortEvents.values())
-    	    	    addPort(portEvent);
-    	    	for (LinkEvent linkEvent : addedLinkEvents.values())
-    	    	    addLink(linkEvent);
-    	    	for (DeviceEvent deviceEvent : addedDeviceEvents.values())
-    	    	    addDevice(deviceEvent);
-    	    	//
-    	    	// Apply the "remove" events in the reverse order:
-    	    	//   device, link, port, switch
-    	    	//
-    	    	for (DeviceEvent deviceEvent : removedDeviceEvents.values())
-    	    	    removeDevice(deviceEvent);
-    	    	for (LinkEvent linkEvent : removedLinkEvents.values())
-    	    	    removeLink(linkEvent);
-    	    	for (PortEvent portEvent : removedPortEvents.values())
-    	    	    removePort(portEvent);
-    	    	for (SwitchEvent switchEvent : removedSwitchEvents.values())
-    	    	    removeSwitch(switchEvent);
+            try {
+                //
+                // Apply the classified events.
+                //
+                // Apply the "add" events in the proper order:
+                //   switch, port, link, device
+                //
+                for (SwitchEvent switchEvent : addedSwitchEvents.values())
+                    addSwitch(switchEvent);
+                for (PortEvent portEvent : addedPortEvents.values())
+                    addPort(portEvent);
+                for (LinkEvent linkEvent : addedLinkEvents.values())
+                    addLink(linkEvent);
+                for (DeviceEvent deviceEvent : addedDeviceEvents.values())
+                    addDevice(deviceEvent);
+                //
+                // Apply the "remove" events in the reverse order:
+                //   device, link, port, switch
+                //
+                for (DeviceEvent deviceEvent : removedDeviceEvents.values())
+                    removeDevice(deviceEvent);
+                for (LinkEvent linkEvent : removedLinkEvents.values())
+                    removeLink(linkEvent);
+                for (PortEvent portEvent : removedPortEvents.values())
+                    removePort(portEvent);
+                for (SwitchEvent switchEvent : removedSwitchEvents.values())
+                    removeSwitch(switchEvent);
 
-    	    	//
-    	    	// Apply reordered events
-    	    	//
-    	    	applyReorderedEvents(! addedSwitchEvents.isEmpty(),
-    	    				! addedPortEvents.isEmpty());
+                //
+                // Apply reordered events
+                //
+                applyReorderedEvents(!addedSwitchEvents.isEmpty(),
+                        !addedPortEvents.isEmpty());
 
-	    }
-    	    finally {
-    		//
-    		// Network Graph modifications completed: Release the lock
-    		//
-    		networkGraph.releaseWriteLock();
-	    }
+            } finally {
+                //
+                // Network Graph modifications completed: Release the lock
+                //
+                networkGraph.releaseWriteLock();
+            }
 
-	    //
-	    // Dispatch the Topology Notification Events to the applications
-	    //
-	    dispatchNetworkGraphEvents();
-	}
+            //
+            // Dispatch the Topology Notification Events to the applications
+            //
+            dispatchNetworkGraphEvents();
+        }
 
-	/**
-	 * Receive a notification that an entry is added.
-	 *
-	 * @param value the value for the entry.
-	 */
-	@Override
-	public void entryAdded(TopologyEvent value) {
-	    EventEntry<TopologyEvent> eventEntry =
-		new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
-					      value);
-	    topologyEvents.add(eventEntry);
-	}
+        /**
+         * Receive a notification that an entry is added.
+         *
+         * @param value the value for the entry.
+         */
+        @Override
+        public void entryAdded(TopologyEvent value) {
+            EventEntry<TopologyEvent> eventEntry =
+                    new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                            value);
+            topologyEvents.add(eventEntry);
+        }
 
-	/**
-	 * Receive a notification that an entry is removed.
-	 *
-	 * @param value the value for the entry.
-	 */
-	@Override
-	public void entryRemoved(TopologyEvent value) {
-	    EventEntry<TopologyEvent> eventEntry =
-		new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
-					      value);
-	    topologyEvents.add(eventEntry);
-	}
+        /**
+         * Receive a notification that an entry is removed.
+         *
+         * @param value the value for the entry.
+         */
+        @Override
+        public void entryRemoved(TopologyEvent value) {
+            EventEntry<TopologyEvent> eventEntry =
+                    new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_REMOVE,
+                            value);
+            topologyEvents.add(eventEntry);
+        }
 
-	/**
-	 * Receive a notification that an entry is updated.
-	 *
-	 * @param value the value for the entry.
-	 */
-	@Override
-	public void entryUpdated(TopologyEvent value) {
-	    // NOTE: The ADD and UPDATE events are processed in same way
-	    entryAdded(value);
-	}
+        /**
+         * Receive a notification that an entry is updated.
+         *
+         * @param value the value for the entry.
+         */
+        @Override
+        public void entryUpdated(TopologyEvent value) {
+            // NOTE: The ADD and UPDATE events are processed in same way
+            entryAdded(value);
+        }
     }
 
     /**
@@ -364,175 +362,175 @@
      * @param datagridService the datagrid service to use.
      */
     void startup(IDatagridService datagridService) {
-	eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
-						   eventHandler,
-						   byte[].class,
-						   TopologyEvent.class);
-	eventHandler.start();
+        eventChannel = datagridService.addListener(EVENT_CHANNEL_NAME,
+                eventHandler,
+                byte[].class,
+                TopologyEvent.class);
+        eventHandler.start();
     }
 
     /**
      * Dispatch Network Graph Events to the listeners.
      */
     private void dispatchNetworkGraphEvents() {
-	if (apiAddedSwitchEvents.isEmpty() &&
-	    apiRemovedSwitchEvents.isEmpty() &&
-	    apiAddedPortEvents.isEmpty() &&
-	    apiRemovedPortEvents.isEmpty() &&
-	    apiAddedLinkEvents.isEmpty() &&
-	    apiRemovedLinkEvents.isEmpty() &&
-	    apiAddedDeviceEvents.isEmpty() &&
-	    apiRemovedDeviceEvents.isEmpty()) {
-	    return;		// No events to dispatch
-	}
+        if (apiAddedSwitchEvents.isEmpty() &&
+                apiRemovedSwitchEvents.isEmpty() &&
+                apiAddedPortEvents.isEmpty() &&
+                apiRemovedPortEvents.isEmpty() &&
+                apiAddedLinkEvents.isEmpty() &&
+                apiRemovedLinkEvents.isEmpty() &&
+                apiAddedDeviceEvents.isEmpty() &&
+                apiRemovedDeviceEvents.isEmpty()) {
+            return;        // No events to dispatch
+        }
 
-	if (log.isDebugEnabled()) {
-	    //
-	    // Debug statements
-	    // TODO: Those statements should be removed in the future
-	    //
-	    for (SwitchEvent switchEvent : apiAddedSwitchEvents)
-		log.debug("Dispatch Network Graph Event: ADDED {}", switchEvent);
-	    for (SwitchEvent switchEvent : apiRemovedSwitchEvents)
-		log.debug("Dispatch Network Graph Event: REMOVED {}", switchEvent);
-	    for (PortEvent portEvent : apiAddedPortEvents)
-		log.debug("Dispatch Network Graph Event: ADDED {}", portEvent);
-	    for (PortEvent portEvent : apiRemovedPortEvents)
-		log.debug("Dispatch Network Graph Event: REMOVED {}", portEvent);
-	    for (LinkEvent linkEvent : apiAddedLinkEvents)
-		log.debug("Dispatch Network Graph Event: ADDED {}", linkEvent);
-	    for (LinkEvent linkEvent : apiRemovedLinkEvents)
-		log.debug("Dispatch Network Graph Event: REMOVED {}", linkEvent);
-	    for (DeviceEvent deviceEvent : apiAddedDeviceEvents)
-		log.debug("Dispatch Network Graph Event: ADDED {}", deviceEvent);
-	    for (DeviceEvent deviceEvent : apiRemovedDeviceEvents)
-		log.debug("Dispatch Network Graph Event: REMOVED {}", deviceEvent);
-	}
+        if (log.isDebugEnabled()) {
+            //
+            // Debug statements
+            // TODO: Those statements should be removed in the future
+            //
+            for (SwitchEvent switchEvent : apiAddedSwitchEvents)
+                log.debug("Dispatch Network Graph Event: ADDED {}", switchEvent);
+            for (SwitchEvent switchEvent : apiRemovedSwitchEvents)
+                log.debug("Dispatch Network Graph Event: REMOVED {}", switchEvent);
+            for (PortEvent portEvent : apiAddedPortEvents)
+                log.debug("Dispatch Network Graph Event: ADDED {}", portEvent);
+            for (PortEvent portEvent : apiRemovedPortEvents)
+                log.debug("Dispatch Network Graph Event: REMOVED {}", portEvent);
+            for (LinkEvent linkEvent : apiAddedLinkEvents)
+                log.debug("Dispatch Network Graph Event: ADDED {}", linkEvent);
+            for (LinkEvent linkEvent : apiRemovedLinkEvents)
+                log.debug("Dispatch Network Graph Event: REMOVED {}", linkEvent);
+            for (DeviceEvent deviceEvent : apiAddedDeviceEvents)
+                log.debug("Dispatch Network Graph Event: ADDED {}", deviceEvent);
+            for (DeviceEvent deviceEvent : apiRemovedDeviceEvents)
+                log.debug("Dispatch Network Graph Event: REMOVED {}", deviceEvent);
+        }
 
-	// Deliver the events
-	for (INetworkGraphListener listener : this.networkGraphListeners) {
-	    // TODO: Should copy before handing them over to listener?
-	    listener.networkGraphEvents(apiAddedSwitchEvents,
-					apiRemovedSwitchEvents,
-					apiAddedPortEvents,
-					apiRemovedPortEvents,
-					apiAddedLinkEvents,
-					apiRemovedLinkEvents,
-					apiAddedDeviceEvents,
-					apiRemovedDeviceEvents);
-	}
+        // Deliver the events
+        for (INetworkGraphListener listener : this.networkGraphListeners) {
+            // TODO: Should copy before handing them over to listener?
+            listener.networkGraphEvents(apiAddedSwitchEvents,
+                    apiRemovedSwitchEvents,
+                    apiAddedPortEvents,
+                    apiRemovedPortEvents,
+                    apiAddedLinkEvents,
+                    apiRemovedLinkEvents,
+                    apiAddedDeviceEvents,
+                    apiRemovedDeviceEvents);
+        }
 
-	//
-	// Cleanup
-	//
-	apiAddedSwitchEvents.clear();
-	apiRemovedSwitchEvents.clear();
-	apiAddedPortEvents.clear();
-	apiRemovedPortEvents.clear();
-	apiAddedLinkEvents.clear();
-	apiRemovedLinkEvents.clear();
-	apiAddedDeviceEvents.clear();
-	apiRemovedDeviceEvents.clear();
+        //
+        // Cleanup
+        //
+        apiAddedSwitchEvents.clear();
+        apiRemovedSwitchEvents.clear();
+        apiAddedPortEvents.clear();
+        apiRemovedPortEvents.clear();
+        apiAddedLinkEvents.clear();
+        apiRemovedLinkEvents.clear();
+        apiAddedDeviceEvents.clear();
+        apiRemovedDeviceEvents.clear();
     }
 
     /**
      * Apply reordered events.
      *
      * @param hasAddedSwitchEvents true if there were Added Switch Events.
-     * @param hasAddedPortEvents true if there were Added Port Events.
+     * @param hasAddedPortEvents   true if there were Added Port Events.
      */
     private void applyReorderedEvents(boolean hasAddedSwitchEvents,
-				      boolean hasAddedPortEvents) {
-	if (! (hasAddedSwitchEvents || hasAddedPortEvents))
-	    return;		// Nothing to do
+                                      boolean hasAddedPortEvents) {
+        if (!(hasAddedSwitchEvents || hasAddedPortEvents))
+            return;        // Nothing to do
 
-	//
-	// Try to apply the reordered events.
-	//
-	// NOTE: For simplicity we try to apply all events of a particular
-	// type if any "parent" type event was processed:
-	//  - Apply reordered Port Events if Switches were added
-	//  - Apply reordered Link and Device Events if Switches or Ports
-	//    were added
-	//
+        //
+        // Try to apply the reordered events.
+        //
+        // NOTE: For simplicity we try to apply all events of a particular
+        // type if any "parent" type event was processed:
+        //  - Apply reordered Port Events if Switches were added
+        //  - Apply reordered Link and Device Events if Switches or Ports
+        //    were added
+        //
 
-	//
-	// Apply reordered Port Events if Switches were added
-	//
-	if (hasAddedSwitchEvents) {
-	    Map<ByteBuffer, PortEvent> portEvents = reorderedAddedPortEvents;
-	    reorderedAddedPortEvents = new HashMap<>();
-	    for (PortEvent portEvent : portEvents.values())
-		addPort(portEvent);
-	}
-	//
-	// Apply reordered Link and Device Events if Switches or Ports
-	// were added.
-	//
-	Map<ByteBuffer, LinkEvent> linkEvents = reorderedAddedLinkEvents;
-	reorderedAddedLinkEvents = new HashMap<>();
-	for (LinkEvent linkEvent : linkEvents.values())
-	    addLink(linkEvent);
-	//
-	Map<ByteBuffer, DeviceEvent> deviceEvents = reorderedAddedDeviceEvents;
-	reorderedAddedDeviceEvents = new HashMap<>();
-	for (DeviceEvent deviceEvent : deviceEvents.values())
-	    addDevice(deviceEvent);
+        //
+        // Apply reordered Port Events if Switches were added
+        //
+        if (hasAddedSwitchEvents) {
+            Map<ByteBuffer, PortEvent> portEvents = reorderedAddedPortEvents;
+            reorderedAddedPortEvents = new HashMap<>();
+            for (PortEvent portEvent : portEvents.values())
+                addPort(portEvent);
+        }
+        //
+        // Apply reordered Link and Device Events if Switches or Ports
+        // were added.
+        //
+        Map<ByteBuffer, LinkEvent> linkEvents = reorderedAddedLinkEvents;
+        reorderedAddedLinkEvents = new HashMap<>();
+        for (LinkEvent linkEvent : linkEvents.values())
+            addLink(linkEvent);
+        //
+        Map<ByteBuffer, DeviceEvent> deviceEvents = reorderedAddedDeviceEvents;
+        reorderedAddedDeviceEvents = new HashMap<>();
+        for (DeviceEvent deviceEvent : deviceEvents.values())
+            addDevice(deviceEvent);
     }
 
     /**
      * Switch discovered event.
      *
      * @param switchEvent the switch event.
-     * @param portEvents the corresponding port events for the switch.
+     * @param portEvents  the corresponding port events for the switch.
      */
     @Override
     public void putSwitchDiscoveryEvent(SwitchEvent switchEvent,
-					Collection<PortEvent> portEvents) {
-	if (datastore.addSwitch(switchEvent, portEvents)) {
-	    // Send out notification
-	    TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
-	    eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
-	    
-	    // Send out notification for each port
-	    for (PortEvent portEvent : portEvents) {
-		topologyEvent = new TopologyEvent(portEvent);
-		eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
-	    }
+                                        Collection<PortEvent> portEvents) {
+        if (datastore.addSwitch(switchEvent, portEvents)) {
+            // Send out notification
+            TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
+            eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
 
-	    //
-	    // Keep track of the added ports
-	    //
-	    // Get the old Port Events
-	    Map<ByteBuffer, PortEvent> oldPortEvents =
-		discoveredAddedPortEvents.get(switchEvent.getDpid());
-	    if (oldPortEvents == null)
-		oldPortEvents = new HashMap<>();
+            // Send out notification for each port
+            for (PortEvent portEvent : portEvents) {
+                topologyEvent = new TopologyEvent(portEvent);
+                eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
+            }
 
-	    // Store the new Port Events in the local cache
-	    Map<ByteBuffer, PortEvent> newPortEvents = new HashMap<>();
-	    for (PortEvent portEvent : portEvents) {
-		ByteBuffer id = portEvent.getIDasByteBuffer();
-		newPortEvents.put(id, portEvent);
-	    }
-	    discoveredAddedPortEvents.put(switchEvent.getDpid(),
-					  newPortEvents);
+            //
+            // Keep track of the added ports
+            //
+            // Get the old Port Events
+            Map<ByteBuffer, PortEvent> oldPortEvents =
+                    discoveredAddedPortEvents.get(switchEvent.getDpid());
+            if (oldPortEvents == null)
+                oldPortEvents = new HashMap<>();
 
-	    //
-	    // Extract the removed ports
-	    //
-	    List<PortEvent> removedPortEvents = new LinkedList<>();
-	    for (Map.Entry<ByteBuffer, PortEvent> entry : oldPortEvents.entrySet()) {
-		ByteBuffer key = entry.getKey();
-		PortEvent portEvent = entry.getValue();
-		if (! newPortEvents.containsKey(key))
-		    removedPortEvents.add(portEvent);
-	    }
+            // Store the new Port Events in the local cache
+            Map<ByteBuffer, PortEvent> newPortEvents = new HashMap<>();
+            for (PortEvent portEvent : portEvents) {
+                ByteBuffer id = portEvent.getIDasByteBuffer();
+                newPortEvents.put(id, portEvent);
+            }
+            discoveredAddedPortEvents.put(switchEvent.getDpid(),
+                    newPortEvents);
 
-	    // Cleanup old removed ports
-	    for (PortEvent portEvent : removedPortEvents)
-		removePortDiscoveryEvent(portEvent);
-	}
+            //
+            // Extract the removed ports
+            //
+            List<PortEvent> removedPortEvents = new LinkedList<>();
+            for (Map.Entry<ByteBuffer, PortEvent> entry : oldPortEvents.entrySet()) {
+                ByteBuffer key = entry.getKey();
+                PortEvent portEvent = entry.getValue();
+                if (!newPortEvents.containsKey(key))
+                    removedPortEvents.add(portEvent);
+            }
+
+            // Cleanup old removed ports
+            for (PortEvent portEvent : removedPortEvents)
+                removePortDiscoveryEvent(portEvent);
+        }
     }
 
     /**
@@ -542,47 +540,47 @@
      */
     @Override
     public void removeSwitchDiscoveryEvent(SwitchEvent switchEvent) {
-	// Get the old Port Events
-	Map<ByteBuffer, PortEvent> oldPortEvents =
-	    discoveredAddedPortEvents.get(switchEvent.getDpid());
-	if (oldPortEvents == null)
-	    oldPortEvents = new HashMap<>();
+        // Get the old Port Events
+        Map<ByteBuffer, PortEvent> oldPortEvents =
+                discoveredAddedPortEvents.get(switchEvent.getDpid());
+        if (oldPortEvents == null)
+            oldPortEvents = new HashMap<>();
 
-	if (datastore.deactivateSwitch(switchEvent, oldPortEvents.values())) {
-	    // Send out notification
-	    eventChannel.removeEntry(switchEvent.getID());
+        if (datastore.deactivateSwitch(switchEvent, oldPortEvents.values())) {
+            // Send out notification
+            eventChannel.removeEntry(switchEvent.getID());
 
-	    //
-	    // Send out notification for each port.
-	    //
-	    // NOTE: We don't use removePortDiscoveryEvent() for the cleanup,
-	    // because it will attempt to remove the port from the database,
-	    // and the deactiveSwitch() call above already removed all ports.
-	    //
-	    for (PortEvent portEvent : oldPortEvents.values())
-		eventChannel.removeEntry(portEvent.getID());
-	    discoveredAddedPortEvents.remove(switchEvent.getDpid());
+            //
+            // Send out notification for each port.
+            //
+            // NOTE: We don't use removePortDiscoveryEvent() for the cleanup,
+            // because it will attempt to remove the port from the database,
+            // and the deactiveSwitch() call above already removed all ports.
+            //
+            for (PortEvent portEvent : oldPortEvents.values())
+                eventChannel.removeEntry(portEvent.getID());
+            discoveredAddedPortEvents.remove(switchEvent.getDpid());
 
-	    // Cleanup for each link
-	    Map<ByteBuffer, LinkEvent> oldLinkEvents =
-		discoveredAddedLinkEvents.get(switchEvent.getDpid());
-	    if (oldLinkEvents != null) {
-		for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
-		    removeLinkDiscoveryEvent(linkEvent);
-		}
-		discoveredAddedLinkEvents.remove(switchEvent.getDpid());
-	    }
+            // Cleanup for each link
+            Map<ByteBuffer, LinkEvent> oldLinkEvents =
+                    discoveredAddedLinkEvents.get(switchEvent.getDpid());
+            if (oldLinkEvents != null) {
+                for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
+                    removeLinkDiscoveryEvent(linkEvent);
+                }
+                discoveredAddedLinkEvents.remove(switchEvent.getDpid());
+            }
 
-	    // Cleanup for each device
-	    Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
-		discoveredAddedDeviceEvents.get(switchEvent.getDpid());
-	    if (oldDeviceEvents != null) {
-		for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
-		    removeDeviceDiscoveryEvent(deviceEvent);
-		}
-		discoveredAddedDeviceEvents.remove(switchEvent.getDpid());
-	    }
-	}
+            // Cleanup for each device
+            Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
+                    discoveredAddedDeviceEvents.get(switchEvent.getDpid());
+            if (oldDeviceEvents != null) {
+                for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
+                    removeDeviceDiscoveryEvent(deviceEvent);
+                }
+                discoveredAddedDeviceEvents.remove(switchEvent.getDpid());
+            }
+        }
     }
 
     /**
@@ -592,22 +590,22 @@
      */
     @Override
     public void putPortDiscoveryEvent(PortEvent portEvent) {
-	if (datastore.addPort(portEvent)) {
-	    // Send out notification
-	    TopologyEvent topologyEvent = new TopologyEvent(portEvent);
-	    eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
+        if (datastore.addPort(portEvent)) {
+            // Send out notification
+            TopologyEvent topologyEvent = new TopologyEvent(portEvent);
+            eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
 
-	    // Store the new Port Event in the local cache
-	    Map<ByteBuffer, PortEvent> oldPortEvents =
-		discoveredAddedPortEvents.get(portEvent.getDpid());
-	    if (oldPortEvents == null) {
-		oldPortEvents = new HashMap<>();
-		discoveredAddedPortEvents.put(portEvent.getDpid(),
-					      oldPortEvents);
-	    }
-	    ByteBuffer id = portEvent.getIDasByteBuffer();
-	    oldPortEvents.put(id, portEvent);
-	}
+            // Store the new Port Event in the local cache
+            Map<ByteBuffer, PortEvent> oldPortEvents =
+                    discoveredAddedPortEvents.get(portEvent.getDpid());
+            if (oldPortEvents == null) {
+                oldPortEvents = new HashMap<>();
+                discoveredAddedPortEvents.put(portEvent.getDpid(),
+                        oldPortEvents);
+            }
+            ByteBuffer id = portEvent.getIDasByteBuffer();
+            oldPortEvents.put(id, portEvent);
+        }
     }
 
     /**
@@ -617,49 +615,49 @@
      */
     @Override
     public void removePortDiscoveryEvent(PortEvent portEvent) {
-	if (datastore.deactivatePort(portEvent)) {
-	    // Send out notification
-	    eventChannel.removeEntry(portEvent.getID());
+        if (datastore.deactivatePort(portEvent)) {
+            // Send out notification
+            eventChannel.removeEntry(portEvent.getID());
 
-	    // Cleanup the Port Event from the local cache
-	    Map<ByteBuffer, PortEvent> oldPortEvents =
-		discoveredAddedPortEvents.get(portEvent.getDpid());
-	    if (oldPortEvents != null) {
-		ByteBuffer id = portEvent.getIDasByteBuffer();
-		oldPortEvents.remove(id);
-	    }
+            // Cleanup the Port Event from the local cache
+            Map<ByteBuffer, PortEvent> oldPortEvents =
+                    discoveredAddedPortEvents.get(portEvent.getDpid());
+            if (oldPortEvents != null) {
+                ByteBuffer id = portEvent.getIDasByteBuffer();
+                oldPortEvents.remove(id);
+            }
 
-	    // Cleanup for the incoming link
-	    Map<ByteBuffer, LinkEvent> oldLinkEvents =
-		discoveredAddedLinkEvents.get(portEvent.getDpid());
-	    if (oldLinkEvents != null) {
-		for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
-		    if (linkEvent.getDst().equals(portEvent.id)) {
-			removeLinkDiscoveryEvent(linkEvent);
-			// XXX If we change our model to allow multiple Link on
-			// a Port, this loop must be fixed to allow continuing.
-			break;
-		    }
-		}
-	    }
+            // Cleanup for the incoming link
+            Map<ByteBuffer, LinkEvent> oldLinkEvents =
+                    discoveredAddedLinkEvents.get(portEvent.getDpid());
+            if (oldLinkEvents != null) {
+                for (LinkEvent linkEvent : new ArrayList<>(oldLinkEvents.values())) {
+                    if (linkEvent.getDst().equals(portEvent.id)) {
+                        removeLinkDiscoveryEvent(linkEvent);
+                        // XXX If we change our model to allow multiple Link on
+                        // a Port, this loop must be fixed to allow continuing.
+                        break;
+                    }
+                }
+            }
 
-	    // Cleanup for the connected devices
-	    // TODO: The implementation below is probably wrong
-	    List<DeviceEvent> removedDeviceEvents = new LinkedList<>();
-	    Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
-		discoveredAddedDeviceEvents.get(portEvent.getDpid());
-	    if (oldDeviceEvents != null) {
-		for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
-		    for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
-			if (swp.equals(portEvent.id)) {
-			    removedDeviceEvents.add(deviceEvent);
-			}
-		    }
-		}
-		for (DeviceEvent deviceEvent : removedDeviceEvents)
-		    removeDeviceDiscoveryEvent(deviceEvent);
-	    }
-	}
+            // Cleanup for the connected devices
+            // TODO: The implementation below is probably wrong
+            List<DeviceEvent> removedDeviceEvents = new LinkedList<>();
+            Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
+                    discoveredAddedDeviceEvents.get(portEvent.getDpid());
+            if (oldDeviceEvents != null) {
+                for (DeviceEvent deviceEvent : new ArrayList<>(oldDeviceEvents.values())) {
+                    for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
+                        if (swp.equals(portEvent.id)) {
+                            removedDeviceEvents.add(deviceEvent);
+                        }
+                    }
+                }
+                for (DeviceEvent deviceEvent : removedDeviceEvents)
+                    removeDeviceDiscoveryEvent(deviceEvent);
+            }
+        }
     }
 
     /**
@@ -669,22 +667,22 @@
      */
     @Override
     public void putLinkDiscoveryEvent(LinkEvent linkEvent) {
-	if (datastore.addLink(linkEvent)) {
-	    // Send out notification
-	    TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
-	    eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
+        if (datastore.addLink(linkEvent)) {
+            // Send out notification
+            TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
+            eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
 
-	    // Store the new Link Event in the local cache
-	    Map<ByteBuffer, LinkEvent> oldLinkEvents =
-		discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
-	    if (oldLinkEvents == null) {
-		oldLinkEvents = new HashMap<>();
-		discoveredAddedLinkEvents.put(linkEvent.getDst().getDpid(),
-					      oldLinkEvents);
-	    }
-	    ByteBuffer id = linkEvent.getIDasByteBuffer();
-	    oldLinkEvents.put(id, linkEvent);
-	}
+            // Store the new Link Event in the local cache
+            Map<ByteBuffer, LinkEvent> oldLinkEvents =
+                    discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
+            if (oldLinkEvents == null) {
+                oldLinkEvents = new HashMap<>();
+                discoveredAddedLinkEvents.put(linkEvent.getDst().getDpid(),
+                        oldLinkEvents);
+            }
+            ByteBuffer id = linkEvent.getIDasByteBuffer();
+            oldLinkEvents.put(id, linkEvent);
+        }
     }
 
     /**
@@ -694,18 +692,18 @@
      */
     @Override
     public void removeLinkDiscoveryEvent(LinkEvent linkEvent) {
-	if (datastore.removeLink(linkEvent)) {
-	    // Send out notification
-	    eventChannel.removeEntry(linkEvent.getID());
+        if (datastore.removeLink(linkEvent)) {
+            // Send out notification
+            eventChannel.removeEntry(linkEvent.getID());
 
-	    // Cleanup the Link Event from the local cache
-	    Map<ByteBuffer, LinkEvent> oldLinkEvents =
-		discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
-	    if (oldLinkEvents != null) {
-		ByteBuffer id = linkEvent.getIDasByteBuffer();
-		oldLinkEvents.remove(id);
-	    }
-	}
+            // Cleanup the Link Event from the local cache
+            Map<ByteBuffer, LinkEvent> oldLinkEvents =
+                    discoveredAddedLinkEvents.get(linkEvent.getDst().getDpid());
+            if (oldLinkEvents != null) {
+                ByteBuffer id = linkEvent.getIDasByteBuffer();
+                oldLinkEvents.remove(id);
+            }
+        }
     }
 
     /**
@@ -715,26 +713,26 @@
      */
     @Override
     public void putDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
-	if (datastore.addDevice(deviceEvent)) {
-	    // Send out notification
-	    TopologyEvent topologyEvent = new TopologyEvent(deviceEvent);
-	    eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
-	    log.debug("Put the device info into the cache of the graph. mac {}", deviceEvent.getMac());
-	    
-	    // Store the new Device Event in the local cache
-	    // TODO: The implementation below is probably wrong
-	    for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
-		Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
-		    discoveredAddedDeviceEvents.get(swp.getDpid());
-		if (oldDeviceEvents == null) {
-		    oldDeviceEvents = new HashMap<>();
-		    discoveredAddedDeviceEvents.put(swp.getDpid(),
-						    oldDeviceEvents);
-		}
-		ByteBuffer id = deviceEvent.getIDasByteBuffer();
-		oldDeviceEvents.put(id, deviceEvent);
-	    }
-	}
+        if (datastore.addDevice(deviceEvent)) {
+            // Send out notification
+            TopologyEvent topologyEvent = new TopologyEvent(deviceEvent);
+            eventChannel.addEntry(topologyEvent.getID(), topologyEvent);
+            log.debug("Put the device info into the cache of the graph. mac {}", deviceEvent.getMac());
+
+            // Store the new Device Event in the local cache
+            // TODO: The implementation below is probably wrong
+            for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
+                Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
+                        discoveredAddedDeviceEvents.get(swp.getDpid());
+                if (oldDeviceEvents == null) {
+                    oldDeviceEvents = new HashMap<>();
+                    discoveredAddedDeviceEvents.put(swp.getDpid(),
+                            oldDeviceEvents);
+                }
+                ByteBuffer id = deviceEvent.getIDasByteBuffer();
+                oldDeviceEvents.put(id, deviceEvent);
+            }
+        }
     }
 
     /**
@@ -744,22 +742,22 @@
      */
     @Override
     public void removeDeviceDiscoveryEvent(DeviceEvent deviceEvent) {
-	if (datastore.removeDevice(deviceEvent)) {
-	    // Send out notification
-	    eventChannel.removeEntry(deviceEvent.getID());
-	    log.debug("Remove the device info into the cache of the graph. mac {}", deviceEvent.getMac());
+        if (datastore.removeDevice(deviceEvent)) {
+            // Send out notification
+            eventChannel.removeEntry(deviceEvent.getID());
+            log.debug("Remove the device info into the cache of the graph. mac {}", deviceEvent.getMac());
 
-	    // Cleanup the Device Event from the local cache
-	    // TODO: The implementation below is probably wrong
-	    ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
-	    for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
-		Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
-		    discoveredAddedDeviceEvents.get(swp.getDpid());
-		if (oldDeviceEvents != null) {
-		    oldDeviceEvents.remove(id);
-		}
-	    }
-	}
+            // Cleanup the Device Event from the local cache
+            // TODO: The implementation below is probably wrong
+            ByteBuffer id = ByteBuffer.wrap(deviceEvent.getID());
+            for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
+                Map<ByteBuffer, DeviceEvent> oldDeviceEvents =
+                        discoveredAddedDeviceEvents.get(swp.getDpid());
+                if (oldDeviceEvents != null) {
+                    oldDeviceEvents.remove(id);
+                }
+            }
+        }
     }
 
     /**
@@ -768,15 +766,15 @@
      * @param switchEvent the Switch Event with the switch to add.
      */
     private void addSwitch(SwitchEvent switchEvent) {
-	Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
-	if (sw == null) {
-	    sw = new SwitchImpl(networkGraph, switchEvent.getDpid());
-	    networkGraph.putSwitch(sw);
-	} else {
-	    // TODO: Update the switch attributes
-	    // TODO: Nothing to do for now
-	}
-	apiAddedSwitchEvents.add(switchEvent);
+        Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
+        if (sw == null) {
+            sw = new SwitchImpl(networkGraph, switchEvent.getDpid());
+            networkGraph.putSwitch(sw);
+        } else {
+            // TODO: Update the switch attributes
+            // TODO: Nothing to do for now
+        }
+        apiAddedSwitchEvents.add(switchEvent);
     }
 
     /**
@@ -785,28 +783,28 @@
      * @param switchEvent the Switch Event with the switch to remove.
      */
     private void removeSwitch(SwitchEvent switchEvent) {
-	Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
-	if (sw == null) {
-	    log.warn("Switch {} already removed, ignoring", switchEvent);
-	    return;
-	}
+        Switch sw = networkGraph.getSwitch(switchEvent.getDpid());
+        if (sw == null) {
+            log.warn("Switch {} already removed, ignoring", switchEvent);
+            return;
+        }
 
-	//
-	// Remove all Ports on the Switch
-	//
-	ArrayList<PortEvent> portsToRemove = new ArrayList<>();
-	for (Port port : sw.getPorts()) {
-	    log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
-		     port, switchEvent);
-	    PortEvent portEvent = new PortEvent(port.getDpid(),
-						port.getNumber());
-	    portsToRemove.add(portEvent);
-	}
-	for (PortEvent portEvent : portsToRemove)
-	    removePort(portEvent);
+        //
+        // Remove all Ports on the Switch
+        //
+        ArrayList<PortEvent> portsToRemove = new ArrayList<>();
+        for (Port port : sw.getPorts()) {
+            log.warn("Port {} on Switch {} should be removed prior to removing Switch. Removing Port now.",
+                    port, switchEvent);
+            PortEvent portEvent = new PortEvent(port.getDpid(),
+                    port.getNumber());
+            portsToRemove.add(portEvent);
+        }
+        for (PortEvent portEvent : portsToRemove)
+            removePort(portEvent);
 
-	networkGraph.removeSwitch(switchEvent.getDpid());
-	apiRemovedSwitchEvents.add(switchEvent);
+        networkGraph.removeSwitch(switchEvent.getDpid());
+        apiRemovedSwitchEvents.add(switchEvent);
     }
 
     /**
@@ -815,23 +813,23 @@
      * @param portEvent the Port Event with the port to add.
      */
     private void addPort(PortEvent portEvent) {
-	Switch sw = networkGraph.getSwitch(portEvent.getDpid());
-	if (sw == null) {
-	    // Reordered event: delay the event in local cache
-	    ByteBuffer id = portEvent.getIDasByteBuffer();
-	    reorderedAddedPortEvents.put(id, portEvent);
-	    return;
-	}
-	SwitchImpl switchImpl = getSwitchImpl(sw);
+        Switch sw = networkGraph.getSwitch(portEvent.getDpid());
+        if (sw == null) {
+            // Reordered event: delay the event in local cache
+            ByteBuffer id = portEvent.getIDasByteBuffer();
+            reorderedAddedPortEvents.put(id, portEvent);
+            return;
+        }
+        SwitchImpl switchImpl = getSwitchImpl(sw);
 
-	Port port = sw.getPort(portEvent.getNumber());
-	if (port == null) {
-	    port = new PortImpl(networkGraph, sw, portEvent.getNumber());
-	    switchImpl.addPort(port);
-	} else {
-	    // TODO: Update the port attributes
-	}
-	apiAddedPortEvents.add(portEvent);
+        Port port = sw.getPort(portEvent.getNumber());
+        if (port == null) {
+            port = new PortImpl(networkGraph, sw, portEvent.getNumber());
+            switchImpl.addPort(port);
+        } else {
+            // TODO: Update the port attributes
+        }
+        apiAddedPortEvents.add(portEvent);
     }
 
     /**
@@ -840,59 +838,59 @@
      * @param portEvent the Port Event with the port to remove.
      */
     private void removePort(PortEvent portEvent) {
-	Switch sw = networkGraph.getSwitch(portEvent.getDpid());
-	if (sw == null) {
-	    log.warn("Parent Switch for Port {} already removed, ignoring",
-		     portEvent);
-	    return;
-	}
+        Switch sw = networkGraph.getSwitch(portEvent.getDpid());
+        if (sw == null) {
+            log.warn("Parent Switch for Port {} already removed, ignoring",
+                    portEvent);
+            return;
+        }
 
-	Port port = sw.getPort(portEvent.getNumber());
-	if (port == null) {
-	    log.warn("Port {} already removed, ignoring", portEvent);
-	    return;
-	}
+        Port port = sw.getPort(portEvent.getNumber());
+        if (port == null) {
+            log.warn("Port {} already removed, ignoring", portEvent);
+            return;
+        }
 
-	//
-	// Remove all Devices attached to the Port
-	//
-	ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
-	for (Device device : port.getDevices()) {
-	    log.debug("Removing Device {} on Port {}", device, portEvent);
-	    DeviceEvent deviceEvent = new DeviceEvent(device.getMacAddress());
-	    SwitchPort switchPort = new SwitchPort(port.getSwitch().getDpid(),
-						   port.getNumber());
-	    deviceEvent.addAttachmentPoint(switchPort);
-	    devicesToRemove.add(deviceEvent);
-	}
-	for (DeviceEvent deviceEvent : devicesToRemove)
-	    removeDevice(deviceEvent);
+        //
+        // Remove all Devices attached to the Port
+        //
+        ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
+        for (Device device : port.getDevices()) {
+            log.debug("Removing Device {} on Port {}", device, portEvent);
+            DeviceEvent deviceEvent = new DeviceEvent(device.getMacAddress());
+            SwitchPort switchPort = new SwitchPort(port.getSwitch().getDpid(),
+                    port.getNumber());
+            deviceEvent.addAttachmentPoint(switchPort);
+            devicesToRemove.add(deviceEvent);
+        }
+        for (DeviceEvent deviceEvent : devicesToRemove)
+            removeDevice(deviceEvent);
 
-	//
-	// Remove all Links connected to the Port
-	//
-	Set<Link> links = new HashSet<>();
-	links.add(port.getOutgoingLink());
-	links.add(port.getIncomingLink());
-	ArrayList<LinkEvent> linksToRemove = new ArrayList<>();
-	for (Link link : links) {
-	    if (link == null)
-		continue;
-	    log.debug("Removing Link {} on Port {}", link, portEvent);
-	    LinkEvent linkEvent = new LinkEvent(link.getSrcSwitch().getDpid(),
-						link.getSrcPort().getNumber(),
-						link.getDstSwitch().getDpid(),
-						link.getDstPort().getNumber());
-	    linksToRemove.add(linkEvent);
-	}
-	for (LinkEvent linkEvent : linksToRemove)
-	    removeLink(linkEvent);
+        //
+        // Remove all Links connected to the Port
+        //
+        Set<Link> links = new HashSet<>();
+        links.add(port.getOutgoingLink());
+        links.add(port.getIncomingLink());
+        ArrayList<LinkEvent> linksToRemove = new ArrayList<>();
+        for (Link link : links) {
+            if (link == null)
+                continue;
+            log.debug("Removing Link {} on Port {}", link, portEvent);
+            LinkEvent linkEvent = new LinkEvent(link.getSrcSwitch().getDpid(),
+                    link.getSrcPort().getNumber(),
+                    link.getDstSwitch().getDpid(),
+                    link.getDstPort().getNumber());
+            linksToRemove.add(linkEvent);
+        }
+        for (LinkEvent linkEvent : linksToRemove)
+            removeLink(linkEvent);
 
-	// Remove the Port from the Switch
-	SwitchImpl switchImpl = getSwitchImpl(sw);
-	switchImpl.removePort(port);
+        // Remove the Port from the Switch
+        SwitchImpl switchImpl = getSwitchImpl(sw);
+        switchImpl.removePort(port);
 
-	apiRemovedPortEvents.add(portEvent);
+        apiRemovedPortEvents.add(portEvent);
     }
 
     /**
@@ -901,52 +899,52 @@
      * @param linkEvent the Link Event with the link to add.
      */
     private void addLink(LinkEvent linkEvent) {
-	Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
-					    linkEvent.getSrc().number);
-	Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
-					    linkEvent.getDst().number);
-	if ((srcPort == null) || (dstPort == null)) {
-	    // Reordered event: delay the event in local cache
-	    ByteBuffer id = linkEvent.getIDasByteBuffer();
-	    reorderedAddedLinkEvents.put(id, linkEvent);
-	    return;
-	}
+        Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
+                linkEvent.getSrc().number);
+        Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
+                linkEvent.getDst().number);
+        if ((srcPort == null) || (dstPort == null)) {
+            // Reordered event: delay the event in local cache
+            ByteBuffer id = linkEvent.getIDasByteBuffer();
+            reorderedAddedLinkEvents.put(id, linkEvent);
+            return;
+        }
 
-	// Get the Link instance from the Destination Port Incoming Link
-	Link link = dstPort.getIncomingLink();
-	assert(link == srcPort.getOutgoingLink());
-	if (link == null) {
-	    link = new LinkImpl(networkGraph, srcPort, dstPort);
-	    PortImpl srcPortImpl = getPortImpl(srcPort);
-	    PortImpl dstPortImpl = getPortImpl(dstPort);
-	    srcPortImpl.setOutgoingLink(link);
-	    dstPortImpl.setIncomingLink(link);
+        // Get the Link instance from the Destination Port Incoming Link
+        Link link = dstPort.getIncomingLink();
+        assert (link == srcPort.getOutgoingLink());
+        if (link == null) {
+            link = new LinkImpl(networkGraph, srcPort, dstPort);
+            PortImpl srcPortImpl = getPortImpl(srcPort);
+            PortImpl dstPortImpl = getPortImpl(dstPort);
+            srcPortImpl.setOutgoingLink(link);
+            dstPortImpl.setIncomingLink(link);
 
-	    // Remove all Devices attached to the Ports
-	    ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
-	    ArrayList<Port> ports = new ArrayList<>();
-	    ports.add(srcPort);
-	    ports.add(dstPort);
-	    for (Port port : ports) {
-		for (Device device : port.getDevices()) {
-		    log.error("Device {} on Port {} should have been removed prior to adding Link {}",
-			      device, port, linkEvent);
-		    DeviceEvent deviceEvent =
-			new DeviceEvent(device.getMacAddress());
-		    SwitchPort switchPort =
-			new SwitchPort(port.getSwitch().getDpid(),
-				       port.getNumber());
-		    deviceEvent.addAttachmentPoint(switchPort);
-		    devicesToRemove.add(deviceEvent);
-		}
-	    }
-	    for (DeviceEvent deviceEvent : devicesToRemove)
-		removeDevice(deviceEvent);
-	} else {
-	    // TODO: Update the link attributes
-	}
+            // Remove all Devices attached to the Ports
+            ArrayList<DeviceEvent> devicesToRemove = new ArrayList<>();
+            ArrayList<Port> ports = new ArrayList<>();
+            ports.add(srcPort);
+            ports.add(dstPort);
+            for (Port port : ports) {
+                for (Device device : port.getDevices()) {
+                    log.error("Device {} on Port {} should have been removed prior to adding Link {}",
+                            device, port, linkEvent);
+                    DeviceEvent deviceEvent =
+                            new DeviceEvent(device.getMacAddress());
+                    SwitchPort switchPort =
+                            new SwitchPort(port.getSwitch().getDpid(),
+                                    port.getNumber());
+                    deviceEvent.addAttachmentPoint(switchPort);
+                    devicesToRemove.add(deviceEvent);
+                }
+            }
+            for (DeviceEvent deviceEvent : devicesToRemove)
+                removeDevice(deviceEvent);
+        } else {
+            // TODO: Update the link attributes
+        }
 
-	apiAddedLinkEvents.add(linkEvent);
+        apiAddedLinkEvents.add(linkEvent);
     }
 
     /**
@@ -955,43 +953,43 @@
      * @param linkEvent the Link Event with the link to remove.
      */
     private void removeLink(LinkEvent linkEvent) {
-	Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
-					    linkEvent.getSrc().number);
-	if (srcPort == null) {
-	    log.warn("Src Port for Link {} already removed, ignoring",
-		     linkEvent);
-	    return;
-	}
+        Port srcPort = networkGraph.getPort(linkEvent.getSrc().dpid,
+                linkEvent.getSrc().number);
+        if (srcPort == null) {
+            log.warn("Src Port for Link {} already removed, ignoring",
+                    linkEvent);
+            return;
+        }
 
-	Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
-					    linkEvent.getDst().number);
-	if (dstPort == null) {
-	    log.warn("Dst Port for Link {} already removed, ignoring",
-		     linkEvent);
-	    return;
-	}
+        Port dstPort = networkGraph.getPort(linkEvent.getDst().dpid,
+                linkEvent.getDst().number);
+        if (dstPort == null) {
+            log.warn("Dst Port for Link {} already removed, ignoring",
+                    linkEvent);
+            return;
+        }
 
-	//
-	// Remove the Link instance from the Destination Port Incoming Link
-	// and the Source Port Outgoing Link.
-	//
-	Link link = dstPort.getIncomingLink();
-	if (link == null) {
-	    log.warn("Link {} already removed on destination Port", linkEvent);
-	}
-	link = srcPort.getOutgoingLink();
-	if (link == null) {
-	    log.warn("Link {} already removed on src Port", linkEvent);
-	}
-	getPortImpl(dstPort).setIncomingLink(null);
-	getPortImpl(srcPort).setOutgoingLink(null);
+        //
+        // Remove the Link instance from the Destination Port Incoming Link
+        // and the Source Port Outgoing Link.
+        //
+        Link link = dstPort.getIncomingLink();
+        if (link == null) {
+            log.warn("Link {} already removed on destination Port", linkEvent);
+        }
+        link = srcPort.getOutgoingLink();
+        if (link == null) {
+            log.warn("Link {} already removed on src Port", linkEvent);
+        }
+        getPortImpl(dstPort).setIncomingLink(null);
+        getPortImpl(srcPort).setOutgoingLink(null);
 
-	apiRemovedLinkEvents.add(linkEvent);
+        apiRemovedLinkEvents.add(linkEvent);
     }
 
     /**
      * Add a device to the Network Graph.
-     *
+     * <p/>
      * TODO: Device-related work is incomplete.
      * TODO: Eventually, we might need to consider reordering
      * or addLink() and addDevice() events on the same port.
@@ -999,86 +997,86 @@
      * @param deviceEvent the Device Event with the device to add.
      */
     private void addDevice(DeviceEvent deviceEvent) {
-	Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
-	
-	if (device == null) {
-		log.debug("Existing device was not found in networkGraph. New device. mac {}", deviceEvent.getMac());
-	    device = new DeviceImpl(networkGraph, deviceEvent.getMac());
-	}
-	
-	DeviceImpl deviceImpl = getDeviceImpl(device);
+        Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
 
-	// Update the IP addresses
-	for (InetAddress ipAddr : deviceEvent.getIpAddresses())
-	    deviceImpl.addIpAddress(ipAddr);
+        if (device == null) {
+            log.debug("Existing device was not found in networkGraph. New device. mac {}", deviceEvent.getMac());
+            device = new DeviceImpl(networkGraph, deviceEvent.getMac());
+        }
 
-	// Process each attachment point
-	boolean attachmentFound = false;
-	for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
-	    // Attached Ports must exist
-	    Port port = networkGraph.getPort(swp.dpid, swp.number);
-	    if (port == null) {
-		// Reordered event: delay the event in local cache
-		ByteBuffer id = deviceEvent.getIDasByteBuffer();
-		reorderedAddedDeviceEvents.put(id, deviceEvent);
-		continue;
-	    }
-	    // Attached Ports must not have Link
-	    if (port.getOutgoingLink() != null ||
-		port.getIncomingLink() != null) {
-		log.warn("Link (Out:{},In:{}) exist on the attachment point, skipping mutation.",
-			 port.getOutgoingLink(),
-			 port.getIncomingLink());
-		continue;
-	    }
+        DeviceImpl deviceImpl = getDeviceImpl(device);
 
-	    // Add Device <-> Port attachment
-	    PortImpl portImpl = getPortImpl(port);
-	    portImpl.addDevice(device);
-	    deviceImpl.addAttachmentPoint(port);
-	    attachmentFound = true;
-	}
+        // Update the IP addresses
+        for (InetAddress ipAddr : deviceEvent.getIpAddresses())
+            deviceImpl.addIpAddress(ipAddr);
 
-	// Update the device in the Network Graph
-	if (attachmentFound) {
-    	log.debug("Storing the info into networkGraph. mac {}", deviceEvent.getMac());
-	    networkGraph.putDevice(device);
-	    apiAddedDeviceEvents.add(deviceEvent);
-	}
+        // Process each attachment point
+        boolean attachmentFound = false;
+        for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
+            // Attached Ports must exist
+            Port port = networkGraph.getPort(swp.dpid, swp.number);
+            if (port == null) {
+                // Reordered event: delay the event in local cache
+                ByteBuffer id = deviceEvent.getIDasByteBuffer();
+                reorderedAddedDeviceEvents.put(id, deviceEvent);
+                continue;
+            }
+            // Attached Ports must not have Link
+            if (port.getOutgoingLink() != null ||
+                    port.getIncomingLink() != null) {
+                log.warn("Link (Out:{},In:{}) exist on the attachment point, skipping mutation.",
+                        port.getOutgoingLink(),
+                        port.getIncomingLink());
+                continue;
+            }
+
+            // Add Device <-> Port attachment
+            PortImpl portImpl = getPortImpl(port);
+            portImpl.addDevice(device);
+            deviceImpl.addAttachmentPoint(port);
+            attachmentFound = true;
+        }
+
+        // Update the device in the Network Graph
+        if (attachmentFound) {
+            log.debug("Storing the info into networkGraph. mac {}", deviceEvent.getMac());
+            networkGraph.putDevice(device);
+            apiAddedDeviceEvents.add(deviceEvent);
+        }
     }
 
     /**
      * Remove a device from the Network Graph.
-     *
+     * <p/>
      * TODO: Device-related work is incomplete.
      *
      * @param deviceEvent the Device Event with the device to remove.
      */
     private void removeDevice(DeviceEvent deviceEvent) {
-	Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
-	if (device == null) {
-	    log.warn("Device {} already removed, ignoring", deviceEvent);
-	    return;
-	}
-	DeviceImpl deviceImpl = getDeviceImpl(device);
+        Device device = networkGraph.getDeviceByMac(deviceEvent.getMac());
+        if (device == null) {
+            log.warn("Device {} already removed, ignoring", deviceEvent);
+            return;
+        }
+        DeviceImpl deviceImpl = getDeviceImpl(device);
 
-	// Process each attachment point
-	for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
-	    // Attached Ports must exist
-	    Port port = networkGraph.getPort(swp.dpid, swp.number);
-	    if (port == null) {
-		log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
-		continue;
-	    }
+        // Process each attachment point
+        for (SwitchPort swp : deviceEvent.getAttachmentPoints()) {
+            // Attached Ports must exist
+            Port port = networkGraph.getPort(swp.dpid, swp.number);
+            if (port == null) {
+                log.warn("Port for the attachment point {} did not exist. skipping attachment point mutation", swp);
+                continue;
+            }
 
-	    // Remove Device <-> Port attachment
-	    PortImpl portImpl = getPortImpl(port);
-	    portImpl.removeDevice(device);
-	    deviceImpl.removeAttachmentPoint(port);
-	}
+            // Remove Device <-> Port attachment
+            PortImpl portImpl = getPortImpl(port);
+            portImpl.removeDevice(device);
+            deviceImpl.removeAttachmentPoint(port);
+        }
 
-	networkGraph.removeDevice(device);
-	apiRemovedDeviceEvents.add(deviceEvent);
+        networkGraph.removeDevice(device);
+        apiRemovedDeviceEvents.add(deviceEvent);
     }
 
     /**
@@ -1088,10 +1086,10 @@
      * @return the SwitchImpl-casted switch implementation.
      */
     private SwitchImpl getSwitchImpl(Switch sw) {
-	if (sw instanceof SwitchImpl) {
-	    return (SwitchImpl)sw;
-	}
-	throw new ClassCastException("SwitchImpl expected, but found: " + sw);
+        if (sw instanceof SwitchImpl) {
+            return (SwitchImpl) sw;
+        }
+        throw new ClassCastException("SwitchImpl expected, but found: " + sw);
     }
 
     /**
@@ -1101,10 +1099,10 @@
      * @return the PortImpl-casted port implementation.
      */
     private PortImpl getPortImpl(Port port) {
-	if (port instanceof PortImpl) {
-	    return (PortImpl)port;
-	}
-	throw new ClassCastException("PortImpl expected, but found: " + port);
+        if (port instanceof PortImpl) {
+            return (PortImpl) port;
+        }
+        throw new ClassCastException("PortImpl expected, but found: " + port);
     }
 
     /**
@@ -1114,10 +1112,10 @@
      * @return the LinkImpl-casted link implementation.
      */
     private LinkImpl getLinkImpl(Link link) {
-	if (link instanceof LinkImpl) {
-	    return (LinkImpl)link;
-	}
-	throw new ClassCastException("LinkImpl expected, but found: " + link);
+        if (link instanceof LinkImpl) {
+            return (LinkImpl) link;
+        }
+        throw new ClassCastException("LinkImpl expected, but found: " + link);
     }
 
     /**
@@ -1127,10 +1125,10 @@
      * @return the DeviceImpl-casted device implementation.
      */
     private DeviceImpl getDeviceImpl(Device device) {
-	if (device instanceof DeviceImpl) {
-	    return (DeviceImpl)device;
-	}
-	throw new ClassCastException("DeviceImpl expected, but found: " + device);
+        if (device instanceof DeviceImpl) {
+            return (DeviceImpl) device;
+        }
+        throw new ClassCastException("DeviceImpl expected, but found: " + device);
     }
 
     /**
@@ -1140,60 +1138,60 @@
      * the whole topology.
      */
     private Collection<EventEntry<TopologyEvent>> readWholeTopologyFromDB() {
-	Collection<EventEntry<TopologyEvent>> collection =
-	    new LinkedList<EventEntry<TopologyEvent>>();
+        Collection<EventEntry<TopologyEvent>> collection =
+                new LinkedList<EventEntry<TopologyEvent>>();
 
-	// XXX May need to clear whole topology first, depending on
-	// how we initially subscribe to replication events
+        // XXX May need to clear whole topology first, depending on
+        // how we initially subscribe to replication events
 
-	// Add all active switches
-	for (KVSwitch sw : KVSwitch.getAllSwitches()) {
-	    if (sw.getStatus() != KVSwitch.STATUS.ACTIVE) {
-		continue;
-	    }
+        // Add all active switches
+        for (KVSwitch sw : KVSwitch.getAllSwitches()) {
+            if (sw.getStatus() != KVSwitch.STATUS.ACTIVE) {
+                continue;
+            }
 
-	    SwitchEvent switchEvent = new SwitchEvent(sw.getDpid());
-	    TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
-	    EventEntry<TopologyEvent> eventEntry =
-		new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
-					      topologyEvent);
-	    collection.add(eventEntry);
-	}
+            SwitchEvent switchEvent = new SwitchEvent(sw.getDpid());
+            TopologyEvent topologyEvent = new TopologyEvent(switchEvent);
+            EventEntry<TopologyEvent> eventEntry =
+                    new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                            topologyEvent);
+            collection.add(eventEntry);
+        }
 
-	// Add all active ports
-	for (KVPort p : KVPort.getAllPorts()) {
-	    if (p.getStatus() != KVPort.STATUS.ACTIVE) {
-		continue;
-	    }
+        // Add all active ports
+        for (KVPort p : KVPort.getAllPorts()) {
+            if (p.getStatus() != KVPort.STATUS.ACTIVE) {
+                continue;
+            }
 
-	    PortEvent portEvent = new PortEvent(p.getDpid(), p.getNumber());
-	    TopologyEvent topologyEvent = new TopologyEvent(portEvent);
-	    EventEntry<TopologyEvent> eventEntry =
-		new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
-					      topologyEvent);
-	    collection.add(eventEntry);
-	}
+            PortEvent portEvent = new PortEvent(p.getDpid(), p.getNumber());
+            TopologyEvent topologyEvent = new TopologyEvent(portEvent);
+            EventEntry<TopologyEvent> eventEntry =
+                    new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                            topologyEvent);
+            collection.add(eventEntry);
+        }
 
-	// TODO Is Device going to be in DB? If so, read from DB.
-	//	for (KVDevice d : KVDevice.getAllDevices()) {
-	//	    DeviceEvent devEvent = new DeviceEvent( MACAddress.valueOf(d.getMac()) );
-	//	    for (byte[] portId : d.getAllPortIds() ) {
-	//		devEvent.addAttachmentPoint( new SwitchPort( KVPort.getDpidFromKey(portId), KVPort.getNumberFromKey(portId) ));
-	//	    }
-	//	}
+        // TODO Is Device going to be in DB? If so, read from DB.
+        //      for (KVDevice d : KVDevice.getAllDevices()) {
+        //          DeviceEvent devEvent = new DeviceEvent( MACAddress.valueOf(d.getMac()) );
+        //          for (byte[] portId : d.getAllPortIds() ) {
+        //              devEvent.addAttachmentPoint( new SwitchPort( KVPort.getDpidFromKey(portId), KVPort.getNumberFromKey(portId) ));
+        //          }
+        //      }
 
-	for (KVLink l : KVLink.getAllLinks()) {
-	    LinkEvent linkEvent = new LinkEvent(l.getSrc().dpid,
-						l.getSrc().number,
-						l.getDst().dpid,
-						l.getDst().number);
-	    TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
-	    EventEntry<TopologyEvent> eventEntry =
-		new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
-					      topologyEvent);
-	    collection.add(eventEntry);
-	}
+        for (KVLink l : KVLink.getAllLinks()) {
+            LinkEvent linkEvent = new LinkEvent(l.getSrc().dpid,
+                    l.getSrc().number,
+                    l.getDst().dpid,
+                    l.getDst().number);
+            TopologyEvent topologyEvent = new TopologyEvent(linkEvent);
+            EventEntry<TopologyEvent> eventEntry =
+                    new EventEntry<TopologyEvent>(EventEntry.Type.ENTRY_ADD,
+                            topologyEvent);
+            collection.add(eventEntry);
+        }
 
-	return collection;
+        return collection;
     }
 }
