Removed Floodlight DeviceManager and created a stripped-down device manager that pushes device data from every packet seen into the network map
diff --git a/conf/onos-embedded.properties b/conf/onos-embedded.properties
index 8ae143e..dddacdb 100644
--- a/conf/onos-embedded.properties
+++ b/conf/onos-embedded.properties
@@ -1,7 +1,6 @@
 floodlight.modules = net.floodlightcontroller.core.FloodlightProvider,\
 net.floodlightcontroller.threadpool.ThreadPool,\
 net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
-net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
 net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.onrc.onos.datagrid.HazelcastDatagrid,\
 net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
diff --git a/conf/onos.properties b/conf/onos.properties
index b748b40..e77e6e0 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -1,7 +1,6 @@
 floodlight.modules = net.floodlightcontroller.core.FloodlightProvider,\
 net.floodlightcontroller.threadpool.ThreadPool,\
 net.onrc.onos.ofcontroller.floodlightlistener.NetworkGraphPublisher, \
-net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
 net.floodlightcontroller.ui.web.StaticWebRoutable,\
 net.onrc.onos.datagrid.HazelcastDatagrid,\
 net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
index 13b9182..2eddadf 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
@@ -2,6 +2,7 @@
 
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.devicemanager.OnosDevice;
 
 public interface IDeviceStorage extends INetMapStorage {
 	
@@ -12,5 +13,7 @@
 	public IDeviceObject getDeviceByMac(String mac);
 	public IDeviceObject getDeviceByIP(int ipv4Address);
 	public void changeDeviceAttachments(IDevice device);
-	public void changeDeviceIPv4Address(IDevice device);	
+	public void changeDeviceIPv4Address(IDevice device);
+	
+	public void addOnosDevice(OnosDevice onosDevice);
 }
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 4bbc054..a71b762 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
@@ -11,6 +11,8 @@
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.devicemanager.OnosDevice;
 
 import org.openflow.util.HexString;
 import org.slf4j.Logger;
@@ -314,5 +316,72 @@
 			}
 		}
 	}
