diff --git a/build.xml b/build.xml
index 385c82399e3ab696865d3ce64eafbf642c21ce0c..3acd1ecf9e03b716194b449a40844da847343bdc 100644
--- a/build.xml
+++ b/build.xml
@@ -67,9 +67,6 @@
         <include name="jython-2.5.2.jar"/>
         <include name="libthrift-0.7.0.jar"/>
         <include name="guava-13.0.1.jar" />
-        <include name="httpclient-4.2.2.jar" />
-        <include name="httpcore-4.2.2.jar" />
-        <include name="json-simple-1.1.1.jar" />
     </patternset>
 
     <path id="classpath">
diff --git a/lib/httpclient-4.2.2.jar b/lib/httpclient-4.2.2.jar
deleted file mode 100644
index 5f768c46407a6506d46766d1011f2fac342ec333..0000000000000000000000000000000000000000
Binary files a/lib/httpclient-4.2.2.jar and /dev/null differ
diff --git a/lib/httpcore-4.2.2.jar b/lib/httpcore-4.2.2.jar
deleted file mode 100644
index a64cd2f5e3eff5ea0ff91a545ba2da4dc3fd612b..0000000000000000000000000000000000000000
Binary files a/lib/httpcore-4.2.2.jar and /dev/null differ
diff --git a/lib/json-simple-1.1.1.jar b/lib/json-simple-1.1.1.jar
deleted file mode 100644
index 66347a6c86b7d6442358ca7643e4dc484fb01866..0000000000000000000000000000000000000000
Binary files a/lib/json-simple-1.1.1.jar and /dev/null differ
diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
index bf897567280040891f82cf0997dd793a33b1af6b..fb7cd7d44d2167386a78534725956737adffdaad 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
@@ -374,6 +374,16 @@ public interface IOFSwitch {
      * @return value for name
      */
     Object getAttribute(String name);
+    
+    /**
+     * Check if the given attribute is present and if so whether it is equal
+     * to "other"
+     * @param name the name of the attribute to check
+     * @param other the object to compare the attribute against.
+     * @return true iff the specified attribute is set and equals() the given
+     * other object.
+     */
+    boolean attributeEquals(String name, Object other);
 
     /**
      * Set properties for switch specific behavior
diff --git a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java
index 39c017724eb632a2355e190c82635b018ecf9eb8..17bbcf07e292b25b7ad2dae2c675a80389aa199e 100644
--- a/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java
+++ b/src/main/java/net/floodlightcontroller/core/OFSwitchBase.java
@@ -147,13 +147,20 @@ public abstract class OFSwitchBase implements IOFSwitch {
         this.setAttribute(PROP_SUPPORTS_OFPP_TABLE, new Boolean(true));
     }
     
+    
+    @Override
+    public boolean attributeEquals(String name, Object other) {
+        Object attr = this.attributes.get(name);
+        if (attr == null)
+            return false;
+        return attr.equals(other);
+    }
+    
 
     @Override
     public Object getAttribute(String name) {
-        if (this.attributes.containsKey(name)) {
-            return this.attributes.get(name);
-        }
-        return null;
+        // returns null if key doesn't exist
+        return this.attributes.get(name);
     }
     
     @Override
@@ -172,6 +179,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
         return this.attributes.containsKey(name);
     }
         
+    @Override
     @JsonIgnore
     public void setChannel(Channel channel) {
         this.channel = channel;
@@ -452,6 +460,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
         this.floodlightProvider = floodlightProvider;
     }
     
+    @Override
     @JsonIgnore
     public void setThreadPoolService(IThreadPoolService tp) {
         this.threadPool = tp;
@@ -560,6 +569,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
      * switch list from being modified out from under the listeners.
      * @return 
      */
+    @Override
     @JsonIgnore
     public Lock getListenerReadLock() {
         return listenerLock.readLock();
@@ -572,6 +582,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
      * message from the switch.
      * @return
      */
+    @Override
     @JsonIgnore
     public Lock getListenerWriteLock() {
         return listenerLock.writeLock();
@@ -581,6 +592,7 @@ public abstract class OFSwitchBase implements IOFSwitch {
      * Get the IP Address for the switch
      * @return the inet address
      */
+    @Override
     @JsonSerialize(using=ToStringSerializer.class)
     public SocketAddress getInetAddress() {
         return channel.getRemoteAddress();
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index c4f502236253db5c3463ab6ae66be4f66dd26b9e..5f9cbd81d9153ef73ecc302094e10a7f2e513a10 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -1446,6 +1446,7 @@ public class Controller implements IFloodlightProviderService,
 
     @Override
     public Map<Long, IOFSwitch> getSwitches() {
+        if (activeSwitches == null) return null;
         return Collections.unmodifiableMap(this.activeSwitches);
     }
 
diff --git a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
index f9ec793b3ba9797ec06912dc5579772fccd15fb1..a65b28f6c1788ee351726038193b11999d045dcc 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/RoleChanger.java
@@ -187,7 +187,7 @@ public class RoleChanger {
     @LogMessageDoc(level="ERROR",
                    message="RoleRequestWorker task had an uncaught exception.",
                    explanation="An unknown occured while processing an HA " +
-                   		"role change event.",
+                               "role change event.",
                    recommendation=LogMessageDoc.GENERIC_ACTION)                              
     protected class RoleRequestWorker extends Thread  {
         @Override
@@ -278,7 +278,7 @@ public class RoleChanger {
             message="Failed to send role request message " + 
                     "to switch {switch}: {message}. Disconnecting",
             explanation="An I/O error occurred while attempting to change " +
-            		"the switch HA role.",
+                        "the switch HA role.",
             recommendation=LogMessageDoc.CHECK_SWITCH)                              
     protected void sendRoleRequest(Collection<IOFSwitch> switches,
                                    Role role, long cookie) {
@@ -331,7 +331,7 @@ public class RoleChanger {
             message="Timeout while waiting for role reply from switch {switch}."
                     + " Disconnecting",
             explanation="Timed out waiting for the switch to respond to " +
-            		"a request to change the HA role.",
+                        "a request to change the HA role.",
             recommendation=LogMessageDoc.CHECK_SWITCH)                              
     protected void verifyRoleReplyReceived(Collection<IOFSwitch> switches,
                                    long cookie) {
@@ -425,8 +425,11 @@ public class RoleChanger {
      * @return 
      */
     public boolean checkFirstPendingRoleRequestXid (IOFSwitch sw, int xid) {
-        LinkedList<PendingRoleRequestEntry> pendingRoleRequests =
-                pendingRequestMap.get(sw);
+        LinkedList<PendingRoleRequestEntry> pendingRoleRequests;
+        if (sw == null) {
+            return false;
+        }
+        pendingRoleRequests = pendingRequestMap.get(sw);
         if (pendingRoleRequests == null) {
             return false;
         }
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
index 127b9658d31cfb6a9d19b6cdabcee0f249e0c08a..f5036f0917f7afec074a97be208b55284edc509f 100644
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
+++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
@@ -115,7 +115,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
     public boolean isSameAs(FirewallRule r) {
         if (this.action != r.action
                 || this.wildcard_dl_type != r.wildcard_dl_type
-                || (this.wildcard_dl_type == false && this.dl_type == r.dl_type)
+                || (this.wildcard_dl_type == false && this.dl_type != r.dl_type)
                 || this.wildcard_tp_src != r.wildcard_tp_src
                 || (this.wildcard_tp_src == false && this.tp_src != r.tp_src)
                 || this.wildcard_tp_dst != r.wildcard_tp_dst
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
index f172f63be26459ce241e0c4400a3e63885b5bed4..17ad46a7a067c827605d64df3a4acb9443349233 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/ILinkDiscovery.java
@@ -13,13 +13,15 @@ public interface ILinkDiscovery {
         SWITCH_UPDATED("Switch Updated"),
         SWITCH_REMOVED("Switch Removed"),
         PORT_UP("Port Up"),
-        PORT_DOWN("Port Down");
-        
+        PORT_DOWN("Port Down"),
+        TUNNEL_PORT_ADDED("Tunnel Port Added"),
+        TUNNEL_PORT_REMOVED("Tunnel Port Removed");
+
         private String value;
         UpdateOperation(String v) {
             value = v;
         }
-        
+
         @Override
         public String toString() {
             return value;
@@ -64,7 +66,7 @@ public interface ILinkDiscovery {
             this.srcType = stype;
         }
 
-        // For port up or port down.
+        // For port up or port down; and tunnel port added and removed.
         public LDUpdate(long sw, short port, UpdateOperation operation) {
             this.src = sw;
             this.srcPort = port;
diff --git a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
index 0cc268cde8e6a14ebaf8e06ec6d881f3ee0497f6..1e324d32737d1d12fdbfd0bc7c4a1285a9224888 100644
--- a/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
+++ b/src/main/java/net/floodlightcontroller/linkdiscovery/internal/LinkDiscoveryManager.java
@@ -188,7 +188,7 @@ public class LinkDiscoveryManager implements IOFMessageListener,
      * to false -- Initialized in the init method as well.
      */
     public final boolean AUTOPORTFAST_DEFAULT = false;
-    boolean autoPortFastFeature = AUTOPORTFAST_DEFAULT;
+    protected boolean autoPortFastFeature = AUTOPORTFAST_DEFAULT;
 
     /**
      * Map from link to the most recent time it was verified functioning
diff --git a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
index 2ff0dabfa59c7f6ae7d8e78ffe1c70304e8082c4..3893ed5708d29acf52e80c78b922ee261cee1d88 100644
--- a/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
+++ b/src/main/java/net/floodlightcontroller/loadbalancer/LoadBalancer.java
@@ -1,9 +1,6 @@
 package net.floodlightcontroller.loadbalancer;
 
-import java.io.BufferedReader;
 import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -14,15 +11,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.http.HttpResponse;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.protocol.HTTP;
-import org.json.simple.JSONObject;
+import org.openflow.protocol.OFFlowMod;
+import org.openflow.protocol.OFMatch;
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
 import org.openflow.protocol.OFPacketOut;
@@ -31,6 +21,7 @@ import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
 import org.openflow.protocol.action.OFActionOutput;
 import org.openflow.util.HexString;
+import org.openflow.util.U16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,6 +46,8 @@ import net.floodlightcontroller.packet.UDP;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.routing.IRoutingService;
 import net.floodlightcontroller.routing.Route;
+import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
+import net.floodlightcontroller.staticflowentry.StaticFlowEntries;
 import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.NodePortTuple;
 import net.floodlightcontroller.util.MACAddress;
@@ -87,6 +80,7 @@ public class LoadBalancer implements IFloodlightModule,
     protected IDeviceService deviceManager;
     protected IRoutingService routingEngine;
     protected ITopologyService topology;
+    protected IStaticFlowEntryPusherService sfp;
     
     protected HashMap<String, LBVip> vips;
     protected HashMap<String, LBPool> pools;
@@ -99,6 +93,9 @@ public class LoadBalancer implements IFloodlightModule,
     //Copied from Forwarding with message damper routine for pushing proxy Arp 
     protected static int OFMESSAGE_DAMPER_CAPACITY = 10000; // ms. 
     protected static int OFMESSAGE_DAMPER_TIMEOUT = 250; // ms 
+    protected static String LB_ETHER_TYPE = "0x800";
+    protected static int LB_PRIORITY = 32768;
+    
     // Comparator for sorting by SwitchCluster
     public Comparator<SwitchPort> clusterIdComparator =
             new Comparator<SwitchPort>() {
@@ -483,97 +480,84 @@ public class LoadBalancer implements IFloodlightModule,
      * @param LBMember member
      * @param long pinSwitch
      */
-    @SuppressWarnings("unchecked")
     public void pushStaticVipRoute(boolean inBound, Route route, IPClient client, LBMember member, long pinSwitch) {
         List<NodePortTuple> path = route.getPath();
         if (path.size()>0) {
-            
            for (int i = 0; i < path.size(); i+=2) {
-               JSONObject json = new JSONObject();
+               
                long sw = path.get(i).getNodeId();
-
-               json.put("switch", HexString.toHexString(sw));
+               String swString = HexString.toHexString(path.get(i).getNodeId());
+               String entryName;
+               String matchString = null;
+               String actionString = null;
+               
+               OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory()
+                       .getMessage(OFType.FLOW_MOD);
+
+               fm.setIdleTimeout((short) 0);   // infinite
+               fm.setHardTimeout((short) 0);   // infinite
+               fm.setBufferId(OFPacketOut.BUFFER_ID_NONE);
+               fm.setCommand((short) 0);
+               fm.setFlags((short) 0);
+               fm.setOutPort(OFPort.OFPP_NONE.getValue());
+               fm.setCookie((long) 0);  
+               fm.setPriority(Short.MAX_VALUE);
+               
                if (inBound) {
-                   json.put("name","inbound-vip-"+ member.vipId+"client-"+client.ipAddress+"-port-"+client.targetPort
-                            +"srcswitch-"+path.get(0).getNodeId()+"sw-"+sw);
-                   json.put("src-ip",IPv4.fromIPv4Address(client.ipAddress));
-                   json.put("protocol",String.valueOf(client.nw_proto));
-                   json.put("src-port",String.valueOf(client.srcPort & 0xffff));
-                   json.put("ether-type","0x800");
-                   json.put("priority","32768");
-                   json.put("ingress-port",String.valueOf(path.get(i).getPortId()));
-                   json.put("active","true");
+                   entryName = "inbound-vip-"+ member.vipId+"client-"+client.ipAddress+"-port-"+client.targetPort
+                           +"srcswitch-"+path.get(0).getNodeId()+"sw-"+sw;
+                   matchString = "nw_src="+IPv4.fromIPv4Address(client.ipAddress)+","
+                               + "nw_proto="+String.valueOf(client.nw_proto)+","
+                               + "tp_src="+String.valueOf(client.srcPort & 0xffff)+","
+                               + "dl_type="+LB_ETHER_TYPE+","
+                               + "in_port="+String.valueOf(path.get(i).getPortId());
+
                    if (sw == pinSwitch) {
-                       json.put("actions","set-dst-ip="+IPv4.fromIPv4Address(member.address)+"," 
+                       actionString = "set-dst-ip="+IPv4.fromIPv4Address(member.address)+"," 
                                 + "set-dst-mac="+member.macString+","
-                                + "output="+path.get(i+1).getPortId());
+                                + "output="+path.get(i+1).getPortId();
                    } else {
-                       json.put("actions",
-                               "output="+path.get(i+1).getPortId());
+                       actionString =
+                               "output="+path.get(i+1).getPortId();
                    }
                } else {
-                   json.put("name","outbound-vip-"+ member.vipId+"client-"+client.ipAddress+"-port-"+client.targetPort
-                            +"srcswitch-"+path.get(0).getNodeId()+"sw-"+sw);
-                   json.put("dst-ip",IPv4.fromIPv4Address(client.ipAddress));
-                   json.put("protocol",String.valueOf(client.nw_proto));
-                   json.put("dst-port",String.valueOf(client.srcPort & 0xffff));
-                   json.put("ether-type","0x800");
-                   json.put("priority","32768");
-                   json.put("ingress-port",String.valueOf(path.get(i).getPortId()));
-                   json.put("active","true");
+                   entryName = "outbound-vip-"+ member.vipId+"client-"+client.ipAddress+"-port-"+client.targetPort
+                           +"srcswitch-"+path.get(0).getNodeId()+"sw-"+sw;
+                   matchString = "nw_dst="+IPv4.fromIPv4Address(client.ipAddress)+","
+                               + "nw_proto="+String.valueOf(client.nw_proto)+","
+                               + "tp_dst="+String.valueOf(client.srcPort & 0xffff)+","
+                               + "dl_type="+LB_ETHER_TYPE+","
+                               + "in_port="+String.valueOf(path.get(i).getPortId());
+
                    if (sw == pinSwitch) {
-                       json.put("actions","set-src-ip="+IPv4.fromIPv4Address(vips.get(member.vipId).address)+","
+                       actionString = "set-src-ip="+IPv4.fromIPv4Address(vips.get(member.vipId).address)+","
                                + "set-src-mac="+vips.get(member.vipId).proxyMac.toString()+","
-                               + "output="+path.get(i+1).getPortId());
+                               + "output="+path.get(i+1).getPortId();
                    } else {
-                       json.put("actions",
-                               "output="+path.get(i+1).getPortId());
+                       actionString = "output="+path.get(i+1).getPortId();
                    }
                    
                }
+               
+               StaticFlowEntries.parseActionString(fm, actionString, log);
+
+               fm.setPriority(U16.t(LB_PRIORITY));
+
+               OFMatch ofMatch = new OFMatch();
                try {
-                   HttpClient httpclient = new DefaultHttpClient();
-                   HttpPost httpPost = new HttpPost("http://127.0.0.1:8080/wm/staticflowentrypusher/json");
-                   StringEntity se = new StringEntity(json.toString());  
-                   se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
-                   httpPost.setEntity(se);
-                   
-                   HttpResponse response = null;
-
-                   try {
-                       response = httpclient.execute(httpPost);
-                   } catch (ClientProtocolException cliente) {
-                       cliente.printStackTrace();
-                   } catch (IOException ioe) {
-                       ioe.printStackTrace();
-                   }
-                   
-                   BufferedReader rd = null;
-                   try {
-                       if (response !=null)
-                           rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
-                   } catch (IllegalStateException statee) {
-                       statee.printStackTrace();
-                   } catch (IOException ioe) {
-                       ioe.printStackTrace();
-                   }
-                   
-                   String line = "";
-                   try {
-                       if (rd!= null) {
-                           while ((line = rd.readLine()) != null) {
-                               System.out.println(line);
-                           }
-                       }
-                   } catch (IOException e) {
-                       e.printStackTrace();
-                   }
-               } catch (UnsupportedEncodingException e) {
-                   e.printStackTrace();
-               }            
+                   ofMatch.fromString(matchString);
+               } catch (IllegalArgumentException e) {
+                   log.debug(
+                             "ignoring flow entry {} on switch {} with illegal OFMatch() key: "
+                                     + matchString, entryName, swString);
+               }
+        
+               fm.setMatch(ofMatch);
+               sfp.addFlow(entryName, fm, swString);
+
            }
         }
-        
+               
         return;
     }
 
@@ -775,6 +759,7 @@ public class LoadBalancer implements IFloodlightModule,
         l.add(IDeviceService.class);
         l.add(ITopologyService.class);
         l.add(IRoutingService.class);
+        l.add(IStaticFlowEntryPusherService.class);
 
         return l;
     }
@@ -788,6 +773,7 @@ public class LoadBalancer implements IFloodlightModule,
         deviceManager = context.getServiceImpl(IDeviceService.class);
         routingEngine = context.getServiceImpl(IRoutingService.class);
         topology = context.getServiceImpl(ITopologyService.class);
+        sfp = context.getServiceImpl(IStaticFlowEntryPusherService.class);
         
         messageDamper = new OFMessageDamper(OFMESSAGE_DAMPER_CAPACITY, 
                                             EnumSet.of(OFType.FLOW_MOD),
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index 8b498af5c5d11f7b9edc6ab2b816cde076a1ff76..cd0cd36925bea52c881ab497b7f35a93a39b5168 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -336,60 +336,6 @@ public abstract class ForwardingBase
                     "packet out to a switch",
             recommendation=LogMessageDoc.CHECK_SWITCH)            
     })
-    public void pushPacket(IPacket packet, 
-                           IOFSwitch sw,
-                           int bufferId,
-                           short inPort,
-                           short outPort, 
-                           FloodlightContext cntx,
-                           boolean flush) {
-        
-        
-        if (log.isTraceEnabled()) {
-            log.trace("PacketOut srcSwitch={} inPort={} outPort={}", 
-                      new Object[] {sw, inPort, outPort});
-        }
-
-        OFPacketOut po =
-                (OFPacketOut) floodlightProvider.getOFMessageFactory()
-                                                .getMessage(OFType.PACKET_OUT);
-
-        // set actions
-        List<OFAction> actions = new ArrayList<OFAction>();
-        actions.add(new OFActionOutput(outPort, (short) 0xffff));
-
-        po.setActions(actions)
-          .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-        short poLength =
-                (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
-
-        // set buffer_id, in_port
-        po.setBufferId(bufferId);
-        po.setInPort(inPort);
-
-        // set data - only if buffer_id == -1
-        if (po.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
-            if (packet == null) {
-                log.error("BufferId is not set and packet data is null. " +
-                          "Cannot send packetOut. " +
-                        "srcSwitch={} inPort={} outPort={}",
-                        new Object[] {sw, inPort, outPort});
-                return;
-            }
-            byte[] packetData = packet.serialize();
-            poLength += packetData.length;
-            po.setPacketData(packetData);
-        }
-
-        po.setLength(poLength);
-
-        try {
-            counterStore.updatePktOutFMCounterStoreLocal(sw, po);
-            messageDamper.write(sw, po, cntx, flush);
-        } catch (IOException e) {
-            log.error("Failure writing packet out", e);
-        }
-    }
 
     /**
      * Pushes a packet-out to a switch.  The assumption here is that
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
index 4f8ad79aac14af53901b0debe3d7f165f9119428..490c50ecb7d6d971368bc50d319e075d679f7faf 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
@@ -5,11 +5,11 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -29,18 +29,15 @@ import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.core.util.AppCookie;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.staticflowentry.web.StaticFlowEntryWebRoutable;
-import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
 import net.floodlightcontroller.storage.IResultSet;
-import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.IStorageSourceListener;
-
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.StorageException;
 
 import org.openflow.protocol.OFFlowMod;
 import org.openflow.protocol.OFFlowRemoved;
 import org.openflow.protocol.OFMatch;
 import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPort;
 import org.openflow.protocol.OFType;
 import org.openflow.util.HexString;
 import org.openflow.util.U16;
@@ -653,6 +650,16 @@ public class StaticFlowEntryPusher
     
     @Override
     public void deleteAllFlows() {
+        for (String entry : entry2dpid.keySet()) {
+            deleteFlow(entry);
+        }
+        
+        /*
+        FIXME: Since the OF spec 1.0 is not clear on how
+        to match on cookies. Once all switches come to a
+        common implementation we can possibly re-enable this
+        fix.
+        
         // Send a delete for each switch
         Set<String> swSet = new HashSet<String>();
         for (String dpid : entry2dpid.values()) {
@@ -673,11 +680,24 @@ public class StaticFlowEntryPusher
         
         // Reset our DB
         storageSource.deleteMatchingRowsAsync(TABLE_NAME, null);
+        */
     }
     
     @Override
     public void deleteFlowsForSwitch(long dpid) {
-        sendDeleteByCookie(dpid);
+        String sDpid = HexString.toHexString(dpid);
+        
+        for (Entry<String, String> e : entry2dpid.entrySet()) {
+            if (e.getValue().equals(sDpid))
+                deleteFlow(e.getKey());
+        }
+        
+        /*
+        FIXME: Since the OF spec 1.0 is not clear on how
+        to match on cookies. Once all switches come to a
+        common implementation we can possibly re-enable this
+        fix.
+        //sendDeleteByCookie(dpid);
         
         String sDpid = HexString.toHexString(dpid);
         // Clear all internal flows for this switch
@@ -692,6 +712,7 @@ public class StaticFlowEntryPusher
         } else {
             log.warn("Map of storage entries for switch {} was null", sDpid);
         }
+        */
     }
     
     /**
@@ -701,6 +722,11 @@ public class StaticFlowEntryPusher
      * disable having flow specific cookies.
      * @param dpid The DPID of the switch to clear all it's flows.
      */
+    /*
+    FIXME: Since the OF spec 1.0 is not clear on how
+    to match on cookies. Once all switches come to a
+    common implementation we can possibly re-enable this
+    fix.
     private void sendDeleteByCookie(long dpid) {
         if (log.isDebugEnabled())
             log.debug("Deleting all static flows on switch {}", HexString.toHexString(dpid));
@@ -729,6 +755,7 @@ public class StaticFlowEntryPusher
             return;
         }
     }
+    */
     
     @Override
     public Map<String, Map<String, OFFlowMod>> getFlows() {
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
index 81a497cde444f0cab42a934a9c62eb61ed702291..e0496a4e54530193e2c307540d8f191c26710efb 100644
--- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
@@ -89,7 +89,7 @@ public class TopologyManager implements
     /**
      * set of tunnel links
      */
-    protected Map<NodePortTuple, Set<Link>> tunnelLinks; 
+    protected Set<NodePortTuple> tunnelPorts;
 
     protected ILinkDiscoveryService linkDiscovery;
     protected IThreadPoolService threadPool;
@@ -120,6 +120,10 @@ public class TopologyManager implements
      */
     protected boolean dtLinksUpdated;
 
+    /** Flag that indicates if tunnel ports were updated or not
+     */
+    protected boolean tunnelPortsUpdated;
+
     protected final int TOPOLOGY_COMPUTE_INTERVAL_MS = 500;
 
     /**
@@ -152,6 +156,7 @@ public class TopologyManager implements
         boolean newInstanceFlag;
         linksUpdated = false;
         dtLinksUpdated = false;
+        tunnelPortsUpdated = false;
         applyUpdates();
         newInstanceFlag = createNewInstance();
         lastUpdateTime = new Date();
@@ -492,10 +497,9 @@ public class TopologyManager implements
 
     @Override
     public Set<NodePortTuple> getTunnelPorts() {
-        return tunnelLinks.keySet();
+        return tunnelPorts;
     }
 
-    @Override
     public Set<NodePortTuple> getBlockedPorts() {
         Set<NodePortTuple> bp;
         Set<NodePortTuple> blockedPorts =
@@ -679,7 +683,7 @@ public class TopologyManager implements
         switchPortLinks = new HashMap<NodePortTuple, Set<Link>>();
         directLinks = new HashMap<NodePortTuple, Set<Link>>();
         portBroadcastDomainLinks = new HashMap<NodePortTuple, Set<Link>>();
-        tunnelLinks = new HashMap<NodePortTuple, Set<Link>>();
+        tunnelPorts = new HashSet<NodePortTuple>();
         topologyAware = new ArrayList<ITopologyListener>();
         ldUpdates = new LinkedBlockingQueue<LDUpdate>();
         appliedUpdates = new ArrayList<LDUpdate>();
@@ -800,6 +804,27 @@ public class TopologyManager implements
         }
     }
 
+    /**
+     * Get the set of ports to eliminate for sending out BDDP.  The method
+     * returns all the ports that are suppressed for link discovery on the
+     * switch.
+     * packets.
+     * @param sid
+     * @return
+     */
+    protected Set<Short> getPortsToEliminateForBDDP(long sid) {
+        Set<NodePortTuple> suppressedNptList = linkDiscovery.getSuppressLLDPsInfo();
+        if (suppressedNptList == null) return null;
+
+        Set<Short> resultPorts = new HashSet<Short>();
+        for(NodePortTuple npt: suppressedNptList) {
+            if (npt.getNodeId() == sid) {
+                resultPorts.add(npt.getPortId());
+            }
+        }
+
+        return resultPorts;
+    }
 
     /**
      * The BDDP packets are forwarded out of all the ports out of an
@@ -848,6 +873,11 @@ public class TopologyManager implements
                 }
             }
 
+            Set<Short> portsToEliminate = getPortsToEliminateForBDDP(sid);
+            if (portsToEliminate != null) {
+                ports.removeAll(portsToEliminate);
+            }
+
             // remove the incoming switch port
             if (pinSwitch == sid) {
                 ports.remove(pi.getInPort());
@@ -914,12 +944,28 @@ public class TopologyManager implements
             } else if (update.getOperation() == UpdateOperation.LINK_REMOVED){
                 removeLink(update.getSrc(), update.getSrcPort(), 
                            update.getDst(), update.getDstPort());
+            } else if (update.getOperation() == UpdateOperation.TUNNEL_PORT_ADDED) {
+                addTunnelPort(update.getSrc(), update.getSrcPort());
+            } else if (update.getOperation() == UpdateOperation.TUNNEL_PORT_REMOVED) {
+                removeTunnelPort(update.getSrc(), update.getSrcPort());
             }
             // Add to the list of applied updates.
             appliedUpdates.add(update);
         }
     }
 
+    public void addTunnelPort(long sw, short port) {
+        NodePortTuple npt = new NodePortTuple(sw, port);
+        tunnelPorts.add(npt);
+        tunnelPortsUpdated = true;
+    }
+
+    public void removeTunnelPort(long sw, short port) {
+        NodePortTuple npt = new NodePortTuple(sw, port);
+        tunnelPorts.remove(npt);
+        tunnelPortsUpdated = true;
+    }
+
     /**
      * This function computes a new topology.
      */
@@ -962,7 +1008,7 @@ public class TopologyManager implements
         }
 
         // Remove all tunnel links.
-        for(NodePortTuple npt: tunnelLinks.keySet()) {
+        for(NodePortTuple npt: tunnelPorts) {
             if (switchPortLinks.get(npt) == null) continue;
             for(Link link: switchPortLinks.get(npt)) {
                 removeLinkFromStructure(openflowLinks, link);
@@ -973,7 +1019,7 @@ public class TopologyManager implements
                                                    blockedPorts,
                                                    openflowLinks, 
                                                    broadcastDomainPorts,
-                                                   tunnelLinks.keySet());
+                                                   tunnelPorts);
         nt.compute();
         // We set the instances with and without tunnels to be identical.
         // If needed, we may compute them differently.
@@ -1146,8 +1192,6 @@ public class TopologyManager implements
 
     public void addOrUpdateLink(long srcId, short srcPort, long dstId, 
                                 short dstPort, LinkType type) {
-        boolean flag1 = false, flag2 = false;
-
         Link link = new Link(srcId, srcPort, dstId, dstPort);
         addPortToSwitch(srcId, srcPort);
         addPortToSwitch(dstId, dstPort);
@@ -1156,17 +1200,9 @@ public class TopologyManager implements
 
         if (type.equals(LinkType.MULTIHOP_LINK)) {
             addLinkToStructure(portBroadcastDomainLinks, link);
-            flag1 = removeLinkFromStructure(tunnelLinks, link);
-            flag2 = removeLinkFromStructure(directLinks, link);
-            dtLinksUpdated = flag1 || flag2;
-        } else if (type.equals(LinkType.TUNNEL)) {
-            addLinkToStructure(tunnelLinks, link);
-            removeLinkFromStructure(portBroadcastDomainLinks, link);
-            removeLinkFromStructure(directLinks, link);
-            dtLinksUpdated = true;
+            dtLinksUpdated = removeLinkFromStructure(directLinks, link);
         } else if (type.equals(LinkType.DIRECT_LINK)) {
             addLinkToStructure(directLinks, link);
-            removeLinkFromStructure(tunnelLinks, link);
             removeLinkFromStructure(portBroadcastDomainLinks, link);
             dtLinksUpdated = true;
         }
@@ -1174,14 +1210,8 @@ public class TopologyManager implements
     }
 
     public void removeLink(Link link)  {
-        boolean flag1 = false, flag2 = false;
-
-        flag1 = removeLinkFromStructure(directLinks, link);
-        flag2 = removeLinkFromStructure(tunnelLinks, link);
-
         linksUpdated = true;
-        dtLinksUpdated = flag1 || flag2;
-
+        dtLinksUpdated = removeLinkFromStructure(directLinks, link);
         removeLinkFromStructure(portBroadcastDomainLinks, link);
         removeLinkFromStructure(switchPortLinks, link);
 
@@ -1219,9 +1249,9 @@ public class TopologyManager implements
 
     public void clear() {
         switchPorts.clear();
+        tunnelPorts.clear();
         switchPortLinks.clear();
         portBroadcastDomainLinks.clear();
-        tunnelLinks.clear();
         directLinks.clear();
         appliedUpdates.clear();
     }
@@ -1234,6 +1264,7 @@ public class TopologyManager implements
         this.clear();
         linksUpdated = true;
         dtLinksUpdated = true;
+        tunnelPortsUpdated = true;
         createNewInstance();
         lastUpdateTime = new Date();
     }
diff --git a/src/main/java/org/openflow/util/IProducer.java b/src/main/java/org/openflow/util/IProducer.java
new file mode 100644
index 0000000000000000000000000000000000000000..52ae79a52b5dc47af63f71d0aceeb3ee26105727
--- /dev/null
+++ b/src/main/java/org/openflow/util/IProducer.java
@@ -0,0 +1,9 @@
+package org.openflow.util;
+
+public interface IProducer {
+
+    public void registerConsumer(Class<?> iface, Object anObj);
+
+    public void deregisterConsumer(Class<?> iface, Object anObj);
+
+}
diff --git a/src/main/java/org/openflow/util/ProducerConsumer.java b/src/main/java/org/openflow/util/ProducerConsumer.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2244ef3524483b0a2fc70e8f2ba433efd363c01
--- /dev/null
+++ b/src/main/java/org/openflow/util/ProducerConsumer.java
@@ -0,0 +1,223 @@
+package org.openflow.util;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The following implement a producer/consumer design pattern in which both
+ * producers and consumers explicitly employ a centralized registration
+ * mechanism, and java Interfaces are used as contracts.<br>
+ */
+public class ProducerConsumer {
+
+    /*
+     * Class variables
+     */
+    protected static ProducerConsumer singleton;
+
+    /*
+     * Default constructor
+     */
+    protected ProducerConsumer() {
+        producerMap = new Hashtable<Class<?>, Set<IProducer>>();
+    }
+
+    /*
+     * Instance variables
+     */
+
+    // Interface/IProducer map
+    protected Map<Class<?>, Set<IProducer>> producerMap;
+
+    /*
+     * Protected methods
+     */
+
+    protected void _registerConsumer(Object consumer, Class<?>[] interfaces,
+                                     Set<Class<?>> iSet,
+                                     Set<Class<?>> iUniqueSet) {
+        // *...Process all interfaces...*/
+        for (Class<?> iface : interfaces) {
+
+            // *...Protect against repeated interfaces...*/
+            if (!iUniqueSet.contains(iface)) {
+                iUniqueSet.add(iface);
+
+                Set<IProducer> producers = producerMap.get(iface);
+
+                if (producers != null) {
+                    for (IProducer producer : producers)
+                        producer.registerConsumer(iface, consumer);
+                    iSet.add(iface);
+                }
+
+                // *...Recurse...*/
+                _registerConsumer(consumer, iface.getInterfaces(), iSet,
+                                  iUniqueSet);
+            }
+        }
+    }
+
+    protected void _registerConsumer(Object consumer, Class<?> clazz,
+                                     Set<Class<?>> iSet,
+                                     Set<Class<?>> iUniqueSet) {
+        if (clazz != null) {
+            // *...Process all interfaces...*/
+            _registerConsumer(consumer, clazz.getInterfaces(), iSet,
+                              iUniqueSet);
+
+            // *...Recurse the class hierarchy...*/
+            _registerConsumer(consumer, clazz.getSuperclass(), iSet,
+                              iUniqueSet);
+        }
+    }
+
+    protected int _deregisterConsumer(Object consumer,
+                                      Class<?>[] interfaces,
+                                      Set<Class<?>> iUniqueSet) {
+        int count = 0;
+
+        // *...Process all interfaces...*/
+        for (Class<?> iface : interfaces) {
+
+            // *...Protect against repeated interfaces...*/
+            if (!iUniqueSet.contains(iface)) {
+                iUniqueSet.add(iface);
+
+                Set<IProducer> producers = producerMap.get(iface);
+
+                if (producers != null) {
+                    for (IProducer producer : producers)
+                        producer.deregisterConsumer(iface, consumer);
+
+                    count++;
+                }
+
+                // *...Recurse...*/
+                count += _deregisterConsumer(consumer,
+                                             iface.getInterfaces(),
+                                             iUniqueSet);
+            }
+        }
+
+        return count;
+    }
+
+    protected int _deregisterConsumer(Object consumer, Class<?> clazz,
+                                      Set<Class<?>> iUniqueSet) {
+        int count = 0;
+
+        if (clazz != null) {
+            // *...Process all interfaces...*/
+            count += _deregisterConsumer(consumer, clazz.getInterfaces(),
+                                         iUniqueSet);
+
+            // *...Recurse the class hierarchy...*/
+            count += _deregisterConsumer(consumer, clazz.getSuperclass(),
+                                         iUniqueSet);
+        }
+
+        return count;
+    }
+
+    /*
+     * Singleton API
+     */
+
+    /**
+     * @return singleton ProducerConsumer
+     */
+    public static synchronized ProducerConsumer getSingleton() {
+        if (singleton == null) singleton = new ProducerConsumer();
+
+        return singleton;
+    }
+
+    /*
+     * Producer APIs
+     */
+
+    /**
+     * Producer registration
+     * 
+     * @param producer
+     *            object that implements IProducer
+     * @param iface
+     *            interface supported by the producer
+     * @return whether there was a previously registered producer, or true if
+     *         one or more the arguments were invalid
+     */
+    public boolean registerProducer(IProducer producer, Class<?> iface) {
+        if (producer != null && iface != null && iface.isInterface()) {
+            Set<IProducer> producers = producerMap.get(iface);
+
+            if (producers == null) {
+                producers = new HashSet<IProducer>();
+                producerMap.put(iface, producers);
+            }
+
+            return producers.add(producer);
+        } else
+            return true;
+    }
+
+    /**
+     * Producer deregistration
+     * 
+     * @param producer
+     *            object that implements IProducer
+     * @param iface
+     *            interface supported by the producer
+     * @return whether the interface/producer pair was removed, or false if one
+     *         or more the arguments were invalid
+     */
+    public boolean deregisterProducer(IProducer producer, Class<?> iface) {
+        if (producer != null && iface != null && iface.isInterface()) {
+            Set<IProducer> producers = producerMap.get(iface);
+
+            if (producers != null) return producers.remove(producer);
+        }
+
+        return false;
+    }
+
+    /*
+     * Consumer APIs
+     */
+
+    /**
+     * Consumer registration
+     * 
+     * @param consumer
+     *            object that implements producer-specific interfaces
+     * @return set of supported interfaces
+     */
+    public Set<Class<?>> registerConsumer(Object consumer) {
+        Set<Class<?>> iSet = new HashSet<Class<?>>();
+
+        if (consumer != null)
+                             _registerConsumer(consumer,
+                                               consumer.getClass(), iSet,
+                                               new HashSet<Class<?>>());
+
+        return iSet;
+    }
+
+    /**
+     * Consumer deregistration
+     * 
+     * @param consumer
+     *            object to deregister
+     * @return number of unregistered interfaces
+     */
+    public int deregisterConsumer(Object consumer) {
+        if (consumer != null)
+            return _deregisterConsumer(consumer, consumer.getClass(),
+                                       new HashSet<Class<?>>());
+        else
+            return 0;
+    }
+
+}
diff --git a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
index cb446b2a9ec19cd46d59620e8b160e5e1ef3f4a7..037e816897b7a080212a89803cadf6485d4da659 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/RoleChangerTest.java
@@ -390,6 +390,19 @@ public class RoleChangerTest {
                 roleChanger.checkFirstPendingRoleRequestXid(sw, xid));
     }
     
+    @Test
+    public void testCheckFirstPendingRoleRequestNullSw() {
+        int xid = 54321;
+        long cookie = 232323;
+        Role role = Role.MASTER;
+        OFSwitchImpl sw = new OFSwitchImpl();
+        setupPendingRoleRequest(sw, xid, role, cookie);
+        // pass null as sw object, which is true during handshake
+        assertEquals(false,
+                roleChanger.checkFirstPendingRoleRequestXid(null, xid));
+        roleChanger.pendingRequestMap.get(sw).clear();
+    }
+    
     @Test
     public void testCheckFirstPendingRoleRequestCookie() {
         int xid = 54321;
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
index aaeea904f0b9fff519e9a60fd7920c0400d528a9..59f3090457561b8e51eea89ce0006801eed43e73 100644
--- a/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
+++ b/src/test/java/net/floodlightcontroller/topology/TopologyInstanceTest.java
@@ -108,6 +108,7 @@ public class TopologyInstanceTest {
             }
             TopologyInstance ti = topologyManager.getCurrentInstance(tunnelsEnabled);
             Set<NodePortTuple> computed = ti.getBroadcastNodePortsInCluster(npt.nodeId);
+            log.info("computed: {}", computed);
             if (computed != null)
                 assertTrue(computed.equals(expected));
             else if (computed == null)
@@ -295,120 +296,6 @@ public class TopologyInstanceTest {
         verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts);
     }
 
-    @Test
-    public void testTunnelLinkDeletion() throws Exception {
-
-        //      +-------+             +-------+
-        //      |       |             |       |
-        //      |   1  1|-------------|1  2   |
-        //      |   2   |             |   2   |
-        //      +-------+             +-------+
-        //          |                     |
-        //          |                     |
-        //      +-------+                 |
-        //      |   1   |                 |
-        //      |   3  2|-----------------+
-        //      |   3   |
-        //      +-------+
-        //
-        //
-        //      +-------+
-        //      |   1   |
-        //      |   4  2|----------------+
-        //      |   3   |                |
-        //      +-------+                |
-        //          |                    |
-        //          |                    |
-        //      +-------+             +-------+
-        //      |   1   |             |   2   |
-        //      |   5  2|-------------|1  6   |
-        //      |       |             |       |
-        //      +-------+             +-------+
-        {
-            int [][] linkArray = {
-                                  {1, 1, 2, 1, DIRECT_LINK},
-                                  {2, 1, 1, 1, DIRECT_LINK},
-                                  {1, 2, 3, 1, TUNNEL_LINK},
-                                  {3, 1, 1, 2, TUNNEL_LINK},
-                                  {2, 2, 3, 2, TUNNEL_LINK},
-                                  {3, 2, 2, 2, TUNNEL_LINK},
-
-                                  {4, 2, 6, 2, DIRECT_LINK},
-                                  {6, 2, 4, 2, DIRECT_LINK},
-                                  {4, 3, 5, 1, TUNNEL_LINK},
-                                  {5, 1, 4, 3, TUNNEL_LINK},
-                                  {5, 2, 6, 1, TUNNEL_LINK},
-                                  {6, 1, 5, 2, TUNNEL_LINK},
-
-            };
-
-            int [][] expectedClusters = {
-                                         {1, 2},
-                                         {4, 6},
-            };
-            int [][][] expectedBroadcastPorts = {
-                                                 {{1,1}, {2,1}},
-                                                 {{4,2}, {6,2}}
-            };
-
-            createTopologyFromLinks(linkArray);
-            topologyManager.createNewInstance();
-            verifyClusters(expectedClusters, false);
-            verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts, false);
-        }
-
-        //      +-------+             +-------+
-        //      |       |    TUNNEL   |       |
-        //      |   1  1|-------------|1  2   |
-        //      |   2   |             |   2   |
-        //      +-------+             +-------+
-        //          |                     |
-        //          |                     |
-        //      +-------+                 |
-        //      |   1   |                 |
-        //      |   3  2|-----------------+
-        //      |   3   |
-        //      +-------+
-        //          | 
-        //          |   TUNNEL
-        //          |
-        //      +-------+
-        //      |   1   |    TUNNEL
-        //      |   4  2|----------------+
-        //      |   3   |                |
-        //      +-------+                |
-        //          |                    |
-        //          |                    |
-        //      +-------+             +-------+
-        //      |   1   |             |   2   |
-        //      |   5  2|-------------|1  6   |
-        //      |       |             |       |
-        //      +-------+             +-------+
-
-        {
-            int [][] linkArray = {
-                                  {3, 3, 4, 1, TUNNEL_LINK},
-                                  {4, 1, 3, 3, TUNNEL_LINK},
-
-            };
-            int [][] expectedClusters = {
-                                         {1, 2},
-                                         {4, 6},
-                                         {3},
-                                         {5},
-            };
-            int [][][] expectedBroadcastPorts = {
-                                                 {{1,1}, {2,1}},
-                                                 {{4,2}, {6,2}}
-            };
-
-            createTopologyFromLinks(linkArray);
-            topologyManager.createNewInstance();
-            verifyClusters(expectedClusters, false);
-            verifyExpectedBroadcastPortsInClusters(expectedBroadcastPorts, false);
-        }
-    }
-
     @Test
     public void testLoopDetectionWithIslands() throws Exception {
 
@@ -440,15 +327,15 @@ public class TopologyInstanceTest {
         //      +-------+             +-------+
         {
             int [][] linkArray = {
-                                  {1, 1, 2, 1, TUNNEL_LINK},
-                                  {2, 1, 1, 1, TUNNEL_LINK},
+                                  {1, 1, 2, 1, DIRECT_LINK},
+                                  {2, 1, 1, 1, DIRECT_LINK},
                                   {1, 2, 3, 1, DIRECT_LINK},
                                   {3, 1, 1, 2, DIRECT_LINK},
                                   {2, 2, 3, 2, DIRECT_LINK},
                                   {3, 2, 2, 2, DIRECT_LINK},
 
-                                  {4, 2, 6, 2, TUNNEL_LINK},
-                                  {6, 2, 4, 2, TUNNEL_LINK},
+                                  {4, 2, 6, 2, DIRECT_LINK},
+                                  {6, 2, 4, 2, DIRECT_LINK},
                                   {4, 3, 5, 1, DIRECT_LINK},
                                   {5, 1, 4, 3, DIRECT_LINK},
                                   {5, 2, 6, 1, DIRECT_LINK},
@@ -461,8 +348,8 @@ public class TopologyInstanceTest {
                                          {4, 5, 6}
             };
             int [][][] expectedBroadcastPorts = {
-                                                 {{1,2}, {3,1}, {2,2}, {3,2}},
-                                                 {{4,3}, {5,1}, {5,2}, {6,1}},
+                                                 {{1,1}, {2,1}, {1,2}, {3,1}},
+                                                 {{4,3}, {5,1}, {4,2}, {6,2}},
             };
 
             createTopologyFromLinks(linkArray);
@@ -501,17 +388,17 @@ public class TopologyInstanceTest {
 
         {
             int [][] linkArray = {
-                                  {3, 3, 4, 1, TUNNEL_LINK},
-                                  {4, 1, 3, 3, TUNNEL_LINK},
+                                  {3, 3, 4, 1, DIRECT_LINK},
+                                  {4, 1, 3, 3, DIRECT_LINK},
 
             };
             int [][] expectedClusters = {
-                                         {1, 2, 3}, 
-                                         {4, 5, 6}
+                                         {1, 2, 3, 4, 5, 6}
             };
             int [][][] expectedBroadcastPorts = {
-                                                 {{1,2}, {3,1}, {2,2}, {3,2}},
-                                                 {{4,3}, {5,1}, {5,2}, {6,1}},
+                                                 {{1,1}, {2,1}, {1,2}, {3,1},
+                                                  {3,3}, {4,1}, {4,3}, {5,1},
+                                                  {4,2}, {6,2}},
             };
 
             createTopologyFromLinks(linkArray);
diff --git a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
index 113cecbaea0492d36831d1221ad9c1e904c59891..913bf83a96fa0c6a8613572624da2a8ec1a55fec 100644
--- a/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
+++ b/src/test/java/net/floodlightcontroller/topology/TopologyManagerTest.java
@@ -50,78 +50,54 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
         assertTrue(tm.getTunnelPorts().size()==0);
 
-        tm.addOrUpdateLink((long)1, (short)3, (long)2, (short)3, ILinkDiscovery.LinkType.TUNNEL);
-        assertTrue(tm.getSwitchPorts().size() == 2);  // for two nodes.
-        assertTrue(tm.getSwitchPorts().get((long)1).size()==3);
-        assertTrue(tm.getSwitchPorts().get((long)2).size()==3);
-        assertTrue(tm.getSwitchPortLinks().size()==6);
-        assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
-        assertTrue(tm.getTunnelPorts().size()==2);
-
         tm.removeLink((long)1, (short)2, (long)2, (short)2);
-        log.info("# of switchports. {}", tm.getSwitchPorts().get((long)1).size());
-        assertTrue(tm.getSwitchPorts().get((long)1).size()==2);
-        assertTrue(tm.getSwitchPorts().get((long)2).size()==2);
-        assertTrue(tm.getSwitchPorts().size() == 2);  // for two nodes.
-        assertTrue(tm.getSwitchPortLinks().size()==4);
-        assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
-        assertTrue(tm.getTunnelPorts().size()==2);
-
-        tm.removeLink((long)1, (short)1, (long)2, (short)1);
-        assertTrue(tm.getSwitchPorts().size() == 2);  // for two nodes.
         assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
+        assertTrue(tm.getSwitchPorts().size() == 2);
         assertTrue(tm.getSwitchPortLinks().size()==2);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
-        assertTrue(tm.getTunnelPorts().size()==2);
 
-        tm.removeLink((long)1, (short)3, (long)2, (short)3);
+        tm.removeLink((long)1, (short)1, (long)2, (short)1);
         assertTrue(tm.getSwitchPorts().size() == 0); 
         assertTrue(tm.getSwitchPortLinks().size()==0);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==0);
-        assertTrue(tm.getTunnelPorts().size()==0);
     }
 
     @Test
     public void testBasic2() throws Exception {
         tm.addOrUpdateLink((long)1, (short)1, (long)2, (short)1, ILinkDiscovery.LinkType.DIRECT_LINK);
         tm.addOrUpdateLink((long)2, (short)2, (long)3, (short)1, ILinkDiscovery.LinkType.MULTIHOP_LINK);
-        tm.addOrUpdateLink((long)3, (short)2, (long)1, (short)2, ILinkDiscovery.LinkType.TUNNEL);
         assertTrue(tm.getSwitchPorts().size() == 3);  // for two nodes.
-        assertTrue(tm.getSwitchPorts().get((long)1).size()==2);
+        assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==2);
-        assertTrue(tm.getSwitchPorts().get((long)3).size()==2);
-        assertTrue(tm.getSwitchPortLinks().size()==6);
+        assertTrue(tm.getSwitchPorts().get((long)3).size()==1);
+        assertTrue(tm.getSwitchPortLinks().size()==4);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
-        assertTrue(tm.getTunnelPorts().size()==2);
 
         tm.removeLink((long)1, (short)1, (long)2, (short)1);
-        assertTrue(tm.getSwitchPorts().size() == 3);  // for two nodes.
-        assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
+        assertTrue(tm.getSwitchPorts().size() == 2);
+        assertTrue(tm.getSwitchPorts().get((long)1) == null);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
-        assertTrue(tm.getSwitchPorts().get((long)3).size()==2);
-        assertTrue(tm.getSwitchPortLinks().size()==4);
+        assertTrue(tm.getSwitchPorts().get((long)3).size()==1);
+        assertTrue(tm.getSwitchPortLinks().size()==2);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
-        assertTrue(tm.getTunnelPorts().size()==2);
 
         // nonexistent link // no null pointer exceptions.
         tm.removeLink((long)3, (short)1, (long)2, (short)2);
-        assertTrue(tm.getSwitchPorts().size() == 3);  // for two nodes.
-        assertTrue(tm.getSwitchPorts().get((long)1).size()==1);
+        assertTrue(tm.getSwitchPorts().size() == 2);
+        assertTrue(tm.getSwitchPorts().get((long)1) == null);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
-        assertTrue(tm.getSwitchPorts().get((long)3).size()==2);
-        assertTrue(tm.getSwitchPortLinks().size()==4);
+        assertTrue(tm.getSwitchPorts().get((long)3).size()==1);
+        assertTrue(tm.getSwitchPortLinks().size()==2);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
-        assertTrue(tm.getTunnelPorts().size()==2);
 
         tm.removeLink((long)3, (short)2, (long)1, (short)2);
-        assertTrue(tm.getSwitchPorts().size() == 2);  // for two nodes.
+        assertTrue(tm.getSwitchPorts().size() == 2);
         assertTrue(tm.getSwitchPorts().get((long)1)==null);
         assertTrue(tm.getSwitchPorts().get((long)2).size()==1);
         assertTrue(tm.getSwitchPorts().get((long)3).size()==1);
         assertTrue(tm.getSwitchPortLinks().size()==2);
         assertTrue(tm.getPortBroadcastDomainLinks().size()==2);
-        assertTrue(tm.getTunnelPorts().size()==0);
 
         tm.removeLink((long)2, (short)2, (long)3, (short)1);
         assertTrue(tm.getSwitchPorts().size() == 0);  // for two nodes.
@@ -137,6 +113,6 @@ public class TopologyManagerTest extends FloodlightTestCase {
         assert(tm.switchPorts.isEmpty());
         assert(tm.switchPortLinks.isEmpty());
         assert(tm.portBroadcastDomainLinks.isEmpty());
-        assert(tm.tunnelLinks.isEmpty());
+        assert(tm.tunnelPorts.isEmpty());
     }
 }
diff --git a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
index 95fc5acedea46df21d8c9b0476dbbc3ee33a7ce3..6fd8e092226b8cebd4988bc0073b4ed9a912d2e6 100644
--- a/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
+++ b/src/test/java/net/floodlightcontroller/util/OFMessageDamperMockSwitch.java
@@ -398,4 +398,10 @@ public class OFMessageDamperMockSwitch implements IOFSwitch {
         return null;
     }
 
+    @Override
+    public boolean attributeEquals(String name, Object other) {
+        fail("Unexpected method call");
+        return false;
+    }
+
 }
\ No newline at end of file