Merge in refactored FlowManager API which caused confict as I had updated Forwarding recently
diff --git a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
index 95daf96..4d85b7d 100644
--- a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
@@ -15,6 +15,7 @@
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.registry.controller.IControllerRegistryService;
 
 public class FloodlightProvider implements IFloodlightModule {
@@ -52,6 +53,7 @@
         dependencies.add(IThreadPoolService.class);
         // Following added by ONOS
         dependencies.add(IControllerRegistryService.class);
+        dependencies.add(ILinkDiscoveryService.class);
 
         return dependencies;
     }
@@ -71,6 +73,8 @@
        // Following added by ONOS
        controller.setMastershipService(
     		   context.getServiceImpl(IControllerRegistryService.class));
+       controller.setLinkDiscoveryService(
+    		   context.getServiceImpl(ILinkDiscoveryService.class));
 
        controller.init(context.getConfigParams(this));
     }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 17f1be8..31f80cc 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -75,6 +75,7 @@
 import net.floodlightcontroller.storage.StorageException;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.registry.controller.IControllerRegistryService;
 import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
 import net.onrc.onos.registry.controller.RegistryException;
@@ -189,6 +190,8 @@
     protected IThreadPoolService threadPool;
     protected IControllerRegistryService registryService;
     
+    protected ILinkDiscoveryService linkDiscovery;
+    
     // Configuration options
     protected int openFlowPort = 6633;
     protected int workerThreads = 0;
@@ -407,6 +410,10 @@
 		this.registryService = serviceImpl;		
 	}
 	