+	
+	/**
+	 * Takes an {@link OnosDevice} and adds it into the database. There is no
+	 * checking of the database data and removing old data - an 
+	 * {@link OnosDevice} basically corresponds to a packet we've just seen,
+	 * and we need to add that information into the database.
+	 */
+	@Override
+	public void addOnosDevice(OnosDevice onosDevice) {
+		
+		String macAddress = HexString.toHexString(onosDevice.getMacAddress().toBytes());
+		
+		try {
+			IDeviceObject device = ope.searchDevice(macAddress);
+			
+			if (device == null) {
+				device = ope.newDevice();
+				device.setType("device");
+				device.setState("ACTIVE");
+				device.setMACAddress(macAddress);
+			}
+			
+			// Check if the device has the IP address, add it if it doesn't
+			// TODO multiple IP addresses
+			if (onosDevice.getIpv4Address() != null) {
+				boolean hasIpAddress = false;
+				for (IIpv4Address ipv4Address : device.getIpv4Addresses()) {
+					if (ipv4Address.getIpv4Address() == onosDevice.getIpv4Address().intValue()) {
+						hasIpAddress = true;
+						break;
+					}
+				}
+				
+				if (!hasIpAddress) {
+					IIpv4Address ipv4Address = ope.ensureIpv4Address(onosDevice.getIpv4Address().intValue());
+					IDeviceObject oldDevice = ipv4Address.getDevice();
+					if (oldDevice != null && oldDevice.getMACAddress() != macAddress) {
+						oldDevice.removeIpv4Address(ipv4Address);
+					}
+					device.addIpv4Address(ipv4Address);
+				}
+			}
+			
+			// Check if the device has the attachment point, add it if not
+			String switchDpid = HexString.toHexString(onosDevice.getSwitchDPID());
+			boolean hasAttachmentPoint = false;
+			for (IPortObject portObject : device.getAttachedPorts()) {
+				ISwitchObject switchObject = portObject.getSwitch();
+				if (switchObject.getDPID().equals(switchDpid)
+						&& portObject.getNumber() == onosDevice.getSwitchPort()) {
+					hasAttachmentPoint = true;
+					break;
+				}
+			}
+			
+			if (!hasAttachmentPoint) {
+				IPortObject portObject = ope.searchPort(switchDpid, onosDevice.getSwitchPort());
+				portObject.setDevice(device);
+			}
+			
+			ope.commit();
+		}
+		catch (TitanException e) {
+			log.error("addOnosDevice {} failed:", macAddress, e);
+			ope.rollback();
+		}
+	}
 
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/IOnosDeviceService.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/IOnosDeviceService.java
new file mode 100644
index 0000000..1e40aa5
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/IOnosDeviceService.java
@@ -0,0 +1,14 @@
+package net.onrc.onos.ofcontroller.devicemanager;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+/**
+ * {@link OnosDeviceManager} doesn't yet provide any API to fellow modules,
+ * however making it export a dummy service means we can specify it as 
+ * a dependency of Forwarding
+ * @author jono
+ *
+ */
+public interface IOnosDeviceService extends IFloodlightService {
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java
new file mode 100644
index 0000000..34d2c38
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDevice.java
@@ -0,0 +1,274 @@
+/**
+*    Copyright 2011,2012, Big Switch Networks, Inc. 
+*    Originally created by David Erickson, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+package net.onrc.onos.ofcontroller.devicemanager;
+
+import java.util.Date;
+
+import net.floodlightcontroller.devicemanager.internal.Entity;
+import net.floodlightcontroller.packet.IPv4;
+import net.floodlightcontroller.util.MACAddress;
+
+/**
+ * An entity on the network is a visible trace of a device that corresponds
+ * to a packet received from a particular interface on the edge of a network,
+ * with a particular VLAN tag, and a particular MAC address, along with any
+ * other packet characteristics we might want to consider as helpful for
+ * disambiguating devices.
+ * 
+ * Entities are the most basic element of devices; devices consist of one or
+ * more entities.  Entities are immutable once created, except for the last
+ * seen timestamp.
+ *  
+ * @author readams
+ *
+ */
+public class OnosDevice { //implements Comparable<OnosDevice> {
+    /**
+     * Timeout for computing {@link Entity#activeSince}.
+     * @see {@link Entity#activeSince}
+     */
+    private static int ACTIVITY_TIMEOUT = 30000;
+    
+    /**
+     * The MAC address associated with this entity
+     */
+    private MACAddress macAddress;
+    
+    /**
+     * The IP address associated with this entity, or null if no IP learned
+     * from the network observation associated with this entity
+     */
+    private Integer ipv4Address;
+    
+    /**
+     * The VLAN tag on this entity, or null if untagged
+     */
+    private Short vlan;
+    
+    /**
+     * The DPID of the switch for the ingress point for this entity,
+     * or null if not present
+     */
+    private long switchDPID;
+    
+    /**
+     * The port number of the switch for the ingress point for this entity,
+     * or null if not present
+     */
+    private short switchPort;
+    
+    /**
+     * The last time we observed this entity on the network
+     */
+    private Date lastSeenTimestamp;
+
+    /**
+     * The time between {@link Entity#activeSince} and 
+     * {@link Entity#lastSeenTimestamp} is a period of activity for this
+     * entity where it was observed repeatedly.  If, when the entity is
+     * observed, the  is longer ago than the activity timeout, 
+     * {@link Entity#lastSeenTimestamp} and {@link Entity#activeSince} will 
+     * be set to the current time.
+     */
+    private Date activeSince;
+    
+    private int hashCode = 0;
+
+    // ************
+    // Constructors
+    // ************
+    
+    /**
+     * Create a new entity
+     * 
+     * @param macAddress
+     * @param vlan
+     * @param ipv4Address
+     * @param switchDPID
+     * @param switchPort
+     * @param lastSeenTimestamp
+     */
+    public OnosDevice(MACAddress macAddress, Short vlan, 
+                  Integer ipv4Address, Long switchDPID, short switchPort, 
+                  Date lastSeenTimestamp) {
+        this.macAddress = macAddress;
+        this.ipv4Address = ipv4Address;
+        this.vlan = vlan;
+        this.switchDPID = switchDPID;
+        this.switchPort = switchPort;
+        this.lastSeenTimestamp = lastSeenTimestamp;
+        this.activeSince = lastSeenTimestamp;
+    }
+
+    // ***************
+    // Getters/Setters
+    // ***************
+
+    public MACAddress getMacAddress() {
+        return macAddress;
+    }
+
+    public Integer getIpv4Address() {
+        return ipv4Address;
+    }
+
+    public Short getVlan() {
+        return vlan;
+    }
+
+    public Long getSwitchDPID() {
+        return switchDPID;
+    }
+
+    public short getSwitchPort() {
+        return switchPort;
+    }
+
+    public Date getLastSeenTimestamp() {
+        return lastSeenTimestamp;
+    }
+
+    /**
+     * Set the last seen timestamp and also update {@link Entity#activeSince}
+     * if appropriate
+     * @param lastSeenTimestamp the new last seen timestamp
+     * @see {@link Entity#activeSince}
+     */
+    public void setLastSeenTimestamp(Date lastSeenTimestamp) {
+        if (activeSince == null ||
+            (activeSince.getTime() +  ACTIVITY_TIMEOUT) <
+                lastSeenTimestamp.getTime())
+            this.activeSince = lastSeenTimestamp;
+        this.lastSeenTimestamp = lastSeenTimestamp;
+    }
+
+    public Date getActiveSince() {
+        return activeSince;
+    }
+
+    public void setActiveSince(Date activeSince) {
+        this.activeSince = activeSince;
+    }
+    
+    /*
+    @Override
+    public int hashCode() {
+        if (hashCode != 0) return hashCode;
+        final int prime = 31;
+        hashCode = 1;
+        hashCode = prime * hashCode
+                 + ((ipv4Address == null) ? 0 : ipv4Address.hashCode());
+        //hashCode = prime * hashCode + (int) (macAddress ^ (macAddress >>> 32));
+        hashCode = prime * macAddress.hashCode();
+        hashCode = prime * hashCode + (int) (switchDPID ^ (switchDPID >>> 32));
+        hashCode = prime * hashCode + switchPort;
+        hashCode = prime * hashCode + ((vlan == null) ? 0 : vlan.hashCode());
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        Entity other = (Entity) obj;
+        if (hashCode() != other.hashCode()) return false;
+        if (ipv4Address == null) {
+            if (other.ipv4Address != null) return false;
+        } else if (!ipv4Address.equals(other.ipv4Address)) return false;
+        if (macAddress != other.macAddress) return false;
+        if (switchDPID == null) {
+            if (other.switchDPID != null) return false;
+        } else if (!switchDPID.equals(other.switchDPID)) return false;
+        if (switchPort == null) {
+            if (other.switchPort != null) return false;
+        } else if (!switchPort.equals(other.switchPort)) return false;
+        if (vlan == null) {
+            if (other.vlan != null) return false;
+        } else if (!vlan.equals(other.vlan)) return false;
+        return true;
+    }
+    */
+
+    
+    
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("Entity [macAddress=");
+        builder.append(macAddress.toString());
+        builder.append(", ipv4Address=");
+        builder.append(IPv4.fromIPv4Address(ipv4Address==null ?
+                       0 : ipv4Address.intValue()));
+        builder.append(", vlan=");
+        builder.append(vlan);
+        builder.append(", switchDPID=");
+        builder.append(switchDPID);
+        builder.append(", switchPort=");
+        builder.append(switchPort);
+        builder.append(", lastSeenTimestamp=");
+        builder.append(lastSeenTimestamp == null? "null" : lastSeenTimestamp.getTime());
+        builder.append(", activeSince=");
+        builder.append(activeSince == null? "null" : activeSince.getTime());
+        builder.append("]");
+        return builder.toString();
+    }
+
+    /*
+    @Override
+    public int compareTo(OnosDevice o) {
+        if (macAddress < o.macAddress) return -1;
+        if (macAddress > o.macAddress) return 1;
+
+        int r;
+        if (switchDPID == null)
+            r = o.switchDPID == null ? 0 : -1;
+        else if (o.switchDPID == null)
+            r = 1;
+        else
+            r = switchDPID.compareTo(o.switchDPID);
+        if (r != 0) return r;
+
+        if (switchPort == null)
+            r = o.switchPort == null ? 0 : -1;
+        else if (o.switchPort == null)
+            r = 1;
+        else
+            r = switchPort.compareTo(o.switchPort);
+        if (r != 0) return r;
+
+        if (ipv4Address == null)
+            r = o.ipv4Address == null ? 0 : -1;
+        else if (o.ipv4Address == null)
+            r = 1;
+        else
+            r = ipv4Address.compareTo(o.ipv4Address);
+        if (r != 0) return r;
+
+        if (vlan == null)
+            r = o.vlan == null ? 0 : -1;
+        else if (o.vlan == null)
+            r = 1;
+        else
+            r = vlan.compareTo(o.vlan);
+        if (r != 0) return r;
+
+        return 0;
+    }*/
+    
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
new file mode 100644
index 0000000..a776eaa
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/devicemanager/OnosDeviceManager.java
@@ -0,0 +1,189 @@
+package net.onrc.onos.ofcontroller.devicemanager;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.FloodlightContext;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFMessageListener;
+import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.IUpdate;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.packet.ARP;
+import net.floodlightcontroller.packet.DHCP;
+import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.IPv4;
+import net.floodlightcontroller.packet.UDP;
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
+
+import org.openflow.protocol.OFMessage;
+import org.openflow.protocol.OFPacketIn;
+import org.openflow.protocol.OFType;
+
+public class OnosDeviceManager implements IFloodlightModule, IOFMessageListener,
+										IOnosDeviceService {
+	private IDeviceStorage deviceStorage;
+	
+	private IFloodlightProviderService floodlightProvider;
+
+	public class OnosDeviceUpdate implements IUpdate {
+		private OnosDevice device;
+		
+		public OnosDeviceUpdate(OnosDevice device) {
+			this.device = device;
+		}
+		
+		@Override
+		public void dispatch() {
+			deviceStorage.addOnosDevice(device);
+		}
+	}
+	
+	@Override
+	public String getName() {
+		return "onosdevicemanager";
+	}
+
+	@Override
+	public boolean isCallbackOrderingPrereq(OFType type, String name) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public boolean isCallbackOrderingPostreq(OFType type, String name) {
+		return type == OFType.PACKET_IN && 
+				("proxyarpmanager".equals(name) || "onosforwarding".equals(name));
+	}
+
+	@Override
+	public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
+		if (msg.getType().equals(OFType.PACKET_IN)) {
+			OFPacketIn pi = (OFPacketIn) msg;
+			
+			Ethernet eth = IFloodlightProviderService.bcStore.
+					get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+			
+			return processPacketIn(sw, pi, eth);
+		}
+		
+		return Command.CONTINUE;
+	}
+	
+	private Command processPacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
+		
+        // Extract source entity information
+        OnosDevice srcDevice =
+                getSourceDeviceFromPacket(eth, sw.getId(), pi.getInPort());
+        if (srcDevice == null)
+            return Command.STOP;
+        
+        floodlightProvider.publishUpdate(new OnosDeviceUpdate(srcDevice));
+        
+        return Command.CONTINUE;
+	}
+	
+    /**
+     * Get IP address from packet if the packet is either an ARP 
+     * or a DHCP packet
+     * @param eth
+     * @param dlAddr
+     * @return
+     */
+    private int getSrcNwAddr(Ethernet eth, long dlAddr) {
+        if (eth.getPayload() instanceof ARP) {
+            ARP arp = (ARP) eth.getPayload();
+            if ((arp.getProtocolType() == ARP.PROTO_TYPE_IP) &&
+                    (Ethernet.toLong(arp.getSenderHardwareAddress()) == dlAddr)) {
+                return IPv4.toIPv4Address(arp.getSenderProtocolAddress());
+            }
+        } else if (eth.getPayload() instanceof IPv4) {
+            IPv4 ipv4 = (IPv4) eth.getPayload();
+            if (ipv4.getPayload() instanceof UDP) {
+                UDP udp = (UDP)ipv4.getPayload();
+                if (udp.getPayload() instanceof DHCP) {
+                    DHCP dhcp = (DHCP)udp.getPayload();
+                    if (dhcp.getOpCode() == DHCP.OPCODE_REPLY) {
+                        return ipv4.getSourceAddress();
+                    }
+                }
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Parse an entity from an {@link Ethernet} packet.
+     * @param eth the packet to parse
+     * @param sw the switch on which the packet arrived
+     * @param pi the original packetin
+     * @return the entity from the packet
+     */
+    private OnosDevice getSourceDeviceFromPacket(Ethernet eth,
+                                             long swdpid,
+                                             short port) {
+        byte[] dlAddrArr = eth.getSourceMACAddress();
+        long dlAddr = Ethernet.toLong(dlAddrArr);
+
+        // Ignore broadcast/multicast source
+        if ((dlAddrArr[0] & 0x1) != 0)
+            return null;
+
+        short vlan = eth.getVlanID();
+        int nwSrc = getSrcNwAddr(eth, dlAddr);
+        return new OnosDevice(MACAddress.valueOf(dlAddr),
+                          ((vlan >= 0) ? vlan : null),
+                          ((nwSrc != 0) ? nwSrc : null),
+                          swdpid,
+                          port,
+                          new Date());
+    }
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+		List<Class<? extends IFloodlightService>> services = 
+				new ArrayList<Class<? extends IFloodlightService>>();
+		services.add(IOnosDeviceService.class);
+		return services;
+	}
+
+	@Override
+	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+		Map<Class<? extends IFloodlightService>, IFloodlightService> impls = 
+				new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+		impls.put(IOnosDeviceService.class, this);
+		return impls;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+		List<Class<? extends IFloodlightService>> dependencies = 
+				new ArrayList<Class<? extends IFloodlightService>>();
+		dependencies.add(IFloodlightProviderService.class);
+		return dependencies;
+	}
+
+	@Override
+	public void init(FloodlightModuleContext context)
+			throws FloodlightModuleException {
+		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+		
+		deviceStorage = new DeviceStorageImpl();
+		deviceStorage.init("");
+	}
+
+	@Override
+	public void startUp(FloodlightModuleContext context) {
+		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+	}
+
+}
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 4b31667..da5a6f4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/floodlightlistener/NetworkGraphPublisher.java
@@ -8,13 +8,6 @@
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.net.InetAddresses;
-
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchListener;
@@ -25,7 +18,6 @@
 import net.floodlightcontroller.core.util.SingletonTask;
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.onrc.onos.datagrid.IDatagridService;
@@ -35,10 +27,10 @@
 import net.onrc.onos.graph.LocalTopologyEventListener;
 import net.onrc.onos.ofcontroller.core.IDeviceStorage;
 import net.onrc.onos.ofcontroller.core.ILinkStorage;
