diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCache.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCache.java
index 83a3b55..0e965ff 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCache.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCache.java
@@ -11,89 +11,133 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/*
+ * TODO clean out old ARP entries out of the cache periodically. We currently
+ * don't do this which means the cache memory size will never decrease. We
+ * already have a periodic thread that can be used to do this in
+ * ProxyArpManager.
+ */
+
 /**
  * Implements a basic ARP cache which maps IPv4 addresses to MAC addresses.
  * Mappings time out after a short period of time (currently 1 min). We don't
- * try and refresh the mapping before the entry times out because as a controller
- * we don't know if the mapping is still needed.
- */
-
-/* TODO clean out old ARP entries out of the cache periodically. We currently 
- * don't do this which means the cache memory size will never decrease. We already
- * have a periodic thread that can be used to do this in ProxyArpManager.
+ * try and refresh the mapping before the entry times out because as a
+ * controller we don't know if the mapping is still needed.
  */
 class ArpCache {
-	private final static Logger log = LoggerFactory.getLogger(ArpCache.class);
-	
-	private final static long ARP_ENTRY_TIMEOUT = 60000; //ms (1 min)
-	
-	//Protected by locking on the ArpCache object
-	private final Map<InetAddress, ArpCacheEntry> arpCache;
-	
-	private static class ArpCacheEntry {
-		private final MACAddress macAddress;
-		private long timeLastSeen;	
+    private static final Logger log = LoggerFactory.getLogger(ArpCache.class);
 
-		public ArpCacheEntry(MACAddress macAddress) {
-			this.macAddress = macAddress;
-			this.timeLastSeen = System.currentTimeMillis();
-		}
+    private static final long ARP_ENTRY_TIMEOUT = 60000; // ms (1 min)
 
-		public MACAddress getMacAddress() {
-			return macAddress;
-		}
-		
-		public void setTimeLastSeen(long time){
-			timeLastSeen = time;
-		}
-		
-		public boolean isExpired() {
-			return System.currentTimeMillis() - timeLastSeen > ARP_ENTRY_TIMEOUT;
-		}
-	}
+    // Protected by locking on the ArpCache object (this)
+    private final Map<InetAddress, ArpCacheEntry> arpCache;
 
-	ArpCache() {
-		arpCache = new HashMap<InetAddress, ArpCacheEntry>();
-	}
+    /**
+     * Represents a MAC address entry with a timestamp in the ARP cache.
+     * ARP cache entries are considered invalid if their timestamp is older
+     * than a timeout value.
+     */
+    private static class ArpCacheEntry {
+        private final MACAddress macAddress;
+        private long timeLastSeen;
 
-	synchronized MACAddress lookup(InetAddress ipAddress){	
-		ArpCacheEntry arpEntry = arpCache.get(ipAddress);
-		
-		if (arpEntry == null){
-			return null;
-		}
-		
-		if (arpEntry.isExpired()) {
-			//Entry has timed out so we'll remove it and return null
-			log.trace("Removing expired ARP entry for {}", ipAddress.getHostAddress());
-			
-			arpCache.remove(ipAddress);
-			return null;
-		}
-		
-		return arpEntry.getMacAddress();
-	}
+        /**
+         * Class constructor, specifying the MAC address for the entry.
+         * @param macAddress MAC address for the entry
+         */
+        public ArpCacheEntry(MACAddress macAddress) {
+            this.macAddress = macAddress;
+            this.timeLastSeen = System.currentTimeMillis();
+        }
 
-	synchronized void update(InetAddress ipAddress, MACAddress macAddress){
-		ArpCacheEntry arpEntry = arpCache.get(ipAddress);
-		
-		if (arpEntry != null && arpEntry.getMacAddress().equals(macAddress)){
-			arpEntry.setTimeLastSeen(System.currentTimeMillis());
-		}
-		else {
-			arpCache.put(ipAddress, new ArpCacheEntry(macAddress));
-		}
-	}
-	
-	synchronized List<String> getMappings() {
-		List<String> result = new ArrayList<String>(arpCache.size());
-		
-		for (Map.Entry<InetAddress, ArpCacheEntry> entry : arpCache.entrySet()) {
-			result.add(entry.getKey().getHostAddress() + " => " + 
-					entry.getValue().getMacAddress().toString() + 
-					(entry.getValue().isExpired()?" : EXPIRED":" : VALID"));
-		}
-		
-		return result;
-	}
+        /**
+         * Returns the MAC address this entry represents.
+         * @return this entry's MAC address
+         */
+        public MACAddress getMacAddress() {
+            return macAddress;
+        }
+
+        /**
+         * Update the timestamp for this entry.
+         * @param time the new timestamp to update the entry with
+         */
+        public void setTimeLastSeen(long time) {
+            timeLastSeen = time;
+        }
+
+        /**
+         * Returns whether the entry has timed out or not.
+         * @return true if the entry has timed out.
+         */
+        public boolean isExpired() {
+            return System.currentTimeMillis() - timeLastSeen > ARP_ENTRY_TIMEOUT;
+        }
+    }
+
+    /**
+     * Class constructor.
+     */
+    ArpCache() {
+        arpCache = new HashMap<InetAddress, ArpCacheEntry>();
+    }
+
+    /**
+     * Get the MAC address that is mapped to an IP address in the ARP cache.
+     * @param ipAddress the IP address to look up
+     * @return the MAC address if found in the cache, null if not
+     */
+    synchronized MACAddress lookup(InetAddress ipAddress) {
+        ArpCacheEntry arpEntry = arpCache.get(ipAddress);
+
+        if (arpEntry == null) {
+            return null;
+        }
+
+        if (arpEntry.isExpired()) {
+            // Entry has timed out so we'll remove it and return null
+            log.trace("Removing expired ARP entry for {}",
+                    ipAddress.getHostAddress());
+
+            arpCache.remove(ipAddress);
+            return null;
+        }
+
+        return arpEntry.getMacAddress();
+    }
+
+    /**
+     * Update an entry in the ARP cache. If the IP to MAC mapping is already
+     * in the cache, its timestamp will be updated. If not, the entry will
+     * be added with a new timestamp of the current time.
+     * @param ipAddress the IP address that will be mapped in the cache
+     * @param macAddress the MAC address that maps to {@code ipAddress}
+     */
+    synchronized void update(InetAddress ipAddress, MACAddress macAddress) {
+        ArpCacheEntry arpEntry = arpCache.get(ipAddress);
+
+        if (arpEntry != null && arpEntry.getMacAddress().equals(macAddress)) {
+            arpEntry.setTimeLastSeen(System.currentTimeMillis());
+        } else {
+            arpCache.put(ipAddress, new ArpCacheEntry(macAddress));
+        }
+    }
+
+    /**
+     * Retrieve a list of all mappings in the ARP cache.
+     * @return list of all ARP mappings, formatted as a human-readable string
+     *
+     */
+    synchronized List<String> getMappings() {
+        List<String> result = new ArrayList<String>(arpCache.size());
+
+        for (Map.Entry<InetAddress, ArpCacheEntry> entry : arpCache.entrySet()) {
+            result.add(entry.getKey().getHostAddress()
+                    + " => "
+                    + entry.getValue().getMacAddress().toString()
+                    + (entry.getValue().isExpired() ? " : EXPIRED" : " : VALID"));
+        }
+
+        return result;
+    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCacheResource.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCacheResource.java
index 252e66e..242543c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCacheResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpCacheResource.java
@@ -5,14 +5,22 @@
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
 
+/**
+ * REST resource to view the IP to MAC mappings in the ARP cache.
+ *
+ */
 public class ArpCacheResource extends ServerResource {
 
-	@Get("json")
-	public List<String> getArpCache() {
-		IProxyArpService arp = (IProxyArpService) getContext().getAttributes().
-				get(IProxyArpService.class.getCanonicalName());
-		
-		return arp.getMappings();
-	}
+    /**
+     * Handler for a REST call to retrieve the ARP cache.
+     * @return list of mappings formatted as a human-readable string.
+     */
+    @Get("json")
+    public List<String> getArpCache() {
+        IProxyArpService arp = (IProxyArpService) getContext().getAttributes()
+                .get(IProxyArpService.class.getCanonicalName());
+
+        return arp.getMappings();
+    }
 
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java
index a8afc55..48d04e0 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpReplyNotification.java
@@ -5,24 +5,42 @@
 
 import net.floodlightcontroller.util.MACAddress;
 
+/**
+ * Inter-instance notification that an ARP reply has been received. The
+ * notification contains both the IP address and the MAC address.
+ */
 public class ArpReplyNotification implements Serializable {
 
-	private static final long serialVersionUID = 1L;
-	
-	private InetAddress targetAddress;
-	private MACAddress targetMacAddress;
-	
-	public ArpReplyNotification(InetAddress targetAddress, MACAddress targetMacAddress) {
-		this.targetAddress = targetAddress;
-		this.targetMacAddress = targetMacAddress;
-	}
+    private static final long serialVersionUID = 1L;
 
-	public InetAddress getTargetAddress() {
-		return targetAddress;
-	}
+    private InetAddress targetAddress;
+    private MACAddress targetMacAddress;
 
-	public MACAddress getTargetMacAddress() {
-		return targetMacAddress;
-	}
+    /**
+     * Class constructor.
+     * @param targetAddress IP address received from the ARP reply
+     * @param targetMacAddress MAC address received from the ARP reply
+     */
+    public ArpReplyNotification(InetAddress targetAddress,
+            MACAddress targetMacAddress) {
+        this.targetAddress = targetAddress;
+        this.targetMacAddress = targetMacAddress;
+    }
+
+    /**
+     * Returns the IP address of the ARP reply.
+     * @return the IP address
+     */
+    public InetAddress getTargetAddress() {
+        return targetAddress;
+    }
+
+    /**
+     * Returns the MAC address of the ARP reply.
+     * @return the MAC address
+     */
+    public MACAddress getTargetMacAddress() {
+        return targetMacAddress;
+    }
 
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpWebRoutable.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpWebRoutable.java
index eefa2db..606fb29 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpWebRoutable.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ArpWebRoutable.java
@@ -6,17 +6,31 @@
 import org.restlet.Restlet;
 import org.restlet.routing.Router;
 
+/**
+ * Routing class for ARP module REST URLs.
+ */
 public class ArpWebRoutable implements RestletRoutable {
 
-	@Override
-	public Restlet getRestlet(Context context) {
-		Router router = new Router(context);
-		router.attach("/cache/json", ArpCacheResource.class);
-		return router;
-	}
+    /**
+     * Get a router configured with ARP module REST URLs.
+     *
+     * @param context the restlet context to build a router with
+     * @return the router
+     */
+    @Override
+    public Restlet getRestlet(Context context) {
+        Router router = new Router(context);
+        router.attach("/cache/json", ArpCacheResource.class);
+        return router;
+    }
 
-	@Override
-	public String basePath() {
-		return "/wm/arp";
-	}
+    /**
+     * Get the base path of the ARP module URLs.
+     *
+     * @return the string base path
+     */
+    @Override
+    public String basePath() {
+        return "/wm/arp";
+    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
index 135c061..22fe965 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
@@ -2,7 +2,9 @@
 
 import java.net.InetAddress;
 
-//TODO This class is too generic to be handled by ProxyArpService.
+// TODO This class is too generic to be handled by ProxyArpService.
+// TODO The generic broadcast packet shouldn't contain an IP address which is
+// only for ARP packets.
 /**
  * Notification to all ONOS instances to broadcast this packet out the edge of
  * the network. The edge is defined as any port that doesn't have a link to
@@ -10,33 +12,60 @@
  * on.
  *
  */
-public class BroadcastPacketOutNotification extends
-		PacketOutNotification {
-	
-	private static final long serialVersionUID = 1L;
-	
-	private final InetAddress address;
-	private final long inSwitch;
-	private final short inPort;
+public class BroadcastPacketOutNotification extends PacketOutNotification {
 
-	public BroadcastPacketOutNotification(byte[] packet, InetAddress address,
-			long inSwitch, short inPort) {
-		super(packet);
-		
-		this.address = address;
-		this.inSwitch = inSwitch;
-		this.inPort = inPort;
-	}
+    private static final long serialVersionUID = 1L;
 
-	public long getInSwitch() {
-		return inSwitch;
-	}
+    private final InetAddress address;
+    private final long inSwitch;
+    private final short inPort;
 
-	public short getInPort() {
-		return inPort;
-	}
+    /**
+     * Class constructor.
+     *
+     * @param packet
+     *        packet data to send in the packet-out
+     * @param address
+     *        target IP address if the packet is an ARP packet
+     * @param inSwitch
+     *        dpid of the switch the packet was received on
+     * @param inPort
+     *        port number of the receiving port
+     */
+    public BroadcastPacketOutNotification(byte[] packet, InetAddress address,
+            long inSwitch, short inPort) {
+        super(packet);
 
-	public InetAddress getTargetAddress() {
-		return address;
-	}
+        this.address = address;
+        this.inSwitch = inSwitch;
+        this.inPort = inPort;
+    }
+
+    /**
+     * Get the dpid of the switch the packet was received on.
+     *
+     * @return receiving switch dpid
+     */
+    public long getInSwitch() {
+        return inSwitch;
+    }
+
+    /**
+     * Get the port number of the port the packet was received on.
+     *
+     * @return receiving port number
+     */
+    public short getInPort() {
+        return inPort;
+    }
+
+    /**
+     * Get the target IP address if the packet is an ARP packet.
+     *
+     * @return the target IP address for ARP packets, or null if the packet is
+     *         not an ARP packet
+     */
+    public InetAddress getTargetAddress() {
+        return address;
+    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java
index 75f1d5d..98fcf0c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpReplyEventHandler.java
@@ -1,5 +1,12 @@
 package net.onrc.onos.ofcontroller.proxyarp;
 
+/**
+ * Listener interface for ARP reply event callbacks.
+ */
 public interface IArpReplyEventHandler {
-	public void arpReplyEvent(ArpReplyNotification arpReply);
+    /**
+     * An ARP reply has been received.
+     * @param arpReply data about the received ARP reply
+     */
+    public void arpReplyEvent(ArpReplyNotification arpReply);
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpRequester.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpRequester.java
index 66a17a2..51a6295 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpRequester.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IArpRequester.java
@@ -5,17 +5,20 @@
 import net.floodlightcontroller.util.MACAddress;
 
 /**
- * Callback interface for modules using the {@link IProxyArpService} to
- * send ARP requests.
+ * Callback interface for modules using the {@link IProxyArpService} to send ARP
+ * requests.
  *
  */
 public interface IArpRequester {
-	/**
-	 * Callback method that will be called by the {@link IProxyArpService} 
-	 * when it receives a reply for a request previously submitted by this
-	 * {@code IArpRequester}.
-	 * @param ipAddress The IP address than an ARP request was sent for
-	 * @param macAddress The MAC address mapped to the requested IP address
-	 */
-	public void arpResponse(InetAddress ipAddress, MACAddress macAddress);
+    /**
+     * Callback method that will be called by the {@link IProxyArpService} when
+     * it receives a reply for a request previously submitted by this
+     * {@code IArpRequester}.
+     *
+     * @param ipAddress
+     *        The IP address than an ARP request was sent for
+     * @param macAddress
+     *        The MAC address mapped to the requested IP address
+     */
+    public void arpResponse(InetAddress ipAddress, MACAddress macAddress);
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java
index 86b3728..ce98703 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IPacketOutEventHandler.java
@@ -1,18 +1,20 @@
 package net.onrc.onos.ofcontroller.proxyarp;
 
 /**
- * Classes may implement this interface if they wish to subscribe to 
- * packet out notifications from the datagrid service. Packet out notifications
- * are used to direct other ONOS instances to send packets out particular
- * ports under their control.
+ * Classes may implement this interface if they wish to subscribe to packet out
+ * notifications from the datagrid service. Packet out notifications are used to
+ * direct other ONOS instances to send packets out particular ports under their
+ * control.
  *
  */
 public interface IPacketOutEventHandler {
 
-	/**
-	 * Notify the packet out event handler that an packet out notification has
-	 * been received.
-	 * @param packetOutNotification An object describing the notification
-	 */
-	public void packetOutNotification(PacketOutNotification packetOutNotification);
+    /**
+     * Notify the packet out event handler that an packet out notification has
+     * been received.
+     *
+     * @param packetOutNotification An object describing the notification
+     */
+    public void packetOutNotification(
+            PacketOutNotification packetOutNotification);
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
index 2029513..57993e5 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
@@ -6,29 +6,37 @@
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.util.MACAddress;
 
-//Extends IFloodlightService so we can access it from REST API resources
+// Extends IFloodlightService so we can access it from REST API resources
+/**
+ * Provides ARP services to other modules.
+ */
 public interface IProxyArpService extends IFloodlightService {
-	/**
-	 * Returns the MAC address if there is a valid entry in the cache.
-	 * Otherwise returns null.
-	 * @param ipAddress
-	 * @return
-	 */
-	public MACAddress getMacAddress(InetAddress ipAddress);
-	
-	/**
-	 * Tell the IProxyArpService to send an ARP request for the IP address.
-	 * The request will be broadcast out all edge ports in the network.
-	 * @param ipAddress
-	 * @param requester
-	 * @param retry Whether to keep sending requests until the MAC is learnt
-	 */
-	public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
-			boolean retry);
-	
-	/**
-	 * Returns a snapshot of the entire ARP cache.
-	 * @return
-	 */
-	public List<String> getMappings();
+    /**
+     * Returns the MAC address if there is a valid entry in the cache. Otherwise
+     * returns null.
+     *
+     * @param ipAddress the IP address to request the ARP mapping for
+     * @return the MACAddress that maps to the specified IP address, or null if
+     *         no mapping is found
+     */
+    public MACAddress getMacAddress(InetAddress ipAddress);
+
+    /**
+     * Tell the IProxyArpService to send an ARP request for the IP address. The
+     * request will be broadcast out all edge ports in the network.
+     *
+     * @param ipAddress the IP address to send an ARP request for
+     * @param requester the {@link IArpRequester} object that will be called if
+     *                  a reply is received
+     * @param retry whether to keep sending requests until the MAC is learnt
+     */
+    public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
+            boolean retry);
+
+    /**
+     * Returns a snapshot of the entire ARP cache.
+     *
+     * @return a list of mappings formatted as a human-readable string
+     */
+    public List<String> getMappings();
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java
index 3d37d25..a201939 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/PacketOutNotification.java
@@ -4,18 +4,21 @@
 
 /**
  * A PacketOutNotification contains data sent between ONOS instances that
- * directs other instances to send a packet out a set of ports.
- * This is an abstract base class that will be subclassed by specific
- * types of notifications.
- *
+ * directs other instances to send a packet out a set of ports. This is an
+ * abstract base class that will be subclassed by specific types of
+ * notifications.
  */
 public abstract class PacketOutNotification implements Serializable {
 
-	private static final long serialVersionUID = 1L;
-	
-	protected final byte[] packet;
+    private static final long serialVersionUID = 1L;
 
-	public PacketOutNotification(byte[] packet) {
-		this.packet = packet;
-	}
+    protected final byte[] packet;
+
+    /**
+     * Class constructor.
+     * @param packet the packet data to send in the packet-out
+     */
+    public PacketOutNotification(byte[] packet) {
+        this.packet = packet;
+    }
 }
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 2294a60..33d4d7d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -46,780 +46,798 @@
 import com.google.common.collect.SetMultimap;
 
 public class ProxyArpManager implements IProxyArpService, IOFMessageListener,
-										IPacketOutEventHandler, IArpReplyEventHandler, 
-										IFloodlightModule {
-	private final static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
-	
-	private final long ARP_TIMER_PERIOD = 100; //ms  
+        IPacketOutEventHandler, IArpReplyEventHandler, IFloodlightModule {
+    private static final Logger log = LoggerFactory
+            .getLogger(ProxyArpManager.class);
 
-	private static final int ARP_REQUEST_TIMEOUT = 2000; //ms
-			
-	private IFloodlightProviderService floodlightProvider;
-	private IDatagridService datagrid;
-	private IConfigInfoService configService;
-	private IRestApiService restApi;
-	private IFlowPusherService flowPusher;
-	
-	private short vlan;
-	private static final short NO_VLAN = 0;
-	
-	//private ArpCache arpCache;
+    private static final long ARP_TIMER_PERIOD = 100; // ms
 
-	private SetMultimap<InetAddress, ArpRequest> arpRequests;
-	
-	private static class ArpRequest {
-		private final IArpRequester requester;
-		private final boolean retry;
-		private boolean sent = false;
-		private long requestTime;
-		
-		public ArpRequest(IArpRequester requester, boolean retry){
-			this.requester = requester;
-			this.retry = retry;
-		}
-		
-		public ArpRequest(ArpRequest old) {
-			this.requester = old.requester;
-			this.retry = old.retry;
-		}
-		
-		public boolean isExpired() {
-			return sent && ((System.currentTimeMillis() - requestTime) > ARP_REQUEST_TIMEOUT);
-		}
-		
-		public boolean shouldRetry() {
-			return retry;
-		}
-		
-		public void dispatchReply(InetAddress ipAddress, MACAddress replyMacAddress) {
-			requester.arpResponse(ipAddress, replyMacAddress);
-		}
-		
-		public void setRequestTime() {
-			this.requestTime = System.currentTimeMillis();
-			this.sent = true;
-		}
-	}
-	
-	private class HostArpRequester implements IArpRequester {
-		private final ARP arpRequest;
-		private final long dpid;
-		private final short port;
-		
-		public HostArpRequester(ARP arpRequest, long dpid, short port) {
-			this.arpRequest = arpRequest;
-			this.dpid = dpid;
-			this.port = port;
-		}
+    private static final int ARP_REQUEST_TIMEOUT = 2000; // ms
 
-		@Override
-		public void arpResponse(InetAddress ipAddress, MACAddress macAddress) {
-			ProxyArpManager.this.sendArpReply(arpRequest, dpid, port, macAddress);
-		}
-	}
-	
-	@Override
-	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-		Collection<Class<? extends IFloodlightService>> l 
-			= new ArrayList<Class<? extends IFloodlightService>>();
-		l.add(IProxyArpService.class);
-		return l;
-	}
+    private IFloodlightProviderService floodlightProvider;
+    private IDatagridService datagrid;
+    private IConfigInfoService configService;
+    private IRestApiService restApi;
+    private IFlowPusherService flowPusher;
 
-	@Override
-	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-		Map<Class<? extends IFloodlightService>, IFloodlightService> m 
-			= new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
-		m.put(IProxyArpService.class, this);
-		return m;
-	}
+    private short vlan;
+    private static final short NO_VLAN = 0;
 
-	@Override
-	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-		Collection<Class<? extends IFloodlightService>> dependencies 
-			= new ArrayList<Class<? extends IFloodlightService>>();
-		dependencies.add(IFloodlightProviderService.class);
-		dependencies.add(IRestApiService.class);
-		dependencies.add(IDatagridService.class);
-		dependencies.add(IConfigInfoService.class);
-		dependencies.add(IFlowPusherService.class);
-		return dependencies;
-	}
-	
-	@Override
-	public void init(FloodlightModuleContext context){
-		this.floodlightProvider = 
-				context.getServiceImpl(IFloodlightProviderService.class);
-		this.datagrid = context.getServiceImpl(IDatagridService.class);
-		this.configService = context.getServiceImpl(IConfigInfoService.class);
-		this.restApi = context.getServiceImpl(IRestApiService.class);
-		this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
-		
-		//arpCache = new ArpCache();
+    private SetMultimap<InetAddress, ArpRequest> arpRequests;
 
-		arpRequests = Multimaps.synchronizedSetMultimap(
-				HashMultimap.<InetAddress, ArpRequest>create());
-		
-	}
-	
-	@Override
-	public void startUp(FloodlightModuleContext context) {
-		this.vlan = configService.getVlan();
-		log.info("vlan set to {}", this.vlan);
-		
-		restApi.addRestletRoutable(new ArpWebRoutable());
-		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-		
-		datagrid.registerPacketOutEventHandler(this);
-		datagrid.registerArpReplyEventHandler(this);
-		
-		Timer arpTimer = new Timer("arp-processing");
-		arpTimer.scheduleAtFixedRate(new TimerTask() {
-			@Override
-			public void run() {
-				doPeriodicArpProcessing();
-			}
-		}, 0, ARP_TIMER_PERIOD);
-	}
-	
-	/*
-	 * Function that runs periodically to manage the asynchronous request mechanism.
-	 * It basically cleans up old ARP requests if we don't get a response for them.
-	 * The caller can designate that a request should be retried indefinitely, and
-	 * this task will handle that as well.
-	 */
-	private void doPeriodicArpProcessing() {
-		SetMultimap<InetAddress, ArpRequest> retryList 
-				= HashMultimap.<InetAddress, ArpRequest>create();
+    private static class ArpRequest {
+        private final IArpRequester requester;
+        private final boolean retry;
+        private boolean sent = false;
+        private long requestTime;
 
-		//Have to synchronize externally on the Multimap while using an iterator,
-		//even though it's a synchronizedMultimap
-		synchronized (arpRequests) {			
-			Iterator<Map.Entry<InetAddress, ArpRequest>> it 
-				= arpRequests.entries().iterator();
-			
-			while (it.hasNext()) {
-				Map.Entry<InetAddress, ArpRequest> entry
-						= it.next();
-				ArpRequest request = entry.getValue();
-				if (request.isExpired()) {
-					log.debug("Cleaning expired ARP request for {}", 
-							entry.getKey().getHostAddress());
-		
-					// If the ARP request is expired and then delete the device
-					// TODO check whether this is OK from this thread
-					// TODO: Fix the code below after deviceStorage was removed
-					/*
-					IDeviceObject targetDevice = 
-							deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(entry.getKey()));
-					if (targetDevice != null) {
-						deviceStorage.removeDevice(targetDevice);
-						if (log.isDebugEnabled()) {
-							log.debug("RemoveDevice: {} due to no have not recieve the ARP reply", targetDevice);
-						}
-					}
-					*/
-					
-					it.remove();
-					
-					if (request.shouldRetry()) {
-						retryList.put(entry.getKey(), request);
-					}
-				}
-			}
-		}
-		
-		for (Map.Entry<InetAddress, Collection<ArpRequest>> entry 
-				: retryList.asMap().entrySet()) {
-			
-			InetAddress address = entry.getKey();
-			
-			log.debug("Resending ARP request for {}", address.getHostAddress());
-			
-			// Only ARP requests sent by the controller will have the retry flag
-			// set, so for now we can just send a new ARP request for that address.
-			sendArpRequestForAddress(address);
-			
-			for (ArpRequest request : entry.getValue()) {
-				arpRequests.put(address, new ArpRequest(request));
-			}
-		}
-	}
-	
-	@Override
-	public String getName() {
-		return "proxyarpmanager";
-	}
+        public ArpRequest(IArpRequester requester, boolean retry) {
+            this.requester = requester;
+            this.retry = retry;
+        }
 
-	@Override
-	public boolean isCallbackOrderingPrereq(OFType type, String name) {
-		if (type == OFType.PACKET_IN) {
-			return "devicemanager".equals(name) || "onosdevicemanager".equals(name);
-		}
-		else {
-			return false;
-		}
-	}
+        public ArpRequest(ArpRequest old) {
+            this.requester = old.requester;
+            this.retry = old.retry;
+        }
 
-	@Override
-	public boolean isCallbackOrderingPostreq(OFType type, String name) {
-		return type == OFType.PACKET_IN && "onosforwarding".equals(name);
-	}
+        public boolean isExpired() {
+            return sent
+                    && ((System.currentTimeMillis() - requestTime) > ARP_REQUEST_TIMEOUT);
+        }
 
-	@Override
-	public Command receive(
-			IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-		
-		OFPacketIn pi = (OFPacketIn) msg;
-		
-		Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, 
+        public boolean shouldRetry() {
+            return retry;
+        }
+
+        public void dispatchReply(InetAddress ipAddress,
+                MACAddress replyMacAddress) {
+            requester.arpResponse(ipAddress, replyMacAddress);
+        }
+
+        public void setRequestTime() {
+            this.requestTime = System.currentTimeMillis();
+            this.sent = true;
+        }
+    }
+
+    private class HostArpRequester implements IArpRequester {
+        private final ARP arpRequest;
+        private final long dpid;
+        private final short port;
+
+        public HostArpRequester(ARP arpRequest, long dpid, short port) {
+            this.arpRequest = arpRequest;
+            this.dpid = dpid;
+            this.port = port;
+        }
+
+        @Override
+        public void arpResponse(InetAddress ipAddress, MACAddress macAddress) {
+            ProxyArpManager.this.sendArpReply(arpRequest, dpid, port,
+                    macAddress);
+        }
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l =
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IProxyArpService.class);
+        return l;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+        Map<Class<? extends IFloodlightService>, IFloodlightService> m =
+                new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+        m.put(IProxyArpService.class, this);
+        return m;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        Collection<Class<? extends IFloodlightService>> dependencies =
+                new ArrayList<Class<? extends IFloodlightService>>();
+        dependencies.add(IFloodlightProviderService.class);
+        dependencies.add(IRestApiService.class);
+        dependencies.add(IDatagridService.class);
+        dependencies.add(IConfigInfoService.class);
+        dependencies.add(IFlowPusherService.class);
+        return dependencies;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context) {
+        this.floodlightProvider = context
+                .getServiceImpl(IFloodlightProviderService.class);
+        this.datagrid = context.getServiceImpl(IDatagridService.class);
+        this.configService = context.getServiceImpl(IConfigInfoService.class);
+        this.restApi = context.getServiceImpl(IRestApiService.class);
+        this.flowPusher = context.getServiceImpl(IFlowPusherService.class);
+
+        // arpCache = new ArpCache();
+
+        arpRequests = Multimaps.synchronizedSetMultimap(HashMultimap
+                .<InetAddress, ArpRequest>create());
+
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        this.vlan = configService.getVlan();
+        log.info("vlan set to {}", this.vlan);
+
+        restApi.addRestletRoutable(new ArpWebRoutable());
+        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+
+        datagrid.registerPacketOutEventHandler(this);
+        datagrid.registerArpReplyEventHandler(this);
+
+        Timer arpTimer = new Timer("arp-processing");
+        arpTimer.scheduleAtFixedRate(new TimerTask() {
+            @Override
+            public void run() {
+                doPeriodicArpProcessing();
+            }
+        }, 0, ARP_TIMER_PERIOD);
+    }
+
+    /*
+     * Function that runs periodically to manage the asynchronous request mechanism.
+     * It basically cleans up old ARP requests if we don't get a response for them.
+     * The caller can designate that a request should be retried indefinitely, and
+     * this task will handle that as well.
+     */
+    private void doPeriodicArpProcessing() {
+        SetMultimap<InetAddress, ArpRequest> retryList = HashMultimap
+                .<InetAddress, ArpRequest>create();
+
+        // Have to synchronize externally on the Multimap while using an
+        // iterator,
+        // even though it's a synchronizedMultimap
+        synchronized (arpRequests) {
+            Iterator<Map.Entry<InetAddress, ArpRequest>> it = arpRequests
+                    .entries().iterator();
+
+            while (it.hasNext()) {
+                Map.Entry<InetAddress, ArpRequest> entry = it.next();
+                ArpRequest request = entry.getValue();
+                if (request.isExpired()) {
+                    log.debug("Cleaning expired ARP request for {}", entry
+                            .getKey().getHostAddress());
+
+                    // If the ARP request is expired and then delete the device
+                    // TODO check whether this is OK from this thread
+                    // TODO: Fix the code below after deviceStorage was removed
+                    /*
+                    IDeviceObject targetDevice =
+                    		deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(entry.getKey()));
+                    if (targetDevice != null) {
+                    	deviceStorage.removeDevice(targetDevice);
+                    	if (log.isDebugEnabled()) {
+                    		log.debug("RemoveDevice: {} due to no have not recieve the ARP reply", targetDevice);
+                    	}
+                    }
+                    */
+
+                    it.remove();
+
+                    if (request.shouldRetry()) {
+                        retryList.put(entry.getKey(), request);
+                    }
+                }
+            }
+        }
+
+        for (Map.Entry<InetAddress, Collection<ArpRequest>> entry : retryList
+                .asMap().entrySet()) {
+
+            InetAddress address = entry.getKey();
+
+            log.debug("Resending ARP request for {}", address.getHostAddress());
+
+            // Only ARP requests sent by the controller will have the retry flag
+            // set, so for now we can just send a new ARP request for that
+            // address.
+            sendArpRequestForAddress(address);
+
+            for (ArpRequest request : entry.getValue()) {
+                arpRequests.put(address, new ArpRequest(request));
+            }
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "proxyarpmanager";
+    }
+
+    @Override
+    public boolean isCallbackOrderingPrereq(OFType type, String name) {
+        if (type == OFType.PACKET_IN) {
+            return "devicemanager".equals(name)
+                    || "onosdevicemanager".equals(name);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isCallbackOrderingPostreq(OFType type, String name) {
+        return type == OFType.PACKET_IN && "onosforwarding".equals(name);
+    }
+
+    @Override
+    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
+
+        OFPacketIn pi = (OFPacketIn) msg;
+
+        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
                 IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-		
-		if (eth.getEtherType() == Ethernet.TYPE_ARP){
-			ARP arp = (ARP) eth.getPayload();	
-			if (arp.getOpCode() == ARP.OP_REQUEST) {
-				handleArpRequest(sw, pi, arp, eth);
-			}
-			else if (arp.getOpCode() == ARP.OP_REPLY) {
-				// For replies we simply send a notification via Hazelcast
-				sendArpReplyNotification(eth, pi);
-				
-				//handleArpReply(sw, pi, arp);
-			}
-			
-			// Stop ARP packets here
-			return Command.STOP;
-		}
-		
-		// Propagate everything else
-		return Command.CONTINUE;
-	}
-	
-	private void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp, Ethernet eth) {
-		if (log.isTraceEnabled()) {
-			log.trace("ARP request received for {}", 
-					inetAddressToString(arp.getTargetProtocolAddress()));
-		}
 
-		InetAddress target;
-		try {
-			target = InetAddress.getByAddress(arp.getTargetProtocolAddress());
-		} catch (UnknownHostException e) {
-			log.debug("Invalid address in ARP request", e);
-			return;
-		}
+        if (eth.getEtherType() == Ethernet.TYPE_ARP) {
+            ARP arp = (ARP) eth.getPayload();
+            if (arp.getOpCode() == ARP.OP_REQUEST) {
+                handleArpRequest(sw, pi, arp, eth);
+            } else if (arp.getOpCode() == ARP.OP_REPLY) {
+                // For replies we simply send a notification via Hazelcast
+                sendArpReplyNotification(eth, pi);
 
-		if (configService.fromExternalNetwork(sw.getId(), pi.getInPort())) {
-			//If the request came from outside our network, we only care if
-			//it was a request for one of our interfaces.
-			if (configService.isInterfaceAddress(target)) {
-				log.trace("ARP request for our interface. Sending reply {} => {}",
-						target.getHostAddress(), configService.getRouterMacAddress());
+                // handleArpReply(sw, pi, arp);
+            }
 
-				sendArpReply(arp, sw.getId(), pi.getInPort(), 
-						configService.getRouterMacAddress());
-			}
+            // Stop ARP packets here
+            return Command.STOP;
+        }
 
-			return;
-		}
-		
-		//MACAddress macAddress = arpCache.lookup(target);
+        // Propagate everything else
+        return Command.CONTINUE;
+    }
 
-		arpRequests.put(target, new ArpRequest(
-				new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
+    private void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp,
+            Ethernet eth) {
+        if (log.isTraceEnabled()) {
+            log.trace("ARP request received for {}",
+                    inetAddressToString(arp.getTargetProtocolAddress()));
+        }
 
-		// TODO: Fix the code below after deviceStorage was removed
-		/*
-		IDeviceObject targetDevice = 
-				deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(target));
-		*/
+        InetAddress target;
+        try {
+            target = InetAddress.getByAddress(arp.getTargetProtocolAddress());
+        } catch (UnknownHostException e) {
+            log.debug("Invalid address in ARP request", e);
+            return;
+        }
 
-		// TODO: Fix the code below after deviceStorage was removed
-		/*
-		if (targetDevice == null) {
-			if (log.isTraceEnabled()) {
-				log.trace("No device info found for {} - broadcasting",
-						target.getHostAddress());
-			}
-			
-			// We don't know the device so broadcast the request out
-			datagrid.sendPacketOutNotification(
-					new BroadcastPacketOutNotification(eth.serialize(),
-							target, sw.getId(), pi.getInPort()));
-		}
-		else {
-			// Even if the device exists in our database, we do not reply to
-			// the request directly, but check whether the device is still valid
-			MACAddress macAddress = MACAddress.valueOf(targetDevice.getMACAddress());
+        if (configService.fromExternalNetwork(sw.getId(), pi.getInPort())) {
+            // If the request came from outside our network, we only care if
+            // it was a request for one of our interfaces.
+            if (configService.isInterfaceAddress(target)) {
+                log.trace(
+                        "ARP request for our interface. Sending reply {} => {}",
+                        target.getHostAddress(),
+                        configService.getRouterMacAddress());
 
-			if (log.isTraceEnabled()) {
-				log.trace("The target Device Record in DB is: {} => {} from ARP request host at {}/{}",
-						new Object [] {
-						inetAddressToString(arp.getTargetProtocolAddress()),
-						macAddress,
-						HexString.toHexString(sw.getId()), pi.getInPort()});
-			}
+                sendArpReply(arp, sw.getId(), pi.getInPort(),
+                        configService.getRouterMacAddress());
+            }
 
-			// sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
+            return;
+        }
 
-			Iterable<IPortObject> outPorts = targetDevice.getAttachedPorts();	
+        // MACAddress macAddress = arpCache.lookup(target);
 
-			if (!outPorts.iterator().hasNext()){
-				if (log.isTraceEnabled()) {
-					log.trace("Device {} exists but is not connected to any ports" + 
-							" - broadcasting", macAddress);
-				}
-				
-				datagrid.sendPacketOutNotification(
-						new BroadcastPacketOutNotification(eth.serialize(), 
-								target, sw.getId(), pi.getInPort()));
-			} 
-			else {
-				for (IPortObject portObject : outPorts) {
-					//long outSwitch = 0;
-					//short outPort = 0;
+        arpRequests.put(
+                target,
+                new ArpRequest(new HostArpRequester(arp, sw.getId(), pi
+                        .getInPort()), false));
 
-					// if (!portObject.getLinkedPorts().iterator().hasNext()) {
-					//	outPort = portObject.getNumber();					
-					// }
-					if (portObject.getLinkedPorts().iterator().hasNext()) {
-						continue;
-					}
+        // TODO: Fix the code below after deviceStorage was removed
+        /*
+        IDeviceObject targetDevice =
+        		deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(target));
+        */
 
-					short outPort = portObject.getNumber();
-					ISwitchObject outSwitchObject = portObject.getSwitch();
-					long outSwitch = HexString.toLong(outSwitchObject.getDPID());
+        // TODO: Fix the code below after deviceStorage was removed
+        /*
+        if (targetDevice == null) {
+        	if (log.isTraceEnabled()) {
+        		log.trace("No device info found for {} - broadcasting",
+        				target.getHostAddress());
+        	}
 
-					if (log.isTraceEnabled()) {
-						log.trace("Probing device {} on port {}/{}", 
-								new Object[] {macAddress, 
-								HexString.toHexString(outSwitch), outPort});
-					}
-					
-					datagrid.sendPacketOutNotification(
-							new SinglePacketOutNotification(eth.serialize(), 
-									target, outSwitch, outPort));
-				}
-			}
-		}
-		*/
-	}
-	
-	private void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp){
-		if (log.isTraceEnabled()) {
-			log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[] { 
-					inetAddressToString(arp.getSenderProtocolAddress()),
-					HexString.toHexString(arp.getSenderHardwareAddress()),
-					HexString.toHexString(sw.getId()), pi.getInPort()});
-		}
-		
-		InetAddress senderIpAddress;
-		try {
-			senderIpAddress = InetAddress.getByAddress(arp.getSenderProtocolAddress());
-		} catch (UnknownHostException e) {
-			log.debug("Invalid address in ARP reply", e);
-			return;
-		}
-		
-		MACAddress senderMacAddress = MACAddress.valueOf(arp.getSenderHardwareAddress());
-		
-		//See if anyone's waiting for this ARP reply
-		Set<ArpRequest> requests = arpRequests.get(senderIpAddress);
-		
-		//Synchronize on the Multimap while using an iterator for one of the sets
-		List<ArpRequest> requestsToSend = new ArrayList<ArpRequest>(requests.size());
-		synchronized (arpRequests) {
-			Iterator<ArpRequest> it = requests.iterator();
-			while (it.hasNext()) {
-				ArpRequest request = it.next();
-				it.remove();
-				requestsToSend.add(request);
-			}
-		}
-		
-		//Don't hold an ARP lock while dispatching requests
-		for (ArpRequest request : requestsToSend) {
-			request.dispatchReply(senderIpAddress, senderMacAddress);
-		}
-	}
-	
-	private void sendArpRequestForAddress(InetAddress ipAddress) {
-		//TODO what should the sender IP address and MAC address be if no
-		//IP addresses are configured? Will there ever be a need to send
-		//ARP requests from the controller in that case?
-		//All-zero MAC address doesn't seem to work - hosts don't respond to it
-		
-		byte[] zeroIpv4 = {0x0, 0x0, 0x0, 0x0};
-		byte[] zeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-		byte[] genericNonZeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x01};
-		byte[] broadcastMac = {(byte)0xff, (byte)0xff, (byte)0xff, 
-				(byte)0xff, (byte)0xff, (byte)0xff};
-		
-		ARP arpRequest = new ARP();
-		
-		arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
-			.setProtocolType(ARP.PROTO_TYPE_IP)
-			.setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
-			.setProtocolAddressLength((byte)IPv4.ADDRESS_LENGTH)
-			.setOpCode(ARP.OP_REQUEST)
-			.setTargetHardwareAddress(zeroMac)
-			.setTargetProtocolAddress(ipAddress.getAddress());
+        	// We don't know the device so broadcast the request out
+        	datagrid.sendPacketOutNotification(
+        			new BroadcastPacketOutNotification(eth.serialize(),
+        					target, sw.getId(), pi.getInPort()));
+        }
+        else {
+        	// Even if the device exists in our database, we do not reply to
+        	// the request directly, but check whether the device is still valid
+        	MACAddress macAddress = MACAddress.valueOf(targetDevice.getMACAddress());
 
-		MACAddress routerMacAddress = configService.getRouterMacAddress();
-		//TODO hack for now as it's unclear what the MAC address should be
-		byte[] senderMacAddress = genericNonZeroMac;
-		if (routerMacAddress != null) {
-			senderMacAddress = routerMacAddress.toBytes();
-		}
-		arpRequest.setSenderHardwareAddress(senderMacAddress);
-		
-		byte[] senderIPAddress = zeroIpv4;
-		Interface intf = configService.getOutgoingInterface(ipAddress);
-		if (intf != null) {
-			senderIPAddress = intf.getIpAddress().getAddress();
-		}
-		
-		arpRequest.setSenderProtocolAddress(senderIPAddress);
-		
-		Ethernet eth = new Ethernet();
-		eth.setSourceMACAddress(senderMacAddress)
-			.setDestinationMACAddress(broadcastMac)
-			.setEtherType(Ethernet.TYPE_ARP)
-			.setPayload(arpRequest);
-		
-		if (vlan != NO_VLAN) {
-			eth.setVlanID(vlan)
-			   .setPriorityCode((byte)0);
-		}
-		
-		//sendArpRequestToSwitches(ipAddress, eth.serialize());
-		datagrid.sendPacketOutNotification(new SinglePacketOutNotification(eth.serialize(),
-				ipAddress, intf.getDpid(),intf.getPort()));
-	}
-	
-	private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest) {
-		sendArpRequestToSwitches(dstAddress, arpRequest, 
-				0, OFPort.OFPP_NONE.getValue());
-	}
-	
-	private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest,
-			long inSwitch, short inPort) {
+        	if (log.isTraceEnabled()) {
+        		log.trace("The target Device Record in DB is: {} => {} from ARP request host at {}/{}",
+        				new Object [] {
+        				inetAddressToString(arp.getTargetProtocolAddress()),
+        				macAddress,
+        				HexString.toHexString(sw.getId()), pi.getInPort()});
+        	}
 
-		if (configService.hasLayer3Configuration()) {
-			Interface intf = configService.getOutgoingInterface(dstAddress);
-			if (intf != null) {
-				sendArpRequestOutPort(arpRequest, intf.getDpid(), intf.getPort());
-			}
-			else {
-				//TODO here it should be broadcast out all non-interface edge ports.
-				//I think we can assume that if it's not a request for an external 
-				//network, it's an ARP for a host in our own network. So we want to 
-				//send it out all edge ports that don't have an interface configured
-				//to ensure it reaches all hosts in our network.
-				log.debug("No interface found to send ARP request for {}",
-						dstAddress.getHostAddress());
-			}
-		}
-		else {
-			//broadcastArpRequestOutEdge(arpRequest, inSwitch, inPort);
-			broadcastArpRequestOutMyEdge(arpRequest, inSwitch, inPort);
-		}
-	}
-	
-	private void sendArpReplyNotification(Ethernet eth, OFPacketIn pi) {
-		ARP arp = (ARP) eth.getPayload();
-		
-		if (log.isTraceEnabled()) {
-			log.trace("Sending ARP reply for {} to other ONOS instances",
-					inetAddressToString(arp.getSenderProtocolAddress()));
-		}
-		
-		InetAddress targetAddress;		
-		MACAddress mac = new MACAddress(arp.getSenderHardwareAddress());
-		
-		try {
-			targetAddress = InetAddress.getByAddress(arp.getSenderProtocolAddress());
-		} catch (UnknownHostException e) {
-			log.error("Unknown host", e);
-			return;
-		}
+        	// sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
 
-		datagrid.sendArpReplyNotification(new ArpReplyNotification(targetAddress, mac));
-	}
-	
-	private void broadcastArpRequestOutMyEdge(byte[] arpRequest,
-			long inSwitch, short inPort) {
-		List<SwitchPort> switchPorts = new ArrayList<SwitchPort>();
-		
-		for (IOFSwitch sw : floodlightProvider.getSwitches().values()) {
-			
-			OFPacketOut po = new OFPacketOut();
-			po.setInPort(OFPort.OFPP_NONE)
-			.setBufferId(-1)
-			.setPacketData(arpRequest);
-			
-			List<OFAction> actions = new ArrayList<OFAction>();
+        	Iterable<IPortObject> outPorts = targetDevice.getAttachedPorts();
 
-			// TODO: Fix the code below after topoSwitchService was removed
-			/*
-			Iterable<IPortObject> ports 
-				= topoSwitchService.getPortsOnSwitch(sw.getStringId());
-			if (ports == null) {
-				continue;
-			}
-			
-			for (IPortObject portObject : ports) {
-				if (!portObject.getLinkedPorts().iterator().hasNext()) {
-					short portNumber = portObject.getNumber();
-					
-					if (sw.getId() == inSwitch && portNumber == inPort) {
-						// This is the port that the ARP message came in,
-						// so don't broadcast out this port
-						continue;
-					}
-					
-					switchPorts.add(new SwitchPort(new Dpid(sw.getId()), 
-							new Port(portNumber)));
-					actions.add(new OFActionOutput(portNumber));
-				}
-			}
-			*/
-			
-			po.setActions(actions);
-			short actionsLength = (short) 
-					(actions.size() * OFActionOutput.MINIMUM_LENGTH);
-			po.setActionsLength(actionsLength);
-			po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength 
-					+ arpRequest.length);
-			
-			flowPusher.add(sw, po);
-		}
-		
-		if (log.isTraceEnabled()) {
-			log.trace("Broadcast ARP request to: {}", switchPorts);
-		}
-	}
-	
-	private void sendArpRequestOutPort(byte[] arpRequest, long dpid, short port) {
-		if (log.isTraceEnabled()) {
-			log.trace("Sending ARP request out {}/{}", 
-					HexString.toHexString(dpid), port);
-		}
-		
-		OFPacketOut po = new OFPacketOut();
-		po.setInPort(OFPort.OFPP_NONE)
-			.setBufferId(-1)
-			.setPacketData(arpRequest);
-			
-		List<OFAction> actions = new ArrayList<OFAction>();
-		actions.add(new OFActionOutput(port));
-		po.setActions(actions);
-		short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
-		po.setActionsLength(actionsLength);
-		po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength 
-				+ arpRequest.length);
-		
-		IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
-		
-		if (sw == null) {
-			log.warn("Switch not found when sending ARP request");
-			return;
-		}
-		
-		flowPusher.add(sw, po);
-	}
-	
-	private void sendArpReply(ARP arpRequest, long dpid, short port, MACAddress targetMac) {
-		if (log.isTraceEnabled()) {
-			log.trace("Sending reply {} => {} to {}", new Object[] {
-					inetAddressToString(arpRequest.getTargetProtocolAddress()),
-					targetMac,
-					inetAddressToString(arpRequest.getSenderProtocolAddress())});
-		}
-		
-		ARP arpReply = new ARP();
-		arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
-			.setProtocolType(ARP.PROTO_TYPE_IP)
-			.setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
-			.setProtocolAddressLength((byte)IPv4.ADDRESS_LENGTH)
-			.setOpCode(ARP.OP_REPLY)
-			.setSenderHardwareAddress(targetMac.toBytes())
-			.setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
-			.setTargetHardwareAddress(arpRequest.getSenderHardwareAddress())
-			.setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
-		
+        	if (!outPorts.iterator().hasNext()){
+        		if (log.isTraceEnabled()) {
+        			log.trace("Device {} exists but is not connected to any ports" +
+        					" - broadcasting", macAddress);
+        		}
 
-		Ethernet eth = new Ethernet();
-		eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
-			.setSourceMACAddress(targetMac.toBytes())
-			.setEtherType(Ethernet.TYPE_ARP)
-			.setPayload(arpReply);
-		
-		if (vlan != NO_VLAN) {
-			eth.setVlanID(vlan)
-			   .setPriorityCode((byte)0);
-		}
-		
-		List<OFAction> actions = new ArrayList<OFAction>();
-		actions.add(new OFActionOutput(port));
-		
-		OFPacketOut po = new OFPacketOut();
-		po.setInPort(OFPort.OFPP_NONE)
-			.setBufferId(-1)
-			.setPacketData(eth.serialize())
-			.setActions(actions)
-			.setActionsLength((short)OFActionOutput.MINIMUM_LENGTH)
-			.setLengthU(OFPacketOut.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH
-					+ po.getPacketData().length);
-		
-		List<OFMessage> msgList = new ArrayList<OFMessage>();
-		msgList.add(po);
+        		datagrid.sendPacketOutNotification(
+        				new BroadcastPacketOutNotification(eth.serialize(),
+        						target, sw.getId(), pi.getInPort()));
+        	}
+        	else {
+        		for (IPortObject portObject : outPorts) {
+        			//long outSwitch = 0;
+        			//short outPort = 0;
 
-		IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
-		
-		if (sw == null) {
-			log.warn("Switch {} not found when sending ARP reply", 
-					HexString.toHexString(dpid));
-			return;
-		}
-		
-		flowPusher.add(sw, po);
-	}
-	
-	private String inetAddressToString(byte[] bytes) {
-		try {
-			return InetAddress.getByAddress(bytes).getHostAddress();
-		} catch (UnknownHostException e) {
-			log.debug("Invalid IP address", e);
-			return "";
-		}
-	}
-	
-	/*
-	 * IProxyArpService methods
-	 */
+        			// if (!portObject.getLinkedPorts().iterator().hasNext()) {
+        			//	outPort = portObject.getNumber();
+        			// }
+        			if (portObject.getLinkedPorts().iterator().hasNext()) {
+        				continue;
+        			}
 
-	@Override
-	public MACAddress getMacAddress(InetAddress ipAddress) {
-		//return arpCache.lookup(ipAddress);
-		return null;
-	}
+        			short outPort = portObject.getNumber();
+        			ISwitchObject outSwitchObject = portObject.getSwitch();
+        			long outSwitch = HexString.toLong(outSwitchObject.getDPID());
 
-	@Override
-	public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
-			boolean retry) {
-		arpRequests.put(ipAddress, new ArpRequest(requester, retry));
-		
-		//Sanity check to make sure we don't send a request for our own address
-		if (!configService.isInterfaceAddress(ipAddress)) {
-			sendArpRequestForAddress(ipAddress);
-		}
-	}
-	
-	@Override
-	public List<String> getMappings() {
-		//return arpCache.getMappings();
-		return new ArrayList<String>();
-	}
+        			if (log.isTraceEnabled()) {
+        				log.trace("Probing device {} on port {}/{}",
+        						new Object[] {macAddress,
+        						HexString.toHexString(outSwitch), outPort});
+        			}
 
-	/*
-	@Override
-	public void arpRequestNotification(ArpMessage arpMessage) {
-		log.debug("Received ARP notification from other instances");
+        			datagrid.sendPacketOutNotification(
+        					new SinglePacketOutNotification(eth.serialize(),
+        							target, outSwitch, outPort));
+        		}
+        	}
+        }
+        */
+    }
 
-		switch (arpMessage.getType()){
-		case REQUEST:
-			if(arpMessage.getOutSwitch() == -1 || arpMessage.getOutPort() == -1){	
-				broadcastArpRequestOutMyEdge(arpMessage.getPacket(),
-						arpMessage.getInSwitch(), arpMessage.getInPort());					
-			}else{					
-				sendArpRequestOutPort(arpMessage.getPacket(),arpMessage.getOutSwitch(),arpMessage.getOutPort());
-				log.debug("OutSwitch in ARP request message is: {}; OutPort in ARP request message is: {}",arpMessage.getOutSwitch(),arpMessage.getOutPort());
-			}
-			break;
-		case REPLY:
-			log.debug("Received ARP reply notification for {}",
-					arpMessage.getAddress());
-			sendArpReplyToWaitingRequesters(arpMessage.getAddress(),arpMessage.getMAC());
-			break;
-		}
-	}
-	*/
-	
-	private void sendArpReplyToWaitingRequesters(InetAddress address, MACAddress mac) {
-		log.debug("Sending ARP reply for {} to requesters", 
-				address.getHostAddress());
-		
-		//See if anyone's waiting for this ARP reply
-		Set<ArpRequest> requests = arpRequests.get(address);
-		
-		//Synchronize on the Multimap while using an iterator for one of the sets
-		List<ArpRequest> requestsToSend = new ArrayList<ArpRequest>(requests.size());
-		synchronized (arpRequests) {
-			Iterator<ArpRequest> it = requests.iterator();
-			while (it.hasNext()) {
-				ArpRequest request = it.next();
-				it.remove();
-				requestsToSend.add(request);
-			}
-		}
-		
-		/*IDeviceObject deviceObject = deviceStorage.getDeviceByIP(
-				InetAddresses.coerceToInteger(address));
-		
-		MACAddress mac = MACAddress.valueOf(deviceObject.getMACAddress());
-		
-		log.debug("Found {} at {} in network map", 
-				address.getHostAddress(), mac);*/
-		
-		//Don't hold an ARP lock while dispatching requests
-		for (ArpRequest request : requestsToSend) {
-			request.dispatchReply(address, mac);
-		}
-	}
+    // Not used because device manager currently updates the database
+    // for ARP replies. May be useful in the future.
+    private void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp) {
+        if (log.isTraceEnabled()) {
+            log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[] {
+                    inetAddressToString(arp.getSenderProtocolAddress()),
+                    HexString.toHexString(arp.getSenderHardwareAddress()),
+                    HexString.toHexString(sw.getId()), pi.getInPort()});
+        }
 
-	@Override
-	public void arpReplyEvent(ArpReplyNotification arpReply) {
-		log.debug("Received ARP reply notification for {}",
-				arpReply.getTargetAddress());
-		sendArpReplyToWaitingRequesters(arpReply.getTargetAddress(), 
-				arpReply.getTargetMacAddress());
-	}
+        InetAddress senderIpAddress;
+        try {
+            senderIpAddress = InetAddress.getByAddress(arp
+                    .getSenderProtocolAddress());
+        } catch (UnknownHostException e) {
+            log.debug("Invalid address in ARP reply", e);
+            return;
+        }
 
-	@Override
-	public void packetOutNotification(
-			PacketOutNotification packetOutNotification) {
-		
-		if (packetOutNotification instanceof SinglePacketOutNotification) {
-			SinglePacketOutNotification notification = 
-					(SinglePacketOutNotification) packetOutNotification;
-			sendArpRequestOutPort(notification.packet, notification.getOutSwitch(), 
-					notification.getOutPort());
-			
-			// set timestamp
-			InetAddress addr = notification.getTargetAddress();
-			if (addr != null) {
-				for (ArpRequest request : arpRequests.get(addr)) {
-					request.setRequestTime();
-				}
-			}
-		}
-		else if (packetOutNotification instanceof BroadcastPacketOutNotification) {
-			BroadcastPacketOutNotification notification = 
-					(BroadcastPacketOutNotification) packetOutNotification;
-			broadcastArpRequestOutMyEdge(notification.packet, 
-					notification.getInSwitch(), notification.getInPort());
-			
-			// set timestamp
-			InetAddress addr = notification.getTargetAddress();
-			if (addr != null) {
-				for (ArpRequest request : arpRequests.get(addr)) {
-					request.setRequestTime();
-				}
-			}
-		}
-		else {
-			log.warn("Unknown packet out notification received");
-		}
-	}
+        MACAddress senderMacAddress = MACAddress.valueOf(arp
+                .getSenderHardwareAddress());
+
+        // See if anyone's waiting for this ARP reply
+        Set<ArpRequest> requests = arpRequests.get(senderIpAddress);
+
+        // Synchronize on the Multimap while using an iterator for one of the
+        // sets
+        List<ArpRequest> requestsToSend = new ArrayList<ArpRequest>(
+                requests.size());
+        synchronized (arpRequests) {
+            Iterator<ArpRequest> it = requests.iterator();
+            while (it.hasNext()) {
+                ArpRequest request = it.next();
+                it.remove();
+                requestsToSend.add(request);
+            }
+        }
+
+        // Don't hold an ARP lock while dispatching requests
+        for (ArpRequest request : requestsToSend) {
+            request.dispatchReply(senderIpAddress, senderMacAddress);
+        }
+    }
+
+    private void sendArpRequestForAddress(InetAddress ipAddress) {
+        // TODO what should the sender IP address and MAC address be if no
+        // IP addresses are configured? Will there ever be a need to send
+        // ARP requests from the controller in that case?
+        // All-zero MAC address doesn't seem to work - hosts don't respond to it
+
+        byte[] zeroIpv4 = {0x0, 0x0, 0x0, 0x0};
+        byte[] zeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+        byte[] genericNonZeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x01};
+        byte[] broadcastMac = {(byte) 0xff, (byte) 0xff, (byte) 0xff,
+                (byte) 0xff, (byte) 0xff, (byte) 0xff};
+
+        ARP arpRequest = new ARP();
+
+        arpRequest
+                .setHardwareType(ARP.HW_TYPE_ETHERNET)
+                .setProtocolType(ARP.PROTO_TYPE_IP)
+                .setHardwareAddressLength(
+                        (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                .setProtocolAddressLength((byte) IPv4.ADDRESS_LENGTH)
+                .setOpCode(ARP.OP_REQUEST).setTargetHardwareAddress(zeroMac)
+                .setTargetProtocolAddress(ipAddress.getAddress());
+
+        MACAddress routerMacAddress = configService.getRouterMacAddress();
+        // TODO hack for now as it's unclear what the MAC address should be
+        byte[] senderMacAddress = genericNonZeroMac;
+        if (routerMacAddress != null) {
+            senderMacAddress = routerMacAddress.toBytes();
+        }
+        arpRequest.setSenderHardwareAddress(senderMacAddress);
+
+        byte[] senderIPAddress = zeroIpv4;
+        Interface intf = configService.getOutgoingInterface(ipAddress);
+        if (intf != null) {
+            senderIPAddress = intf.getIpAddress().getAddress();
+        }
+
+        arpRequest.setSenderProtocolAddress(senderIPAddress);
+
+        Ethernet eth = new Ethernet();
+        eth.setSourceMACAddress(senderMacAddress)
+                .setDestinationMACAddress(broadcastMac)
+                .setEtherType(Ethernet.TYPE_ARP).setPayload(arpRequest);
+
+        if (vlan != NO_VLAN) {
+            eth.setVlanID(vlan).setPriorityCode((byte) 0);
+        }
+
+        // sendArpRequestToSwitches(ipAddress, eth.serialize());
+        datagrid.sendPacketOutNotification(new SinglePacketOutNotification(eth
+                .serialize(), ipAddress, intf.getDpid(), intf.getPort()));
+    }
+
+    private void sendArpRequestToSwitches(InetAddress dstAddress,
+            byte[] arpRequest) {
+        sendArpRequestToSwitches(dstAddress, arpRequest, 0,
+                OFPort.OFPP_NONE.getValue());
+    }
+
+    private void sendArpRequestToSwitches(InetAddress dstAddress,
+            byte[] arpRequest, long inSwitch, short inPort) {
+
+        if (configService.hasLayer3Configuration()) {
+            Interface intf = configService.getOutgoingInterface(dstAddress);
+            if (intf == null) {
+                // TODO here it should be broadcast out all non-interface edge
+                // ports.
+                // I think we can assume that if it's not a request for an
+                // external
+                // network, it's an ARP for a host in our own network. So we
+                // want to
+                // send it out all edge ports that don't have an interface
+                // configured
+                // to ensure it reaches all hosts in our network.
+                log.debug("No interface found to send ARP request for {}",
+                        dstAddress.getHostAddress());
+            } else {
+                sendArpRequestOutPort(arpRequest, intf.getDpid(),
+                        intf.getPort());
+            }
+        } else {
+            // broadcastArpRequestOutEdge(arpRequest, inSwitch, inPort);
+            broadcastArpRequestOutMyEdge(arpRequest, inSwitch, inPort);
+        }
+    }
+
+    private void sendArpReplyNotification(Ethernet eth, OFPacketIn pi) {
+        ARP arp = (ARP) eth.getPayload();
+
+        if (log.isTraceEnabled()) {
+            log.trace("Sending ARP reply for {} to other ONOS instances",
+                    inetAddressToString(arp.getSenderProtocolAddress()));
+        }
+
+        InetAddress targetAddress;
+
+        try {
+            targetAddress = InetAddress.getByAddress(arp
+                    .getSenderProtocolAddress());
+        } catch (UnknownHostException e) {
+            log.error("Unknown host", e);
+            return;
+        }
+
+        MACAddress mac = new MACAddress(arp.getSenderHardwareAddress());
+
+        datagrid.sendArpReplyNotification(new ArpReplyNotification(
+                targetAddress, mac));
+    }
+
+    private void broadcastArpRequestOutMyEdge(byte[] arpRequest, long inSwitch,
+            short inPort) {
+        List<SwitchPort> switchPorts = new ArrayList<SwitchPort>();
+
+        for (IOFSwitch sw : floodlightProvider.getSwitches().values()) {
+
+            OFPacketOut po = new OFPacketOut();
+            po.setInPort(OFPort.OFPP_NONE).setBufferId(-1)
+                    .setPacketData(arpRequest);
+
+            List<OFAction> actions = new ArrayList<OFAction>();
+
+            // TODO: Fix the code below after topoSwitchService was removed
+            /*
+            Iterable<IPortObject> ports
+            	= topoSwitchService.getPortsOnSwitch(sw.getStringId());
+            if (ports == null) {
+            	continue;
+            }
+
+            for (IPortObject portObject : ports) {
+            	if (!portObject.getLinkedPorts().iterator().hasNext()) {
+            		short portNumber = portObject.getNumber();
+
+            		if (sw.getId() == inSwitch && portNumber == inPort) {
+            			// This is the port that the ARP message came in,
+            			// so don't broadcast out this port
+            			continue;
+            		}
+
+            		switchPorts.add(new SwitchPort(new Dpid(sw.getId()),
+            				new Port(portNumber)));
+            		actions.add(new OFActionOutput(portNumber));
+            	}
+            }
+            */
+
+            po.setActions(actions);
+            short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
+            po.setActionsLength(actionsLength);
+            po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
+                    + arpRequest.length);
+
+            flowPusher.add(sw, po);
+        }
+
+        if (log.isTraceEnabled()) {
+            log.trace("Broadcast ARP request to: {}", switchPorts);
+        }
+    }
+
+    private void sendArpRequestOutPort(byte[] arpRequest, long dpid, short port) {
+        if (log.isTraceEnabled()) {
+            log.trace("Sending ARP request out {}/{}",
+                    HexString.toHexString(dpid), port);
+        }
+
+        OFPacketOut po = new OFPacketOut();
+        po.setInPort(OFPort.OFPP_NONE).setBufferId(-1)
+                .setPacketData(arpRequest);
+
+        List<OFAction> actions = new ArrayList<OFAction>();
+        actions.add(new OFActionOutput(port));
+        po.setActions(actions);
+        short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
+        po.setActionsLength(actionsLength);
+        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength
+                + arpRequest.length);
+
+        IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
+
+        if (sw == null) {
+            log.warn("Switch not found when sending ARP request");
+            return;
+        }
+
+        flowPusher.add(sw, po);
+    }
+
+    private void sendArpReply(ARP arpRequest, long dpid, short port,
+            MACAddress targetMac) {
+        if (log.isTraceEnabled()) {
+            log.trace(
+                    "Sending reply {} => {} to {}",
+                    new Object[] {
+                            inetAddressToString(arpRequest
+                                    .getTargetProtocolAddress()),
+                            targetMac,
+                            inetAddressToString(arpRequest
+                                    .getSenderProtocolAddress())});
+        }
+
+        ARP arpReply = new ARP();
+        arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
+                .setProtocolType(ARP.PROTO_TYPE_IP)
+                .setHardwareAddressLength(
+                        (byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
+                .setProtocolAddressLength((byte) IPv4.ADDRESS_LENGTH)
+                .setOpCode(ARP.OP_REPLY)
+                .setSenderHardwareAddress(targetMac.toBytes())
+                .setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
+                .setTargetHardwareAddress(arpRequest.getSenderHardwareAddress())
+                .setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
+                .setSourceMACAddress(targetMac.toBytes())
+                .setEtherType(Ethernet.TYPE_ARP).setPayload(arpReply);
+
+        if (vlan != NO_VLAN) {
+            eth.setVlanID(vlan).setPriorityCode((byte) 0);
+        }
+
+        List<OFAction> actions = new ArrayList<OFAction>();
+        actions.add(new OFActionOutput(port));
+
+        OFPacketOut po = new OFPacketOut();
+        po.setInPort(OFPort.OFPP_NONE)
+                .setBufferId(-1)
+                .setPacketData(eth.serialize())
+                .setActions(actions)
+                .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
+                .setLengthU(
+                        OFPacketOut.MINIMUM_LENGTH
+                                + OFActionOutput.MINIMUM_LENGTH
+                                + po.getPacketData().length);
+
+        List<OFMessage> msgList = new ArrayList<OFMessage>();
+        msgList.add(po);
+
+        IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
+
+        if (sw == null) {
+            log.warn("Switch {} not found when sending ARP reply",
+                    HexString.toHexString(dpid));
+            return;
+        }
+
+        flowPusher.add(sw, po);
+    }
+
+    private String inetAddressToString(byte[] bytes) {
+        try {
+            return InetAddress.getByAddress(bytes).getHostAddress();
+        } catch (UnknownHostException e) {
+            log.debug("Invalid IP address", e);
+            return "";
+        }
+    }
+
+    /*
+     * IProxyArpService methods
+     */
+
+    @Override
+    public MACAddress getMacAddress(InetAddress ipAddress) {
+        // return arpCache.lookup(ipAddress);
+        return null;
+    }
+
+    @Override
+    public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
+            boolean retry) {
+        arpRequests.put(ipAddress, new ArpRequest(requester, retry));
+
+        // Sanity check to make sure we don't send a request for our own address
+        if (!configService.isInterfaceAddress(ipAddress)) {
+            sendArpRequestForAddress(ipAddress);
+        }
+    }
+
+    @Override
+    public List<String> getMappings() {
+        return new ArrayList<String>();
+    }
+
+    /*
+    @Override
+    public void arpRequestNotification(ArpMessage arpMessage) {
+    	log.debug("Received ARP notification from other instances");
+
+    	switch (arpMessage.getType()){
+    	case REQUEST:
+    		if(arpMessage.getOutSwitch() == -1 || arpMessage.getOutPort() == -1){
+    			broadcastArpRequestOutMyEdge(arpMessage.getPacket(),
+    					arpMessage.getInSwitch(), arpMessage.getInPort());
+    		}else{
+    			sendArpRequestOutPort(arpMessage.getPacket(),arpMessage.getOutSwitch(),arpMessage.getOutPort());
+    			log.debug("OutSwitch in ARP request message is: {}; " +
+    			"OutPort in ARP request message is: {}",arpMessage.getOutSwitch(),arpMessage.getOutPort());
+    		}
+    		break;
+    	case REPLY:
+    		log.debug("Received ARP reply notification for {}",
+    				arpMessage.getAddress());
+    		sendArpReplyToWaitingRequesters(arpMessage.getAddress(),arpMessage.getMAC());
+    		break;
+    	}
+    }
+    */
+
+    private void sendArpReplyToWaitingRequesters(InetAddress address,
+            MACAddress mac) {
+        log.debug("Sending ARP reply for {} to requesters",
+                address.getHostAddress());
+
+        // See if anyone's waiting for this ARP reply
+        Set<ArpRequest> requests = arpRequests.get(address);
+
+        // Synchronize on the Multimap while using an iterator for one of the
+        // sets
+        List<ArpRequest> requestsToSend = new ArrayList<ArpRequest>(
+                requests.size());
+        synchronized (arpRequests) {
+            Iterator<ArpRequest> it = requests.iterator();
+            while (it.hasNext()) {
+                ArpRequest request = it.next();
+                it.remove();
+                requestsToSend.add(request);
+            }
+        }
+
+        /*IDeviceObject deviceObject = deviceStorage.getDeviceByIP(
+        		InetAddresses.coerceToInteger(address));
+
+        MACAddress mac = MACAddress.valueOf(deviceObject.getMACAddress());
+
+        log.debug("Found {} at {} in network map",
+        		address.getHostAddress(), mac);*/
+
+        // Don't hold an ARP lock while dispatching requests
+        for (ArpRequest request : requestsToSend) {
+            request.dispatchReply(address, mac);
+        }
+    }
+
+    @Override
+    public void arpReplyEvent(ArpReplyNotification arpReply) {
+        log.debug("Received ARP reply notification for {}",
+                arpReply.getTargetAddress());
+        sendArpReplyToWaitingRequesters(arpReply.getTargetAddress(),
+                arpReply.getTargetMacAddress());
+    }
+
+    @Override
+    public void packetOutNotification(
+            PacketOutNotification packetOutNotification) {
+
+        if (packetOutNotification instanceof SinglePacketOutNotification) {
+            SinglePacketOutNotification notification = (SinglePacketOutNotification) packetOutNotification;
+            sendArpRequestOutPort(notification.packet,
+                    notification.getOutSwitch(), notification.getOutPort());
+
+            // set timestamp
+            InetAddress addr = notification.getTargetAddress();
+            if (addr != null) {
+                for (ArpRequest request : arpRequests.get(addr)) {
+                    request.setRequestTime();
+                }
+            }
+        } else if (packetOutNotification instanceof BroadcastPacketOutNotification) {
+            BroadcastPacketOutNotification notification = (BroadcastPacketOutNotification) packetOutNotification;
+            broadcastArpRequestOutMyEdge(notification.packet,
+                    notification.getInSwitch(), notification.getInPort());
+
+            // set timestamp
+            InetAddress addr = notification.getTargetAddress();
+            if (addr != null) {
+                for (ArpRequest request : arpRequests.get(addr)) {
+                    request.setRequestTime();
+                }
+            }
+        } else {
+            log.warn("Unknown packet out notification received");
+        }
+    }
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
index d654f67..ab9a9b5 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
@@ -5,34 +5,53 @@
 // TODO This class is too generic to be handled by ProxyArpService.
 /**
  * Notification to another ONOS instance to send a packet out a single port.
- *
  */
 public class SinglePacketOutNotification extends PacketOutNotification {
 
-	private static final long serialVersionUID = 1L;
-	
-	private final InetAddress address;
-	private final long outSwitch;
-	private final short outPort;
-	
-	public SinglePacketOutNotification(byte[] packet, InetAddress address,
-			long outSwitch, short outPort) {
-		super(packet);
-		
-		this.address = address;
-		this.outSwitch = outSwitch;
-		this.outPort = outPort;
-	}
+    private static final long serialVersionUID = 1L;
 
-	public long getOutSwitch() {
-		return outSwitch;
-	}
+    private final InetAddress address;
+    private final long outSwitch;
+    private final short outPort;
 
-	public short getOutPort() {
-		return outPort;
-	}
+    /**
+     * Class constructor.
+     * @param packet the packet data to send in the packet-out
+     * @param address target IP address if the packet is an ARP packet
+     * @param outSwitch the dpid of the switch to send the packet on
+     * @param outPort the port number of the port to send the packet out
+     */
+    public SinglePacketOutNotification(byte[] packet, InetAddress address,
+            long outSwitch, short outPort) {
+        super(packet);
 
-	public InetAddress getTargetAddress() {
-		return address;
-	}
+        this.address = address;
+        this.outSwitch = outSwitch;
+        this.outPort = outPort;
+    }
+
+    /**
+     * Get the dpid of the switch the packet will be sent out.
+     * @return the switch's dpid
+     */
+    public long getOutSwitch() {
+        return outSwitch;
+    }
+
+    /**
+     * Get the port number of the port the packet will be sent out.
+     * @return the port number
+     */
+    public short getOutPort() {
+        return outPort;
+    }
+
+    /**
+     * Get the target IP address if the packet is an ARP packet.
+     * @return the target IP address for ARP packets, or null if the packet is
+     *         not an ARP packet
+     */
+    public InetAddress getTargetAddress() {
+        return address;
+    }
 }
