diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
index 5d9a38fc947bae9a079a64f11df579bbe2b652c0..777bfaf44d87997e9a4020f7beec87977e698620 100644
--- a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
+++ b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
@@ -423,11 +423,11 @@ public class OFMessageFilterManager
                 packetClient.pushMessageAsync(sendMsg);
             }
         } catch (TTransportException e) {
-            log.error("Caught TTransportException: {}", e);
+            log.error("Caught TTransportException: {}", e.getMessage());
             disconnectFromPSServer();
             connectToPSServer();
         } catch (Exception e) {
-            log.error("Caught exception: {}", e);
+            log.error("Caught exception: {}", e.getMessage());
             disconnectFromPSServer();
             connectToPSServer();
         }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index d61231fa66a1e94b44b14e84bf850d3162152b80..a2de33dd27ca5da397c6e77635e44e775d1e0bf4 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -656,7 +656,7 @@ public class Controller implements IFloodlightProviderService,
                         // If role is MASTER we will promote switch to active
                         // list when we receive the switch's role reply messages
                         log.debug("This controller's role is {}, " + 
-                        		"sending initial role request msg to {}",
+                                "sending initial role request msg to {}",
                                 role, sw);
                         Collection<OFSwitchImpl> swList = new ArrayList<OFSwitchImpl>(1);
                         swList.add(sw);
@@ -666,7 +666,7 @@ public class Controller implements IFloodlightProviderService,
                         // Role supported not enabled on controller (for now)
                         // automatically promote switch to active state. 
                         log.debug("This controller's role is null, " + 
-                        		"not sending role request msg to {}",
+                                "not sending role request msg to {}",
                                 role, sw);
                         // Need to clear FlowMods before we add the switch
                         // and dispatch updates otherwise we have a race condition.
@@ -773,7 +773,7 @@ public class Controller implements IFloodlightProviderService,
             state.firstRoleReplyReceived = true;
         }
 
-		protected boolean handleVendorMessage(OFVendor vendorMessage) {
+        protected boolean handleVendorMessage(OFVendor vendorMessage) {
             boolean shouldHandleMessage = false;
             int vendor = vendorMessage.getVendor();
             switch (vendor) {
@@ -815,7 +815,9 @@ public class Controller implements IFloodlightProviderService,
             
             switch (m.getType()) {
                 case HELLO:
-                    log.debug("HELLO from {}", sw);
+                    if (log.isDebugEnabled())
+                        log.debug("HELLO from {}", sw);
+                    
                     if (state.hsState.equals(HandshakeState.START)) {
                         state.hsState = HandshakeState.HELLO;
                         sendHelloConfiguration();
@@ -833,7 +835,9 @@ public class Controller implements IFloodlightProviderService,
                 case ECHO_REPLY:
                     break;
                 case FEATURES_REPLY:
-                    log.debug("Features Reply from {}", sw);
+                    if (log.isDebugEnabled())
+                        log.debug("Features Reply from {}", sw);
+                    
                     if (state.hsState.equals(HandshakeState.HELLO)) {
                         sw.setFeaturesReply((OFFeaturesReply) m);
                         sendFeatureReplyConfiguration();
@@ -847,6 +851,9 @@ public class Controller implements IFloodlightProviderService,
                     }
                     break;
                 case GET_CONFIG_REPLY:
+                    if (log.isDebugEnabled())
+                        log.debug("Get config reply from {}", sw);
+                    
                     if (!state.hsState.equals(HandshakeState.FEATURES_REPLY)) {
                         String em = "Unexpected GET_CONFIG_REPLY from " + sw;
                         throw new SwitchStateException(em);
@@ -1288,7 +1295,7 @@ public class Controller implements IFloodlightProviderService,
         // No need to acquire the listener lock, since
         // this method is only called after netty has processed all
         // pending messages
-    	log.debug("removeSwitch: {}", sw);
+        log.debug("removeSwitch: {}", sw);
         if (!this.activeSwitches.remove(sw.getId(), sw) || !sw.isConnected()) {
             log.debug("Not removing switch {}; already removed", sw);
             return;
@@ -1581,7 +1588,7 @@ public class Controller implements IFloodlightProviderService,
     }
     
     protected void updateInactiveSwitchInfo(IOFSwitch sw) {
-    	log.debug("Update DB with inactiveSW {}", sw);
+        log.debug("Update DB with inactiveSW {}", sw);
         // Update the controller info in the storage source to be inactive
         Map<String, Object> switchInfo = new HashMap<String, Object>();
         String datapathIdString = sw.getStringId();
@@ -1662,7 +1669,7 @@ public class Controller implements IFloodlightProviderService,
         //for (Short portNum : oldports.keySet()) {
         //    sw.deletePort(portNum);
         //}
-	}
+    }
     
     protected void removePortInfo(IOFSwitch sw, short portNumber) {
         String datapathIdString = sw.getStringId();
@@ -1702,11 +1709,11 @@ public class Controller implements IFloodlightProviderService,
                     roleString = properties.getProperty("floodlight.role");
                 }
                 catch (IOException exc) {
-                	// Don't treat it as an error if the file specified by the
-                	// rolepath property doesn't exist. This lets us enable the
-                	// HA mechanism by just creating/setting the floodlight.role
-                	// property in that file without having to modify the
-                	// floodlight properties.
+                    // Don't treat it as an error if the file specified by the
+                    // rolepath property doesn't exist. This lets us enable the
+                    // HA mechanism by just creating/setting the floodlight.role
+                    // property in that file without having to modify the
+                    // floodlight properties.
                 }
             }
         }
@@ -2016,9 +2023,9 @@ public class Controller implements IFloodlightProviderService,
         }
     }
 
-	@Override
-	public long getSystemStartTime() {
-		return (this.systemStartTime);
-	}
+    @Override
+    public long getSystemStartTime() {
+        return (this.systemStartTime);
+    }
 
 }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