-import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
-import net.onrc.onos.ofcontroller.core.ISwitchStorage;
 import net.onrc.onos.ofcontroller.core.INetMapStorage.DM_OPERATION;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
+import net.onrc.onos.ofcontroller.core.IOFSwitchPortListener;
+import net.onrc.onos.ofcontroller.core.ISwitchStorage;
 import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
 import net.onrc.onos.ofcontroller.core.internal.LinkStorageImpl;
 import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
@@ -51,6 +43,13 @@
 import net.onrc.onos.registry.controller.IControllerRegistryService.ControlChangeCallback;
 import net.onrc.onos.registry.controller.RegistryException;
 
+import org.openflow.protocol.OFPhysicalPort;
+import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.net.InetAddresses;
+
 public class NetworkGraphPublisher implements IDeviceListener,
 					      IOFSwitchListener,
 					      IOFSwitchPortListener,
@@ -62,7 +61,7 @@
 	protected ISwitchStorage swStore;
 	protected ILinkStorage linkStore;
 	protected final static Logger log = LoggerFactory.getLogger(NetworkGraphPublisher.class);
-	protected IDeviceService deviceService;
+	//protected IDeviceService deviceService;
 	protected IControllerRegistryService registryService;
 	protected GraphDBOperation op;
 	
@@ -431,7 +430,7 @@
 	    Collection<Class<? extends IFloodlightService>> l =
 	            new ArrayList<Class<? extends IFloodlightService>>();
 	        l.add(IFloodlightProviderService.class);
