diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
deleted file mode 100644
index 66e02dd..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.floodlightcontroller.staticflowentry;
-
-import java.util.Map;
-
-import org.openflow.protocol.OFFlowMod;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IStaticFlowEntryPusherService extends IFloodlightService {
-    /**
-     * Adds a static flow.
-     * @param name Name of the flow mod. Must be unique.
-     * @param fm The flow to push.
-     * @param swDpid The switch DPID to push it to, in 00:00:00:00:00:00:00:01 notation.
-     */
-    public void addFlow(String name, OFFlowMod fm, String swDpid);
-    
-    /**
-     * Deletes a static flow
-     * @param name The name of the static flow to delete.
-     */
-    public void deleteFlow(String name);
-    
-    /**
-     * Deletes all static flows for a practicular switch
-     * @param dpid The DPID of the switch to delete flows for.
-     */
-    public void deleteFlowsForSwitch(long dpid);
-    
-    /**
-     * Deletes all flows.
-     */
-    public void deleteAllFlows();
-    
-    /**
-     * Gets all list of all flows
-     */
-    public Map<String, Map<String, OFFlowMod>> getFlows();
-    
-    /**
-     * Gets a list of flows by switch
-     */
-    public Map<String, OFFlowMod> getFlows(String dpid);
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
deleted file mode 100644
index e733843..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
+++ /dev/null
@@ -1,831 +0,0 @@
-package net.floodlightcontroller.staticflowentry;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.packet.IPv4;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionDataLayerDestination;
-import org.openflow.protocol.action.OFActionDataLayerSource;
-import org.openflow.protocol.action.OFActionEnqueue;
-import org.openflow.protocol.action.OFActionNetworkLayerDestination;
-import org.openflow.protocol.action.OFActionNetworkLayerSource;
-import org.openflow.protocol.action.OFActionNetworkTypeOfService;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.protocol.action.OFActionStripVirtualLan;
-import org.openflow.protocol.action.OFActionTransportLayerDestination;
-import org.openflow.protocol.action.OFActionTransportLayerSource;
-import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
-import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
-import org.openflow.util.HexString;
-
-/**
- * Represents static flow entries to be maintained by the controller on the 
- * switches. 
- */
-@LogMessageCategory("Static Flow Pusher")
-public class StaticFlowEntries {
-    protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntries.class);
-    
-    private static class SubActionStruct {
-        OFAction action;
-        int      len;
-    }
-    
-    private static byte[] zeroMac = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-    
-    /**
-     * This function generates a random hash for the bottom half of the cookie
-     * 
-     * @param fm
-     * @param userCookie
-     * @param name
-     * @return A cookie that encodes the application ID and a hash
-     */
-    public static long computeEntryCookie(OFFlowMod fm, int userCookie, String name) {
-        // flow-specific hash is next 20 bits LOOK! who knows if this 
-        int prime = 211;
-        int flowHash = 2311;
-        for (int i=0; i < name.length(); i++)
-            flowHash = flowHash * prime + (int)name.charAt(i);
-        
-        return AppCookie.makeCookie(StaticFlowEntryPusher.STATIC_FLOW_APP_ID, flowHash);
-    }
-    
-    /**
-     * Sets defaults for an OFFlowMod
-     * @param fm The OFFlowMod to set defaults for
-     * @param entryName The name of the entry. Used to compute the cookie.
-     */
-    public static void initDefaultFlowMod(OFFlowMod fm, String entryName) {
-        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(computeEntryCookie(fm, 0, entryName));  
-        fm.setPriority(Short.MAX_VALUE);
-    }
-    
-    /**
-     * Gets the entry name of a flow mod
-     * @param fmJson The OFFlowMod in a JSON representation
-     * @return The name of the OFFlowMod, null if not found
-     * @throws IOException If there was an error parsing the JSON
-     */
-    public static String getEntryNameFromJson(String fmJson) throws IOException{
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-        
-        try {
-            jp = f.createJsonParser(fmJson);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-        
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-        
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-            
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-            
-            if (n == "name")
-                return jp.getText();
-        }
-        
-        return null;
-    }
-    
-    /**
-     * Parses an OFFlowMod (and it's inner OFMatch) to the storage entry format.
-     * @param fm The FlowMod to parse
-     * @param sw The switch the FlowMod is going to be installed on
-     * @param name The name of this static flow entry
-     * @return A Map representation of the storage entry 
-     */
-    public static Map<String, Object> flowModToStorageEntry(OFFlowMod fm, String sw, String name) {
-        Map<String, Object> entry = new HashMap<String, Object>();
-        OFMatch match = fm.getMatch();
-        entry.put(StaticFlowEntryPusher.COLUMN_NAME, name);
-        entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, sw);
-        entry.put(StaticFlowEntryPusher.COLUMN_ACTIVE, Boolean.toString(true));
-        entry.put(StaticFlowEntryPusher.COLUMN_PRIORITY, Short.toString(fm.getPriority()));
-        entry.put(StaticFlowEntryPusher.COLUMN_WILDCARD, Integer.toString(match.getWildcards()));
-        
-        if ((fm.getActions() != null) && (fm.getActions().size() > 0))
-        	entry.put(StaticFlowEntryPusher.COLUMN_ACTIONS, StaticFlowEntries.flowModActionsToString(fm.getActions()));
-        
-        if (match.getInputPort() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_IN_PORT, Short.toString(match.getInputPort()));
-        
-        if (!Arrays.equals(match.getDataLayerSource(), zeroMac))
-        	entry.put(StaticFlowEntryPusher.COLUMN_DL_SRC, HexString.toHexString(match.getDataLayerSource()));
-
-        if (!Arrays.equals(match.getDataLayerDestination(), zeroMac))
-        	entry.put(StaticFlowEntryPusher.COLUMN_DL_DST, HexString.toHexString(match.getDataLayerDestination()));
-        
-        if (match.getDataLayerVirtualLan() != -1)
-        	entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN, Short.toString(match.getDataLayerVirtualLan()));
-        
-        if (match.getDataLayerVirtualLanPriorityCodePoint() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, Short.toString(match.getDataLayerVirtualLanPriorityCodePoint()));
-        
-        if (match.getDataLayerType() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, Short.toString(match.getDataLayerType()));
-        
-        if (match.getNetworkTypeOfService() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, Short.toString(match.getNetworkTypeOfService()));
-        
-        if (match.getNetworkProtocol() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, Short.toString(match.getNetworkProtocol()));
-        
-        if (match.getNetworkSource() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_NW_SRC, IPv4.fromIPv4Address(match.getNetworkSource()));
-        
-        if (match.getNetworkDestination() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_NW_DST, IPv4.fromIPv4Address(match.getNetworkDestination()));
-        
-        if (match.getTransportSource() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_TP_SRC, Short.toString(match.getTransportSource()));
-        
-        if (match.getTransportDestination() != 0)
-        	entry.put(StaticFlowEntryPusher.COLUMN_TP_DST, Short.toString(match.getTransportDestination()));
-        
-        return entry;
-    }
-    
-    /**
-     * Returns a String representation of all the openflow actions.
-     * @param fmActions A list of OFActions to encode into one string
-     * @return A string of the actions encoded for our database
-     */
-    @LogMessageDoc(level="ERROR",
-            message="Could not decode action {action}",
-            explanation="A static flow entry contained an invalid action",
-            recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
-    private static String flowModActionsToString(List<OFAction> fmActions) {
-        StringBuilder sb = new StringBuilder();
-        for (OFAction a : fmActions) {
-            if (sb.length() > 0) {
-                sb.append(',');
-            }
-            switch(a.getType()) {
-                case OUTPUT:
-                    sb.append("output=" + Short.toString(((OFActionOutput)a).getPort()));
-                    break;
-                case OPAQUE_ENQUEUE:
-                    int queue = ((OFActionEnqueue)a).getQueueId();
-                    short port = ((OFActionEnqueue)a).getPort();
-                    sb.append("enqueue=" + Short.toString(port) + ":0x" + String.format("%02x", queue));
-                    break;
-                case STRIP_VLAN:
-                    sb.append("strip-vlan");
-                    break;
-                case SET_VLAN_ID:
-                    sb.append("set-vlan-id=" + 
-                        Short.toString(((OFActionVirtualLanIdentifier)a).getVirtualLanIdentifier()));
-                    break;
-                case SET_VLAN_PCP:
-                    sb.append("set-vlan-priority=" +
-                        Byte.toString(((OFActionVirtualLanPriorityCodePoint)a).getVirtualLanPriorityCodePoint()));
-                    break;
-                case SET_DL_SRC:
-                    sb.append("set-src-mac=" + 
-                        HexString.toHexString(((OFActionDataLayerSource)a).getDataLayerAddress()));
-                    break;
-                case SET_DL_DST:
-                    sb.append("set-dst-mac=" + 
-                        HexString.toHexString(((OFActionDataLayerDestination)a).getDataLayerAddress()));
-                    break;
-                case SET_NW_TOS:
-                    sb.append("set-tos-bits=" +
-                        Byte.toString(((OFActionNetworkTypeOfService)a).getNetworkTypeOfService()));
-                    break;
-                case SET_NW_SRC:
-                    sb.append("set-src-ip=" +
-                        IPv4.fromIPv4Address(((OFActionNetworkLayerSource)a).getNetworkAddress()));
-                    break;
-                case SET_NW_DST:
-                    sb.append("set-dst-ip=" +
-                        IPv4.fromIPv4Address(((OFActionNetworkLayerDestination)a).getNetworkAddress()));
-                    break;
-                case SET_TP_SRC:
-                    sb.append("set-src-port=" +
-                        Short.toString(((OFActionTransportLayerSource)a).getTransportPort()));
-                    break;
-                case SET_TP_DST:
-                    sb.append("set-dst-port=" +
-                        Short.toString(((OFActionTransportLayerDestination)a).getTransportPort()));
-                    break;
-                default:
-                    log.error("Could not decode action: {}", a);
-                    break;
-            }
-                
-        }
-        return sb.toString();
-    }
-    
-    /**
-     * Turns a JSON formatted Static Flow Pusher string into a storage entry
-     * Expects a string in JSON along the lines of:
-     *        {
-     *            "switch":       "AA:BB:CC:DD:EE:FF:00:11",
-     *            "name":         "flow-mod-1",
-     *            "cookie":       "0",
-     *            "priority":     "32768",
-     *            "ingress-port": "1",
-     *            "actions":      "output=2",
-     *        }
-     * @param fmJson The JSON formatted static flow pusher entry
-     * @return The map of the storage entry
-     * @throws IOException If there was an error parsing the JSON
-     */
-    public static Map<String, Object> jsonToStorageEntry(String fmJson) throws IOException {
-        Map<String, Object> entry = new HashMap<String, Object>();
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-        
-        try {
-            jp = f.createJsonParser(fmJson);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-        
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-        
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-            
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-            
-            if (n == "name")
-                entry.put(StaticFlowEntryPusher.COLUMN_NAME, jp.getText());
-            else if (n == "switch")
-                entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, jp.getText());
-            else if (n == "actions")
-                entry.put(StaticFlowEntryPusher.COLUMN_ACTIONS, jp.getText());
-            else if (n == "priority")
-                entry.put(StaticFlowEntryPusher.COLUMN_PRIORITY, jp.getText());
-            else if (n == "active")
-                entry.put(StaticFlowEntryPusher.COLUMN_ACTIVE, jp.getText());
-            else if (n == "wildcards")
-                entry.put(StaticFlowEntryPusher.COLUMN_WILDCARD, jp.getText());
-            else if (n == "ingress-port")
-                entry.put(StaticFlowEntryPusher.COLUMN_IN_PORT, jp.getText());
-            else if (n == "src-mac")
-                entry.put(StaticFlowEntryPusher.COLUMN_DL_SRC, jp.getText());
-            else if (n == "dst-mac")
-                entry.put(StaticFlowEntryPusher.COLUMN_DL_DST, jp.getText());
-            else if (n == "vlan-id")
-                entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN, jp.getText());
-            else if (n == "vlan-priority")
-                entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, jp.getText());
-            else if (n == "ether-type")
-                entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, jp.getText());
-            else if (n == "tos-bits")
-                entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, jp.getText());
-            else if (n == "protocol")
-                entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, jp.getText());
-            else if (n == "src-ip")
-                entry.put(StaticFlowEntryPusher.COLUMN_NW_SRC, jp.getText());
-            else if (n == "dst-ip")
-                entry.put(StaticFlowEntryPusher.COLUMN_NW_DST, jp.getText());
-            else if (n == "src-port")
-                entry.put(StaticFlowEntryPusher.COLUMN_TP_SRC, jp.getText());
-            else if (n == "dst-port")
-                entry.put(StaticFlowEntryPusher.COLUMN_TP_DST, jp.getText());
-        }
-        
-        return entry;
-    }
-    
-    /**
-     * Parses OFFlowMod actions from strings.
-     * @param flowMod The OFFlowMod to set the actions for
-     * @param actionstr The string containing all the actions
-     * @param log A logger to log for errors.
-     */
-    @LogMessageDoc(level="ERROR",
-            message="Unexpected action '{action}', '{subaction}'",
-            explanation="A static flow entry contained an invalid action",
-            recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
-    public static void parseActionString(OFFlowMod flowMod, String actionstr, Logger log) {
-        List<OFAction> actions = new LinkedList<OFAction>();
-        int actionsLength = 0;
-        if (actionstr != null) {
-            actionstr = actionstr.toLowerCase();
-            for (String subaction : actionstr.split(",")) {
-                String action = subaction.split("[=:]")[0];
-                SubActionStruct subaction_struct = null;
-                
-                if (action.equals("output")) {
-                    subaction_struct = StaticFlowEntries.decode_output(subaction, log);
-                }
-                else if (action.equals("enqueue")) {
-                    subaction_struct = decode_enqueue(subaction, log);
-                }
-                else if (action.equals("strip-vlan")) {
-                    subaction_struct = decode_strip_vlan(subaction, log);
-                }
-                else if (action.equals("set-vlan-id")) {
-                    subaction_struct = decode_set_vlan_id(subaction, log);
-                }
-                else if (action.equals("set-vlan-priority")) {
-                    subaction_struct = decode_set_vlan_priority(subaction, log);
-                }
-                else if (action.equals("set-src-mac")) {
-                    subaction_struct = decode_set_src_mac(subaction, log);
-                }
-                else if (action.equals("set-dst-mac")) {
-                    subaction_struct = decode_set_dst_mac(subaction, log);
-                }
-                else if (action.equals("set-tos-bits")) {
-                    subaction_struct = decode_set_tos_bits(subaction, log);
-                }
-                else if (action.equals("set-src-ip")) {
-                    subaction_struct = decode_set_src_ip(subaction, log);
-                }
-                else if (action.equals("set-dst-ip")) {
-                    subaction_struct = decode_set_dst_ip(subaction, log);
-                }
-                else if (action.equals("set-src-port")) {
-                    subaction_struct = decode_set_src_port(subaction, log);
-                }
-                else if (action.equals("set-dst-port")) {
-                    subaction_struct = decode_set_dst_port(subaction, log);
-                }
-                else {
-                    log.error("Unexpected action '{}', '{}'", action, subaction);
-                }
-                
-                if (subaction_struct != null) {
-                    actions.add(subaction_struct.action);
-                    actionsLength += subaction_struct.len;
-                }
-            }
-        }
-        log.debug("action {}", actions);
-        
-        flowMod.setActions(actions);
-        flowMod.setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLength);
-    } 
-    
-    @LogMessageDoc(level="ERROR",
-            message="Invalid subaction: '{subaction}'",
-            explanation="A static flow entry contained an invalid subaction",
-            recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
-    private static SubActionStruct decode_output(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n;
-        
-        n = Pattern.compile("output=(?:((?:0x)?\\d+)|(all)|(controller)|(local)|(ingress-port)|(normal)|(flood))").matcher(subaction);
-        if (n.matches()) {
-            OFActionOutput action = new OFActionOutput();
-            action.setMaxLength((short) Short.MAX_VALUE);
-            short port = OFPort.OFPP_NONE.getValue();
-            if (n.group(1) != null) {
-                try {
-                    port = get_short(n.group(1));
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid port in: '{}' (error ignored)", subaction);
-                    return null;
-                }
-            }
-            else if (n.group(2) != null)
-                port = OFPort.OFPP_ALL.getValue();
-            else if (n.group(3) != null)
-                port = OFPort.OFPP_CONTROLLER.getValue();
-            else if (n.group(4) != null)
-                port = OFPort.OFPP_LOCAL.getValue();
-            else if (n.group(5) != null)
-                port = OFPort.OFPP_IN_PORT.getValue();
-            else if (n.group(6) != null)
-                port = OFPort.OFPP_NORMAL.getValue();
-            else if (n.group(7) != null)
-                port = OFPort.OFPP_FLOOD.getValue();
-            action.setPort(port);
-            log.debug("action {}", action);
-            
-            sa = new SubActionStruct();
-            sa.action = action;
-            sa.len = OFActionOutput.MINIMUM_LENGTH;
-        }
-        else {
-            log.error("Invalid subaction: '{}'", subaction);
-            return null;
-        }
-        
-        return sa;
-    }
-    
-    private static SubActionStruct decode_enqueue(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n;
-        
-        n = Pattern.compile("enqueue=(?:((?:0x)?\\d+)\\:((?:0x)?\\d+))").matcher(subaction);
-        if (n.matches()) {
-            short portnum = 0;
-            if (n.group(1) != null) {
-                try {
-                    portnum = get_short(n.group(1));
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid port-num in: '{}' (error ignored)", subaction);
-                    return null;
-                }
-            }
-
-            int queueid = 0;
-            if (n.group(2) != null) {
-                try {
-                    queueid = get_int(n.group(2));
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid queue-id in: '{}' (error ignored)", subaction);
-                    return null;
-               }
-            }
-            
-            OFActionEnqueue action = new OFActionEnqueue();
-            action.setPort(portnum);
-            action.setQueueId(queueid);
-            log.debug("action {}", action);
-            
-            sa = new SubActionStruct();
-            sa.action = action;
-            sa.len = OFActionEnqueue.MINIMUM_LENGTH;
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-        
-        return sa;
-    }
-    
-    private static SubActionStruct decode_strip_vlan(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("strip-vlan").matcher(subaction);
-        
-        if (n.matches()) {
-            OFActionStripVirtualLan action = new OFActionStripVirtualLan();
-            log.debug("action {}", action);
-            
-            sa = new SubActionStruct();
-            sa.action = action;
-            sa.len = OFActionStripVirtualLan.MINIMUM_LENGTH;
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-    
-    private static SubActionStruct decode_set_vlan_id(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-vlan-id=((?:0x)?\\d+)").matcher(subaction);
-        
-        if (n.matches()) {            
-            if (n.group(1) != null) {
-                try {
-                    short vlanid = get_short(n.group(1));
-                    OFActionVirtualLanIdentifier action = new OFActionVirtualLanIdentifier();
-                    action.setVirtualLanIdentifier(vlanid);
-                    log.debug("  action {}", action);
-
-                    sa = new SubActionStruct();
-                    sa.action = action;
-                    sa.len = OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid VLAN in: {} (error ignored)", subaction);
-                    return null;
-                }
-            }          
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-    
-    private static SubActionStruct decode_set_vlan_priority(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-vlan-priority=((?:0x)?\\d+)").matcher(subaction); 
-        
-        if (n.matches()) {            
-            if (n.group(1) != null) {
-                try {
-                    byte prior = get_byte(n.group(1));
-                    OFActionVirtualLanPriorityCodePoint action = new OFActionVirtualLanPriorityCodePoint();
-                    action.setVirtualLanPriorityCodePoint(prior);
-                    log.debug("  action {}", action);
-                    
-                    sa = new SubActionStruct();
-                    sa.action = action;
-                    sa.len = OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid VLAN priority in: {} (error ignored)", subaction);
-                    return null;
-                }
-            }
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-    
-    private static SubActionStruct decode_set_src_mac(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-src-mac=(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(subaction); 
-
-        if (n.matches()) {
-            byte[] macaddr = get_mac_addr(n, subaction, log);
-            if (macaddr != null) {
-                OFActionDataLayerSource action = new OFActionDataLayerSource();
-                action.setDataLayerAddress(macaddr);
-                log.debug("action {}", action);
-
-                sa = new SubActionStruct();
-                sa.action = action;
-                sa.len = OFActionDataLayerSource.MINIMUM_LENGTH;
-            }            
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-
-    private static SubActionStruct decode_set_dst_mac(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-dst-mac=(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(subaction);
-        
-        if (n.matches()) {
-            byte[] macaddr = get_mac_addr(n, subaction, log);            
-            if (macaddr != null) {
-                OFActionDataLayerDestination action = new OFActionDataLayerDestination();
-                action.setDataLayerAddress(macaddr);
-                log.debug("  action {}", action);
-                
-                sa = new SubActionStruct();
-                sa.action = action;
-                sa.len = OFActionDataLayerDestination.MINIMUM_LENGTH;
-            }
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-    
-    private static SubActionStruct decode_set_tos_bits(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-tos-bits=((?:0x)?\\d+)").matcher(subaction); 
-
-        if (n.matches()) {
-            if (n.group(1) != null) {
-                try {
-                    byte tosbits = get_byte(n.group(1));
-                    OFActionNetworkTypeOfService action = new OFActionNetworkTypeOfService();
-                    action.setNetworkTypeOfService(tosbits);
-                    log.debug("  action {}", action);
-                    
-                    sa = new SubActionStruct();
-                    sa.action = action;
-                    sa.len = OFActionNetworkTypeOfService.MINIMUM_LENGTH;
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid dst-port in: {} (error ignored)", subaction);
-                    return null;
-                }
-            }
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-    
-    private static SubActionStruct decode_set_src_ip(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-src-ip=(?:(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))").matcher(subaction);
-
-        if (n.matches()) {
-            int ipaddr = get_ip_addr(n, subaction, log);
-            OFActionNetworkLayerSource action = new OFActionNetworkLayerSource();
-            action.setNetworkAddress(ipaddr);
-            log.debug("  action {}", action);
-
-            sa = new SubActionStruct();
-            sa.action = action;
-            sa.len = OFActionNetworkLayerSource.MINIMUM_LENGTH;
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-
-    private static SubActionStruct decode_set_dst_ip(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-dst-ip=(?:(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))").matcher(subaction);
-
-        if (n.matches()) {
-            int ipaddr = get_ip_addr(n, subaction, log);
-            OFActionNetworkLayerDestination action = new OFActionNetworkLayerDestination();
-            action.setNetworkAddress(ipaddr);
-            log.debug("action {}", action);
- 
-            sa = new SubActionStruct();
-            sa.action = action;
-            sa.len = OFActionNetworkLayerDestination.MINIMUM_LENGTH;
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-
-    private static SubActionStruct decode_set_src_port(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-src-port=((?:0x)?\\d+)").matcher(subaction); 
-
-        if (n.matches()) {
-            if (n.group(1) != null) {
-                try {
-                    short portnum = get_short(n.group(1));
-                    OFActionTransportLayerSource action = new OFActionTransportLayerSource();
-                    action.setTransportPort(portnum);
-                    log.debug("action {}", action);
-                    
-                    sa = new SubActionStruct();
-                    sa.action = action;
-                    sa.len = OFActionTransportLayerSource.MINIMUM_LENGTH;;
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid src-port in: {} (error ignored)", subaction);
-                    return null;
-                }
-            }
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-
-    private static SubActionStruct decode_set_dst_port(String subaction, Logger log) {
-        SubActionStruct sa = null;
-        Matcher n = Pattern.compile("set-dst-port=((?:0x)?\\d+)").matcher(subaction);
-
-        if (n.matches()) {
-            if (n.group(1) != null) {
-                try {
-                    short portnum = get_short(n.group(1));
-                    OFActionTransportLayerDestination action = new OFActionTransportLayerDestination();
-                    action.setTransportPort(portnum);
-                    log.debug("action {}", action);
-                    
-                    sa = new SubActionStruct();
-                    sa.action = action;
-                    sa.len = OFActionTransportLayerDestination.MINIMUM_LENGTH;;
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid dst-port in: {} (error ignored)", subaction);
-                    return null;
-                }
-            }
-        }
-        else {
-            log.debug("Invalid action: '{}'", subaction);
-            return null;
-        }
-
-        return sa;
-    }
-
-    private static byte[] get_mac_addr(Matcher n, String subaction, Logger log) {
-        byte[] macaddr = new byte[6];
-        
-        for (int i=0; i<6; i++) {
-            if (n.group(i+1) != null) {
-                try {
-                    macaddr[i] = get_byte("0x" + n.group(i+1));
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid src-mac in: '{}' (error ignored)", subaction);
-                    return null;
-                }
-            }
-            else { 
-                log.debug("Invalid src-mac in: '{}' (null, error ignored)", subaction);
-                return null;
-            }
-        }
-        
-        return macaddr;
-    }
-    
-    private static int get_ip_addr(Matcher n, String subaction, Logger log) {
-        int ipaddr = 0;
-
-        for (int i=0; i<4; i++) {
-            if (n.group(i+1) != null) {
-                try {
-                    ipaddr = ipaddr<<8;
-                    ipaddr = ipaddr | get_int(n.group(i+1));
-                }
-                catch (NumberFormatException e) {
-                    log.debug("Invalid src-ip in: '{}' (error ignored)", subaction);
-                    return 0;
-                }
-            }
-            else {
-                log.debug("Invalid src-ip in: '{}' (null, error ignored)", subaction);
-                return 0;
-            }
-        }
-        
-        return ipaddr;
-    }
-    
-    // Parse int as decimal, hex (start with 0x or #) or octal (starts with 0)
-    private static int get_int(String str) {
-        return (int)Integer.decode(str);
-    }
-   
-    // Parse short as decimal, hex (start with 0x or #) or octal (starts with 0)
-    private static short get_short(String str) {
-        return (short)(int)Integer.decode(str);
-    }
-   
-    // Parse byte as decimal, hex (start with 0x or #) or octal (starts with 0)
-    private static byte get_byte(String str) {
-        return Integer.decode(str).byteValue();
-    }
-
-}
-
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
deleted file mode 100644
index 89664a4..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ /dev/null
@@ -1,676 +0,0 @@
-package net.floodlightcontroller.staticflowentry;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IFloodlightProviderService.Role;
-import net.floodlightcontroller.core.IHAListener;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.IOFSwitchListener;
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.staticflowentry.web.StaticFlowEntryWebRoutable;
-
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFFlowRemoved;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.util.HexString;
-import org.openflow.util.U16;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@LogMessageCategory("Static Flow Pusher")
-/**
- * This module is responsible for maintaining a set of static flows on
- * switches. This is just a big 'ol dumb list of flows and something external
- * is responsible for ensuring they make sense for the network.
- */
-public class StaticFlowEntryPusher 
-    implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
-        /*IStorageSourceListener,*/ IOFMessageListener, IHAListener {
-    protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusher.class);
-    public static final String StaticFlowName = "staticflowentry";
-    
-    public static final int STATIC_FLOW_APP_ID = 10;
-
-    public static final String TABLE_NAME = "controller_staticflowtableentry";
-    public static final String COLUMN_NAME = "name";
-    public static final String COLUMN_SWITCH = "switch_id";
-    public static final String COLUMN_ACTIVE = "active";
-    public static final String COLUMN_IDLE_TIMEOUT = "idle_timeout";
-    public static final String COLUMN_HARD_TIMEOUT = "hard_timeout";
-    public static final String COLUMN_PRIORITY = "priority";
-    public static final String COLUMN_COOKIE = "cookie";
-    public static final String COLUMN_WILDCARD = "wildcards";
-    public static final String COLUMN_IN_PORT = "in_port";
-    public static final String COLUMN_DL_SRC = "dl_src";
-    public static final String COLUMN_DL_DST = "dl_dst";
-    public static final String COLUMN_DL_VLAN = "dl_vlan";
-    public static final String COLUMN_DL_VLAN_PCP = "dl_vlan_pcp";
-    public static final String COLUMN_DL_TYPE = "dl_type";
-    public static final String COLUMN_NW_TOS = "nw_tos";
-    public static final String COLUMN_NW_PROTO = "nw_proto";
-    public static final String COLUMN_NW_SRC = "nw_src"; // includes CIDR-style
-                                                         // netmask, e.g.
-                                                         // "128.8.128.0/24"
-    public static final String COLUMN_NW_DST = "nw_dst";
-    public static final String COLUMN_TP_DST = "tp_dst";
-    public static final String COLUMN_TP_SRC = "tp_src";
-    public static final String COLUMN_ACTIONS = "actions";
-    public static String ColumnNames[] = { COLUMN_NAME, COLUMN_SWITCH,
-            COLUMN_ACTIVE, COLUMN_IDLE_TIMEOUT, COLUMN_HARD_TIMEOUT,
-            COLUMN_PRIORITY, COLUMN_COOKIE, COLUMN_WILDCARD, COLUMN_IN_PORT,
-            COLUMN_DL_SRC, COLUMN_DL_DST, COLUMN_DL_VLAN, COLUMN_DL_VLAN_PCP,
-            COLUMN_DL_TYPE, COLUMN_NW_TOS, COLUMN_NW_PROTO, COLUMN_NW_SRC,
-            COLUMN_NW_DST, COLUMN_TP_DST, COLUMN_TP_SRC, COLUMN_ACTIONS };
- 
-
-    protected IFloodlightProviderService floodlightProvider;
-    //protected IStorageSourceService storageSource;
-    protected IRestApiService restApi;
-
-    // Map<DPID, Map<Name, FlowMod>> ; FlowMod can be null to indicate non-active
-    protected Map<String, Map<String, OFFlowMod>> entriesFromStorage;
-    // Entry Name -> DPID of Switch it's on
-    protected Map<String, String> entry2dpid;
-
-    private BasicFactory ofMessageFactory;
-
-    // Class to sort FlowMod's by priority, from lowest to highest
-    class FlowModSorter implements Comparator<String> {
-        private String dpid;
-        public FlowModSorter(String dpid) {
-            this.dpid = dpid;
-        }
-        @Override
-        public int compare(String o1, String o2) {
-            OFFlowMod f1 = entriesFromStorage.get(dpid).get(o1);
-            OFFlowMod f2 = entriesFromStorage.get(dpid).get(o2);
-            if (f1 == null || f2 == null) // sort active=false flows by key
-                return o1.compareTo(o2);
-            return U16.f(f1.getPriority()) - U16.f(f2.getPriority());
-        }
-    };
-
-    /**
-     * used for debugging and unittests
-     * @return the number of static flow entries as cached from storage
-     */
-    public int countEntries() {
-        int size = 0;
-        if (entriesFromStorage == null)
-            return 0;
-        for (String ofswitch : entriesFromStorage.keySet())
-            size += entriesFromStorage.get(ofswitch).size();
-        return size;
-    }
-
-    public IFloodlightProviderService getFloodlightProvider() {
-        return floodlightProvider;
-    }
-
-    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
-        this.floodlightProvider = floodlightProvider;
-    }
-
-    /*
-    public void setStorageSource(IStorageSourceService storageSource) {
-        this.storageSource = storageSource;
-    }
-    */
-
-    /**
-     * Reads from our entriesFromStorage for the specified switch and
-     * sends the FlowMods down to the controller in <b>sorted</b> order.
-     *
-     * Sorted is important to maintain correctness of the switch:
-     * if a packet would match both a lower and a higher priority
-     * rule, then we want it to match the higher priority or nothing,
-     * but never just the lower priority one.  Inserting from high to
-     * low priority fixes this.
-     *
-     * TODO consider adding a "block all" flow mod and then removing it
-     * while starting up.
-     *
-     * @param sw The switch to send entries to
-     */
-    protected void sendEntriesToSwitch(IOFSwitch sw) {
-        String dpid = sw.getStringId();
-
-        if ((entriesFromStorage != null) && (entriesFromStorage.containsKey(dpid))) {
-            Map<String, OFFlowMod> entries = entriesFromStorage.get(dpid);
-            List<String> sortedList = new ArrayList<String>(entries.keySet());
-            // weird that Collections.sort() returns void
-            Collections.sort( sortedList, new FlowModSorter(dpid));
-            for (String entryName : sortedList) {
-                OFFlowMod flowMod = entries.get(entryName);
-                if (flowMod != null) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("Pushing static entry {} for {}", dpid, entryName);
-                    }
-                    writeFlowModToSwitch(sw, flowMod);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Used only for bundle-local indexing
-     * 
-     * @param map
-     * @return
-     */
-
-    protected Map<String, String> computeEntry2DpidMap(
-                Map<String, Map<String, OFFlowMod>> map) {
-        Map<String, String> ret = new HashMap<String, String>();
-        for(String dpid : map.keySet()) {
-            for( String entry: map.get(dpid).keySet())
-                ret.put(entry, dpid);
-        }
-        return ret;
-    }
-    
-    /**
-     * Read entries from storageSource, and store them in a hash
-     * 
-     * @return
-     */
-    /*
-    @LogMessageDoc(level="ERROR",
-            message="failed to access storage: {reason}",
-            explanation="Could not retrieve static flows from the system " +
-            		"database",
-            recommendation=LogMessageDoc.CHECK_CONTROLLER)
-    private Map<String, Map<String, OFFlowMod>> readEntriesFromStorage() {
-        Map<String, Map<String, OFFlowMod>> entries = new ConcurrentHashMap<String, Map<String, OFFlowMod>>();
-        try {
-            Map<String, Object> row;
-            // null1=no predicate, null2=no ordering
-            IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
-                    ColumnNames, null, null);
-            for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
-                row = it.next().getRow();
-                parseRow(row, entries);
-            }
-        } catch (StorageException e) {
-            log.error("failed to access storage: {}", e.getMessage());
-            // if the table doesn't exist, then wait to populate later via
-            // setStorageSource()
-        }
-        return entries;
-    }
-    */
-
-    /**
-     * Take a single row, turn it into a flowMod, and add it to the
-     * entries{$dpid}.{$entryName}=FlowMod 
-     * 
-     * IF an entry is in active, mark it with FlowMod = null
-     * 
-     * @param row
-     * @param entries
-     */
-
-    void parseRow(Map<String, Object> row,
-            Map<String, Map<String, OFFlowMod>> entries) {
-        String switchName = null;
-        String entryName = null;
-
-        StringBuffer matchString = new StringBuffer();
-        if (ofMessageFactory == null) // lazy init
-            ofMessageFactory = new BasicFactory();
-
-        OFFlowMod flowMod = (OFFlowMod) ofMessageFactory
-                .getMessage(OFType.FLOW_MOD);
-
-        if (!row.containsKey(COLUMN_SWITCH) || !row.containsKey(COLUMN_NAME)) {
-            log.debug(
-                    "skipping entry with missing required 'switch' or 'name' entry: {}",
-                    row);
-            return;
-        }
-        // most error checking done with ClassCastException
-        try {
-            // first, snag the required entries, for debugging info
-            switchName = (String) row.get(COLUMN_SWITCH);
-            entryName = (String) row.get(COLUMN_NAME);
-            if (!entries.containsKey(switchName))
-                entries.put(switchName, new HashMap<String, OFFlowMod>());
-            StaticFlowEntries.initDefaultFlowMod(flowMod, entryName);
-            
-            for (String key : row.keySet()) {
-                if (row.get(key) == null)
-                    continue;
-                if ( key.equals(COLUMN_SWITCH) || key.equals(COLUMN_NAME)
-                        || key.equals("id"))
-                    continue; // already handled
-                // explicitly ignore timeouts and wildcards
-                if ( key.equals(COLUMN_HARD_TIMEOUT) || key.equals(COLUMN_IDLE_TIMEOUT) ||
-                        key.equals(COLUMN_WILDCARD))
-                    continue;
-                if ( key.equals(COLUMN_ACTIVE)) {
-                    if  (! Boolean.valueOf((String) row.get(COLUMN_ACTIVE))) {
-                        log.debug("skipping inactive entry {} for switch {}",
-                                entryName, switchName);
-                        entries.get(switchName).put(entryName, null);  // mark this an inactive
-                        return;
-                    }
-                } else if ( key.equals(COLUMN_ACTIONS)){
-                    StaticFlowEntries.parseActionString(flowMod, (String) row.get(COLUMN_ACTIONS), log);
-                } else if ( key.equals(COLUMN_COOKIE)) {
-                    flowMod.setCookie(
-                            StaticFlowEntries.computeEntryCookie(flowMod, 
-                                    Integer.valueOf((String) row.get(COLUMN_COOKIE)), 
-                                    entryName)
-                        );
-                } else if ( key.equals(COLUMN_PRIORITY)) {
-                    flowMod.setPriority(U16.t(Integer.valueOf((String) row.get(COLUMN_PRIORITY))));
-                } else { // the rest of the keys are for OFMatch().fromString()
-                    if (matchString.length() > 0)
-                        matchString.append(",");
-                    matchString.append(key + "=" + row.get(key).toString());
-                }
-            }
-        } catch (ClassCastException e) {
-            if (entryName != null && switchName != null)
-                log.debug(
-                        "skipping entry {} on switch {} with bad data : "
-                                + e.getMessage(), entryName, switchName);
-            else
-                log.debug("skipping entry with bad data: {} :: {} ",
-                        e.getMessage(), e.getStackTrace());
-        }
-
-        OFMatch ofMatch = new OFMatch();
-        String match = matchString.toString();
-        try {
-            ofMatch.fromString(match);
-        } catch (IllegalArgumentException e) {
-            log.debug(
-                    "ignoring flow entry {} on switch {} with illegal OFMatch() key: "
-                            + match, entryName, switchName);
-            return;
-        }
-        flowMod.setMatch(ofMatch);
-
-        entries.get(switchName).put(entryName, flowMod);
-    }
-    
-    @Override
-    public void addedSwitch(IOFSwitch sw) {
-        log.debug("addedSwitch {}; processing its static entries", sw);
-        sendEntriesToSwitch(sw);
-    }
-
-    @Override
-    public void removedSwitch(IOFSwitch sw) {
-        log.debug("removedSwitch {}", sw);
-        // do NOT delete from our internal state; we're tracking the rules,
-        // not the switches
-    }
-    
-    @Override
-    public void switchPortChanged(Long switchId) {
-        // no-op
-    }
-
-    /**
-     * This handles both rowInsert() and rowUpdate()
-     */
-    /*
-    @Override
-    public void rowsModified(String tableName, Set<Object> rowKeys) {
-        log.debug("Modifying Table {}", tableName);
-
-        HashMap<String, Map<String, OFFlowMod>> entriesToAdd = 
-            new HashMap<String, Map<String, OFFlowMod>>();
-        // build up list of what was added 
-        for(Object key: rowKeys) {
-            IResultSet resultSet = storageSource.getRow(tableName, key);
-            for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
-                Map<String, Object> row = it.next().getRow();
-                parseRow(row, entriesToAdd);
-            }            
-        }
-        // batch updates by switch and blast them out
-        for (String dpid : entriesToAdd.keySet()) {
-            if (!entriesFromStorage.containsKey(dpid))
-                entriesFromStorage.put(dpid, new HashMap<String, OFFlowMod>());
-            List<OFMessage> outQueue = new ArrayList<OFMessage>();
-            for(String entry : entriesToAdd.get(dpid).keySet()) {
-                OFFlowMod newFlowMod = entriesToAdd.get(dpid).get(entry);
-                OFFlowMod oldFlowMod = entriesFromStorage.get(dpid).get(entry);
-                if (oldFlowMod != null) {  // remove any pre-existing rule
-                    oldFlowMod.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
-                    outQueue.add(oldFlowMod);
-                }
-                if (newFlowMod != null) {
-                    entriesFromStorage.get(dpid).put(entry, newFlowMod);
-                    outQueue.add(newFlowMod);
-                    entry2dpid.put(entry, dpid);
-                } else {
-                    entriesFromStorage.get(dpid).remove(entry);
-                    entry2dpid.remove(entry);
-                }
-            }
-            
-            writeOFMessagesToSwitch(HexString.toLong(dpid), outQueue);
-        }
-    }
-
-    @Override
-    public void rowsDeleted(String tableName, Set<Object> rowKeys) {
-        if (log.isDebugEnabled()) {
-            log.debug("deleting from Table {}", tableName);
-        }
-        
-        for(Object obj : rowKeys) {
-            if (!(obj instanceof String)) {
-                log.debug("tried to delete non-string key {}; ignoring", obj);
-                continue;
-            }
-            deleteStaticFlowEntry((String) obj);
-        }
-    }
-    */
-    
-    @LogMessageDoc(level="ERROR",
-            message="inconsistent internal state: no switch has rule {rule}",
-            explanation="Inconsistent internat state discovered while " +
-            		"deleting a static flow rule",
-            recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
-    private boolean deleteStaticFlowEntry(String entryName) {
-        String dpid = entry2dpid.get(entryName);
-        if (log.isDebugEnabled()) {
-            log.debug("Deleting flow {} for switch {}", entryName, dpid);
-        }
-        if (dpid == null) {
-            log.error("inconsistent internal state: no switch has rule {}",
-                    entryName);
-            return false;
-        }
-        
-        // send flow_mod delete
-        OFFlowMod flowMod = entriesFromStorage.get(dpid).get(entryName);
-        flowMod.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
-
-        if (entriesFromStorage.containsKey(dpid) && 
-                entriesFromStorage.get(dpid).containsKey(entryName)) {
-            entriesFromStorage.get(dpid).remove(entryName);
-        } else { 
-            log.debug("Tried to delete non-existent entry {} for switch {}", 
-                    entryName, dpid);
-            return false;
-        }
-        
-        writeFlowModToSwitch(HexString.toLong(dpid), flowMod);
-        return true;
-    }
-    
-    /**
-     * Writes a list of OFMessages to a switch
-     * @param dpid The datapath ID of the switch to write to
-     * @param messages The list of OFMessages to write.
-     */
-    @LogMessageDoc(level="ERROR",
-            message="Tried to write to switch {switch} but got {error}",
-            explanation="An I/O error occured while trying to write a " +
-            		"static flow to a switch",
-            recommendation=LogMessageDoc.CHECK_SWITCH)
-    private void writeOFMessagesToSwitch(long dpid, List<OFMessage> messages) {
-        IOFSwitch ofswitch = floodlightProvider.getSwitches().get(dpid);
-        if (ofswitch != null) {  // is the switch connected
-            try {
-                if (log.isDebugEnabled()) {
-                    log.debug("Sending {} new entries to {}", messages.size(), dpid);
-                }
-                ofswitch.write(messages, null);
-                ofswitch.flush();
-            } catch (IOException e) {
-                log.error("Tried to write to switch {} but got {}", dpid, e.getMessage());
-            }
-        }
-    }
-    
-    /**
-     * Writes an OFFlowMod to a switch. It checks to make sure the switch
-     * exists before it sends
-     * @param dpid The data  to write the flow mod to
-     * @param flowMod The OFFlowMod to write
-     */
-    private void writeFlowModToSwitch(long dpid, OFFlowMod flowMod) {
-        Map<Long,IOFSwitch> switches = floodlightProvider.getSwitches();
-        IOFSwitch ofSwitch = switches.get(dpid);
-        if (ofSwitch == null) {
-            if (log.isDebugEnabled()) {
-                log.debug("Not deleting key {} :: switch {} not connected", 
-                          dpid);
-            }
-            return;
-        }
-        writeFlowModToSwitch(ofSwitch, flowMod);
-    }
-    
-    /**
-     * Writes an OFFlowMod to a switch
-     * @param sw The IOFSwitch to write to
-     * @param flowMod The OFFlowMod to write
-     */
-    @LogMessageDoc(level="ERROR",
-            message="Tried to write OFFlowMod to {switch} but got {error}",
-            explanation="An I/O error occured while trying to write a " +
-                    "static flow to a switch",
-            recommendation=LogMessageDoc.CHECK_SWITCH)
-    private void writeFlowModToSwitch(IOFSwitch sw, OFFlowMod flowMod) {
-        try {
-            sw.write(flowMod, null);
-            sw.flush();
-        } catch (IOException e) {
-            log.error("Tried to write OFFlowMod to {} but failed: {}", 
-                    HexString.toHexString(sw.getId()), e.getMessage());
-        }
-    }
-
-    @Override
-    public String getName() {
-        return StaticFlowName;
-    }
-    
-    @Override
-    @LogMessageDoc(level="ERROR",
-        message="Got a FlowRemove message for a infinite " +
-                "timeout flow: {flow} from switch {switch}",
-        explanation="Flows with infinite timeouts should not expire. " +
-        		"The switch has expired the flow anyway.",
-        recommendation=LogMessageDoc.REPORT_SWITCH_BUG)
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        switch (msg.getType()) {
-        case FLOW_REMOVED:
-            break;
-        default:
-            return Command.CONTINUE;
-        }
-        OFFlowRemoved flowRemoved = (OFFlowRemoved) msg;
-        long cookie = flowRemoved.getCookie();
-        /**
-         * This is just to sanity check our assumption that static flows 
-         * never expire.
-         */
-        if( AppCookie.extractApp(cookie) == STATIC_FLOW_APP_ID) {
-            if (flowRemoved.getReason() != 
-                    OFFlowRemoved.OFFlowRemovedReason.OFPRR_DELETE)
-                log.error("Got a FlowRemove message for a infinite " +
-                		  "timeout flow: {} from switch {}", msg, sw);
-            return Command.STOP;    // only for us
-        } else
-            return Command.CONTINUE;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        return false;  // no dependency for non-packet in
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        return false;  // no dependency for non-packet in
-    }
-
-    // IFloodlightModule
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IStaticFlowEntryPusherService.class);
-        return l;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
-                new HashMap<Class<? extends IFloodlightService>,
-                    IFloodlightService>();
-        m.put(IStaticFlowEntryPusherService.class, this);
-        return m;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        //l.add(IStorageSourceService.class);
-        l.add(IRestApiService.class);
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context)
-            throws FloodlightModuleException {
-        floodlightProvider =
-            context.getServiceImpl(IFloodlightProviderService.class);
-        //storageSource =
-            //context.getServiceImpl(IStorageSourceService.class);
-        restApi =
-            context.getServiceImpl(IRestApiService.class);
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {        
-        floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
-        floodlightProvider.addOFSwitchListener(this);
-        floodlightProvider.addHAListener(this);
-        
-        // assumes no switches connected at startup()
-        //storageSource.createTable(TABLE_NAME, null);
-        //storageSource.setTablePrimaryKeyName(TABLE_NAME, COLUMN_NAME);
-        //storageSource.addListener(TABLE_NAME, this);
-        //entriesFromStorage = readEntriesFromStorage(); 
-        //entry2dpid = computeEntry2DpidMap(entriesFromStorage);
-        restApi.addRestletRoutable(new StaticFlowEntryWebRoutable());
-    }
-
-    // IStaticFlowEntryPusherService methods
-    
-    @Override
-    public void addFlow(String name, OFFlowMod fm, String swDpid) {
-        Map<String, Object> fmMap = StaticFlowEntries.flowModToStorageEntry(fm, swDpid, name);
-        entry2dpid.put(name, swDpid);
-        Map<String, OFFlowMod> switchEntries = entriesFromStorage.get(swDpid);
-        if (switchEntries == null) {
-            switchEntries = new HashMap<String, OFFlowMod>();
-            entriesFromStorage.put(swDpid, switchEntries);
-        }
-        switchEntries.put(name, fm);
-        //storageSource.insertRowAsync(TABLE_NAME, fmMap);
-    }
-
-    @Override
-    public void deleteFlow(String name) {
-        //storageSource.deleteRowAsync(TABLE_NAME, name);
-        // TODO - What if there is a delay in storage?
-    }
-    
-    @Override
-    public void deleteAllFlows() {
-        for (String entry : entry2dpid.keySet()) {
-            deleteFlow(entry);
-        }
-    }
-    
-    @Override
-    public void deleteFlowsForSwitch(long dpid) {
-        String sDpid = HexString.toHexString(dpid);
-        
-        for (Entry<String, String> e : entry2dpid.entrySet()) {
-            if (e.getValue().equals(sDpid))
-                deleteFlow(e.getKey());
-        }
-    }
-    
-    @Override
-    public Map<String, Map<String, OFFlowMod>> getFlows() {
-        return entriesFromStorage;
-    }
-    
-    @Override
-    public Map<String, OFFlowMod> getFlows(String dpid) {
-        return entriesFromStorage.get(dpid);
-    }
-
-    
-    // IHAListener
-    
-    @Override
-    public void roleChanged(Role oldRole, Role newRole) {
-        switch(newRole) {
-            case MASTER:
-                if (oldRole == Role.SLAVE) {
-                    log.debug("Re-reading static flows from storage due " +
-                            "to HA change from SLAVE->MASTER");
-                    //entriesFromStorage = readEntriesFromStorage(); 
-                    entry2dpid = computeEntry2DpidMap(entriesFromStorage);
-                }
-                break;
-            case SLAVE:
-                log.debug("Clearing in-memory flows due to " +
-                        "HA change to SLAVE");
-                entry2dpid.clear();
-                entriesFromStorage.clear();
-                break;
-            default:
-            	break;
-        }
-    }
-    
-    @Override
-    public void controllerNodeIPsChanged(
-            Map<String, String> curControllerNodeIPs,
-            Map<String, String> addedControllerNodeIPs,
-            Map<String, String> removedControllerNodeIPs) {
-        // ignore
-    }
-     
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java
deleted file mode 100644
index f103e99..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.floodlightcontroller.staticflowentry.web;
-
-import net.floodlightcontroller.core.web.ControllerSwitchesResource;
-import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
-
-import org.openflow.util.HexString;
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClearStaticFlowEntriesResource extends ServerResource {
-    protected final static Logger log = LoggerFactory.getLogger(ClearStaticFlowEntriesResource.class);
-    
-    @Get
-    public void ClearStaticFlowEntries() {
-        IStaticFlowEntryPusherService sfpService =
-                (IStaticFlowEntryPusherService)getContext().getAttributes().
-                    get(IStaticFlowEntryPusherService.class.getCanonicalName());
-        
-        String param = (String) getRequestAttributes().get("switch");
-        if (log.isDebugEnabled())
-            log.debug("Clearing all static flow entires for switch: " + param);
-        
-        if (param.toLowerCase().equals("all")) {
-            sfpService.deleteAllFlows();
-        } else {
-            try {
-                sfpService.deleteFlowsForSwitch(HexString.toLong(param));
-            } catch (NumberFormatException e){
-                setStatus(Status.CLIENT_ERROR_BAD_REQUEST, 
-                          ControllerSwitchesResource.DPID_ERROR);
-                return;
-            }
-        }
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/ListStaticFlowEntriesResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/ListStaticFlowEntriesResource.java
deleted file mode 100644
index 2bb53ba..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/ListStaticFlowEntriesResource.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package net.floodlightcontroller.staticflowentry.web;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import net.floodlightcontroller.core.web.ControllerSwitchesResource;
-import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
-
-import org.openflow.protocol.OFFlowMod;
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ListStaticFlowEntriesResource extends ServerResource {
-    protected final static Logger log = LoggerFactory.getLogger(ListStaticFlowEntriesResource.class);
-    
-    @Get
-    public Map<String, Map<String, OFFlowMod>> ListStaticFlowEntries() {
-        IStaticFlowEntryPusherService sfpService =
-                (IStaticFlowEntryPusherService)getContext().getAttributes().
-                    get(IStaticFlowEntryPusherService.class.getCanonicalName());
-        
-        String param = (String) getRequestAttributes().get("switch");
-        if (log.isDebugEnabled())
-            log.debug("Listing all static flow entires for switch: " + param);
-        
-        if (param.toLowerCase().equals("all")) {
-            return sfpService.getFlows();
-        } else {
-            try {
-                Map<String, Map<String, OFFlowMod>> retMap = 
-                        new HashMap<String, Map<String, OFFlowMod>>();
-                retMap.put(param, sfpService.getFlows(param));
-                return retMap;
-                
-            } catch (NumberFormatException e){
-                setStatus(Status.CLIENT_ERROR_BAD_REQUEST, 
-                          ControllerSwitchesResource.DPID_ERROR);
-            }
-        }
-        return null;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java
deleted file mode 100644
index 1db262d..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java
+++ /dev/null
@@ -1,137 +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 net.floodlightcontroller.staticflowentry.web;
-
-import java.util.Map;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
-
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Pushes a static flow entry to the storage source
- * @author alexreimers
- *
- */
-@LogMessageCategory("Static Flow Pusher")
-public class StaticFlowEntryPusherResource extends ServerResource {
-    protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class);
-    
-    /**
-     * Checks to see if the user matches IP information without
-     * checking for the correct ether-type (2048).
-     * @param rows The Map that is a string representation of
-     * the static flow.
-     * @reutrn True if they checked the ether-type, false otherwise
-     */
-    private boolean checkMatchIp(Map<String, Object> rows) {
-        boolean matchEther = false;
-        String val = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE);
-        if (val != null) {
-            int type = 0;
-            // check both hex and decimal
-            if (val.startsWith("0x")) {
-                type = Integer.parseInt(val.substring(2), 16);
-            } else {
-                try {
-                    type = Integer.parseInt(val);
-                } catch (NumberFormatException e) { /* fail silently */}
-            }
-            if (type == 2048) matchEther = true;
-        }
-        
-        if ((rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) || 
-                rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC) ||
-                rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO) ||
-                rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_TOS)) &&
-                (matchEther == false))
-            return false;
-        
-        return true;
-    }
-    
-    /**
-     * Takes a Static Flow Pusher string in JSON format and parses it into
-     * our database schema then pushes it to the database.
-     * @param fmJson The Static Flow Pusher entry in JSON format.
-     * @return A string status message
-     */
-    /*
-    @Post
-    @LogMessageDoc(level="ERROR",
-        message="Error parsing push flow mod request: {request}",
-        explanation="An invalid request was sent to static flow pusher",
-        recommendation="Fix the format of the static flow mod request")
-    public String store(String fmJson) {
-        IStorageSourceService storageSource =
-                (IStorageSourceService)getContext().getAttributes().
-                    get(IStorageSourceService.class.getCanonicalName());
-        
-        Map<String, Object> rowValues;
-        try {
-            rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson);
-            String status = null;
-            if (!checkMatchIp(rowValues)) {
-                status = "Warning! Pushing a static flow entry that matches IP " +
-                        "fields without matching for IP payload (ether-type 2048) will cause " +
-                        "the switch to wildcard higher level fields.";
-                log.error(status);
-            } else {
-                status = "Entry pushed";
-            }
-            storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
-            return ("{\"status\" : \"" + status + "\"}");
-        } catch (IOException e) {
-            log.error("Error parsing push flow mod request: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}";
-        }
-    }
-    
-    @Delete
-    @LogMessageDoc(level="ERROR",
-        message="Error deleting flow mod request: {request}",
-        explanation="An invalid delete request was sent to static flow pusher",
-        recommendation="Fix the format of the static flow mod request")
-    public String del(String fmJson) {
-        IStorageSourceService storageSource =
-                (IStorageSourceService)getContext().getAttributes().
-                    get(IStorageSourceService.class.getCanonicalName());
-        String fmName = null;
-        if (fmJson == null) {
-            return "{\"status\" : \"Error! No data posted.\"}";
-        }
-        try {
-            fmName = StaticFlowEntries.getEntryNameFromJson(fmJson);
-            if (fmName == null) {
-                return "{\"status\" : \"Error deleting entry, no name provided\"}";
-            }
-        } catch (IOException e) {
-            log.error("Error deleting flow mod request: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error deleting entry, see log for details\"}";
-        }
-        
-        storageSource.deleteRowAsync(StaticFlowEntryPusher.TABLE_NAME, fmName);
-        return "{\"status\" : \"Entry " + fmName + " deleted\"}";
-    }
-    */
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java
deleted file mode 100644
index b5a6fe1..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.floodlightcontroller.staticflowentry.web;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-public class StaticFlowEntryWebRoutable implements RestletRoutable {
-    /**
-     * Create the Restlet router and bind to the proper resources.
-     */
-    @Override
-    public Restlet getRestlet(Context context) {
-        Router router = new Router(context);
-        router.attach("/json", StaticFlowEntryPusherResource.class);
-        router.attach("/clear/{switch}/json", ClearStaticFlowEntriesResource.class);
-        router.attach("/list/{switch}/json", ListStaticFlowEntriesResource.class);
-        return router;
-    }
-
-    /**
-     * Set the base path for the Topology
-     */
-    @Override
-    public String basePath() {
-        return "/wm/staticflowentrypusher";
-    }
-}
