Added functionality to delete links and to add links to remote switches that have a link to a local switch.
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index 8ad31c2..0247544 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -47,10 +47,12 @@
 import net.floodlightcontroller.core.IInfoProvider;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.internal.OFSwitchImpl;
 import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.annotations.LogMessageCategory;
 import net.floodlightcontroller.core.annotations.LogMessageDoc;
 import net.floodlightcontroller.core.annotations.LogMessageDocs;
+//import net.floodlightcontroller.core.internal.SwitchStorageImpl;
 import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.IFloodlightModule;
@@ -192,6 +194,7 @@
 
     // Storage
     protected LinkStorageImpl linkStore;
+   // protected SwitchStorageImpl swStore;
     
     /**
      * Flag to indicate if automatic port fast is enabled or not.
@@ -200,6 +203,12 @@
     boolean autoPortFastFeature = false;
 
     /**
+     * Map of remote switches that are not connected to this controller. This
+     * is used to learn remote switches in a distributed controller.
+     */
+    protected Map<Long, IOFSwitch> remoteSwitches;
+    
+    /**
      * Map from link to the most recent time it was verified functioning
      */
     protected Map<Link, LinkInfo> links;
@@ -509,6 +518,34 @@
     }
 
     /**
+     * Learn remote switches when running as a distributed controller
+     */
+    protected IOFSwitch addRemoteSwitch(long sw, short port) {
+    	IOFSwitch remotesw = null;
+    	
+    	// add a switch if we have not seen it before
+        if (!remoteSwitches.containsKey(sw)) {
+        	remotesw = new OFSwitchImpl();
+        	remotesw.setupRemoteSwitch(sw);
+        	remoteSwitches.put(remotesw.getId(), remotesw);
+        	log.debug("addRemoteSwitch(): added fake remote sw {}", remotesw);
+        }
+        
+        // add the port if we have not seen it before
+        if (remotesw.getPort(port) != null) {
+        	OFPhysicalPort remoteport = new OFPhysicalPort();
+        	remoteport.setPortNumber(port);
+        	remoteport.setName("fake_" + port);
+        	remoteport.setConfig(0); 
+        	remoteport.setState(0);
+        	remotesw.setPort(remoteport);
+        	log.debug("addRemoteSwitch(): added fake remote port {} to sw {}", remoteport, remotesw);
+        }
+        
+        return remotesw;
+    }
+    
+    /**
      * Send link discovery message out of a given switch port.
      * The discovery message may be a standard LLDP or a modified
      * LLDP, where the dst mac address is set to :ff.  
@@ -769,6 +806,11 @@
                     lldptlv.getValue()[2] == (byte)0xe1 && lldptlv.getValue()[3] == 0x0) {
                 ByteBuffer dpidBB = ByteBuffer.wrap(lldptlv.getValue());
                 remoteSwitch = floodlightProvider.getSwitches().get(dpidBB.getLong(4));
+                if (remoteSwitch == null) {
+                	// floodlight LLDP coming from a remote switch connected to a different controller
+                	// add it to our cache of unconnected remote switches
+                	remoteSwitch = addRemoteSwitch(dpidBB.getLong(4), remotePort);
+                }
             } else if (lldptlv.getType() == 12 && lldptlv.getLength() == 8){
                 otherId = ByteBuffer.wrap(lldptlv.getValue()).getLong();
                 if (myId == otherId)
@@ -1161,7 +1203,7 @@
                 // remove link from storage.
                 removeLinkFromStorage(lt);
 
-                // Write link to network map
+                // remote link from network map
                 linkStore.update(lt, DM_OPERATION.DELETE);
                 
                 // TODO  Whenever link is removed, it has to checked if
@@ -1211,6 +1253,7 @@
                     ((byte)OFPortReason.OFPPR_MODIFY.ordinal() ==
                     ps.getReason() && !portEnabled(ps.getDesc()))) {
                 deleteLinksOnPort(npt, "Port Status Changed");
+                //swStore.deletePort(HexString.toHexString(npt.getNodeId()), npt.getPortId());
                 LDUpdate update = new LDUpdate(sw, port, UpdateOperation.PORT_DOWN);
                 updates.add(update);
                 linkDeleted = true;
@@ -1871,6 +1914,11 @@
         this.linkStore = new LinkStorageImpl();
         this.linkStore.init("/tmp/cassandra.titan");
         
+        // Initialieze the switch storage connector to the network map. We may need to delete switches.
+        // TODO find a better place to delete switches and ports from network map
+        // this.swStore = new SwitchStorageImpl();
+        // this.swStore.init("/tmp/cassandra.titan");
+        
         ScheduledExecutorService ses = threadPool.getScheduledExecutor();
 
         // To be started by the first switch connection