-	        l.add(IDeviceService.class);
+	        //l.add(IDeviceService.class);
 	        l.add(IDatagridService.class);
 	        l.add(IThreadPoolService.class);
 	        return l;
@@ -446,7 +445,7 @@
 		
 		floodlightProvider =
 	            context.getServiceImpl(IFloodlightProviderService.class);
-		deviceService = context.getServiceImpl(IDeviceService.class);
+		//deviceService = context.getServiceImpl(IDeviceService.class);
 		linkDiscovery = context.getServiceImpl(ILinkDiscoveryService.class);
 		threadPool = context.getServiceImpl(IThreadPoolService.class);
 		registryService = context.getServiceImpl(IControllerRegistryService.class);
@@ -470,7 +469,7 @@
 		Map<String, String> configMap = context.getConfigParams(this);
 		String cleanupNeeded = configMap.get(CleanupEnabled);
 
-		deviceService.addListener(this);
+		//deviceService.addListener(this);
 		floodlightProvider.addOFSwitchListener(this);
 		linkDiscovery.addListener(this);
 		
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 bd51fdc..4b2b087 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -25,6 +25,7 @@
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
+import net.onrc.onos.ofcontroller.devicemanager.IOnosDeviceService;
 import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
 import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
 import net.onrc.onos.ofcontroller.proxyarp.ArpMessage;