index 7f06870ca1085fabf50e2eebf3a9beeabd8de5d2..948714f079d8a3806e0bf0377282e58d1bfe1a99 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
@@ -18,8 +18,10 @@
 package net.floodlightcontroller.core.internal;
 
 import java.io.IOException;
+import java.net.SocketAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -37,11 +39,14 @@ import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IFloodlightProviderService.Role;
 import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.types.MacVlanPair;
+import net.floodlightcontroller.core.web.serializers.DPIDSerializer;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.util.TimedCache;
 
 import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.ser.ToStringSerializer;
 import org.jboss.netty.channel.Channel;
 import org.openflow.protocol.OFFeaturesReply;
 import org.openflow.protocol.OFFlowMod;
@@ -82,8 +87,6 @@ public class OFSwitchImpl implements IOFSwitch {
     protected Channel channel;
     protected AtomicInteger transactionIdSource;
     protected Map<Short, OFPhysicalPort> ports;
-    protected Long switchClusterId;
-    protected Map<MacVlanPair,Short> macVlanToPortMap;
     protected Map<Integer,OFStatisticsFuture> statsFutureMap;
     protected Map<Integer, IOFMessageListener> iofMsgListenersMap;
     protected boolean connected;
@@ -132,7 +135,6 @@ public class OFSwitchImpl implements IOFSwitch {
         this.connectedSince = new Date();
         this.transactionIdSource = new AtomicInteger();
         this.ports = new ConcurrentHashMap<Short, OFPhysicalPort>();
-        this.switchClusterId = null;
         this.connected = true;
         this.statsFutureMap = new ConcurrentHashMap<Integer,OFStatisticsFuture>();
         this.iofMsgListenersMap = new ConcurrentHashMap<Integer,IOFMessageListener>();
@@ -241,27 +243,20 @@ public class OFSwitchImpl implements IOFSwitch {
         channel.close();
     }
 
+    @JsonIgnore
     public OFFeaturesReply getFeaturesReply() {
         return this.featuresReply;
     }
     
-    public void setSwitchClusterId(Long id) {
-        this.switchClusterId = id;
-    }
-    
-    public Long getSwitchClusterId() {
-        return switchClusterId;
-    }
-
     public synchronized void setFeaturesReply(OFFeaturesReply featuresReply) {
         this.featuresReply = featuresReply;
         for (OFPhysicalPort port : featuresReply.getPorts()) {
             ports.put(port.getPortNumber(), port);
         }
-        this.switchClusterId = featuresReply.getDatapathId();
         this.stringId = HexString.toHexString(featuresReply.getDatapathId());
     }
 
+    @JsonIgnore
     public synchronized List<OFPhysicalPort> getEnabledPorts() {
         List<OFPhysicalPort> result = new ArrayList<OFPhysicalPort>();
         for (OFPhysicalPort port : ports.values()) {
@@ -280,9 +275,15 @@ public class OFSwitchImpl implements IOFSwitch {
         ports.put(port.getPortNumber(), port);
     }
     
+    @JsonIgnore
     public Map<Short, OFPhysicalPort> getPorts() {
         return ports;
     }
+    
+    @JsonProperty("ports")
+    public Collection<OFPhysicalPort> getPortCollection() {
+        return ports.values();
+    }
 
     public synchronized void deletePort(short portNumber) {
         ports.remove(portNumber);
@@ -306,12 +307,15 @@ public class OFSwitchImpl implements IOFSwitch {
     }
     
     @Override
+    @JsonSerialize(using=DPIDSerializer.class)
+    @JsonProperty("dpid")
     public long getId() {
         if (this.featuresReply == null)
             throw new RuntimeException("Features reply has not yet been set");
         return this.featuresReply.getDatapathId();
     }
 
+    @JsonIgnore
     @Override
     public String getStringId() {
         return stringId;
@@ -335,6 +339,7 @@ public class OFSwitchImpl implements IOFSwitch {
         return connectedSince;
     }
 
+    @JsonIgnore
     @Override
     public int getNextTransactionId() {
         return this.transactionIdSource.incrementAndGet();
@@ -409,6 +414,7 @@ public class OFSwitchImpl implements IOFSwitch {
         this.threadPool = tp;
     }
 
+    @JsonIgnore
     @Override
     public synchronized boolean isConnected() {
         return connected;
@@ -424,6 +430,7 @@ public class OFSwitchImpl implements IOFSwitch {
         return role;
     }
     
+    @JsonIgnore
     @Override
     public boolean isActive() {
         return (role != Role.SLAVE);
@@ -469,6 +476,7 @@ public class OFSwitchImpl implements IOFSwitch {
     }
 
     @Override
+    @JsonIgnore
     public Map<Short, Long> getPortBroadcastHits() {
     	return this.portBroadcastCacheHitMap;
     }
@@ -517,6 +525,15 @@ public class OFSwitchImpl implements IOFSwitch {
     public Lock getListenerWriteLock() {
         return listenerLock.writeLock();
     }
+
+    /**
+     * Get the IP Address for the switch
+     * @return the inet address
+     */
+    @JsonSerialize(using=ToStringSerializer.class)
+    public SocketAddress getInetAddress() {
+        return channel.getRemoteAddress();
+    }
     
     /**
      * Send NX role request message to the switch requesting the specified role.
diff --git a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
index c8f74860e7369ecb789be974bc3343ba86afcf78..454f566cf78fbf5fcf1ec73c705a59e99a0d83d4 100644
--- a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
@@ -17,14 +17,16 @@
 
 package net.floodlightcontroller.core.web;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.Collections;
+import java.util.Iterator;
 
 import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.util.FilterIterator;
 
+import org.openflow.util.HexString;
+import org.restlet.data.Form;
+import org.restlet.data.Status;
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
 
@@ -33,19 +35,47 @@ import org.restlet.resource.ServerResource;
  * @author readams
  */
 public class ControllerSwitchesResource extends ServerResource {
+    public static final String DPID_ERROR = 
+            "Invalid Switch DPID: must be a 64-bit quantity, expressed in " + 
+            "hex as AA:BB:CC:DD:EE:FF:00:11";
+    
     @Get("json")
-    public List<Map<String, String>> retrieve() {
-        List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>();
+    public Iterator<IOFSwitch> retrieve() {
         IFloodlightProviderService floodlightProvider = 
                 (IFloodlightProviderService)getContext().getAttributes().
                     get(IFloodlightProviderService.class.getCanonicalName());
-        Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches();
 
-        for (IOFSwitch s: switches.values()) {
-            Map<String, String> m = new HashMap<String, String>();
-            m.put("dpid", s.getStringId());
-            switchIds.add(m);
+        Long switchDPID = null;
+        
+        Form form = getQuery();
+        String dpid = form.getFirstValue("dpid", true);
+        if (dpid != null) {
+            try {
+                switchDPID = HexString.toLong(dpid);
+            } catch (Exception e) {
+                setStatus(Status.CLIENT_ERROR_BAD_REQUEST, DPID_ERROR);
+                return null;
+            }
         }
-        return switchIds;
+        if (switchDPID != null) {
+            IOFSwitch sw = 
+                    floodlightProvider.getSwitches().get(switchDPID);
+            if (sw != null)
+                return Collections.singleton(sw).iterator();
+            return Collections.<IOFSwitch>emptySet().iterator();
+        }
+        final String dpidStartsWith = 
+                form.getFirstValue("dpid__startswith", true);
+        Iterator<IOFSwitch> switer = 
+                floodlightProvider.getSwitches().values().iterator();
+        if (dpidStartsWith != null) {
+            return new FilterIterator<IOFSwitch>(switer) {
+                @Override
+                protected boolean matches(IOFSwitch value) {
+                    return value.getStringId().startsWith(dpidStartsWith);
+                }
+            };
+        } 
+        return switer;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..66c33f55bfbf5262049c9cf60c2c730fcd69a04a
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/web/serializers/ByteArrayMACSerializer.java
@@ -0,0 +1,40 @@
+/**
+*    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.floodlightcontroller.core.web.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.openflow.util.HexString;
+
+/**
+ * Serialize a MAC as colon-separated hexadecimal
+ */
+public class ByteArrayMACSerializer extends JsonSerializer<byte[]> {
+
+    @Override
+    public void serialize(byte[] mac, JsonGenerator jGen,
+                          SerializerProvider serializer)
+                                  throws IOException, JsonProcessingException {
+        jGen.writeString(HexString.toHexString(mac));
+    }
+
+}
diff --git a/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java b/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..c125c76fc6138924f4ac04ceb918ca7dcbe80d90
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/web/serializers/UShortSerializer.java
@@ -0,0 +1,40 @@
+/**
+*    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.floodlightcontroller.core.web.serializers;
+
+import java.io.IOException;
+
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.JsonSerializer;
+import org.codehaus.jackson.map.SerializerProvider;
+
+/**
+ * Serialize a short value as an unsigned short
+ */
+public class UShortSerializer extends JsonSerializer<Short> {
+
+    @Override
+    public void serialize(Short s, JsonGenerator jGen,
+                          SerializerProvider serializer) throws IOException,
+                                                  JsonProcessingException {
+        if (s == null) jGen.writeNull();
+        else jGen.writeNumber(s.shortValue() & 0xffff);
+    }
+
+}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
index 5d482c48133e1c09d0945bbc2d2117472523ee54..ad29a947fbed2a3af94e24259fe58701f7c5e778 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
@@ -189,17 +189,6 @@ public interface IDeviceService extends IFloodlightService {
      */
     public void addListener(IDeviceListener listener);
     
-    
-    /**
-     * Flush and/or reclassify all entities in a class
-     *
-     * @param entityClass the class to flush.  If null, flush all classes
-     * @param reclassify if true, begin an asynchronous task to reclassify the
-     * flushed entities
-     */
-    public void flushEntityCache(IEntityClass entityClass,
-                                 boolean reclassify);
-
     /**
      * Specify points in the network where attachment points are not to
      * be learned.
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..6029af1b6c855460a45b502e4c4f568761fc648f
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java
@@ -0,0 +1,35 @@
+/**
+*    Copyright 2011, 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.floodlightcontroller.devicemanager;
+
+import java.util.Set;
+
+/**
+ * Implementors of this interface can receive updates from DeviceManager about
+ * the changes entity Classes.
+ *
+ * @author Ananth Suryanarayana (Ananth.Suryanarayana@bigswitch.com)
+ */
+public interface IEntityClassListener {
+
+    /**
+     * Process entity classes change event.
+     * @param  entityClassNames Set of entity classes changed
+     */
+    public void entityClassChanged(Set<String> entityClassNames);
+}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java
index 8d693ce9220155f92ef2aef5ecfec785eee78c84..2569a7df54ed892464810ca415b12a52d1ea76a7 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java
@@ -98,5 +98,11 @@ public interface IEntityClassifierService extends IFloodlightService {
    void deviceUpdate(IDevice oldDevice, 
                      Collection<? extends IDevice> newDevices);
 
+   /**
+    * Adds a listener to listen for IEntityClassifierServices notifications
+    *
+    * @param listener The listener that wants the notifications
+    */
+   public void addListener(IEntityClassListener listener);
 }
 
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java
index 353a72d1b5b8a3e382feb895d6ac24e10bc9c8e8..948272a0c10a845edc33cf8b54a526aae5d7e8f6 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java
@@ -31,6 +31,7 @@ import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField;
 import net.floodlightcontroller.devicemanager.IEntityClass;
+import net.floodlightcontroller.devicemanager.IEntityClassListener;
 import net.floodlightcontroller.devicemanager.IEntityClassifierService;
 
 /**
@@ -46,6 +47,12 @@ public class DefaultEntityClassifier implements
      * A default fixed entity class
      */
     protected static class DefaultEntityClass implements IEntityClass {
+        String name;
+
+        public DefaultEntityClass(String name) {
+            this.name = name;
+        }
+
         @Override
         public EnumSet<IDeviceService.DeviceField> getKeyFields() {
             return keyFields;
@@ -53,7 +60,11 @@ public class DefaultEntityClassifier implements
 
         @Override
         public String getName() {
-            return "DefaultEntityClass";
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
         }
     }
     
@@ -61,7 +72,16 @@ public class DefaultEntityClassifier implements
     static {
         keyFields = EnumSet.of(DeviceField.MAC, DeviceField.VLAN);
     }
-    protected static IEntityClass entityClass = new DefaultEntityClass();
+    protected static DefaultEntityClass entityClass =
+        new DefaultEntityClass("DefaultEntityClass");
+
+    public void setClassifierName (String name) {
+        entityClass.setName(name);
+    }
+
+    public String getClassifierName (String name) {
+        return entityClass.getName();
+    }
     
     @Override
     public IEntityClass classifyEntity(Entity entity) {
@@ -121,4 +141,10 @@ public class DefaultEntityClassifier implements
     public void startUp(FloodlightModuleContext context) {
         // no-op
     }
+
+    @Override
+    public void addListener(IEntityClassListener listener) {
+        // no-op
+        
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index ba859bd9b13a525f8143d3627edc1e04b680d0fd..d5d53e5a9e502a46227a8c08462673cb0b92dfd5 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -49,6 +49,7 @@ import net.floodlightcontroller.core.util.SingletonTask;
 import net.floodlightcontroller.devicemanager.IDevice;
 import net.floodlightcontroller.devicemanager.IDeviceService;
 import net.floodlightcontroller.devicemanager.IEntityClass;
+import net.floodlightcontroller.devicemanager.IEntityClassListener;
 import net.floodlightcontroller.devicemanager.IEntityClassifierService;
 import net.floodlightcontroller.devicemanager.IDeviceListener;
 import net.floodlightcontroller.devicemanager.SwitchPort;
@@ -86,7 +87,7 @@ import org.slf4j.LoggerFactory;
  */
 public class DeviceManagerImpl implements
 IDeviceService, IOFMessageListener,
-IStorageSourceListener, IFloodlightModule,
+IStorageSourceListener, IFloodlightModule, IEntityClassListener,
 IFlowReconcileListener, IInfoProvider, IHAListener {
     protected static Logger logger =
             LoggerFactory.getLogger(DeviceManagerImpl.class);
@@ -461,12 +462,6 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         deviceListeners.add(listener);
     }
 
-    @Override
-    public void flushEntityCache(IEntityClass entityClass,
-                                 boolean reclassify) {
-        // TODO Auto-generated method stub
-    }
-
     // *************
     // IInfoProvider
     // *************
@@ -639,11 +634,12 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
         floodlightProvider.addHAListener(this);
         flowReconcileMgr.addFlowReconcileListener(this);
+        entityClassifier.addListener(this);
 
         Runnable ecr = new Runnable() {
             @Override
             public void run() {
-                cleanupEntities();
+                cleanupEntities(null, false);
                 entityCleanupTask.reschedule(ENTITY_CLEANUP_INTERVAL,
                                              TimeUnit.SECONDS);
             }
@@ -858,11 +854,18 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         if ((dlAddrArr[0] & 0x1) != 0)
             return null;
 
-        long swDpid = ofmWithSwDpid.getSwitchDataPathId();
-        short inPort = ofmWithSwDpid.getOfMatch().getInputPort();
+        Long swDpid = null;
+        Short inPort = null;
+        
+        if (isSource) {
+        	swDpid = ofmWithSwDpid.getSwitchDataPathId();
+        	inPort = ofmWithSwDpid.getOfMatch().getInputPort();
+        }
 
         boolean learnap = true;
-        if (!isValidAttachmentPoint(swDpid, inPort)) {
+        if (swDpid == null ||
+        		inPort == null ||
+        		!isValidAttachmentPoint(swDpid, inPort)) {
             // If this is an internal port or we otherwise don't want
             // to learn on these ports.  In the future, we should
             // handle this case by labeling flows with something that
@@ -1279,10 +1282,46 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         }
     }
 
+    /**
+     * Flush and/or reclassify all entities in a class
+     *
+     * @param entityClass the class to flush.  If null, flush all classes
+     * @param reclassify if true, begin an asynchronous task to reclassify the
+     * flushed entities
+     */
+    private void flushEntityCache (Set<String> entityClassChangedSet,
+                                   boolean reclassify) {
+        if (reclassify) return; // TODO
+
+        /*
+         * TODO This can be running at the same time by timer thread. Check
+         * and make sure that this is thread safe.
+         */
+        cleanupEntities(entityClassChangedSet, true);
+    }
+
+    // *********************
+    // IEntityClassListener
+    // *********************
+    @Override
+    public void entityClassChanged (Set<String> entityClassNames) {
+
+        /*
+         * Flush the entire device entity cache for now.
+         */
+        flushEntityCache(entityClassNames, false);
+        return;
+    }
+
     /**
      * Clean up expired entities/devices
+     *
+     * @param[in] forceCleanup ForceCleanup of entities irrespective of age
+     * @param[in] specificEntities Cleanup only a specific set of entities
      */
-    protected void cleanupEntities() {
+    protected void cleanupEntities (Set<String> specificEntities,
+                                    boolean forceCleanup) {
+
         Calendar c = Calendar.getInstance();
         c.add(Calendar.MILLISECOND, -ENTITY_TIMEOUT);
         Date cutoff = c.getTime();
@@ -1297,13 +1336,23 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         while (diter.hasNext()) {
             Device d = diter.next();
 
+            /*
+             * If we are cleaning entities for a specific set of devices,
+             * skip if not applicable.
+             */
+            if (specificEntities != null && d.getEntityClass() != null &&
+               !specificEntities.contains(d.getEntityClass().getName())) {
+                continue;
+            }
+
             while (true) {
                 deviceUpdates.clear();
                 toRemove.clear();
                 toKeep.clear();
                 for (Entity e : d.getEntities()) {
-                    if (e.getLastSeenTimestamp() != null &&
-                            0 > e.getLastSeenTimestamp().compareTo(cutoff)) {
+                    if (forceCleanup ||
+                        (e.getLastSeenTimestamp() != null &&
+                         0 > e.getLastSeenTimestamp().compareTo(cutoff))) {
                         // individual entity needs to be removed
                         toRemove.add(e);
                     } else {
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index a2eae4a43096dbbb083b3dab5be604ef058b8ced..445956a4d01cc8dd0bd40b1276f5275859f0c01d 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -47,11 +47,9 @@ import org.openflow.protocol.OFMatch;
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
 import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
 import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.U16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -534,29 +532,6 @@ public abstract class ForwardingBase implements
 
     @Override
     public void deviceMoved(IDevice device) {
-        // Build flow mod to delete based on destination mac == device mac
-        OFMatch match = new OFMatch();
-        match.setDataLayerDestination(Ethernet.toByteArray(device.getMACAddress()));
-        match.setWildcards(OFMatch.OFPFW_ALL ^ OFMatch.OFPFW_DL_DST);
-        long cookie =
-                AppCookie.makeCookie(FORWARDING_APP_ID, 0);
-        OFMessage fm = ((OFFlowMod) floodlightProvider.getOFMessageFactory()
-            .getMessage(OFType.FLOW_MOD))
-            .setCommand(OFFlowMod.OFPFC_DELETE)
-            .setOutPort((short) OFPort.OFPP_NONE.getValue())
-            .setMatch(match)
-            .setCookie(cookie)
-            .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH));
-
-        // Flush to all switches
-        for (IOFSwitch outSw : floodlightProvider.getSwitches().values()) {
-            try {
-                outSw.write(fm, null);
-            } catch (IOException e) {
-                log.error("Failure sending flow mod delete for moved device",
-                          e);
-            }
-        }
     }
 
     @Override
diff --git a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
index ea2ddca0275071e07b945eac4e415ea29ded50aa..b985bbbcb856f4181fbd5e7a439dd3080bad2c84 100644
--- a/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
+++ b/src/main/java/net/floodlightcontroller/topology/NodePortTuple.java
@@ -84,4 +84,8 @@ public class NodePortTuple {
             return false;
         return true;
     }
+    
+    public String toKeyString() {
+        return (HexString.toHexString(nodeId)+ "|" + portId);
+    }
 }
diff --git a/src/main/java/org/openflow/protocol/OFPhysicalPort.java b/src/main/java/org/openflow/protocol/OFPhysicalPort.java
index 009bef529214bb6c82826af778fe860f4835f364..58fdae59f56de9df28358e65f1b9cab038ab676e 100644
--- a/src/main/java/org/openflow/protocol/OFPhysicalPort.java
+++ b/src/main/java/org/openflow/protocol/OFPhysicalPort.java
@@ -21,16 +21,16 @@ import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
 import java.util.Arrays;
 
+import net.floodlightcontroller.core.web.serializers.ByteArrayMACSerializer;
+import net.floodlightcontroller.core.web.serializers.UShortSerializer;
 
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 import org.jboss.netty.buffer.ChannelBuffer;
-import org.openflow.protocol.serializers.OFPhysicalPortJSONSerializer;
 
 /**
  * Represents ofp_phy_port
  * @author David Erickson (daviderickson@cs.stanford.edu) - Mar 25, 2010
  */
-@JsonSerialize(using=OFPhysicalPortJSONSerializer.class)
 public class OFPhysicalPort {
     public static int MINIMUM_LENGTH = 48;
     public static int OFP_ETH_ALEN = 6;
@@ -221,6 +221,7 @@ public class OFPhysicalPort {
     /**
      * @return the portNumber
      */
+    @JsonSerialize(using=UShortSerializer.class)
     public short getPortNumber() {
         return portNumber;
     }
@@ -235,6 +236,7 @@ public class OFPhysicalPort {
     /**
      * @return the hardwareAddress
      */
+    @JsonSerialize(using=ByteArrayMACSerializer.class)
     public byte[] getHardwareAddress() {
         return hardwareAddress;
     }
diff --git a/src/main/java/org/openflow/protocol/serializers/OFPhysicalPortJSONSerializer.java b/src/main/java/org/openflow/protocol/serializers/OFPhysicalPortJSONSerializer.java
deleted file mode 100644
index b847a72c6c59add03167666ab998a4ecbde26005..0000000000000000000000000000000000000000
--- a/src/main/java/org/openflow/protocol/serializers/OFPhysicalPortJSONSerializer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
-*    Copyright 2011, 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 org.openflow.protocol.serializers;
-
-import java.io.IOException;
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.map.JsonSerializer;
-import org.codehaus.jackson.map.SerializerProvider;
-import org.openflow.protocol.OFPhysicalPort;
-import org.openflow.util.HexString;
-
-public class OFPhysicalPortJSONSerializer extends JsonSerializer<OFPhysicalPort> {
-
-    /**
-     * Performs the serialization of a OFPhysicalPort object
-     */
-    @Override
-    public void serialize(OFPhysicalPort port, JsonGenerator jGen, SerializerProvider serializer) throws IOException, JsonProcessingException {
-        jGen.writeStartObject();
-        jGen.writeNumberField("advertisedFeatures", port.getAdvertisedFeatures());
-        jGen.writeNumberField("config", port.getConfig());
-        jGen.writeNumberField("currentFeatures", port.getCurrentFeatures());
-        jGen.writeStringField("hardwareAddress", HexString.toHexString(port.getHardwareAddress()));
-        jGen.writeStringField("name", port.getName());
-        jGen.writeNumberField("peerFeatures", port.getPeerFeatures());
-        jGen.writeNumberField("portNumber", port.getPortNumber());
-        jGen.writeNumberField("state", port.getState());
-        jGen.writeNumberField("supportedFeatures", port.getSupportedFeatures());
-        jGen.writeEndObject();
-    }
-
-    /**
-     * Tells SimpleModule that we are the serializer for OFPhysicalPort
-     */
-    @Override
-    public Class<OFPhysicalPort> handledType() {
-        return OFPhysicalPort.class;
-    }
-
-}