+	public void setLinkDiscoveryService(ILinkDiscoveryService linkDiscovery) {
+		this.linkDiscovery = linkDiscovery;
+	}
+	
     @Override
     public Role getRole() {
         synchronized(roleChanger) {
@@ -1298,6 +1305,12 @@
                 updatePortInfo(sw, port);
             log.debug("Port #{} modified for {}", portNumber, sw);
         } else if (m.getReason() == (byte)OFPortReason.OFPPR_ADD.ordinal()) {
+        	// XXX Workaround to prevent race condition where a link is detected
+        	// and attempted to be written to the database before the port is in
+        	// the database. We now suppress link discovery on ports until we're
+        	// sure they're in the database.
+        	linkDiscovery.AddToSuppressLLDPs(sw.getId(), port.getPortNumber());
+        	
             sw.setPort(port);
             SwitchUpdate update = new SwitchUpdate(sw, port, SwitchUpdateType.PORTADDED);
             try {
@@ -1541,6 +1554,14 @@
                     "network problem that can be ignored."
             )
     protected void addSwitch(IOFSwitch sw) {
+    	// XXX Workaround to prevent race condition where a link is detected
+    	// and attempted to be written to the database before the port is in
+    	// the database. We now suppress link discovery on ports until we're
+    	// sure they're in the database.
+    	for (OFPhysicalPort port : sw.getPorts()) {
+    		linkDiscovery.AddToSuppressLLDPs(sw.getId(), port.getPortNumber());
+    	}
+    	
         // TODO: is it safe to modify the HashMap without holding 
         // the old switch's lock?
         OFSwitchImpl oldSw = (OFSwitchImpl) this.activeSwitches.put(sw.getId(), sw);
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index 869333b..3005c60 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -117,6 +117,7 @@
 		@Adjacency(label="host")
 		public void removeDevice(final IDeviceObject device);
 		
+		/*
 		@JsonIgnore
 		@Adjacency(label="inport",direction = Direction.IN)
 		public Iterable<IFlowEntry> getInFlowEntries();
@@ -124,6 +125,7 @@
 		@JsonIgnore
 		@Adjacency(label="outport",direction = Direction.IN)
 		public Iterable<IFlowEntry> getOutFlowEntries();
+		*/
 		
 		@JsonIgnore
 		@Adjacency(label="link")
@@ -538,6 +540,7 @@
 		@Adjacency(label="switch")
 		public void setSwitch(ISwitchObject sw);
 
+		/*
 		@Adjacency(label="inport")
 		public IPortObject getInPort();
 
@@ -549,5 +552,6 @@
 
 		@Adjacency(label="outport")
 		public void setOutPort(IPortObject port);
+		*/
 	}
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
index fd9d535..f5f8b00 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -68,28 +68,34 @@
 	@Override
 	public IDeviceObject addDevice(IDevice device) {
 		IDeviceObject obj = null;
- 		try {
- 			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
- 				log.debug("Adding device {}: found existing device", device.getMACAddressString());
-            } else {
-            	obj = ope.newDevice();
-                log.debug("Adding device {}: creating new device", device.getMACAddressString());
-            }
- 			
-            changeDeviceAttachments(device, obj);
-	        
-            changeDeviceIpv4Addresses(device, obj);
-            
- 			obj.setMACAddress(device.getMACAddressString());
- 			obj.setType("device");
- 			obj.setState("ACTIVE");
- 			ope.commit();
-		
- 			//log.debug("Adding device {}",device.getMACAddressString());
-		} catch (TitanException e) {
-			ope.rollback();
-			log.error("Adding device {} failed", device.getMACAddressString(), e);
-			obj = null;
+		for (int i = 0; i < 6; i++) {
+	 		try {
+	 			if (i > 0) {
+	 				log.debug("Retrying add device: i is {}", i);
+	 			}
+	 			if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
+	 				log.debug("Adding device {}: found existing device", device.getMACAddressString());
+	            } else {
+	            	obj = ope.newDevice();
+	                log.debug("Adding device {}: creating new device", device.getMACAddressString());
+	            }
+	 			
+	            changeDeviceAttachments(device, obj);
+		        
+	            changeDeviceIpv4Addresses(device, obj);
+	            
+	 			obj.setMACAddress(device.getMACAddressString());
+	 			obj.setType("device");
+	 			obj.setState("ACTIVE");
+	 			ope.commit();
+	 			
+	 			break;
+	 			//log.debug("Adding device {}",device.getMACAddressString());
+			} catch (TitanException e) {
+				ope.rollback();
+				log.error("Adding device {} failed", device.getMACAddressString(), e);
+				obj = null;
+			}
 		}
  		
 		return obj;		
@@ -262,8 +268,10 @@
 	
 	private void changeDeviceIpv4Addresses(IDevice device, IDeviceObject deviceObject) {
 		List<String> dbIpv4Addresses = new ArrayList<String>();
+		List<Integer> intDbIpv4Addresses = new ArrayList<Integer>();
 		for (IIpv4Address ipv4Vertex : deviceObject.getIpv4Addresses()) {
 			dbIpv4Addresses.add(InetAddresses.fromInteger(ipv4Vertex.getIpv4Address()).getHostAddress());
+			intDbIpv4Addresses.add(ipv4Vertex.getIpv4Address());
 		}
 		
 		List<String> memIpv4Addresses = new ArrayList<String>();
@@ -275,13 +283,16 @@
 				memIpv4Addresses, dbIpv4Addresses);
 		
 		for (int ipv4Address : device.getIPv4Addresses()) {
-			if (deviceObject.getIpv4Address(ipv4Address) == null) {
+			//if (deviceObject.getIpv4Address(ipv4Address) == null) {
+			if (!intDbIpv4Addresses.contains(ipv4Address)) {
 				IIpv4Address dbIpv4Address = ope.ensureIpv4Address(ipv4Address);
 				
+				/*
 				IDeviceObject oldDevice = dbIpv4Address.getDevice();
 				if (oldDevice != null) {
 					oldDevice.removeIpv4Address(dbIpv4Address);
 				}
+				*/
 				
 				log.debug("Adding IP address {}", 
 						InetAddresses.fromInteger(ipv4Address).getHostAddress());
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoSwitchesResource.java b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoSwitchesResource.java
index a173a70..6d3f161 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoSwitchesResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/web/TopoSwitchesResource.java
@@ -17,12 +17,12 @@
 		String filter = (String) getRequestAttributes().get("filter");
 		
 		if (filter.equals("active")) {
-			return (Iterator<ISwitchObject>) impl.getActiveSwitches().iterator();
+			return impl.getActiveSwitches().iterator();
 		}
 		if (filter.equals("inactive")) {
-			return (Iterator<ISwitchObject>) impl.getInactiveSwitches().iterator();
+			return impl.getInactiveSwitches().iterator();
 		} else {
-		    return (Iterator<ISwitchObject>) impl.getAllSwitches().iterator();
+		    return impl.getAllSwitches().iterator();
 		}
 	}
 
diff --git a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
index 104032b..50fe8f8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -244,10 +244,13 @@
 			    // Publish: add the ports
 			    // TODO: Add only ports that are UP?
 			    for (OFPhysicalPort port : sw.getPorts()) {
-				TopologyElement topologyElementPort =
-				    new TopologyElement(sw.getId(),
-							port.getPortNumber());
-				datagridService.notificationSendTopologyElementAdded(topologyElementPort);
+					TopologyElement topologyElementPort =
+					    new TopologyElement(sw.getId(), port.getPortNumber());
+					datagridService.notificationSendTopologyElementAdded(topologyElementPort);
+					
+					// Allow links to be discovered on this port now that it's
+					// in the database
+					linkDiscovery.RemoveFromSuppressLLDPs(sw.getId(), port.getPortNumber());
 			    }
 
 			    // Add all links that might be connected already
@@ -316,6 +319,10 @@
 	@Override
 	public void switchPortAdded(Long switchId, OFPhysicalPort port) {
 		if (swStore.addPort(HexString.toHexString(switchId), port)) {
+			// Allow links to be discovered on this port now that it's
+			// in the database
+			linkDiscovery.RemoveFromSuppressLLDPs(switchId, port.getPortNumber());
+			
 		    // TODO publish ADD_PORT event here
 		    TopologyElement topologyElement =
 			new TopologyElement(switchId, port.getPortNumber());
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index 75bd8b2..a96f5dc 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -249,11 +249,11 @@
 	flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
 	flowEntryObj.setSwitch(sw);
 	if (flowEntry.flowEntryMatch().matchInPort()) {
-	    IPortObject inport =
-		dbHandler.searchPort(flowEntry.dpid().toString(),
-					flowEntry.flowEntryMatch().inPort().value());
+	    //IPortObject inport =
+		//dbHandler.searchPort(flowEntry.dpid().toString(),
+					//flowEntry.flowEntryMatch().inPort().value());
 	    flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
-	    flowEntryObj.setInPort(inport);
+	    //flowEntryObj.setInPort(inport);
 	}
 	if (flowEntry.flowEntryMatch().matchSrcMac()) {
 	    flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
@@ -291,11 +291,11 @@
 
 	for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
 	    if (fa.actionOutput() != null) {
-		IPortObject outport =
-		    dbHandler.searchPort(flowEntry.dpid().toString(),
-					      fa.actionOutput().port().value());
+		//IPortObject outport =
+		    //dbHandler.searchPort(flowEntry.dpid().toString(),
+					      //fa.actionOutput().port().value());
 		flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
-		flowEntryObj.setOutPort(outport);
+		//flowEntryObj.setOutPort(outport);
 	    }
 	}
 	if (! flowEntry.flowEntryActions().isEmpty()) {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
index 4659c30..b6dffd8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -1,6 +1,9 @@
 package net.onrc.onos.ofcontroller.forwarding;
 
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 import net.floodlightcontroller.core.FloodlightContext;
 import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -29,7 +32,11 @@
 
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFPacketOut;
+import org.openflow.protocol.OFPort;
 import org.openflow.protocol.OFType;
+import org.openflow.protocol.action.OFAction;
+import org.openflow.protocol.action.OFActionOutput;
 import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -127,6 +134,8 @@
 		ISwitchObject switchObject = portObject.getSwitch();
 		long destinationDpid = HexString.toLong(switchObject.getDPID());
 		
+		// TODO SwitchPort, Dpid and Port should probably be immutable
+		// (also, are Dpid and Port are even necessary?)
 		SwitchPort srcSwitchPort = new SwitchPort(
 				new Dpid(sw.getId()), new Port(pi.getInPort())); 
 		SwitchPort dstSwitchPort = new SwitchPort(
@@ -139,7 +148,31 @@
 				dstSwitchPort, dstMacAddress)) {
 			log.debug("Not adding flow because it already exists");
 			
-			// Don't do anything if the flow already exists
+			// TODO check reverse flow as well
+			
+			DataPath shortestPath = 
+					topologyService.getDatabaseShortestPath(srcSwitchPort, dstSwitchPort);
+			
+			if (shortestPath == null || shortestPath.flowEntries().isEmpty()) {
+				log.warn("No path found between {} and {} - not handling packet",
+						srcSwitchPort, dstSwitchPort);
+				return;
+			}
+			
+			Port outPort = shortestPath.flowEntries().get(0).outPort();
+			forwardPacket(pi, sw, outPort.value());
+			return;
+		}
+		
+		// Calculate a shortest path before pushing flow mods.
+		// This will be used later by the packet-out processing, but it uses
+		// the database so will be slow, and we should do it before flow mods.
+		DataPath shortestPath = 
+				topologyService.getDatabaseShortestPath(srcSwitchPort, dstSwitchPort);
+		
+		if (shortestPath == null || shortestPath.flowEntries().isEmpty()) {
+			log.warn("No path found between {} and {} - not handling packet",
+					srcSwitchPort, dstSwitchPort);
 			return;
 		}
 		
@@ -151,19 +184,53 @@
 		dataPath.setSrcPort(srcSwitchPort);
 		dataPath.setDstPort(dstSwitchPort);
 		
+		CallerId callerId = new CallerId("Forwarding");
+		
+		//FlowId flowId = new FlowId(flowService.getNextFlowEntryId());
 		FlowPath flowPath = new FlowPath();
-		flowPath.setInstallerId(new CallerId("Forwarding"));
+		//flowPath.setFlowId(flowId);
+		flowPath.setInstallerId(callerId);
+
 		flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
 		flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
 		flowPath.setFlowEntryMatch(new FlowEntryMatch());
 		flowPath.flowEntryMatch().enableSrcMac(srcMacAddress);
 		flowPath.flowEntryMatch().enableDstMac(dstMacAddress);
 		// For now just forward IPv4 packets. This prevents accidentally
-		// other stuff like ARP.
+		// forwarding other stuff like ARP.
 		flowPath.flowEntryMatch().enableEthernetFrameType(Ethernet.TYPE_IPv4);
 		flowPath.setDataPath(dataPath);
-		
+			
 		FlowId flowId = flowService.addFlow(flowPath);
+		//flowService.addFlow(flowPath, flowId);
+		
+		
+		DataPath reverseDataPath = new DataPath();
+		// Reverse the ports for the reverse path
+		reverseDataPath.setSrcPort(dstSwitchPort);
+		reverseDataPath.setDstPort(srcSwitchPort);
+		
+		//FlowId reverseFlowId = new FlowId(flowService.getNextFlowEntryId());
+		// TODO implement copy constructor for FlowPath
+		FlowPath reverseFlowPath = new FlowPath();
+		//reverseFlowPath.setFlowId(reverseFlowId);
+		reverseFlowPath.setInstallerId(callerId);
+		reverseFlowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
+		reverseFlowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+		reverseFlowPath.setFlowEntryMatch(new FlowEntryMatch());
+		// Reverse the MAC addresses for the reverse path
+		reverseFlowPath.flowEntryMatch().enableSrcMac(dstMacAddress);
+		reverseFlowPath.flowEntryMatch().enableDstMac(srcMacAddress);
+		reverseFlowPath.flowEntryMatch().enableEthernetFrameType(Ethernet.TYPE_IPv4);
+		reverseFlowPath.setDataPath(reverseDataPath);
+		reverseFlowPath.dataPath().srcPort().dpid().toString();
+		
+		// TODO what happens if no path exists?
+		//flowService.addFlow(reverseFlowPath, reverseFlowId);
+		FlowId reverseFlowId = flowService.addFlow(reverseFlowPath);
+		
+		Port outPort = shortestPath.flowEntries().get(0).outPort();
+		forwardPacket(pi, sw, outPort.value());
 	}
 	
 	private boolean flowExists(SwitchPort srcPort, MACAddress srcMac, 
@@ -192,4 +259,31 @@
 		return false;
 	}
 
+	private void forwardPacket(OFPacketIn pi, IOFSwitch sw, short port) {
+		List<OFAction> actions = new ArrayList<OFAction>(1);
+		actions.add(new OFActionOutput(port));
+		
+		OFPacketOut po = new OFPacketOut();
+		po.setInPort(OFPort.OFPP_NONE)
+		.setInPort(pi.getInPort())
+		.setActions(actions)
+		.setActionsLength((short)OFActionOutput.MINIMUM_LENGTH)
+		.setLengthU(OFPacketOut.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
+		
+		if (sw.getBuffers() == 0) {
+			po.setBufferId(OFPacketOut.BUFFER_ID_NONE)
+			.setPacketData(pi.getPacketData())
+			.setLengthU(po.getLengthU() + po.getPacketData().length);
+		}
+		else {
+			po.setBufferId(pi.getBufferId());
+		}
+		
+		try {
+			sw.write(po, null);
+			sw.flush();
+		} catch (IOException e) {
+			log.error("Error writing packet out to switch: {}", e);
+		}
+	}
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 85fd618..3bf6c4e 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -17,7 +17,6 @@
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.packet.ARP;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPv4;
@@ -35,6 +34,9 @@
 import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
 import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
 import net.onrc.onos.ofcontroller.core.internal.TopoSwitchServiceImpl;
+import net.onrc.onos.ofcontroller.util.Dpid;
+import net.onrc.onos.ofcontroller.util.Port;
+import net.onrc.onos.ofcontroller.util.SwitchPort;
 
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
@@ -246,21 +248,14 @@
 	public Command receive(
 			IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
 		
-		//if (msg.getType() != OFType.PACKET_IN){
-			//return Command.CONTINUE;
-		//}
-		log.debug("received packet");
-		
 		OFPacketIn pi = (OFPacketIn) msg;
 		
 		Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, 
                 IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 		
 		if (eth.getEtherType() == Ethernet.TYPE_ARP){
-			log.debug("is arp");
 			ARP arp = (ARP) eth.getPayload();	
 			if (arp.getOpCode() == ARP.OP_REQUEST) {
-				log.debug("is request");
 				//TODO check what the DeviceManager does about propagating
 				//or swallowing ARPs. We want to go after DeviceManager in the
 				//chain but we really need it to CONTINUE ARP packets so we can
@@ -268,7 +263,6 @@
 				handleArpRequest(sw, pi, arp, eth);
 			}
 			else if (arp.getOpCode() == ARP.OP_REPLY) {
-				log.debug("is reply");
 				//handleArpReply(sw, pi, arp);
 			}
 		}
@@ -548,6 +542,8 @@
 	}
 	
 	private void broadcastArpRequestOutMyEdge(byte[] arpRequest) {
+		List<SwitchPort> switchPorts = new ArrayList<SwitchPort>();
+		
 		for (IOFSwitch sw : floodlightProvider.getSwitches().values()) {
 			
 			OFPacketOut po = new OFPacketOut();
@@ -565,6 +561,8 @@
 			
 			for (IPortObject portObject : ports) {
 				if (!portObject.getLinkedPorts().iterator().hasNext()) {
+					switchPorts.add(new SwitchPort(new Dpid(sw.getId()), 
+							new Port(portObject.getNumber())));
 					actions.add(new OFActionOutput(portObject.getNumber()));
 				}
 			}
@@ -583,6 +581,8 @@
 				log.error("Failure writing packet out to switch", e);
 			}
 		}
+		
+		log.debug("Broadcast ARP request for to: {}", switchPorts);
 	}
 	
 	private void sendArpRequestOutPort(byte[] arpRequest, long dpid, short port) {
@@ -722,13 +722,17 @@
 	
 	@Override
 	public void arpRequestNotification(ArpMessage arpMessage) {
-		log.debug("Received ARP notification from other instances");
+		//log.debug("Received ARP notification from other instances");
 		
 		switch (arpMessage.getType()){
 		case REQUEST:
+			log.debug("Received ARP request notification for {}", 
+					arpMessage.getAddress());
 			broadcastArpRequestOutMyEdge(arpMessage.getPacket());
 			break;
 		case REPLY:
+			log.debug("Received ARP reply notification for {}",
+					arpMessage.getAddress());
 			sendArpReplyToWaitingRequesters(arpMessage.getAddress());
 			break;
 		}