@@ -51,8 +52,8 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.ListMultimap;
 import com.google.common.net.InetAddresses;
 
 public class Forwarding implements IOFMessageListener, IFloodlightModule,
@@ -71,7 +72,7 @@
 	private TopologyManager topologyService;
 	
 	private Map<Path, Long> pendingFlows;
-	private Multimap<Long, PacketToPush> waitingPackets;
+	private ListMultimap<Long, PacketToPush> waitingPackets;
 	
 	private final Object lock = new Object();
 	
@@ -139,6 +140,7 @@
 		dependencies.add(IFloodlightProviderService.class);
 		dependencies.add(IFlowService.class);
 		dependencies.add(IFlowPusherService.class);
+		dependencies.add(IOnosDeviceService.class);
 		return dependencies;
 	}
 	
@@ -155,7 +157,8 @@
 		pendingFlows = new ConcurrentHashMap<Path, Long>();
 		//waitingPackets = Multimaps.synchronizedSetMultimap(
 				//HashMultimap.<Long, PacketToPush>create());
-		waitingPackets = HashMultimap.create();
+		//waitingPackets = HashMultimap.create();
+		waitingPackets = LinkedListMultimap.create();
 		
 		deviceStorage = new DeviceStorageImpl();
 		deviceStorage.init("");
