diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDevice.java b/src/main/java/net/floodlightcontroller/devicemanager/IDevice.java
index 95969f8c859299fabd53d5a0d917db3ff90230fe..4593b7bac9d8f4b25f9a3c1e5c4693bfd1a0fca0 100644
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDevice.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IDevice.java
@@ -64,6 +64,11 @@ public interface IDevice {
      * @return an array containing all unique attachment points for the device
      */
     public SwitchPort[] getAttachmentPoints();
+    /**
+     * Get all old attachment points associated with the device.  this is used in host movement scenario.
+     * @return an array containing all unique old attachment points for the device
+     */
+    public SwitchPort[] getOldAP();
     
     /**
      * Get all unique attachment points associated with the device.
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
index e6083f93acf39a4f356443e051d9ef3d4ee3177d..854952937f5a5e07fc847b0eeb030567886c9a3b 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/Device.java
@@ -560,6 +560,30 @@ public class Device implements IDevice {
     // IDevice
     // *******
 
+    @Override
+    public SwitchPort[] getOldAP() {
+        List<SwitchPort> sp = new ArrayList<SwitchPort>();
+        SwitchPort [] returnSwitchPorts = new SwitchPort[] {};
+        if (oldAPs == null) return returnSwitchPorts;
+        if (oldAPs.isEmpty()) return returnSwitchPorts;
+
+        // copy ap list.
+        List<AttachmentPoint> oldAPList;
+        oldAPList = new ArrayList<AttachmentPoint>();
+
+        if (oldAPs != null) oldAPList.addAll(oldAPs);
+        removeExpiredAttachmentPoints(oldAPList);
+
+        if (oldAPList != null) {
+            for(AttachmentPoint ap: oldAPList) {
+                SwitchPort swport = new SwitchPort(ap.getSw(),
+                                                   ap.getPort());
+                    sp.add(swport);
+            }
+        }
+        return sp.toArray(new SwitchPort[sp.size()]);
+    }
+
     @Override
     public SwitchPort[] getAttachmentPoints() {
         return getAttachmentPoints(false);
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index 2c82e6076f2b4c8c4b90961386c8ed9fd779a6f0..dcbd07a21730e1c3dea7bf631b4a7b157395ce8c 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -634,7 +634,6 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
         Device srcDevice = findDeviceByEntity(srcEntity);
         if (srcDevice == null)
             return Command.STOP;
-
         // Store the source device in the context
         fcStore.put(ofm.cntx, CONTEXT_SRC_DEVICE, srcDevice);
 
@@ -1015,8 +1014,10 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
             inPort = ofmWithSwDpid.getOfMatch().getInputPort();
         }
 
-        boolean learnap = true;
-        if (swDpid == null ||
+        /**for the new flow cache design, the flow mods retrived are not always from the source, learn AP should be disabled --meiyang*/
+        boolean learnap = false;
+        /**
+         * if (swDpid == null ||
             inPort == null ||
             !isValidAttachmentPoint(swDpid, inPort)) {
             // If this is an internal port or we otherwise don't want
@@ -1027,6 +1028,7 @@ IFlowReconcileListener, IInfoProvider, IHAListener {
             // as a key field.
             learnap = false;
         }
+        */
 
         short vlan = ofmWithSwDpid.getOfMatch().getDataLayerVirtualLan();
         return new Entity(dlAddr,
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java b/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java
index 4e48683cb2ff79322b083de8bbf4dc1c43461556..77ebe134700e2e879e7d11c255a8391da0e1514b 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FCQueryObj.java
@@ -17,9 +17,14 @@
 package net.floodlightcontroller.flowcache;
 
 import java.util.Arrays;
+import java.util.List;
+
+import org.openflow.protocol.OFPort;
 
 import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
+import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.floodlightcontroller.flowcache.IFlowReconcileEngineService.FCQueryEvType;
+import net.floodlightcontroller.flowcache.PriorityPendingQueue.EventPriority;
 
 
 /**
@@ -27,33 +32,100 @@ import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
  */
 public class FCQueryObj {
 
-    /** The caller of the flow cache query. */
+    /** The caller of the flow query. */
     public IFlowQueryHandler fcQueryHandler;
     /** The application instance name. */
     public String applInstName;
+    /*BVS interface name*/
+    public String appInstInterfaceName;
     /** The vlan Id. */
     public Short[] vlans;
     /** The destination device. */
     public IDevice dstDevice;
     /** The source device. */
     public IDevice srcDevice;
+    /*source switch DPID*/
+    public long srcSwId;
+    /*switch port */
+    public short swPort;
+    public List<String> swPortList;
+    /*ip subnet*/
+    public String srcIpsubnet;
+    public String destIpsubnet;
+    public String srcBVS;
+    public String destBVS;
+    /*BVS priority change*/
+    public int lowP;
+    public int highP;
     /** The caller name */
     public String callerName;
-    /** Event type that triggered this flow query submission */
+    /** Event type and priority that triggered this flow query submission */
     public FCQueryEvType evType;
+    public EventPriority evPriority;
     /** The caller opaque data. Returned unchanged in the query response
      * via the callback. The type of this object could be different for
      * different callers */
     public Object callerOpaqueObj;
+    public DIRECTION direction;
+    public SwitchPort[] oldAp;
+    public enum DIRECTION {
+        INGRESS,
+        EGRESS,
+        BOTH
+    };
 
     /**
-     * Instantiates a new flow cache query object
+     * Instantiates a new flow query object
      */
+    public FCQueryObj(FCQueryEvType evType) {
+        this.evType = evType;
+        this.evPriority = mapEventToPriority(evType);
+        this.fcQueryHandler    = null;
+        this.applInstName     = null;
+        this.srcDevice        = null;
+        this.dstDevice        = null;
+        this.callerName       = null;
+        this.callerOpaqueObj  = null;
+        this.vlans=null;
+        this.appInstInterfaceName = null;
+        this.srcSwId = 0L;
+        this.swPort = OFPort.OFPP_NONE.getValue();
+        this.srcIpsubnet = null;
+        this.destIpsubnet = null;
+        this.srcBVS = null;
+        this.destBVS = null;
+        this.lowP = -1;
+        this.highP = -1;
+        this.oldAp =null;
+        this.direction=null;
+    }
+
+    public static EventPriority mapEventToPriority(FCQueryEvType type) {
+        EventPriority priority=EventPriority.EVENT_LOW;
+        switch (type) {
+            case DEVICE_MOVED:
+                priority=EventPriority.EVENT_HIGH;
+                break;
+            case LINK_DOWN:
+                priority=EventPriority.EVENT_MEDIUM;
+                break;
+            default:
+                break;
+        }
+        return priority;
+    }
+
+    /**
+     * Instantiates a new flow query object
     public FCQueryObj(IFlowQueryHandler fcQueryHandler,
             String        applInstName,
+            String        appInstInterfaceName,
             Short         vlan,
             IDevice       srcDevice,
             IDevice       dstDevice,
+            IOFSwitch     srcSW,
+            short           swPort,
+            String        ipSubnet,
             String        callerName,
             FCQueryEvType evType,
             Object        callerOpaqueObj) {
@@ -64,14 +136,33 @@ public class FCQueryObj {
         this.callerName       = callerName;
         this.evType           = evType;
         this.callerOpaqueObj  = callerOpaqueObj;
-        
         if (vlan != null) {
         	this.vlans = new Short[] { vlan };
         } else {
             this.vlans = null;
         }
+        if (appInstInterfaceName != null) {
+            this.appInstInterfaceName = new String(appInstInterfaceName);
+        } else {
+            this.appInstInterfaceName = null;
+        }
+        if (srcSW != null) {
+            this.srcSW =  srcSW;
+        } else {
+            this.srcSW = null;
+        }
+        if (swPort != OFPort.OFPP_NONE.getValue()) {
+            this.swPort =  swPort;
+        } else {
+            this.swPort = OFPort.OFPP_NONE.getValue();
+        }
+        if (srcIpsubnet != null) {
+            this.srcIpsubnet =new String(ipSubnet);
+        } else {
+            this.srcIpsubnet =null;
+        }
     }
-
+*/
     @Override
     public String toString() {
         return "FCQueryObj [fcQueryCaller=" + fcQueryHandler
@@ -134,8 +225,18 @@ public class FCQueryObj {
             if (other.srcDevice != null) return false;
         } else if (!srcDevice.equals(other.srcDevice)) return false;
         if (!Arrays.equals(vlans, other.vlans)) return false;
+
+        if (srcSwId == 0L) {
+            if (other.srcSwId != 0L) return false;
+        } else if (srcSwId != other.srcSwId) return false;
+        if (!Arrays.equals(vlans, other.vlans)) return false;
+        if (swPort != other.swPort) return false;
+        if (srcIpsubnet == null) {
+            if (other.srcIpsubnet != null) return false;
+        } else if (!srcIpsubnet.equals(other.srcIpsubnet)) return false;
+        if (appInstInterfaceName == null) {
+            if (other.appInstInterfaceName != null) return false;
+        } else if (!appInstInterfaceName.equals(other.appInstInterfaceName)) return false;
         return true;
     }
-    
-    
 }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
index 578fa5b73862559260d6fd2704a5c42fabd364cf..d557016a7acc8849530a2f461f5fb5e97f18be00 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/FlowReconcileManager.java
@@ -22,8 +22,6 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -39,9 +37,10 @@ import net.floodlightcontroller.counter.ICounter;
 import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.counter.SimpleCounter;
 import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
+import net.floodlightcontroller.flowcache.IFlowReconcileEngineService.FCQueryEvType;
 import net.floodlightcontroller.flowcache.IFlowReconcileListener;
 import net.floodlightcontroller.flowcache.OFMatchReconcile;
+import net.floodlightcontroller.flowcache.PriorityPendingQueue.EventPriority;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 
 import org.openflow.protocol.OFType;
@@ -69,7 +68,7 @@ public class FlowReconcileManager
                                                flowReconcileListeners;
 
     /** A FIFO queue to keep all outstanding flows for reconciliation */
-    Queue<OFMatchReconcile> flowQueue;
+    PriorityPendingQueue <OFMatchReconcile> flowQueue;
     
     /** Asynchronous task to feed the flowReconcile pipeline */
     protected SingletonTask flowReconcileTask;
@@ -125,13 +124,13 @@ public class FlowReconcileManager
      *
      * @param ofmRcIn the ofm rc in
      */
-    public void reconcileFlow(OFMatchReconcile ofmRcIn) {
+    public void reconcileFlow(OFMatchReconcile ofmRcIn, EventPriority priority) {
         if (ofmRcIn == null) return;
         
         // Make a copy before putting on the queue.
         OFMatchReconcile myOfmRc = new OFMatchReconcile(ofmRcIn);
     
-        flowQueue.add(myOfmRc);
+        flowQueue.offer(myOfmRc, priority);
     
         Date currTime = new Date();
         long delay = 0;
@@ -169,17 +168,17 @@ public class FlowReconcileManager
     
     @Override
     public void flowQueryGenericHandler(FlowCacheQueryResp flowResp) {
+/** remove temporarily -- meiyang rivisit needed
         if (flowResp.queryObj.evType != FCQueryEvType.GET) {
             OFMatchReconcile ofmRc = new OFMatchReconcile();;
-            /* Re-provision these flows */
             for (QRFlowCacheObj entry : flowResp.qrFlowCacheObjList) {
-                /* reconcile the flows in entry */
                 entry.toOFMatchReconcile(ofmRc,
                         flowResp.queryObj.applInstName,
                         OFMatchReconcile.ReconcileAction.UPDATE_PATH);
                 reconcileFlow(ofmRc);
             }
         }
+        */
         return;
     }
     
@@ -220,7 +219,7 @@ public class FlowReconcileManager
         threadPool = context.getServiceImpl(IThreadPoolService.class);
         counterStore = context.getServiceImpl(ICounterStoreService.class);
     
-        flowQueue = new ConcurrentLinkedQueue<OFMatchReconcile>();
+        flowQueue = new PriorityPendingQueue<OFMatchReconcile>();
         flowReconcileListeners = 
                 new ListenerDispatcher<OFType, IFlowReconcileListener>();
         
@@ -298,8 +297,9 @@ public class FlowReconcileManager
             reconcileCapacity--;
             if (ofmRc != null) {
                 ofmRcList.add(ofmRc);
-                if (logger.isTraceEnabled()) {
-                    logger.trace("Add flow {} to be the reconcileList", ofmRc.cookie);
+               // if (logger.isTraceEnabled())
+                {
+                    logger.info("Add flow {} to be the reconcileList", ofmRc.cookie);
                 }
             } else {
                 break;
@@ -320,8 +320,9 @@ public class FlowReconcileManager
         
             for (IFlowReconcileListener flowReconciler :
                 flowReconcileListeners.getOrderedListeners()) {
-                if (logger.isTraceEnabled()) {
-                    logger.trace("Reconciling flow: call listener {}",
+               // if (logger.isTraceEnabled())
+                {
+                    logger.info("Reconciling flow: call listener {}",
                             flowReconciler.getName());
                 }
                 retCmd = flowReconciler.reconcileFlows(ofmRcList);
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java
index 8c74729247fbcf8ceefcaf29d8bf7c4e5e5576d0..4a358802e18290332f62173efe0efa1b398eb11e 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/IFlowCacheService.java
@@ -50,23 +50,17 @@ public interface IFlowCacheService extends IFloodlightService {
         /** The GET query. Flows need not be reconciled for this query type */
         GET,
         /** A new App was added. */
-        APP_ADDED,
+        BVS_ADDED,
         /** An App was deleted. */
-        APP_DELETED,
+        BVS_DELETED,
         /** Interface rule of an app was modified */
-        APP_INTERFACE_RULE_CHANGED,
+        BVS_INTERFACE_RULE_CHANGED_MATCH_SWITCH_PORT,
         /** Some App configuration was changed */
-        APP_CONFIG_CHANGED,
-        /** An ACL was added */
-        ACL_ADDED,
-        /** An ACL was deleted */
-        ACL_DELETED,
-        /** An ACL rule was added */
-        ACL_RULE_ADDED,
-        /** An ACL rule was deleted */
-        ACL_RULE_DELETED,
+        BVS_PRIORITY_CHANGED,
         /** ACL configuration was changed */
         ACL_CONFIG_CHANGED,
+        /** VRS routing rule was changed */
+        VRS_ROUTING_RULE_CHANGED,
         /** device had moved to a different port in the network */
         DEVICE_MOVED,
         /** device's property had changed, such as tag assignment */
diff --git a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java b/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java
index 20b32f1240da5729b704bd5426916fe0c25af579..a842c7cf42261f26854a0d04a7bbed258b292bce 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/IFlowReconcileService.java
@@ -22,7 +22,8 @@ package net.floodlightcontroller.flowcache;
 
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
+import net.floodlightcontroller.flowcache.IFlowReconcileEngineService.FCQueryEvType;
+import net.floodlightcontroller.flowcache.PriorityPendingQueue.EventPriority;
 
 public interface IFlowReconcileService extends IFloodlightService {
     /**
@@ -49,7 +50,7 @@ public interface IFlowReconcileService extends IFloodlightService {
      *
      * @param ofmRcIn the ofm rc in
      */
-    public void reconcileFlow(OFMatchReconcile ofmRcIn);
+    public void reconcileFlow(OFMatchReconcile ofmRcIn, EventPriority priority) ;
     
     /**
      * Updates the flows to a device after the device moved to a new location
@@ -88,4 +89,5 @@ public interface IFlowReconcileService extends IFloodlightService {
      * @param flowResp
      */
     public void flowQueryGenericHandler(FlowCacheQueryResp flowResp);
+
 }
diff --git a/src/main/java/net/floodlightcontroller/flowcache/PendingSwitchResp.java b/src/main/java/net/floodlightcontroller/flowcache/PendingSwitchResp.java
index 695456134d24dc63e1385c1b9af1884d722e7aa9..29e691fded824567a1f89adc072f2b3d6acb571a 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/PendingSwitchResp.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/PendingSwitchResp.java
@@ -16,7 +16,8 @@
 
 package net.floodlightcontroller.flowcache;
 
-import net.floodlightcontroller.flowcache.IFlowCacheService.FCQueryEvType;
+import net.floodlightcontroller.flowcache.IFlowReconcileEngineService.FCQueryEvType;
+
 
 /**
  * The Class PendingSwitchResp. This object is used to track the pending
diff --git a/src/main/java/net/floodlightcontroller/flowcache/PortDownReconciliation.java b/src/main/java/net/floodlightcontroller/flowcache/PortDownReconciliation.java
index 7360b4f5af30eb2eb228d03cb38027ce920f259e..28c5950918f67fb723e009f38bc9069326fad8bb 100644
--- a/src/main/java/net/floodlightcontroller/flowcache/PortDownReconciliation.java
+++ b/src/main/java/net/floodlightcontroller/flowcache/PortDownReconciliation.java
@@ -50,6 +50,7 @@ import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.flowcache.IFlowReconcileListener;
 import net.floodlightcontroller.flowcache.IFlowReconcileService;
 import net.floodlightcontroller.flowcache.OFMatchReconcile;
+import net.floodlightcontroller.flowcache.PriorityPendingQueue.EventPriority;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery;
 import net.floodlightcontroller.linkdiscovery.LinkInfo;
 import net.floodlightcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
@@ -117,7 +118,7 @@ public class PortDownReconciliation implements IFloodlightModule,
                 ofmr.outPort = ldu.getSrcPort();
 
                 // Tell the reconcile manager to reconcile matching flows
-                frm.reconcileFlow(ofmr);
+                frm.reconcileFlow(ofmr, EventPriority.EVENT_HIGH);
             }
         }
     }
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index 5a6827f49cd1b5e21a0a94490e70bd6dc106af5d..d8b76126118ca1739c835cef56305e9220b97f76 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -250,7 +250,9 @@ public abstract class ForwardingBase
                 // cache. Don't set the flag for ARP messages - TODO generalize check
                 if ((reqeustFlowRemovedNotifn)
                         && (match.getDataLayerType() != Ethernet.TYPE_ARP)) {
+                    /**with new flow cache design, we don't need the flow removal message from switch anymore
                     fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+                    */
                     match.setWildcards(fm.getMatch().getWildcards());
                 }
             }
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
index 3e227bde13f3853eb45f8586a04cb3369346bf6d..0ceedfc966f9a6281d9528ead03d2fcc52c939a2 100644
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
+++ b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
@@ -476,7 +476,7 @@ public class VirtualNetworkFilter
         .setMatch(match)
         .setActions(actions)
         .setLengthU(OFFlowMod.MINIMUM_LENGTH);
-        fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
+//        fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
         try {
             if (log.isTraceEnabled()) {
                 log.trace("write drop flow-mod srcSwitch={} match={} " +