diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
deleted file mode 100644
index 3f8ff6c..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java
+++ /dev/null
@@ -1,667 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-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.IFloodlightProviderService;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-
-import java.util.ArrayList;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.routing.RoutingDecision;
-import net.floodlightcontroller.storage.IResultSet;
-import net.floodlightcontroller.storage.IStorageSourceService;
-import net.floodlightcontroller.storage.StorageException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Stateless firewall implemented as a Google Summer of Code project.
- * Configuration done through REST API
- * 
- * @author Amer Tahir
- * @edited KC Wang
- */
-public class Firewall implements IFirewallService, IOFMessageListener,
-        IFloodlightModule {
-
-    // service modules needed
-    protected IFloodlightProviderService floodlightProvider;
-    protected IStorageSourceService storageSource;
-    protected IRestApiService restApi;
-    protected static Logger logger;
-
-    protected List<FirewallRule> rules; // protected by synchronized
-    protected boolean enabled;
-    protected int subnet_mask = IPv4.toIPv4Address("255.255.255.0");
-
-    // constant strings for storage/parsing
-    public static final String TABLE_NAME = "controller_firewallrules";
-    public static final String COLUMN_RULEID = "ruleid";
-    public static final String COLUMN_DPID = "dpid";
-    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_TYPE = "dl_type";
-    public static final String COLUMN_NW_SRC_PREFIX = "nw_src_prefix";
-    public static final String COLUMN_NW_SRC_MASKBITS = "nw_src_maskbits";
-    public static final String COLUMN_NW_DST_PREFIX = "nw_dst_prefix";
-    public static final String COLUMN_NW_DST_MASKBITS = "nw_dst_maskbits";
-    public static final String COLUMN_NW_PROTO = "nw_proto";
-    public static final String COLUMN_TP_SRC = "tp_src";
-    public static final String COLUMN_TP_DST = "tp_dst";
-    public static final String COLUMN_WILDCARD_DPID = "wildcard_dpid";
-    public static final String COLUMN_WILDCARD_IN_PORT = "wildcard_in_port";
-    public static final String COLUMN_WILDCARD_DL_SRC = "wildcard_dl_src";
-    public static final String COLUMN_WILDCARD_DL_DST = "wildcard_dl_dst";
-    public static final String COLUMN_WILDCARD_DL_TYPE = "wildcard_dl_type";
-    public static final String COLUMN_WILDCARD_NW_SRC = "wildcard_nw_src";
-    public static final String COLUMN_WILDCARD_NW_DST = "wildcard_nw_dst";
-    public static final String COLUMN_WILDCARD_NW_PROTO = "wildcard_nw_proto";
-    public static final String COLUMN_WILDCARD_TP_SRC = "wildcard_tp_src";
-    public static final String COLUMN_WILDCARD_TP_DST = "wildcard_tp_dst";
-    public static final String COLUMN_PRIORITY = "priority";
-    public static final String COLUMN_ACTION = "action";
-    public static String ColumnNames[] = { COLUMN_RULEID, COLUMN_DPID,
-            COLUMN_IN_PORT, COLUMN_DL_SRC, COLUMN_DL_DST, COLUMN_DL_TYPE,
-            COLUMN_NW_SRC_PREFIX, COLUMN_NW_SRC_MASKBITS, COLUMN_NW_DST_PREFIX,
-            COLUMN_NW_DST_MASKBITS, COLUMN_NW_PROTO, COLUMN_TP_SRC,
-            COLUMN_TP_DST, COLUMN_WILDCARD_DPID, COLUMN_WILDCARD_IN_PORT,
-            COLUMN_WILDCARD_DL_SRC, COLUMN_WILDCARD_DL_DST,
-            COLUMN_WILDCARD_DL_TYPE, COLUMN_WILDCARD_NW_SRC,
-            COLUMN_WILDCARD_NW_DST, COLUMN_WILDCARD_NW_PROTO, COLUMN_PRIORITY,
-            COLUMN_ACTION };
-
-    @Override
-    public String getName() {
-        return "firewall";
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        // no prereq
-        return false;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        return (type.equals(OFType.PACKET_IN) && name.equals("forwarding"));
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFirewallService.class);
-        return l;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-        Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
-        // We are the class that implements the service
-        m.put(IFirewallService.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;
-    }
-
-    /**
-     * Reads the rules from the storage and creates a sorted arraylist of
-     * FirewallRule from them.
-     * 
-     * Similar to getStorageRules(), which only reads contents for REST GET and
-     * does no parsing, checking, nor putting into FirewallRule objects
-     * 
-     * @return the sorted arraylist of FirewallRule instances (rules from
-     *         storage)
-     */
-    protected ArrayList<FirewallRule> readRulesFromStorage() {
-        ArrayList<FirewallRule> l = new ArrayList<FirewallRule>();
-
-        try {
-            Map<String, Object> row;
-
-            // (..., null, null) for no predicate, no ordering
-            IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
-                    ColumnNames, null, null);
-
-            // put retrieved rows into FirewallRules
-            for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
-                row = it.next().getRow();
-                // now, parse row
-                FirewallRule r = new FirewallRule();
-                if (!row.containsKey(COLUMN_RULEID)
-                        || !row.containsKey(COLUMN_DPID)) {
-                    logger.error(
-                            "skipping entry with missing required 'ruleid' or 'switchid' entry: {}",
-                            row);
-                    return l;
-                }
-                try {
-                    r.ruleid = Integer
-                            .parseInt((String) row.get(COLUMN_RULEID));
-                    r.dpid = Long.parseLong((String) row.get(COLUMN_DPID));
-
-                    for (String key : row.keySet()) {
-                        if (row.get(key) == null)
-                            continue;
-                        if (key.equals(COLUMN_RULEID)
-                                || key.equals(COLUMN_DPID)
-                                || key.equals("id")) {
-                            continue; // already handled
-                        } 
-                        
-                        else if (key.equals(COLUMN_IN_PORT)) {
-                            r.in_port = Short.parseShort((String) row
-                                    .get(COLUMN_IN_PORT));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_SRC)) {
-                            r.dl_src = Long.parseLong((String) row
-                                    .get(COLUMN_DL_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_DST)) {
-                            r.dl_dst = Long.parseLong((String) row
-                                    .get(COLUMN_DL_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_TYPE)) {
-                            r.dl_type = Short.parseShort((String) row
-                                    .get(COLUMN_DL_TYPE));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_SRC_PREFIX)) {
-                            r.nw_src_prefix = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_SRC_PREFIX));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_SRC_MASKBITS)) {
-                            r.nw_src_maskbits = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_SRC_MASKBITS));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_DST_PREFIX)) {
-                            r.nw_dst_prefix = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_DST_PREFIX));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_DST_MASKBITS)) {
-                            r.nw_dst_maskbits = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_DST_MASKBITS));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_PROTO)) {
-                            r.nw_proto = Short.parseShort((String) row
-                                    .get(COLUMN_NW_PROTO));
-                        } 
-                        
-                        else if (key.equals(COLUMN_TP_SRC)) {
-                            r.tp_src = Short.parseShort((String) row
-                                    .get(COLUMN_TP_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_TP_DST)) {
-                            r.tp_dst = Short.parseShort((String) row
-                                    .get(COLUMN_TP_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DPID)) {
-                            r.wildcard_dpid = Boolean.parseBoolean((String) row
-                                    .get(COLUMN_WILDCARD_DPID));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_IN_PORT)) {
-                            r.wildcard_in_port = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_IN_PORT));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_SRC)) {
-                            r.wildcard_dl_src = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_DST)) {
-                            r.wildcard_dl_dst = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_TYPE)) {
-                            r.wildcard_dl_type = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_TYPE));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_SRC)) {
-                            r.wildcard_nw_src = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_DST)) {
-                            r.wildcard_nw_dst = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_PROTO)) {
-                            r.wildcard_nw_proto = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_PROTO));
-                        } 
-                        
-                        else if (key.equals(COLUMN_PRIORITY)) {
-                            r.priority = Integer.parseInt((String) row
-                                    .get(COLUMN_PRIORITY));
-                        } 
-                        
-                        else if (key.equals(COLUMN_ACTION)) {
-                            int tmp = Integer.parseInt((String) row.get(COLUMN_ACTION));
-                            if (tmp == FirewallRule.FirewallAction.DENY.ordinal())
-                                r.action = FirewallRule.FirewallAction.DENY;
-                            else if (tmp == FirewallRule.FirewallAction.ALLOW.ordinal())
-                                r.action = FirewallRule.FirewallAction.ALLOW;
-                            else {
-                                r.action = null;
-                                logger.error("action not recognized");
-                            }
-                        }
-                    }
-                } catch (ClassCastException e) {
-                    logger.error(
-                            "skipping rule {} with bad data : "
-                                    + e.getMessage(), r.ruleid);
-                }
-                if (r.action != null)
-                    l.add(r);
-            }
-        } catch (StorageException e) {
-            logger.error("failed to access storage: {}", e.getMessage());
-            // if the table doesn't exist, then wait to populate later via
-            // setStorageSource()
-        }
-
-        // now, sort the list based on priorities
-        Collections.sort(l);
-
-        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);
-        rules = new ArrayList<FirewallRule>();
-        logger = LoggerFactory.getLogger(Firewall.class);
-
-        // start disabled
-        enabled = false;
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        // register REST interface
-        restApi.addRestletRoutable(new FirewallWebRoutable());
-
-        // always place firewall in pipeline at bootup
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-
-        // storage, create table and read rules
-        storageSource.createTable(TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(TABLE_NAME, COLUMN_RULEID);
-        synchronized (rules) {
-            this.rules = readRulesFromStorage();
-        }
-    }
-
-    @Override
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        if (!this.enabled)
-            return Command.CONTINUE;
-
-        switch (msg.getType()) {
-        case PACKET_IN:
-            IRoutingDecision decision = null;
-            if (cntx != null) {
-                decision = IRoutingDecision.rtStore.get(cntx,
-                        IRoutingDecision.CONTEXT_DECISION);
-
-                return this.processPacketInMessage(sw, (OFPacketIn) msg,
-                        decision, cntx);
-            }
-            break;
-        default:
-            break;
-        }
-
-        return Command.CONTINUE;
-    }
-
-    @Override
-    public void enableFirewall(boolean enabled) {
-        logger.info("Setting firewall to {}", enabled);
-        this.enabled = enabled;
-    }
-
-    @Override
-    public List<FirewallRule> getRules() {
-        return this.rules;
-    }
-
-    // Only used to serve REST GET
-    // Similar to readRulesFromStorage(), which actually checks and stores
-    // record into FirewallRule list
-    @Override
-    public List<Map<String, Object>> getStorageRules() {
-        ArrayList<Map<String, Object>> l = new ArrayList<Map<String, Object>>();
-        try {
-            // null1=no predicate, null2=no ordering
-            IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
-                    ColumnNames, null, null);
-            for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
-                l.add(it.next().getRow());
-            }
-        } catch (StorageException e) {
-            logger.error("failed to access storage: {}", e.getMessage());
-            // if the table doesn't exist, then wait to populate later via
-            // setStorageSource()
-        }
-        return l;
-    }
-
-    @Override
-    public String getSubnetMask() {
-        return IPv4.fromIPv4Address(this.subnet_mask);
-    }
-
-    @Override
-    public void setSubnetMask(String newMask) {
-        if (newMask.trim().isEmpty())
-            return;
-        this.subnet_mask = IPv4.toIPv4Address(newMask.trim());
-    }
-
-    @Override
-    public synchronized void addRule(FirewallRule rule) {
-        
-        // generate random ruleid for each newly created rule
-        // may want to return to caller if useful
-        // may want to check conflict
-        rule.ruleid = rule.genID();
-        
-        int i = 0;
-        // locate the position of the new rule in the sorted arraylist
-        for (i = 0; i < this.rules.size(); i++) {
-            if (this.rules.get(i).priority >= rule.priority)
-                break;
-        }
-        // now, add rule to the list
-        if (i <= this.rules.size()) {
-            this.rules.add(i, rule);
-        } else {
-            this.rules.add(rule);
-        }
-        // add rule to database
-        Map<String, Object> entry = new HashMap<String, Object>();
-        entry.put(COLUMN_RULEID, Integer.toString(rule.ruleid));
-        entry.put(COLUMN_DPID, Long.toString(rule.dpid));
-        entry.put(COLUMN_IN_PORT, Short.toString(rule.in_port));
-        entry.put(COLUMN_DL_SRC, Long.toString(rule.dl_src));
-        entry.put(COLUMN_DL_DST, Long.toString(rule.dl_dst));
-        entry.put(COLUMN_DL_TYPE, Short.toString(rule.dl_type));
-        entry.put(COLUMN_NW_SRC_PREFIX, Integer.toString(rule.nw_src_prefix));
-        entry.put(COLUMN_NW_SRC_MASKBITS, Integer.toString(rule.nw_src_maskbits));
-        entry.put(COLUMN_NW_DST_PREFIX, Integer.toString(rule.nw_dst_prefix));
-        entry.put(COLUMN_NW_DST_MASKBITS, Integer.toString(rule.nw_dst_maskbits));
-        entry.put(COLUMN_NW_PROTO, Short.toString(rule.nw_proto));
-        entry.put(COLUMN_TP_SRC, Integer.toString(rule.tp_src));
-        entry.put(COLUMN_TP_DST, Integer.toString(rule.tp_dst));
-        entry.put(COLUMN_WILDCARD_DPID,
-                Boolean.toString(rule.wildcard_dpid));
-        entry.put(COLUMN_WILDCARD_IN_PORT,
-                Boolean.toString(rule.wildcard_in_port));
-        entry.put(COLUMN_WILDCARD_DL_SRC,
-                Boolean.toString(rule.wildcard_dl_src));
-        entry.put(COLUMN_WILDCARD_DL_DST,
-                Boolean.toString(rule.wildcard_dl_dst));
-        entry.put(COLUMN_WILDCARD_DL_TYPE,
-                Boolean.toString(rule.wildcard_dl_type));
-        entry.put(COLUMN_WILDCARD_NW_SRC,
-                Boolean.toString(rule.wildcard_nw_src));
-        entry.put(COLUMN_WILDCARD_NW_DST,
-                Boolean.toString(rule.wildcard_nw_dst));
-        entry.put(COLUMN_WILDCARD_NW_PROTO,
-                Boolean.toString(rule.wildcard_nw_proto));
-        entry.put(COLUMN_WILDCARD_TP_SRC,
-                Boolean.toString(rule.wildcard_tp_src));
-        entry.put(COLUMN_WILDCARD_TP_DST,
-                Boolean.toString(rule.wildcard_tp_dst));
-        entry.put(COLUMN_PRIORITY, Integer.toString(rule.priority));
-        entry.put(COLUMN_ACTION, Integer.toString(rule.action.ordinal()));
-        storageSource.insertRow(TABLE_NAME, entry);
-    }
-
-    @Override
-    public synchronized void deleteRule(int ruleid) {
-        Iterator<FirewallRule> iter = this.rules.iterator();
-        while (iter.hasNext()) {
-            FirewallRule r = iter.next();
-            if (r.ruleid == ruleid) {
-                // found the rule, now remove it
-                iter.remove();
-                break;
-            }
-        }
-        // delete from database
-        storageSource.deleteRow(TABLE_NAME, Integer.toString(ruleid));
-    }
-
-    /**
-     * Iterates over the firewall rules and tries to match them with the
-     * incoming packet (flow). Uses the FirewallRule class's matchWithFlow
-     * method to perform matching. It maintains a pair of wildcards (allow and
-     * deny) which are assigned later to the firewall's decision, where 'allow'
-     * wildcards are applied if the matched rule turns out to be an ALLOW rule
-     * and 'deny' wildcards are applied otherwise. Wildcards are applied to
-     * firewall decision to optimize flows in the switch, ensuring least number
-     * of flows per firewall rule. So, if a particular field is not "ANY" (i.e.
-     * not wildcarded) in a higher priority rule, then if a lower priority rule
-     * matches the packet and wildcards it, it can't be wildcarded in the
-     * switch's flow entry, because otherwise some packets matching the higher
-     * priority rule might escape the firewall. The reason for keeping different
-     * two different wildcards is that if a field is not wildcarded in a higher
-     * priority allow rule, the same field shouldn't be wildcarded for packets
-     * matching the lower priority deny rule (non-wildcarded fields in higher
-     * priority rules override the wildcarding of those fields in lower priority
-     * rules of the opposite type). So, to ensure that wildcards are
-     * appropriately set for different types of rules (allow vs. deny), separate
-     * wildcards are maintained. Iteration is performed on the sorted list of
-     * rules (sorted in decreasing order of priority).
-     * 
-     * @param sw
-     *            the switch instance
-     * @param pi
-     *            the incoming packet data structure
-     * @param cntx
-     *            the floodlight context
-     * @return an instance of RuleWildcardsPair that specify rule that matches
-     *         and the wildcards for the firewall decision
-     */
-    protected RuleWildcardsPair matchWithRule(IOFSwitch sw, OFPacketIn pi,
-            FloodlightContext cntx) {
-        FirewallRule matched_rule = null;
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-        WildcardsPair wildcards = new WildcardsPair();
-
-        synchronized (rules) {
-            Iterator<FirewallRule> iter = this.rules.iterator();
-            FirewallRule rule = null;
-            // iterate through list to find a matching firewall rule
-            while (iter.hasNext()) {
-                // get next rule from list
-                rule = iter.next();
-
-                // check if rule matches
-                if (rule.matchesFlow(sw.getId(), pi.getInPort(), eth, wildcards) == true) {
-                    matched_rule = rule;
-                    break;
-                }
-            }
-        }
-
-        // make a pair of rule and wildcards, then return it
-        RuleWildcardsPair ret = new RuleWildcardsPair();
-        ret.rule = matched_rule;
-        if (matched_rule == null || matched_rule.action == FirewallRule.FirewallAction.DENY) {
-            ret.wildcards = wildcards.drop;
-        } else {
-            ret.wildcards = wildcards.allow;
-        }
-        return ret;
-    }
-
-    /**
-     * Checks whether an IP address is a broadcast address or not (determines
-     * using subnet mask)
-     * 
-     * @param IPAddress
-     *            the IP address to check
-     * @return true if it is a broadcast address, false otherwise
-     */
-    protected boolean IPIsBroadcast(int IPAddress) {
-        // inverted subnet mask
-        int inv_subnet_mask = ~this.subnet_mask;
-        return ((IPAddress & inv_subnet_mask) == inv_subnet_mask);
-    }
-
-    public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
-            IRoutingDecision decision, FloodlightContext cntx) {
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
-        // Allowing L2 broadcast + ARP broadcast request (also deny malformed
-        // broadcasts -> L2 broadcast + L3 unicast)
-        if (eth.isBroadcast() == true) {
-            boolean allowBroadcast = true;
-            // the case to determine if we have L2 broadcast + L3 unicast
-            // don't allow this broadcast packet if such is the case (malformed
-            // packet)
-            if (eth.getEtherType() == Ethernet.TYPE_IPv4
-                    && this.IPIsBroadcast(((IPv4) eth.getPayload())
-                            .getDestinationAddress()) == false) {
-                allowBroadcast = false;
-            }
-            if (allowBroadcast == true) {
-                if (logger.isTraceEnabled())
-                    logger.trace("Allowing broadcast traffic for PacketIn={}",
-                            pi);
-                                        
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.MULTICAST);
-                decision.addToContext(cntx);
-            } else {
-                if (logger.isTraceEnabled())
-                    logger.trace(
-                            "Blocking malformed broadcast traffic for PacketIn={}",
-                            pi);
-
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.DROP);
-                decision.addToContext(cntx);
-            }
-            return Command.CONTINUE;
-        }
-        /*
-         * ARP response (unicast) can be let through without filtering through
-         * rules by uncommenting the code below
-         */
-        /*
-         * else if (eth.getEtherType() == Ethernet.TYPE_ARP) {
-         * logger.info("allowing ARP traffic"); decision = new
-         * FirewallDecision(IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-         * decision.addToContext(cntx); return Command.CONTINUE; }
-         */
-
-        // check if we have a matching rule for this packet/flow
-        // and no decision is taken yet
-        if (decision == null) {
-            RuleWildcardsPair match_ret = this.matchWithRule(sw, pi, cntx);
-            FirewallRule rule = match_ret.rule;
-
-            if (rule == null || rule.action == FirewallRule.FirewallAction.DENY) {
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.DROP);
-                decision.setWildcards(match_ret.wildcards);
-                decision.addToContext(cntx);
-                if (logger.isTraceEnabled()) {
-                    if (rule == null)
-                        logger.trace(
-                                "No firewall rule found for PacketIn={}, blocking flow",
-                                pi);
-                    else if (rule.action == FirewallRule.FirewallAction.DENY) {
-                        logger.trace("Deny rule={} match for PacketIn={}",
-                                rule, pi);
-                    }
-                }
-            } else {
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-                decision.setWildcards(match_ret.wildcards);
-                decision.addToContext(cntx);
-                if (logger.isTraceEnabled())
-                    logger.trace("Allow rule={} match for PacketIn={}", rule,
-                            pi);
-            }
-        }
-
-        return Command.CONTINUE;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
deleted file mode 100644
index 1f4d71a..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.io.IOException;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.resource.Post;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FirewallResource extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(FirewallResource.class);
-    
-    @Get("json")
-    public Object handleRequest() {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        String op = (String) getRequestAttributes().get("op");
-
-        // REST API check status
-        if (op.equalsIgnoreCase("status")) {
-            if (firewall.isEnabled())
-                return "{\"result\" : \"firewall enabled\"}";
-            else
-                return "{\"result\" : \"firewall disabled\"}";
-        }
-
-        // REST API enable firewall
-        if (op.equalsIgnoreCase("enable")) {
-            firewall.enableFirewall(true);
-            return "{\"status\" : \"success\", \"details\" : \"firewall running\"}";
-        } 
-        
-        // REST API disable firewall
-        if (op.equalsIgnoreCase("disable")) {
-            firewall.enableFirewall(false);
-            return "{\"status\" : \"success\", \"details\" : \"firewall stopped\"}";
-        } 
-        
-        // REST API retrieving rules from storage
-        // currently equivalent to /wm/firewall/rules/json
-        if (op.equalsIgnoreCase("storageRules")) {
-            return firewall.getStorageRules();
-        } 
-        
-        // REST API set local subnet mask -- this only makes sense for one subnet
-        // will remove later
-        if (op.equalsIgnoreCase("subnet-mask")) {
-            return firewall.getSubnetMask();
-        }
-
-        // no known options found
-        return "{\"status\" : \"failure\", \"details\" : \"invalid operation\"}";
-    }
-    
-    /**
-     * Allows setting of subnet mask
-     * @param fmJson The Subnet Mask in JSON format.
-     * @return A string status message
-     */
-    @Post
-    public String handlePost(String fmJson) {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        String newMask;
-        try {
-            newMask = jsonExtractSubnetMask(fmJson);
-        } catch (IOException e) {
-            log.error("Error parsing new subnet mask: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error! Could not parse new subnet mask, see log for details.\"}";
-        }
-        firewall.setSubnetMask(newMask);
-        return ("{\"status\" : \"subnet mask set\"}");
-    }
-    
-    /**
-     * Extracts subnet mask from a JSON string
-     * @param fmJson The JSON formatted string
-     * @return The subnet mask
-     * @throws IOException If there was an error parsing the JSON
-     */
-    public static String jsonExtractSubnetMask(String fmJson) throws IOException {
-        String subnet_mask = "";
-        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 == "subnet-mask") {
-                subnet_mask = jp.getText();
-                break;
-            }
-        }
-
-        return subnet_mask;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
deleted file mode 100644
index d9b2612..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
+++ /dev/null
@@ -1,392 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.TCP;
-import net.floodlightcontroller.packet.UDP;
-
-public class FirewallRule implements Comparable<FirewallRule> {
-    public int ruleid;
-
-    public long dpid; 
-    public short in_port; 
-    public long dl_src; 
-    public long dl_dst; 
-    public short dl_type; 
-    public int nw_src_prefix; 
-    public int nw_src_maskbits;
-    public int nw_dst_prefix;
-    public int nw_dst_maskbits;
-    public short nw_proto;
-    public short tp_src;
-    public short tp_dst;
-
-    public boolean wildcard_dpid;
-    public boolean wildcard_in_port; 
-    public boolean wildcard_dl_src;
-    public boolean wildcard_dl_dst;
-    public boolean wildcard_dl_type;
-    public boolean wildcard_nw_src;
-    public boolean wildcard_nw_dst;
-    public boolean wildcard_nw_proto;
-    public boolean wildcard_tp_src;
-    public boolean wildcard_tp_dst;
-
-    public int priority = 0;
-
-    public FirewallAction action;
-
-    public enum FirewallAction {
-        /*
-         * DENY: Deny rule
-         * ALLOW: Allow rule
-         */
-        DENY, ALLOW
-    }
-
-    public FirewallRule() {
-        this.in_port = 0; 
-        this.dl_src = 0;
-        this.nw_src_prefix = 0;
-        this.nw_src_maskbits = 0; 
-        this.dl_dst = 0;
-        this.nw_proto = 0;
-        this.tp_src = 0;
-        this.tp_dst = 0;
-        this.dl_dst = 0;
-        this.nw_dst_prefix = 0;
-        this.nw_dst_maskbits = 0; 
-        this.dpid = -1;
-        this.wildcard_dpid = true; 
-        this.wildcard_in_port = true; 
-        this.wildcard_dl_src = true; 
-        this.wildcard_dl_dst = true; 
-        this.wildcard_dl_type = true; 
-        this.wildcard_nw_src = true; 
-        this.wildcard_nw_dst = true; 
-        this.wildcard_nw_proto = true; 
-        this.wildcard_tp_src = true; 
-        this.wildcard_tp_dst = true; 
-        this.priority = 0; 
-        this.action = FirewallAction.ALLOW; 
-        this.ruleid = 0; 
-    }
-
-    /**
-     * Generates a unique ID for the instance
-     * 
-     * @return int representing the unique id
-     */
-    public int genID() {
-        int uid = this.hashCode();
-        if (uid < 0) {
-            uid = Math.abs(uid);
-            uid = uid * 15551;
-        }
-        return uid;
-    }
-
-    /**
-     * Comparison method for Collections.sort method
-     * 
-     * @param rule
-     *            the rule to compare with
-     * @return number representing the result of comparison 0 if equal negative
-     *         if less than 'rule' greater than zero if greater priority rule
-     *         than 'rule'
-     */
-    @Override
-    public int compareTo(FirewallRule rule) {
-        return this.priority - rule.priority;
-    }
-
-    /**
-     * Determines if this instance matches an existing rule instance
-     * 
-     * @param r
-     *            : the FirewallRule instance to compare with
-     * @return boolean: true if a match is found
-     **/
-    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_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
-                || (this.wildcard_tp_dst == false &&this.tp_dst != r.tp_dst)
-                || this.wildcard_dpid != r.wildcard_dpid
-                || (this.wildcard_dpid == false && this.dpid != r.dpid)
-                || this.wildcard_in_port != r.wildcard_in_port
-                || (this.wildcard_in_port == false && this.in_port != r.in_port)
-                || this.wildcard_nw_src != r.wildcard_nw_src
-                || (this.wildcard_nw_src == false && (this.nw_src_prefix != r.nw_src_prefix || this.nw_src_maskbits != r.nw_src_maskbits))
-                || this.wildcard_dl_src != r.wildcard_dl_src
-                || (this.wildcard_dl_src == false && this.dl_src != r.dl_src)
-                || this.wildcard_nw_proto != r.wildcard_nw_proto
-                || (this.wildcard_nw_proto == false && this.nw_proto != r.nw_proto)
-                || this.wildcard_nw_dst != r.wildcard_nw_dst
-                || (this.wildcard_nw_dst == false && (this.nw_dst_prefix != r.nw_dst_prefix || this.nw_dst_maskbits != r.nw_dst_maskbits))
-                || this.wildcard_dl_dst != r.wildcard_dl_dst                
-                || (this.wildcard_dl_dst == false && this.dl_dst != r.dl_dst)) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Matches this rule to a given flow - incoming packet
-     * 
-     * @param switchDpid
-     *            the Id of the connected switch
-     * @param inPort
-     *            the switch port where the packet originated from
-     * @param packet
-     *            the Ethernet packet that arrives at the switch
-     * @param wildcards
-     *            the pair of wildcards (allow and deny) given by Firewall
-     *            module that is used by the Firewall module's matchWithRule
-     *            method to derive wildcards for the decision to be taken
-     * @return true if the rule matches the given packet-in, false otherwise
-     */
-    public boolean matchesFlow(long switchDpid, short inPort, Ethernet packet,
-            WildcardsPair wildcards) {
-        IPacket pkt = packet.getPayload();
-
-        // dl_type type
-        IPv4 pkt_ip = null;
-
-        // nw_proto types
-        TCP pkt_tcp = null;
-        UDP pkt_udp = null;
-
-        // tp_src and tp_dst (tp port numbers)
-        short pkt_tp_src = 0;
-        short pkt_tp_dst = 0;
-
-        // switchID matches?
-        if (wildcard_dpid == false && dpid != switchDpid)
-            return false;
-
-        // in_port matches?
-        if (wildcard_in_port == false && in_port != inPort)
-            return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_IN_PORT;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_IN_PORT;
-        }
-
-        // mac address (src and dst) match?
-        if (wildcard_dl_src == false
-                && dl_src != packet.getSourceMAC().toLong())
-            return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_DL_SRC;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_DL_SRC;
-        }
-
-        if (wildcard_dl_dst == false
-                && dl_dst != packet.getDestinationMAC().toLong())
-            return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_DL_DST;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_DL_DST;
-        }
-
-        // dl_type check: ARP, IP
-
-        // if this is not an ARP rule but the pkt is ARP,
-        // return false match - no need to continue protocol specific check
-        if (wildcard_dl_type == false) {
-            if (dl_type == Ethernet.TYPE_ARP) {
-                if (packet.getEtherType() != Ethernet.TYPE_ARP)
-                    return false;
-                else {
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
-                    }
-                }
-            } else if (dl_type == Ethernet.TYPE_IPv4) {
-                if (packet.getEtherType() != Ethernet.TYPE_IPv4)
-                    return false;
-                else {
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
-                    }
-                    // IP packets, proceed with ip address check
-                    pkt_ip = (IPv4) pkt;
-
-                    // IP addresses (src and dst) match?
-                    if (wildcard_nw_src == false
-                            && this.matchIPAddress(nw_src_prefix,
-                                    nw_src_maskbits, pkt_ip.getSourceAddress()) == false)
-                        return false;
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL;
-                        wildcards.drop |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_NW_SRC_ALL;
-                        wildcards.allow |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
-                    }
-
-                    if (wildcard_nw_dst == false
-                            && this.matchIPAddress(nw_dst_prefix,
-                                    nw_dst_maskbits,
-                                    pkt_ip.getDestinationAddress()) == false)
-                        return false;
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL;
-                        wildcards.drop |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_NW_DST_ALL;
-                        wildcards.allow |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
-                    }
-
-                    // nw_proto check
-                    if (wildcard_nw_proto == false) {
-                        if (nw_proto == IPv4.PROTOCOL_TCP) {
-                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_TCP)
-                                return false;
-                            else {
-                                pkt_tcp = (TCP) pkt_ip.getPayload();
-                                pkt_tp_src = pkt_tcp.getSourcePort();
-                                pkt_tp_dst = pkt_tcp.getDestinationPort();
-                            }
-                        } else if (nw_proto == IPv4.PROTOCOL_UDP) {
-                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_UDP)
-                                return false;
-                            else {
-                                pkt_udp = (UDP) pkt_ip.getPayload();
-                                pkt_tp_src = pkt_udp.getSourcePort();
-                                pkt_tp_dst = pkt_udp.getDestinationPort();
-                            }
-                        } else if (nw_proto == IPv4.PROTOCOL_ICMP) {
-                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_ICMP)
-                                return false;
-                            else {
-                                // nothing more needed for ICMP
-                            }
-                        }
-                        if (action == FirewallRule.FirewallAction.DENY) {
-                            wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
-                        } else {
-                            wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
-                        }
-
-                        // TCP/UDP source and destination ports match?
-                        if (pkt_tcp != null || pkt_udp != null) {
-                            // does the source port match?
-                            if (tp_src != 0 && tp_src != pkt_tp_src)
-                                return false;
-                            if (action == FirewallRule.FirewallAction.DENY) {
-                                wildcards.drop &= ~OFMatch.OFPFW_TP_SRC;
-                            } else {
-                                wildcards.allow &= ~OFMatch.OFPFW_TP_SRC;
-                            }
-
-                            // does the destination port match?
-                            if (tp_dst != 0 && tp_dst != pkt_tp_dst)
-                                return false;
-                            if (action == FirewallRule.FirewallAction.DENY) {
-                                wildcards.drop &= ~OFMatch.OFPFW_TP_DST;
-                            } else {
-                                wildcards.allow &= ~OFMatch.OFPFW_TP_DST;
-                            }
-                        }
-                    }
-
-                }
-            } else {
-                // non-IP packet - not supported - report no match
-                return false;
-            }
-        }
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
-        }
-
-        // all applicable checks passed
-        return true;
-    }
-
-    /**
-     * Determines if rule's CIDR address matches IP address of the packet
-     * 
-     * @param rulePrefix
-     *            prefix part of the CIDR address
-     * @param ruleBits
-     *            the size of mask of the CIDR address
-     * @param packetAddress
-     *            the IP address of the incoming packet to match with
-     * @return true if CIDR address matches the packet's IP address, false
-     *         otherwise
-     */
-    protected boolean matchIPAddress(int rulePrefix, int ruleBits,
-            int packetAddress) {
-        boolean matched = true;
-
-        int rule_iprng = 32 - ruleBits;
-        int rule_ipint = rulePrefix;
-        int pkt_ipint = packetAddress;
-        // if there's a subnet range (bits to be wildcarded > 0)
-        if (rule_iprng > 0) {
-            // right shift bits to remove rule_iprng of LSB that are to be
-            // wildcarded
-            rule_ipint = rule_ipint >> rule_iprng;
-            pkt_ipint = pkt_ipint >> rule_iprng;
-            // now left shift to return to normal range, except that the
-            // rule_iprng number of LSB
-            // are now zeroed
-            rule_ipint = rule_ipint << rule_iprng;
-            pkt_ipint = pkt_ipint << rule_iprng;
-        }
-        // check if we have a match
-        if (rule_ipint != pkt_ipint)
-            matched = false;
-
-        return matched;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 2521;
-        int result = super.hashCode();
-        result = prime * result + (int) dpid;
-        result = prime * result + in_port;
-        result = prime * result + (int) dl_src;
-        result = prime * result + (int) dl_dst;
-        result = prime * result + dl_type;
-        result = prime * result + nw_src_prefix;
-        result = prime * result + nw_src_maskbits;
-        result = prime * result + nw_dst_prefix;
-        result = prime * result + nw_dst_maskbits;
-        result = prime * result + nw_proto;
-        result = prime * result + tp_src;
-        result = prime * result + tp_dst;
-        result = prime * result + action.ordinal();
-        result = prime * result + priority;
-        result = prime * result + (new Boolean(wildcard_dpid)).hashCode();
-        result = prime * result + (new Boolean(wildcard_in_port)).hashCode();
-        result = prime * result + (new Boolean(wildcard_dl_src)).hashCode();
-        result = prime * result + (new Boolean(wildcard_dl_dst)).hashCode();
-        result = prime * result + (new Boolean(wildcard_dl_type)).hashCode();
-        result = prime * result + (new Boolean(wildcard_nw_src)).hashCode();
-        result = prime * result + (new Boolean(wildcard_nw_dst)).hashCode();
-        result = prime * result + (new Boolean(wildcard_nw_proto)).hashCode();
-        result = prime * result + (new Boolean(wildcard_tp_src)).hashCode();
-        result = prime * result + (new Boolean(wildcard_tp_dst)).hashCode();
-        return result;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
deleted file mode 100644
index 7a31d38..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
+++ /dev/null
@@ -1,292 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.openflow.util.HexString;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Post;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-
-public class FirewallRulesResource extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(FirewallRulesResource.class);
-
-    @Get("json")
-    public Object handleRequest() {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        return firewall.getRules();
-    }
-
-    /**
-     * Takes a Firewall Rule string in JSON format and parses it into
-     * our firewall rule data structure, then adds it to the firewall.
-     * @param fmJson The Firewall rule entry in JSON format.
-     * @return A string status message
-     */
-    @Post
-    public String store(String fmJson) {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        FirewallRule rule;
-        try {
-            rule = jsonToFirewallRule(fmJson);
-        } catch (IOException e) {
-            log.error("Error parsing firewall rule: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
-        }
-        String status = null;
-        if (checkRuleExists(rule, firewall.getRules())) {
-            status = "Error! A similar firewall rule already exists.";
-            log.error(status);
-        } else {
-            // add rule to firewall
-            firewall.addRule(rule);
-            status = "Rule added";
-        }
-        return ("{\"status\" : \"" + status + "\"}");
-    }
-
-    /**
-     * Takes a Firewall Rule string in JSON format and parses it into
-     * our firewall rule data structure, then deletes it from the firewall.
-     * @param fmJson The Firewall rule entry in JSON format.
-     * @return A string status message
-     */
-    
-    @Delete
-    public String remove(String fmJson) {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        FirewallRule rule;
-        try {
-            rule = jsonToFirewallRule(fmJson);
-        } catch (IOException e) {
-            log.error("Error parsing firewall rule: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
-        }
-        String status = null;
-        boolean exists = false;
-        Iterator<FirewallRule> iter = firewall.getRules().iterator();
-        while (iter.hasNext()) {
-            FirewallRule r = iter.next();
-            if (r.ruleid == rule.ruleid) {
-                exists = true;
-                break;
-            }
-        }
-        if (!exists) {
-            status = "Error! Can't delete, a rule with this ID doesn't exist.";
-            log.error(status);
-        } else {
-            // delete rule from firewall
-            firewall.deleteRule(rule.ruleid);
-            status = "Rule deleted";
-        }
-        return ("{\"status\" : \"" + status + "\"}");
-    }
-
-    /**
-     * Turns a JSON formatted Firewall Rule string into a FirewallRule instance
-     * @param fmJson The JSON formatted static firewall rule
-     * @return The FirewallRule instance
-     * @throws IOException If there was an error parsing the JSON
-     */
-     
-    public static FirewallRule jsonToFirewallRule(String fmJson) throws IOException {
-        FirewallRule rule = new FirewallRule();
-        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;
-
-            String tmp;
-            
-            // This is currently only applicable for remove().  In store(), ruleid takes a random number
-            if (n == "ruleid") {
-                rule.ruleid = Integer.parseInt((String)jp.getText());
-            }
-            
-            // This assumes user having dpid info for involved switches
-            else if (n == "switchid") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("-1") == false) {
-                    // user inputs hex format dpid 
-                    rule.dpid = HexString.toLong(tmp);                    
-                    rule.wildcard_dpid = false;
-                }
-            } 
-            
-            else if (n == "src-inport") {
-                rule.in_port = Short.parseShort(jp.getText());
-                rule.wildcard_in_port = false;
-            } 
-            
-            else if (n == "src-mac") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_dl_src = false;
-                    rule.dl_src = Ethernet.toLong(Ethernet.toMACAddress(tmp));
-                }
-            } 
-            
-            else if (n == "dst-mac") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_dl_dst = false;
-                    rule.dl_dst = Ethernet.toLong(Ethernet.toMACAddress(tmp));
-                }
-            } 
-            
-            else if (n == "dl-type") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ARP")) {
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_ARP;
-                }
-            } 
-            
-            else if (n == "src-ip") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_nw_src = false;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                    int[] cidr = IPCIDRToPrefixBits(tmp);
-                    rule.nw_src_prefix = cidr[0];
-                    rule.nw_src_maskbits = cidr[1];
-                }
-            } 
-            
-            else if (n == "dst-ip") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_nw_dst = false;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                    int[] cidr = IPCIDRToPrefixBits(tmp);
-                    rule.nw_dst_prefix = cidr[0];
-                    rule.nw_dst_maskbits = cidr[1];
-                }
-            } 
-            
-            else if (n == "nw-proto") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("TCP")) {
-                    rule.wildcard_nw_proto = false;
-                    rule.nw_proto = IPv4.PROTOCOL_TCP;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                } else if (tmp.equalsIgnoreCase("UDP")) {
-                    rule.wildcard_nw_proto = false;
-                    rule.nw_proto = IPv4.PROTOCOL_UDP;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                } else if (tmp.equalsIgnoreCase("ICMP")) {
-                    rule.wildcard_nw_proto = false;
-                    rule.nw_proto = IPv4.PROTOCOL_ICMP;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                } 
-            } 
-            
-            else if (n == "tp-src") {
-                rule.wildcard_tp_src = false;
-                rule.tp_src = Short.parseShort(jp.getText());
-            } 
-            
-            else if (n == "tp-dst") {
-                rule.wildcard_tp_dst = false;
-                rule.tp_dst = Short.parseShort(jp.getText());
-            } 
-            
-            else if (n == "priority") {
-                rule.priority = Integer.parseInt(jp.getText());
-            } 
-            
-            else if (n == "action") {
-                if (jp.getText().equalsIgnoreCase("allow") == true) {
-                    rule.action = FirewallRule.FirewallAction.ALLOW;
-                } else if (jp.getText().equalsIgnoreCase("deny") == true) {
-                    rule.action = FirewallRule.FirewallAction.DENY;
-                }
-            }
-        }
-
-        return rule;
-    }
-
-    public static int[] IPCIDRToPrefixBits(String cidr) {
-        int ret[] = new int[2];
-
-        // as IP can also be a prefix rather than an absolute address
-        // split it over "/" to get the bit range
-        String[] parts = cidr.split("/");
-        String cidr_prefix = parts[0].trim();
-        int cidr_bits = 0;
-        if (parts.length == 2) {
-            try {
-                cidr_bits = Integer.parseInt(parts[1].trim());
-            } catch (Exception exp) {
-                cidr_bits = 32;
-            }
-        }
-        ret[0] = IPv4.toIPv4Address(cidr_prefix);
-        ret[1] = cidr_bits;
-
-        return ret;
-    }
-
-    public static boolean checkRuleExists(FirewallRule rule, List<FirewallRule> rules) {
-        Iterator<FirewallRule> iter = rules.iterator();
-        while (iter.hasNext()) {
-            FirewallRule r = iter.next();
-
-            // check if we find a similar rule
-            if (rule.isSameAs(r)) {
-                return true;
-            }
-        }
-
-        // no rule matched, so it doesn't exist in the rules
-        return false;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java b/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java
deleted file mode 100644
index 3a9beab..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-import org.restlet.Context;
-import org.restlet.routing.Router;
-
-public class FirewallWebRoutable implements RestletRoutable {
-    /**
-     * Create the Restlet router and bind to the proper resources.
-     */
-    @Override
-    public Router getRestlet(Context context) {
-        Router router = new Router(context);
-        router.attach("/module/{op}/json", FirewallResource.class);
-        router.attach("/rules/json", FirewallRulesResource.class);
-        return router;
-    }
-
-    /**
-     * Set the base path for the Firewall
-     */
-    @Override
-    public String basePath() {
-        return "/wm/firewall";
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java b/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java
deleted file mode 100644
index ae9d89f..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IFirewallService extends IFloodlightService {
-
-    /**
-     * Enables/disables the firewall.
-     * @param enable Whether to enable or disable the firewall.
-     */
-    public void enableFirewall(boolean enable);
-
-    /**
-     * Returns operational status of the firewall
-     * @return boolean enabled;
-     */
-    public boolean isEnabled();
- 
-    /**
-     * Returns all of the firewall rules
-     * @return List of all rules
-     */
-    public List<FirewallRule> getRules();
-    
-    /**
-     * Returns the subnet mask
-     * @return subnet mask
-     */
-    public String getSubnetMask();
-    
-    /**
-     * Sets the subnet mask
-     * @param newMask The new subnet mask
-     */
-    public void setSubnetMask(String newMask);
-
-    /**
-     * Returns all of the firewall rules in storage
-     * for debugging and unit-testing purposes
-     * @return List of all rules in storage
-     */
-    public List<Map<String, Object>> getStorageRules();
-
-    /**
-     * Adds a new Firewall rule
-     */
-    public void addRule(FirewallRule rule);
-
-    /**
-     * Deletes a Firewall rule
-     */
-    public void deleteRule(int ruleid);
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java b/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java
deleted file mode 100644
index 3fab409..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-public class RuleWildcardsPair {
-    public FirewallRule rule;
-    public int wildcards = OFMatch.OFPFW_ALL;
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java b/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java
deleted file mode 100644
index 2e5f123..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-public class WildcardsPair {
-    public int allow = OFMatch.OFPFW_ALL;
-    public int drop = OFMatch.OFPFW_ALL;
-}