@@ -176,7 +179,8 @@
 	@Override
 	public boolean isCallbackOrderingPrereq(OFType type, String name) {
 		return (type == OFType.PACKET_IN) && 
-				(name.equals("devicemanager") || name.equals("proxyarpmanager"));
+				(name.equals("devicemanager") || name.equals("proxyarpmanager")
+				|| name.equals("onosdevicemanager"));
 	}
 
 	@Override
@@ -234,7 +238,7 @@
 		// our non-ARP packets.
 		// TODO This should be refactored later to account for the new use case.
 		datagrid.sendArpRequest(ArpMessage.newRequest(targetAddress, eth.serialize(),
-				sw.getId(), pi.getInPort()));
+				-1L, (short)-1, sw.getId(), pi.getInPort()));
 	}
 	
 	private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
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 5d09f96..23ee9ce 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -223,13 +223,15 @@
 							entry.getKey().getHostAddress());
 		
 					//if he ARP Request is expired and then delete the device
+					/*
 					IDeviceObject targetDevice = 
 							deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(entry.getKey()));
 					
 					if(targetDevice!=null)
 					{deviceStorage.removeDevice(targetDevice);
 					 log.debug("RemoveDevice: {} due to no have not recieve the ARP reply", targetDevice.toString());
-					}				
+					}
+					*/				
 					
 					it.remove();
 					
@@ -263,7 +265,7 @@
 	@Override
 	public boolean isCallbackOrderingPrereq(OFType type, String name) {
 		if (type == OFType.PACKET_IN) {
-			return "devicemanager".equals(name);
+			return "devicemanager".equals(name) || "onosdevicemanager".equals(name);
 		}
 		else {
 			return false;
@@ -272,7 +274,7 @@
 
 	@Override
 	public boolean isCallbackOrderingPostreq(OFType type, String name) {
-		return false;
+		return type == OFType.PACKET_IN && "onosforwarding".equals(name);
 	}
 
 	@Override
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index a842665..b37fbf6 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -21,3 +21,4 @@
 net.onrc.onos.ofcontroller.forwarding.Forwarding
 net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager
 net.onrc.onos.ofcontroller.core.config.DefaultConfiguration
+net.onrc.onos.ofcontroller.devicemanager.OnosDeviceManager