diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index c28a45e1c6e18d93aeac8c9f009e0f9d34ccf385..a5b2a8a0bd940aa63ce3ff74d4e081369d859ea1 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -101,13 +101,10 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 public class Controller implements IFloodlightProviderService, IStorageSourceListener, IInfoProvider {
 
     protected static final Logger log = LoggerFactory.getLogger(Controller.class);
-    protected static final INotificationManager notifier =
-            NotificationManagerFactory.getNotificationManager(Controller.class);
+    protected static final INotificationManager notifier = NotificationManagerFactory.getNotificationManager(Controller.class);
 
-    static final String ERROR_DATABASE =
-            "The controller could not communicate with the system database.";
-    static final String SWITCH_SYNC_STORE_NAME =
-            Controller.class.getCanonicalName() + ".stateStore";
+    static final String ERROR_DATABASE = "The controller could not communicate with the system database.";
+    static final String SWITCH_SYNC_STORE_NAME = Controller.class.getCanonicalName() + ".stateStore";
 
     protected ConcurrentMap<OFType, ListenerDispatcher<OFType,IOFMessageListener>> messageListeners;
     
@@ -731,8 +728,6 @@ public class Controller implements IFloodlightProviderService, IStorageSourceLis
         }
     }
     
-    //TODO @Ryan createServerBootStrap() was here. Implemented how/where?
-
     private void setConfigParams(Map<String, String> configParams) throws FloodlightModuleException {
         String ofPort = configParams.get("openflowPort");
         if (!Strings.isNullOrEmpty(ofPort)) {
diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
index 052fde940a492b2b12c0e283193ff38dbb09c96b..e95a7d4e47b10fd662b414f62ae2c2d61d0cb843 100644
--- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java
+++ b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
@@ -173,19 +173,15 @@ public class Firewall implements IFirewallService, IOFMessageListener,
             Map<String, Object> row;
 
             // (..., null, null) for no predicate, no ordering
-            IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
-                    ColumnNames, null, null);
+            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);
+                if (!row.containsKey(COLUMN_RULEID) || !row.containsKey(COLUMN_DPID)) {
+                    logger.error( "skipping entry with missing required 'ruleid' or 'switchid' entry: {}", row);
                     return l;
                 }
                 try {
@@ -194,140 +190,69 @@ public class Firewall implements IFirewallService, IOFMessageListener,
                     r.dpid = DatapathId.of((String) row.get(COLUMN_DPID));
 
                     for (String key : row.keySet()) {
-                        if (row.get(key) == null)
+                        if (row.get(key) == null) {
                             continue;
-                        if (key.equals(COLUMN_RULEID)
-                                || key.equals(COLUMN_DPID)
-                                || key.equals("id")) {
+                        }
+                        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 = OFPort.of(Integer.parseInt((String) row
-                                    .get(COLUMN_IN_PORT)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_SRC)) {
-                            r.dl_src = MacAddress.of(Long.parseLong((String) row
-                                    .get(COLUMN_DL_SRC)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_DST)) {
-                            r.dl_dst = MacAddress.of(Long.parseLong((String) row
-                                    .get(COLUMN_DL_DST)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_TYPE)) {
-                            r.dl_type = EthType.of(Integer.parseInt((String) row
-                                    .get(COLUMN_DL_TYPE)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_SRC_PREFIX)) {
-                            r.nw_src_prefix_and_mask = IPv4AddressWithMask.of(Integer.parseInt((String) row
-                                    .get(COLUMN_NW_SRC_PREFIX)), r.nw_src_prefix_and_mask.getMask().getInt());
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_SRC_MASKBITS)) {
-                            r.nw_src_prefix_and_mask = IPv4AddressWithMask.of(r.nw_src_prefix_and_mask.getValue().getInt(), Integer.parseInt((String) row
-                                    .get(COLUMN_NW_SRC_MASKBITS)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_DST_PREFIX)) {
-                            r.nw_dst_prefix_and_mask = IPv4AddressWithMask.of(Integer.parseInt((String) row
-                                    .get(COLUMN_NW_DST_PREFIX)), r.nw_dst_prefix_and_mask.getMask().getInt());
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_DST_MASKBITS)) {
-                            r.nw_dst_prefix_and_mask = IPv4AddressWithMask.of(r.nw_dst_prefix_and_mask.getValue().getInt(), Integer.parseInt((String) row
-                                    .get(COLUMN_NW_DST_MASKBITS)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_PROTO)) {
-                            r.nw_proto = IpProtocol.of(Short.parseShort((String) row
-                                    .get(COLUMN_NW_PROTO)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_TP_SRC)) {
-                            r.tp_src = TransportPort.of(Integer.parseInt((String) row
-                                    .get(COLUMN_TP_SRC)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_TP_DST)) {
-                            r.tp_dst = TransportPort.of(Integer.parseInt((String) row
-                                    .get(COLUMN_TP_DST)));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DPID)) {
-                            r.any_dpid = Boolean.parseBoolean((String) row
-                                    .get(COLUMN_WILDCARD_DPID));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_IN_PORT)) {
-                            r.any_in_port = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_IN_PORT));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_SRC)) {
-                            r.any_dl_src = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_DST)) {
-                            r.any_dl_dst = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_TYPE)) {
-                            r.any_dl_type = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_TYPE));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_SRC)) {
-                            r.any_nw_src = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_DST)) {
-                            r.any_nw_dst = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_PROTO)) {
-                            r.any_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)) {
+                        } else if (key.equals(COLUMN_IN_PORT)) {
+                            r.in_port = OFPort.of(Integer.parseInt((String) row.get(COLUMN_IN_PORT)));
+                        } else if (key.equals(COLUMN_DL_SRC)) {
+                            r.dl_src = MacAddress.of(Long.parseLong((String) row.get(COLUMN_DL_SRC)));
+                        }  else if (key.equals(COLUMN_DL_DST)) {
+                            r.dl_dst = MacAddress.of(Long.parseLong((String) row.get(COLUMN_DL_DST)));
+                        } else if (key.equals(COLUMN_DL_TYPE)) {
+                            r.dl_type = EthType.of(Integer.parseInt((String) row.get(COLUMN_DL_TYPE)));
+                        } else if (key.equals(COLUMN_NW_SRC_PREFIX)) {
+                            r.nw_src_prefix_and_mask = IPv4AddressWithMask.of(Integer.parseInt((String) row.get(COLUMN_NW_SRC_PREFIX)), r.nw_src_prefix_and_mask.getMask().getInt());
+                        } else if (key.equals(COLUMN_NW_SRC_MASKBITS)) {
+                            r.nw_src_prefix_and_mask = IPv4AddressWithMask.of(r.nw_src_prefix_and_mask.getValue().getInt(), Integer.parseInt((String) row.get(COLUMN_NW_SRC_MASKBITS)));
+                        } else if (key.equals(COLUMN_NW_DST_PREFIX)) {
+                            r.nw_dst_prefix_and_mask = IPv4AddressWithMask.of(Integer.parseInt((String) row.get(COLUMN_NW_DST_PREFIX)), r.nw_dst_prefix_and_mask.getMask().getInt());
+                        } else if (key.equals(COLUMN_NW_DST_MASKBITS)) {
+                            r.nw_dst_prefix_and_mask = IPv4AddressWithMask.of(r.nw_dst_prefix_and_mask.getValue().getInt(), Integer.parseInt((String) row.get(COLUMN_NW_DST_MASKBITS)));
+                        } else if (key.equals(COLUMN_NW_PROTO)) {
+                            r.nw_proto = IpProtocol.of(Short.parseShort((String) row.get(COLUMN_NW_PROTO)));
+                        } else if (key.equals(COLUMN_TP_SRC)) {
+                            r.tp_src = TransportPort.of(Integer.parseInt((String) row.get(COLUMN_TP_SRC)));
+                        } else if (key.equals(COLUMN_TP_DST)) {
+                            r.tp_dst = TransportPort.of(Integer.parseInt((String) row.get(COLUMN_TP_DST)));
+                        } else if (key.equals(COLUMN_WILDCARD_DPID)) {
+                            r.any_dpid = Boolean.parseBoolean((String) row.get(COLUMN_WILDCARD_DPID));
+                        } else if (key.equals(COLUMN_WILDCARD_IN_PORT)) {
+                            r.any_in_port = Boolean.parseBoolean((String) row.get(COLUMN_WILDCARD_IN_PORT));
+                        } else if (key.equals(COLUMN_WILDCARD_DL_SRC)) {
+                            r.any_dl_src = Boolean.parseBoolean((String) row.get(COLUMN_WILDCARD_DL_SRC));
+                        } else if (key.equals(COLUMN_WILDCARD_DL_DST)) {
+                            r.any_dl_dst = Boolean.parseBoolean((String) row.get(COLUMN_WILDCARD_DL_DST));
+                        } else if (key.equals(COLUMN_WILDCARD_DL_TYPE)) {
+                            r.any_dl_type = Boolean.parseBoolean((String) row.get(COLUMN_WILDCARD_DL_TYPE));
+                        } else if (key.equals(COLUMN_WILDCARD_NW_SRC)) {
+                            r.any_nw_src = Boolean.parseBoolean((String) row.get(COLUMN_WILDCARD_NW_SRC));
+                        } else if (key.equals(COLUMN_WILDCARD_NW_DST)) {
+                            r.any_nw_dst = Boolean.parseBoolean((String) row.get(COLUMN_WILDCARD_NW_DST));
+                        } else if (key.equals(COLUMN_WILDCARD_NW_PROTO)) {
+                            r.any_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())
+                            if (tmp == FirewallRule.FirewallAction.DROP.ordinal()) {
+                                r.action = FirewallRule.FirewallAction.DROP;
+                            } else if (tmp == FirewallRule.FirewallAction.ALLOW.ordinal()) {
                                 r.action = FirewallRule.FirewallAction.ALLOW;
-                            else {
+                            } else {
                                 r.action = null;
                                 logger.error("action not recognized");
                             }
                         }
                     }
                 } catch (ClassCastException e) {
-                    logger.error(
-                            "skipping rule {} with bad data : "
-                                    + e.getMessage(), r.ruleid);
+                    logger.error("skipping rule {} with bad data : " + e.getMessage(), r.ruleid);
                 }
-                if (r.action != null)
+                if (r.action != null) {
                     l.add(r);
+                }
             }
         } catch (StorageException e) {
             logger.error("failed to access storage: {}", e.getMessage());
@@ -342,10 +267,8 @@ public class Firewall implements IFirewallService, IOFMessageListener,
     }
 
     @Override
-    public void init(FloodlightModuleContext context)
-            throws FloodlightModuleException {
-        floodlightProvider = context
-                .getServiceImpl(IFloodlightProviderService.class);
+    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>();
@@ -371,15 +294,15 @@ public class Firewall implements IFirewallService, IOFMessageListener,
 
     @Override
     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        if (!this.enabled)
+        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;
@@ -409,8 +332,7 @@ public class Firewall implements IFirewallService, IOFMessageListener,
         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);
+            IResultSet resultSet = storageSource.executeQuery(TABLE_NAME, ColumnNames, null, null);
             for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
                 l.add(it.next().getRow());
             }
@@ -544,7 +466,9 @@ public class Firewall implements IFirewallService, IOFMessageListener,
                 rule = iter.next();
 
                 // check if rule matches
-                if (rule.matchesFlow(sw.getId(), pi.getInPort(), eth, adp) == true) {
+                // AllowDropPair adp's allow and drop matches will modified with what matches
+                // TODO @Ryan might need to re-init adp each time (look into later) 
+                if (rule.matchesThisPacket(sw.getId(), pi.getInPort(), eth, adp) == true) {
                     matched_rule = rule;
                     break;
                 }
@@ -554,7 +478,7 @@ public class Firewall implements IFirewallService, IOFMessageListener,
         // make a pair of rule and wildcards, then return it
         RuleMatchPair rmp = new RuleMatchPair();
         rmp.rule = matched_rule;
-        if (matched_rule == null || matched_rule.action == FirewallRule.FirewallAction.DENY) {
+        if (matched_rule == null || matched_rule.action == FirewallRule.FirewallAction.DROP) {
             rmp.match = adp.drop.build();
         } else {
             rmp.match = adp.allow.build();
@@ -577,16 +501,14 @@ public class Firewall implements IFirewallService, IOFMessageListener,
     }
 
     public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+        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)
+            // don't allow this broadcast packet if such is the case (malformed packet)
             if ((eth.getPayload() instanceof IPv4) && (((IPv4) eth.getPayload()).getDestinationAddress().isBroadcast() == false)) {
                 allowBroadcast = false;
             }
@@ -622,13 +544,14 @@ public class Firewall implements IFirewallService, IOFMessageListener,
          * decision.addToContext(cntx); return Command.CONTINUE; }
          */
 
-        // check if we have a matching rule for this packet/flow
-        // and no decision is taken yet
+        // check if we have a matching rule for this packet/flow and no decision has been made yet
         if (decision == null) {
+        	// check if the packet we received matches an existing rule
             RuleMatchPair rmp = this.matchWithRule(sw, pi, cntx);
             FirewallRule rule = rmp.rule;
 
-            if (rule == null || rule.action == FirewallRule.FirewallAction.DENY) {
+            // Drop the packet if we don't have a rule allowing or dropping it or if we explicitly drop it
+            if (rule == null || rule.action == FirewallRule.FirewallAction.DROP) {
                 decision = new RoutingDecision(sw.getId(), pi.getInPort(), 
                 		IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_SRC_DEVICE), 
                 		IRoutingDecision.RoutingAction.DROP);
@@ -637,19 +560,20 @@ public class Firewall implements IFirewallService, IOFMessageListener,
                 if (logger.isTraceEnabled()) {
                     if (rule == null) {
                         logger.trace("No firewall rule found for PacketIn={}, blocking flow", pi);
-                    } else if (rule.action == FirewallRule.FirewallAction.DENY) {
+                    } else if (rule.action == FirewallRule.FirewallAction.DROP) {
                         logger.trace("Deny rule={} match for PacketIn={}", rule, pi);
                     }
                 }
+            // Found a rule and the rule is not a drop, so allow the packet
             } else {
                 decision = new RoutingDecision(sw.getId(), pi.getInPort(), 
                 		IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
                         IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
                 decision.setMatch(rmp.match);
                 decision.addToContext(cntx);
-                if (logger.isTraceEnabled())
-                    logger.trace("Allow rule={} match for PacketIn={}", rule,
-                            pi);
+                if (logger.isTraceEnabled()) {
+                    logger.trace("Allow rule={} match for PacketIn={}", rule, pi);
+                }
             }
         }
 
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
index c5110ad74bd15fc4fb61f76fdc6c3f20303f3bd6..fb99e5612ba921f3dcff4628eea88d142e777e54 100644
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
+++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
@@ -50,6 +50,10 @@ public class FirewallRule implements Comparable<FirewallRule> {
     public TransportPort tp_src;
     public TransportPort tp_dst;
 
+    /* Specify whether or not a match field is relevant.
+     * true = anything goes; don't care what it is
+     * false = field must match (w or w/o mask depending on field)
+     */
     public boolean any_dpid;
     public boolean any_in_port; 
     public boolean any_dl_src;
@@ -67,10 +71,10 @@ public class FirewallRule implements Comparable<FirewallRule> {
 
     public enum FirewallAction {
         /*
-         * DENY: Deny rule
+         * DROP: Drop rule
          * ALLOW: Allow rule
          */
-        DENY, ALLOW
+        DROP, ALLOW
     }
 
     /**
@@ -167,7 +171,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
     }
 
     /**
-     * Matches this rule to a given flow - incoming packet
+     * Checks if this rule is a match for the incoming packet's MatchFields
      * 
      * @param switchDpid
      *            the Id of the connected switch
@@ -176,12 +180,12 @@ public class FirewallRule implements Comparable<FirewallRule> {
      * @param packet
      *            the Ethernet packet that arrives at the switch
      * @param allow-drop-pair
-     *            the pair of matches (allow and deny) given by Firewall
+     *            the pair of matches (allow and drop) given by the Firewall
      *            module that is used by the Firewall module's matchWithRule
      *            method to derive the match object for the decision to be taken
      * @return true if the rule matches the given packet-in, false otherwise
      */
-    public boolean matchesFlow(DatapathId switchDpid, OFPort inPort, Ethernet packet, AllowDropPair adp) {
+    public boolean matchesThisPacket(DatapathId switchDpid, OFPort inPort, Ethernet packet, AllowDropPair adp) {
         IPacket pkt = packet.getPayload();
 
         // dl_type type
@@ -202,7 +206,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
         // in_port matches?
         if (any_in_port == false && !in_port.equals(inPort))
             return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
+        if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_IN_PORT;
             adp.drop.setExact(MatchField.IN_PORT, this.in_port);
         } else {
@@ -213,7 +217,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
         // mac address (src and dst) match?
         if (any_dl_src == false && !dl_src.equals(packet.getSourceMAC()))
             return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
+        if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_DL_SRC;
             adp.drop.setExact(MatchField.ETH_SRC, this.dl_src);
         } else {
@@ -223,7 +227,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
 
         if (any_dl_dst == false && !dl_dst.equals(packet.getDestinationMAC()))
             return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
+        if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_DL_DST;
             adp.drop.setExact(MatchField.ETH_DST, this.dl_dst);
         } else {
@@ -240,7 +244,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
                 if (packet.getEtherType() != EthType.ARP.getValue())
                     return false;
                 else {
-                    if (action == FirewallRule.FirewallAction.DENY) {
+                    if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
                     	adp.drop.setExact(MatchField.ETH_TYPE, this.dl_type);
                     } else {
@@ -252,7 +256,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
                 if (packet.getEtherType() != EthType.IPv4.getValue())
                     return false;
                 else {
-                    if (action == FirewallRule.FirewallAction.DENY) {
+                    if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
                     	adp.drop.setExact(MatchField.IP_PROTO, this.nw_proto);
                     } else {
@@ -265,7 +269,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
                     // IP addresses (src and dst) match?
                     if (any_nw_src == false && this.matchIPAddress(nw_src_prefix_and_mask.getValue().getInt(), nw_src_prefix_and_mask.getMask().getInt(), pkt_ip.getSourceAddress()) == false)
                         return false;
-                    if (action == FirewallRule.FirewallAction.DENY) {
+                    if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL;
                         //wildcards.drop |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
                     	adp.drop.setMasked(MatchField.IPV4_SRC, nw_src_prefix_and_mask);
@@ -277,7 +281,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
 
                     if (any_nw_dst == false && this.matchIPAddress(nw_dst_prefix_and_mask.getValue().getInt(), nw_dst_prefix_and_mask.getMask().getInt(), pkt_ip.getDestinationAddress()) == false)
                         return false;
-                    if (action == FirewallRule.FirewallAction.DENY) {
+                    if (action == FirewallRule.FirewallAction.DROP) {
                         //wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL;
                         //wildcards.drop |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
                     	adp.drop.setMasked(MatchField.IPV4_DST, nw_dst_prefix_and_mask);
@@ -312,7 +316,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
                                 // nothing more needed for ICMP
                             }
                         }
-                        if (action == FirewallRule.FirewallAction.DENY) {
+                        if (action == FirewallRule.FirewallAction.DROP) {
                             //wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
                         	adp.drop.setExact(MatchField.IP_PROTO, this.nw_proto);
                         } else {
@@ -326,7 +330,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
                             if (tp_src.getPort() != 0 && tp_src.getPort() != pkt_tp_src.getPort()) {
                                 return false;
                             }
-                            if (action == FirewallRule.FirewallAction.DENY) {
+                            if (action == FirewallRule.FirewallAction.DROP) {
                                 //wildcards.drop &= ~OFMatch.OFPFW_TP_SRC;
                                 if (pkt_tcp != null) {
                                 	adp.drop.setExact(MatchField.TCP_SRC, this.tp_src);
@@ -346,7 +350,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
                             if (tp_dst.getPort() != 0 && tp_dst.getPort() != pkt_tp_dst.getPort()) {
                                 return false;
                             }
-                            if (action == FirewallRule.FirewallAction.DENY) {
+                            if (action == FirewallRule.FirewallAction.DROP) {
                                 //wildcards.drop &= ~OFMatch.OFPFW_TP_DST;
                                 if (pkt_tcp != null) {
                                 	adp.drop.setExact(MatchField.TCP_DST, this.tp_dst);
@@ -370,7 +374,7 @@ public class FirewallRule implements Comparable<FirewallRule> {
                 return false;
             }
         }
-        if (action == FirewallRule.FirewallAction.DENY) {
+        if (action == FirewallRule.FirewallAction.DROP) {
             //wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
         	adp.drop.setExact(MatchField.ETH_TYPE, this.dl_type);
         } else {
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
index b1b870907914b0a088321c5c8718a7de3116835a..90c3d13a2d24f9aa128c8480852dd3a15d4baf77 100644
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
+++ b/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
@@ -268,7 +268,7 @@ public class FirewallRulesResource extends ServerResource {
                 if (jp.getText().equalsIgnoreCase("allow") == true) {
                     rule.action = FirewallRule.FirewallAction.ALLOW;
                 } else if (jp.getText().equalsIgnoreCase("deny") == true) {
-                    rule.action = FirewallRule.FirewallAction.DENY;
+                    rule.action = FirewallRule.FirewallAction.DROP;
                 }
             }
         }
diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
index 64a663da22a03522a2b15cbbd1571b28c8f4764a..093b9e7d514805ab5db4573e1fbacc0121fdb9a1 100644
--- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
@@ -1,19 +1,19 @@
 /**
-*    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.
-**/
+ *    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.forwarding;
 
@@ -45,375 +45,378 @@ import net.floodlightcontroller.routing.IRoutingDecision;
 import net.floodlightcontroller.routing.IRoutingService;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.util.MatchMaskUtils;
 
 import org.projectfloodlight.openflow.protocol.OFFlowMod;
 import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
 import org.projectfloodlight.openflow.protocol.OFPacketOut;
+import org.projectfloodlight.openflow.types.DatapathId;
+import org.projectfloodlight.openflow.types.OFBufferId;
 import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.types.U64;
 import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @LogMessageCategory("Flow Programming")
 public class Forwarding extends ForwardingBase implements IFloodlightModule {
-    protected static Logger log = LoggerFactory.getLogger(Forwarding.class);
-
-    @Override
-    @LogMessageDoc(level="ERROR",
-                   message="Unexpected decision made for this packet-in={}",
-                   explanation="An unsupported PacketIn decision has been " +
-                   		"passed to the flow programming component",
-                   recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
-    public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
-        // If a decision has been made we obey it
-        // otherwise we just forward
-        if (decision != null) {
-            if (log.isTraceEnabled()) {
-                log.trace("Forwaring decision={} was made for PacketIn={}", decision.getRoutingAction().toString(), pi);
-            }
-
-            switch(decision.getRoutingAction()) {
-                case NONE:
-                    // don't do anything
-                    return Command.CONTINUE;
-                case FORWARD_OR_FLOOD:
-                case FORWARD:
-                    doForwardFlow(sw, pi, cntx, false);
-                    return Command.CONTINUE;
-                case MULTICAST:
-                    // treat as broadcast
-                    doFlood(sw, pi, cntx);
-                    return Command.CONTINUE;
-                case DROP:
-                    doDropFlow(sw, pi, decision, cntx);
-                    return Command.CONTINUE;
-                default:
-                    log.error("Unexpected decision made for this packet-in={}", pi, decision.getRoutingAction());
-                    return Command.CONTINUE;
-            }
-        } else {
-            if (log.isTraceEnabled()) {
-                log.trace("No decision was made for PacketIn={}, forwarding", pi);
-            }
-
-            if (eth.isBroadcast() || eth.isMulticast()) {
-                // For now we treat multicast as broadcast
-                doFlood(sw, pi, cntx);
-            } else {
-                doForwardFlow(sw, pi, cntx, false);
-            }
-        }
-
-        return Command.CONTINUE;
-    }
-
-    @LogMessageDoc(level="ERROR",
-            message="Failure writing drop flow mod",
-            explanation="An I/O error occured while trying to write a " +
-            		"drop flow mod to a switch",
-            recommendation=LogMessageDoc.CHECK_SWITCH)
-    protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
-        // initialize match structure and populate it based on the packet in's match
-        Match.Builder mb = pi.getMatch().createBuilder();
-        Match m = null;
-        if (decision.getMatch() != null) {
-            m = decision.getMatch();
-        }
-
-        // Create flow-mod based on packet-in and src-switch
-        OFFlowMod fm =
-                (OFFlowMod) floodlightProvider.getOFMessageFactory()
-                                              .getMessage(OFType.FLOW_MOD);
-        List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to
-                                                            // drop
-        long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);
-
-        fm.setCookie(cookie)
-          .setHardTimeout((short) 0)
-          .setIdleTimeout((short) 5)
-          .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-          .setMatch(match)
-          .setActions(actions)
-          .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH);
-
-        try {
-            if (log.isDebugEnabled()) {
-                log.debug("write drop flow-mod sw={} match={} flow-mod={}",
-                          new Object[] { sw, match, fm });
-            }
-            messageDamper.write(sw, fm, cntx);
-        } catch (IOException e) {
-            log.error("Failure writing drop flow mod", e);
-        }
-    }
-
-    protected void doForwardFlow(IOFSwitch sw, OFPacketIn pi,
-                                 FloodlightContext cntx,
-                                 boolean requestFlowRemovedNotifn) {
-        OFMatch match = new OFMatch();
-        match.loadFromPacket(pi.getPacketData(), pi.getInPort());
-
-        // Check if we have the location of the destination
-        IDevice dstDevice =
-                IDeviceService.fcStore.
-                    get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
-
-        if (dstDevice != null) {
-            IDevice srcDevice =
-                    IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE);
-            Long srcIsland = topology.getL2DomainId(sw.getId());
-
-            if (srcDevice == null) {
-                log.debug("No device entry found for source device");
-                return;
-            }
-            if (srcIsland == null) {
-                log.debug("No openflow island found for source {}/{}",
-                          sw.getStringId(), pi.getInPort());
-                return;
-            }
-
-            // Validate that we have a destination known on the same island
-            // Validate that the source and destination are not on the same switchport
-            boolean on_same_island = false;
-            boolean on_same_if = false;
-            for (SwitchPort dstDap : dstDevice.getAttachmentPoints()) {
-                long dstSwDpid = dstDap.getSwitchDPID();
-                Long dstIsland = topology.getL2DomainId(dstSwDpid);
-                if ((dstIsland != null) && dstIsland.equals(srcIsland)) {
-                    on_same_island = true;
-                    if ((sw.getId() == dstSwDpid) &&
-                        (pi.getInPort() == dstDap.getPort())) {
-                        on_same_if = true;
-                    }
-                    break;
-                }
-            }
-
-            if (!on_same_island) {
-                // Flood since we don't know the dst device
-                if (log.isTraceEnabled()) {
-                    log.trace("No first hop island found for destination " +
-                              "device {}, Action = flooding", dstDevice);
-                }
-                doFlood(sw, pi, cntx);
-                return;
-            }
-
-            if (on_same_if) {
-                if (log.isTraceEnabled()) {
-                    log.trace("Both source and destination are on the same " +
-                              "switch/port {}/{}, Action = NOP",
-                              sw.toString(), pi.getInPort());
-                }
-                return;
-            }
-
-            // Install all the routes where both src and dst have attachment
-            // points.  Since the lists are stored in sorted order we can
-            // traverse the attachment points in O(m+n) time
-            SwitchPort[] srcDaps = srcDevice.getAttachmentPoints();
-            Arrays.sort(srcDaps, clusterIdComparator);
-            SwitchPort[] dstDaps = dstDevice.getAttachmentPoints();
-            Arrays.sort(dstDaps, clusterIdComparator);
-
-            int iSrcDaps = 0, iDstDaps = 0;
-
-            while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) {
-                SwitchPort srcDap = srcDaps[iSrcDaps];
-                SwitchPort dstDap = dstDaps[iDstDaps];
-
-                // srcCluster and dstCluster here cannot be null as
-                // every switch will be at least in its own L2 domain.
-                Long srcCluster =
-                        topology.getL2DomainId(srcDap.getSwitchDPID());
-                Long dstCluster =
-                        topology.getL2DomainId(dstDap.getSwitchDPID());
-
-                int srcVsDest = srcCluster.compareTo(dstCluster);
-                if (srcVsDest == 0) {
-                    if (!srcDap.equals(dstDap)) {
-                        Route route =
-                                routingEngine.getRoute(srcDap.getSwitchDPID(),
-                                                       (short)srcDap.getPort(),
-                                                       dstDap.getSwitchDPID(),
-                                                       (short)dstDap.getPort(), 0); //cookie = 0, i.e., default route
-                        if (route != null) {
-                            if (log.isTraceEnabled()) {
-                                log.trace("pushRoute match={} route={} " +
-                                          "destination={}:{}",
-                                          new Object[] {match, route,
-                                                        dstDap.getSwitchDPID(),
-                                                        dstDap.getPort()});
-                            }
-                            long cookie =
-                                    AppCookie.makeCookie(FORWARDING_APP_ID, 0);
-
-                            // if there is prior routing decision use wildcard
-                            Integer wildcard_hints = null;
-                            IRoutingDecision decision = null;
-                            if (cntx != null) {
-                                decision = IRoutingDecision.rtStore
-                                        .get(cntx,
-                                                IRoutingDecision.CONTEXT_DECISION);
-                            }
-                            if (decision != null) {
-                                wildcard_hints = decision.getWildcards();
-                            } else {
-                            	// L2 only wildcard if there is no prior route decision
-                                wildcard_hints = ((Integer) sw
-                                        .getAttribute(IOFSwitch.PROP_FASTWILDCARDS))
-                                        .intValue()
-                                        & ~OFMatch.OFPFW_IN_PORT
-                                        & ~OFMatch.OFPFW_DL_VLAN
-                                        & ~OFMatch.OFPFW_DL_SRC
-                                        & ~OFMatch.OFPFW_DL_DST
-                                        & ~OFMatch.OFPFW_NW_SRC_MASK
-                                        & ~OFMatch.OFPFW_NW_DST_MASK;
-                            }
-
-                            pushRoute(route, match, wildcard_hints, pi, sw.getId(), cookie,
-                                      cntx, requestFlowRemovedNotifn, false,
-                                      OFFlowMod.OFPFC_ADD);
-                        }
-                    }
-                    iSrcDaps++;
-                    iDstDaps++;
-                } else if (srcVsDest < 0) {
-                    iSrcDaps++;
-                } else {
-                    iDstDaps++;
-                }
-            }
-        } else {
-            // Flood since we don't know the dst device
-            doFlood(sw, pi, cntx);
-        }
-    }
-
-    /**
-     * Creates a OFPacketOut with the OFPacketIn data that is flooded on all ports unless
-     * the port is blocked, in which case the packet will be dropped.
-     * @param sw The switch that receives the OFPacketIn
-     * @param pi The OFPacketIn that came to the switch
-     * @param cntx The FloodlightContext associated with this OFPacketIn
-     */
-    @LogMessageDoc(level="ERROR",
-                   message="Failure writing PacketOut " +
-                   		"switch={switch} packet-in={packet-in} " +
-                   		"packet-out={packet-out}",
-                   explanation="An I/O error occured while writing a packet " +
-                   		"out message to the switch",
-                   recommendation=LogMessageDoc.CHECK_SWITCH)
-    protected void doFlood(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
-        if (topologyService.isIncomingBroadcastAllowed(sw.getId(),
-                                                pi.getInPort()) == false) {
-            if (log.isTraceEnabled()) {
-                log.trace("doFlood, drop broadcast packet, pi={}, " +
-                          "from a blocked port, srcSwitch=[{},{}], linkInfo={}",
-                          new Object[] {pi, sw.getId(),pi.getInPort()});
-            }
-            return;
-        }
-
-        // Set Action to flood
-        OFPacketOut po =
-            (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
-        List<OFAction> actions = new ArrayList<OFAction>();
-        if (sw.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD)) {
-            actions.add(new OFActionOutput(OFPort.OFPP_FLOOD.getValue(),
-                                           (short)0xFFFF));
-        } else {
-            actions.add(new OFActionOutput(OFPort.OFPP_ALL.getValue(),
-                                           (short)0xFFFF));
-        }
-        po.setActions(actions);
-        po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-
-        // set buffer-id, in-port and packet-data based on packet-in
-        short poLength = (short)(po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
-        po.setBufferId(OFPacketOut.BUFFER_ID_NONE);
-        po.setInPort(pi.getInPort());
-        byte[] packetData = pi.getPacketData();
-        poLength += packetData.length;
-        po.setPacketData(packetData);
-        po.setLength(poLength);
-
-        try {
-            if (log.isTraceEnabled()) {
-                log.trace("Writing flood PacketOut switch={} packet-in={} packet-out={}",
-                          new Object[] {sw, pi, po});
-            }
-            messageDamper.write(sw, po, cntx);
-        } catch (IOException e) {
-            log.error("Failure writing PacketOut switch={} packet-in={} packet-out={}",
-                    new Object[] {sw, pi, po}, e);
-        }
-
-        return;
-    }
-
-    // IFloodlightModule methods
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        // We don't export any services
-        return null;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        // We don't have any services
-        return null;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l =
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        l.add(IDeviceService.class);
-        l.add(IRoutingService.class);
-        l.add(ITopologyService.class);
-        l.add(ICounterStoreService.class);
-        return l;
-    }
-
-    @Override
-    @LogMessageDocs({
-        @LogMessageDoc(level="WARN",
-                message="Error parsing flow idle timeout, " +
-                        "using default of {number} seconds",
-                explanation="The properties file contains an invalid " +
-                        "flow idle timeout",
-                recommendation="Correct the idle timeout in the " +
-                        "properties file."),
-        @LogMessageDoc(level="WARN",
-                message="Error parsing flow hard timeout, " +
-                        "using default of {number} seconds",
-                explanation="The properties file contains an invalid " +
-                            "flow hard timeout",
-                recommendation="Correct the hard timeout in the " +
-                                "properties file.")
-    })
-    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
-        super.init();
-        this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
-        this.deviceManager = context.getServiceImpl(IDeviceService.class);
-        this.routingEngine = context.getServiceImpl(IRoutingService.class);
-        this.topology = context.getServiceImpl(ITopologyService.class);
-        this.counterStore = context.getServiceImpl(ICounterStoreService.class);
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        super.startUp();
-    }
+	protected static Logger log = LoggerFactory.getLogger(Forwarding.class);
+
+	protected static int DEFAULT_HARD_TIMEOUT = 0; // not final b/c could be configured from config file
+	protected static int DEFAULT_IDLE_TIMEOUT = 5;
+
+	@Override
+	@LogMessageDoc(level="ERROR",
+	message="Unexpected decision made for this packet-in={}",
+	explanation="An unsupported PacketIn decision has been " +
+			"passed to the flow programming component",
+			recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
+	public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
+		Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
+
+		// We found a routing decision (i.e. Firewall is enabled... it's the only thing that makes RoutingDecisions)
+		if (decision != null) {
+			if (log.isTraceEnabled()) {
+				log.trace("Forwaring decision={} was made for PacketIn={}", decision.getRoutingAction().toString(), pi);
+			}
+
+			switch(decision.getRoutingAction()) {
+			case NONE:
+				// don't do anything
+				return Command.CONTINUE;
+			case FORWARD_OR_FLOOD:
+			case FORWARD:
+				doForwardFlow(sw, pi, cntx, false);
+				return Command.CONTINUE;
+			case MULTICAST:
+				// treat as broadcast
+				doFlood(sw, pi, cntx);
+				return Command.CONTINUE;
+			case DROP:
+				doDropFlow(sw, pi, decision, cntx);
+				return Command.CONTINUE;
+			default:
+				log.error("Unexpected decision made for this packet-in={}", pi, decision.getRoutingAction());
+				return Command.CONTINUE;
+			}
+		} else { // No routing decision was found. Forward to destination or flood if bcast or mcast.
+			if (log.isTraceEnabled()) {
+				log.trace("No decision was made for PacketIn={}, forwarding", pi);
+			}
+
+			if (eth.isBroadcast() || eth.isMulticast()) {
+				doFlood(sw, pi, cntx);
+			} else {
+				doForwardFlow(sw, pi, cntx, false);
+			}
+		}
+
+		return Command.CONTINUE;
+	}
+
+	@LogMessageDoc(level="ERROR",
+			message="Failure writing drop flow mod",
+			explanation="An I/O error occured while trying to write a " +
+					"drop flow mod to a switch",
+					recommendation=LogMessageDoc.CHECK_SWITCH)
+	protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
+		// initialize match structure and populate it based on the packet in's match
+		Match.Builder mb = null;
+		if (decision.getMatch() != null) {
+			/* TODO @Ryan This routing decision should be a match object with all appropriate fields set,
+			 * not just masked. If it's a decision that matches the packet we received, then simply setting
+			 * the masks to the new match will create the same match in the end. We can just use the routing
+			 * match object instead (right?).
+			 * 
+			 * The Firewall is currently the only module/service that sets routing decisions in the context 
+			 * store (or instantiates any for that matter). It's disabled by default, so as-is a decision's 
+			 * match should always be null, meaning this will never be true.
+			 */
+			mb = decision.getMatch().createBuilder();
+		} else {
+			mb = pi.getMatch().createBuilder(); // otherwise no route is known so go based on packet's match object
+		}
+
+		OFFlowMod.Builder fmb = sw.getOFFactory().buildFlowAdd(); // this will be a drop-flow; a flow that will not output to any ports
+		List<OFAction> actions = new ArrayList<OFAction>(); // set no action to drop
+		U64 cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);
+
+		fmb.setCookie(cookie)
+		.setHardTimeout(DEFAULT_HARD_TIMEOUT)
+		.setIdleTimeout(DEFAULT_IDLE_TIMEOUT)
+		.setBufferId(OFBufferId.NO_BUFFER)
+		.setMatch(mb.build())
+		.setActions(actions); // empty list
+
+		try {
+			if (log.isDebugEnabled()) {
+				log.debug("write drop flow-mod sw={} match={} flow-mod={}",
+						new Object[] { sw, mb.build(), fmb.build() });
+			}
+			boolean dampened = messageDamper.write(sw, fmb.build(), cntx);
+			log.debug("OFMessage dampened: {}", dampened);
+		} catch (IOException e) {
+			log.error("Failure writing drop flow mod", e);
+		}
+	}
+
+	protected void doForwardFlow(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx, boolean requestFlowRemovedNotifn) {
+		Match m = pi.getMatch();
+
+		// Check if we have the location of the destination
+		IDevice dstDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
+
+		if (dstDevice != null) {
+			IDevice srcDevice = IDeviceService.fcStore.get(cntx, IDeviceService.CONTEXT_SRC_DEVICE);
+			DatapathId srcIsland = topologyService.getL2DomainId(sw.getId());
+
+			if (srcDevice == null) {
+				log.debug("No device entry found for source device");
+				return;
+			}
+			if (srcIsland == null) {
+				log.debug("No openflow island found for source {}/{}",
+						sw.getStringId(), pi.getInPort());
+				return;
+			}
+
+			// Validate that we have a destination known on the same island
+			// Validate that the source and destination are not on the same switchport
+			boolean on_same_island = false;
+			boolean on_same_if = false;
+			for (SwitchPort dstDap : dstDevice.getAttachmentPoints()) {
+				DatapathId dstSwDpid = dstDap.getSwitchDPID();
+				DatapathId dstIsland = topologyService.getL2DomainId(dstSwDpid);
+				if ((dstIsland != null) && dstIsland.equals(srcIsland)) {
+					on_same_island = true;
+					if ((sw.getId().equals(dstSwDpid)) && (pi.getInPort().equals(dstDap.getPort()))) {
+						on_same_if = true;
+					}
+					break;
+				}
+			}
+
+			if (!on_same_island) {
+				// Flood since we don't know the dst device
+				if (log.isTraceEnabled()) {
+					log.trace("No first hop island found for destination " +
+							"device {}, Action = flooding", dstDevice);
+				}
+				doFlood(sw, pi, cntx);
+				return;
+			}
+
+			if (on_same_if) {
+				if (log.isTraceEnabled()) {
+					log.trace("Both source and destination are on the same " +
+							"switch/port {}/{}, Action = NOP",
+							sw.toString(), pi.getInPort());
+				}
+				return;
+			}
+
+			// Install all the routes where both src and dst have attachment
+			// points.  Since the lists are stored in sorted order we can
+			// traverse the attachment points in O(m+n) time
+			SwitchPort[] srcDaps = srcDevice.getAttachmentPoints();
+			Arrays.sort(srcDaps, clusterIdComparator);
+			SwitchPort[] dstDaps = dstDevice.getAttachmentPoints();
+			Arrays.sort(dstDaps, clusterIdComparator);
+
+			int iSrcDaps = 0, iDstDaps = 0;
+
+			while ((iSrcDaps < srcDaps.length) && (iDstDaps < dstDaps.length)) {
+				SwitchPort srcDap = srcDaps[iSrcDaps];
+				SwitchPort dstDap = dstDaps[iDstDaps];
+
+				// srcCluster and dstCluster here cannot be null as
+				// every switch will be at least in its own L2 domain.
+				DatapathId srcCluster = topologyService.getL2DomainId(srcDap.getSwitchDPID());
+				DatapathId dstCluster = topologyService.getL2DomainId(dstDap.getSwitchDPID());
+
+				int srcVsDest = srcCluster.compareTo(dstCluster);
+				if (srcVsDest == 0) {
+					if (!srcDap.equals(dstDap)) {
+						Route route =
+								routingEngineService.getRoute(srcDap.getSwitchDPID(), 
+										srcDap.getPort(),
+										dstDap.getSwitchDPID(),
+										dstDap.getPort(), U64.of(0)); //cookie = 0, i.e., default route
+										if (route != null) {
+											if (log.isTraceEnabled()) {
+												log.trace("pushRoute match={} route={} " +
+														"destination={}:{}",
+														new Object[] { m, route,
+														dstDap.getSwitchDPID(),
+														dstDap.getPort()});
+											}
+											U64 cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);
+
+											// if there is prior routing decision use route's match
+											Match routeMatch = null;
+											IRoutingDecision decision = null;
+											if (cntx != null) {
+												decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
+											}
+											if (decision != null) {
+												routeMatch = decision.getMatch();
+											} else {
+												// A Match will contain only what you want to match on.
+												// Absence of a MatchField --> it can be anything (wildcarded).
+												// Remove all matches except for L2 and L3 addresses & VLAN
+												// to allow forwarding on a (V)LAN
+												routeMatch = MatchMaskUtils.maskL4AndUp(m);
+											}
+
+											pushRoute(route, routeMatch, pi, sw.getId(), cookie,
+													cntx, requestFlowRemovedNotifn, false,
+													OFFlowModCommand.ADD);
+										}
+					}
+					iSrcDaps++;
+					iDstDaps++;
+				} else if (srcVsDest < 0) {
+					iSrcDaps++;
+				} else {
+					iDstDaps++;
+				}
+			}
+		} else {
+			// Flood since we don't know the dst device
+			doFlood(sw, pi, cntx);
+		}
+	}
+
+	/**
+	 * Creates a OFPacketOut with the OFPacketIn data that is flooded on all ports unless
+	 * the port is blocked, in which case the packet will be dropped.
+	 * @param sw The switch that receives the OFPacketIn
+	 * @param pi The OFPacketIn that came to the switch
+	 * @param cntx The FloodlightContext associated with this OFPacketIn
+	 */
+	@LogMessageDoc(level="ERROR",
+			message="Failure writing PacketOut " +
+					"switch={switch} packet-in={packet-in} " +
+					"packet-out={packet-out}",
+					explanation="An I/O error occured while writing a packet " +
+							"out message to the switch",
+							recommendation=LogMessageDoc.CHECK_SWITCH)
+	protected void doFlood(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
+		if (topologyService.isIncomingBroadcastAllowed(sw.getId(),
+				pi.getInPort()) == false) {
+			if (log.isTraceEnabled()) {
+				log.trace("doFlood, drop broadcast packet, pi={}, " +
+						"from a blocked port, srcSwitch=[{},{}], linkInfo={}",
+						new Object[] {pi, sw.getId(),pi.getInPort()});
+			}
+			return;
+		}
+
+		// Set Action to flood
+		OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut();
+		List<OFAction> actions = new ArrayList<OFAction>();
+		if (sw.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_FLOOD)) {
+			actions.add(sw.getOFFactory().actions().output(OFPort.FLOOD, Integer.MAX_VALUE)); // FLOOD is a more selective/efficient version of ALL
+		} else {
+			actions.add(sw.getOFFactory().actions().output(OFPort.ALL, Integer.MAX_VALUE));
+		}
+		pob.setActions(actions);
+
+		// set buffer-id, in-port and packet-data based on packet-in
+		pob.setBufferId(OFBufferId.NO_BUFFER);
+		pob.setInPort(pi.getInPort());
+		pob.setData(pi.getData());
+
+		try {
+			if (log.isTraceEnabled()) {
+				log.trace("Writing flood PacketOut switch={} packet-in={} packet-out={}",
+						new Object[] {sw, pi, pob.build()});
+			}
+			messageDamper.write(sw, pob.build(), cntx);
+		} catch (IOException e) {
+			log.error("Failure writing PacketOut switch={} packet-in={} packet-out={}",
+					new Object[] {sw, pi, pob.build()}, e);
+		}
+
+		return;
+	}
+
+	// IFloodlightModule methods
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+		// We don't export any services
+		return null;
+	}
+
+	@Override
+	public Map<Class<? extends IFloodlightService>, IFloodlightService>
+	getServiceImpls() {
+		// We don't have any services
+		return null;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+		Collection<Class<? extends IFloodlightService>> l =
+				new ArrayList<Class<? extends IFloodlightService>>();
+		l.add(IFloodlightProviderService.class);
+		l.add(IDeviceService.class);
+		l.add(IRoutingService.class);
+		l.add(ITopologyService.class);
+		l.add(IDebugCounterService.class);
+		return l;
+	}
+
+	@Override
+	@LogMessageDocs({
+		@LogMessageDoc(level="WARN",
+				message="Error parsing flow idle timeout, " +
+						"using default of {number} seconds",
+						explanation="The properties file contains an invalid " +
+								"flow idle timeout",
+								recommendation="Correct the idle timeout in the " +
+				"properties file."),
+				@LogMessageDoc(level="WARN",
+				message="Error parsing flow hard timeout, " +
+						"using default of {number} seconds",
+						explanation="The properties file contains an invalid " +
+								"flow hard timeout",
+								recommendation="Correct the hard timeout in the " +
+						"properties file.")
+	})
+	public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+		super.init();
+		this.floodlightProviderService = context.getServiceImpl(IFloodlightProviderService.class);
+		this.deviceManagerService = context.getServiceImpl(IDeviceService.class);
+		this.routingEngineService = context.getServiceImpl(IRoutingService.class);
+		this.topologyService = context.getServiceImpl(ITopologyService.class);
+		this.debugCounterService = context.getServiceImpl(IDebugCounterService.class);
+
+		Map<String, String> configParameters = context.getConfigParams(this);
+		String tmp = configParameters.get("hard-timeout");
+		if (tmp != null) {
+			DEFAULT_HARD_TIMEOUT = Integer.parseInt(tmp);
+			log.info("Default hard timeout set to {}.", DEFAULT_HARD_TIMEOUT);
+		} else {
+			log.info("Default hard timeout not configured. Using {}.", DEFAULT_HARD_TIMEOUT);
+		}
+		tmp = configParameters.get("idle-timeout");
+		if (tmp != null) {
+			DEFAULT_IDLE_TIMEOUT = Integer.parseInt(tmp);
+			log.info("Default idle timeout set to {}.", DEFAULT_IDLE_TIMEOUT);
+		} else {
+			log.info("Default idle timeout not configured. Using {}.", DEFAULT_IDLE_TIMEOUT);
+		}
+
+
+
+	}
+
+	@Override
+	public void startUp(FloodlightModuleContext context) {
+		super.startUp();
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
index 8e28c2127e4a16205afbffdb705cee32ebabbc11..7e347294c30dd4822e83e3c3980ea35ac49489f0 100644
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
+++ b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
@@ -150,9 +150,11 @@ public class LearningSwitch
         if (vlan == VlanVid.FULL_MASK) {
             vlan = VlanVid.ofVlan(0);
         }
+        
         Map<MacVlanPair, OFPort> swMap = macVlanToSwitchPortMap.get(sw);
-        if (swMap != null)
+        if (swMap != null) {
             swMap.remove(new MacVlanPair(mac, vlan));
+        }
     }
 
     /**
@@ -167,8 +169,9 @@ public class LearningSwitch
             vlan = VlanVid.FULL_MASK;
         }
         Map<MacVlanPair, OFPort> swMap = macVlanToSwitchPortMap.get(sw);
-        if (swMap != null)
+        if (swMap != null) {
             return swMap.get(new MacVlanPair(mac, vlan));
+        }
 
         // if none found
         return null;
@@ -187,8 +190,9 @@ public class LearningSwitch
      */
     public void clearLearnedTable(IOFSwitch sw) {
         Map<MacVlanPair, OFPort> swMap = macVlanToSwitchPortMap.get(sw);
-        if (swMap != null)
+        if (swMap != null) {
             swMap.clear();
+        }
     }
 
     @Override
@@ -342,9 +346,7 @@ public class LearningSwitch
      * @param packetInMessage The corresponding PacketIn.
      * @param egressPort The switchport to output the PacketOut.
      */
-    private void writePacketOutForPacketIn(IOFSwitch sw,
-                                          OFPacketIn packetInMessage,
-                                          OFPort egressPort) {
+    private void writePacketOutForPacketIn(IOFSwitch sw, OFPacketIn packetInMessage, OFPort egressPort) {
         // from openflow 1.0 spec - need to set these on a struct ofp_packet_out:
         // uint32_t buffer_id; /* ID assigned by datapath (-1 if none). */
         // uint16_t in_port; /* Packet's input port (OFPP_NONE if none). */
@@ -543,19 +545,15 @@ public class LearningSwitch
     }
 
     @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m =
-                new HashMap<Class<? extends IFloodlightService>,
-                    IFloodlightService>();
+    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,  IFloodlightService> m = 
+        		new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
         m.put(ILearningSwitchService.class, this);
         return m;
     }
 
     @Override
-    public Collection<Class<? extends IFloodlightService>>
-            getModuleDependencies() {
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
         Collection<Class<? extends IFloodlightService>> l =
                 new ArrayList<Class<? extends IFloodlightService>>();
         l.add(IFloodlightProviderService.class);
@@ -565,16 +563,11 @@ public class LearningSwitch
     }
 
     @Override
-    public void init(FloodlightModuleContext context)
-            throws FloodlightModuleException {
-        macVlanToSwitchPortMap =
-                new ConcurrentHashMap<IOFSwitch, Map<MacVlanPair, OFPort>>();
-        floodlightProviderService =
-                context.getServiceImpl(IFloodlightProviderService.class);
-        debugCounterService =
-                context.getServiceImpl(IDebugCounterService.class);
-        restApiService =
-                context.getServiceImpl(IRestApiService.class);
+    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+        macVlanToSwitchPortMap = new ConcurrentHashMap<IOFSwitch, Map<MacVlanPair, OFPort>>();
+        floodlightProviderService = context.getServiceImpl(IFloodlightProviderService.class);
+        debugCounterService = context.getServiceImpl(IDebugCounterService.class);
+        restApiService = context.getServiceImpl(IRestApiService.class);
     }
 
     @Override
@@ -593,8 +586,7 @@ public class LearningSwitch
             }
         } catch (NumberFormatException e) {
             log.warn("Error parsing flow idle timeout, " +
-                     "using default of {} seconds",
-                     FLOWMOD_DEFAULT_IDLE_TIMEOUT);
+                     "using default of {} seconds", FLOWMOD_DEFAULT_IDLE_TIMEOUT);
         }
         try {
             String hardTimeout = configOptions.get("hardtimeout");
@@ -603,8 +595,7 @@ public class LearningSwitch
             }
         } catch (NumberFormatException e) {
             log.warn("Error parsing flow hard timeout, " +
-                     "using default of {} seconds",
-                     FLOWMOD_DEFAULT_HARD_TIMEOUT);
+                     "using default of {} seconds", FLOWMOD_DEFAULT_HARD_TIMEOUT);
         }
         try {
             String priority = configOptions.get("priority");
@@ -616,11 +607,8 @@ public class LearningSwitch
                      "using default of {}",
                      FLOWMOD_PRIORITY);
         }
-        log.debug("FlowMod idle timeout set to {} seconds",
-                  FLOWMOD_DEFAULT_IDLE_TIMEOUT);
-        log.debug("FlowMod hard timeout set to {} seconds",
-                  FLOWMOD_DEFAULT_HARD_TIMEOUT);
-        log.debug("FlowMod priority set to {}",
-                FLOWMOD_PRIORITY);
+        log.debug("FlowMod idle timeout set to {} seconds", FLOWMOD_DEFAULT_IDLE_TIMEOUT);
+        log.debug("FlowMod hard timeout set to {} seconds", FLOWMOD_DEFAULT_HARD_TIMEOUT);
+        log.debug("FlowMod priority set to {}", FLOWMOD_PRIORITY);
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index 7d808973396e15ec085d26304c2bce4590491d80..a339426845d024c242fb8c534122024d20ab8435 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -202,14 +202,9 @@ public abstract class ForwardingBase implements IOFMessageListener {
 								"flow modification to a switch",
 								recommendation=LogMessageDoc.CHECK_SWITCH)
 	})
-	public boolean pushRoute(Route route, Match match,
-			Integer wildcard_hints,
-			OFPacketIn pi,
-			DatapathId pinSwitch,
-			U64 cookie,
-			FloodlightContext cntx,
-			boolean reqeustFlowRemovedNotifn,
-			boolean doFlush,
+	public boolean pushRoute(Route route, Match match, OFPacketIn pi,
+			DatapathId pinSwitch, U64 cookie, FloodlightContext cntx,
+			boolean reqeustFlowRemovedNotifn, boolean doFlush,
 			OFFlowModCommand flowModCommand) {
 
 		boolean srcSwitchIncluded = false;
@@ -228,6 +223,7 @@ public abstract class ForwardingBase implements IOFMessageListener {
 				return srcSwitchIncluded;
 			}
 			
+			// need to build flow mod based on what type it is. Cannot set command later
 			OFFlowMod.Builder fmb;
 			switch (flowModCommand) {
 			case ADD:
@@ -246,15 +242,13 @@ public abstract class ForwardingBase implements IOFMessageListener {
 				log.error("Could not decode OFFlowModCommand. Using MODIFY_STRICT. (Should another be used as the default?)");        
 			case MODIFY_STRICT:
 				fmb = sw.getOFFactory().buildFlowModifyStrict();
-				break;			}
+				break;			
+			}
 			
 			OFActionOutput.Builder aob = sw.getOFFactory().actions().buildOutput();
 			List<OFAction> actions = new ArrayList<OFAction>();	
 			Match.Builder mb = match.createBuilder();
 
-			// set the match. TODO @Ryan look into setting Match's wildcards before hand, then pass in correctly
-			//fmb.setMatch(wildcard(match, sw, wildcard_hints));
-
 			// set input and output ports on the switch
 			OFPort outPort = switchPortList.get(indx).getPortId();
 			OFPort inPort = switchPortList.get(indx - 1).getPortId();
@@ -302,15 +296,6 @@ public abstract class ForwardingBase implements IOFMessageListener {
 		return srcSwitchIncluded;
 	}
 
-	/* TODO @Ryan get rid of this once wildcard/masked matches are set properly wherever they need to be 
-	 * protected Match wildcard(Match match, IOFSwitch sw, Integer wildcard_hints) {
-	 *
-		if (wildcard_hints != null) {
-			return match.clone().setWildcards(wildcard_hints.intValue());
-		}
-		return match.clone();
-	}*/
-
 	/**
 	 * Pushes a packet-out to a switch. If bufferId != BUFFER_ID_NONE we
 	 * assume that the packetOut switch is the same as the packetIn switch
@@ -352,8 +337,7 @@ public abstract class ForwardingBase implements IOFMessageListener {
 	 * @param outport   output port
 	 * @param cntx      context of the packet
 	 */
-	protected void pushPacket(IOFSwitch sw, OFPacketIn pi,
-			boolean useBufferId,
+	protected void pushPacket(IOFSwitch sw, OFPacketIn pi, boolean useBufferId,
 			OFPort outport, FloodlightContext cntx) {
 
 		if (pi == null) {
@@ -381,7 +365,7 @@ public abstract class ForwardingBase implements IOFMessageListener {
 		OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut();
 		// set actions
 		List<OFAction> actions = new ArrayList<OFAction>();
-		actions.add(sw.getOFFactory().actions().output(outport, Integer.MAX_VALUE)); //TODO @Ryan is MAX_VALUE == 0xffff previously?
+		actions.add(sw.getOFFactory().actions().output(outport, Integer.MAX_VALUE));
 		pob.setActions(actions);
 
 		if (useBufferId) {
@@ -415,11 +399,8 @@ public abstract class ForwardingBase implements IOFMessageListener {
 	 * @param ports
 	 * @param cntx
 	 */
-	public void packetOutMultiPort(byte[] packetData,
-			IOFSwitch sw,
-			OFPort inPort,
-			Set<OFPort> outPorts,
-			FloodlightContext cntx) {
+	public void packetOutMultiPort(byte[] packetData, IOFSwitch sw, 
+			OFPort inPort, Set<OFPort> outPorts, FloodlightContext cntx) {
 		//setting actions
 		List<OFAction> actions = new ArrayList<OFAction>();
 
@@ -456,11 +437,8 @@ public abstract class ForwardingBase implements IOFMessageListener {
 	 * Accepts a PacketIn instead of raw packet data. Note that the inPort
 	 * and switch can be different than the packet in switch/port
 	 */
-	public void packetOutMultiPort(OFPacketIn pi,
-			IOFSwitch sw,
-			OFPort inPort,
-			Set<OFPort> outPorts,
-			FloodlightContext cntx) {
+	public void packetOutMultiPort(OFPacketIn pi, IOFSwitch sw,
+			OFPort inPort, Set<OFPort> outPorts, FloodlightContext cntx) {
 		packetOutMultiPort(pi.getData(), sw, inPort, outPorts, cntx);
 	}
 
@@ -469,52 +447,11 @@ public abstract class ForwardingBase implements IOFMessageListener {
 	 * Accepts an IPacket instead of raw packet data. Note that the inPort
 	 * and switch can be different than the packet in switch/port
 	 */
-	public void packetOutMultiPort(IPacket packet,
-			IOFSwitch sw,
-			OFPort inPort,
-			Set<OFPort> outPorts,
-			FloodlightContext cntx) {
+	public void packetOutMultiPort(IPacket packet, IOFSwitch sw,
+			OFPort inPort, Set<OFPort> outPorts, FloodlightContext cntx) {
 		packetOutMultiPort(packet.serialize(), sw, inPort, outPorts, cntx);
 	}
 
-	/*TODO @Ryan what are these? outdated? protected boolean isInBroadcastCache(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
-        // Get the cluster id of the switch.
-        // Get the hash of the Ethernet packet.
-        if (sw == null) return true;
-
-        // If the feature is disabled, always return false;
-        if (!broadcastCacheFeature) return false;
-
-        Ethernet eth =
-            IFloodlightProviderService.bcStore.get(cntx,
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
-        Long broadcastHash;
-        broadcastHash = topology.getL2DomainId(sw.getId()).getLong() * prime1 +
-                        pi.getInPort().getPortNumber() * prime2 + eth.hashCode();
-        if (broadcastCache.update(broadcastHash)) {
-            //TODO @Ryan isn't implemented anymore, nuke it? sw.updateBroadcastCache(broadcastHash, pi.getInPort());
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    protected boolean isInSwitchBroadcastCache(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
-        if (sw == null) return true;
-
-        // If the feature is disabled, always return false;
-        if (!broadcastCacheFeature) return false;
-
-        // Get the hash of the Ethernet packet.
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
-        long hash = pi.getInPort().getPortNumber() * prime2 + eth.hashCode();
-
-        // some FORWARD_OR_FLOOD packets are unicast with unknown destination mac
-        return sw.updateBroadcastCache(hash, pi.getInPort());
-    }*/
-
 	@LogMessageDocs({
 		@LogMessageDoc(level="ERROR",
 				message="Failure writing deny flow mod",
@@ -523,8 +460,7 @@ public abstract class ForwardingBase implements IOFMessageListener {
 						recommendation=LogMessageDoc.CHECK_SWITCH)
 	})
 	public static boolean blockHost(IOFSwitchService switchService,
-			SwitchPort sw_tup, MacAddress host_mac,
-			short hardTimeout, U64 cookie) {
+			SwitchPort sw_tup, MacAddress host_mac, short hardTimeout, U64 cookie) {
 
 		if (sw_tup == null) {
 			return false;
@@ -566,9 +502,7 @@ public abstract class ForwardingBase implements IOFMessageListener {
 
 	@Override
 	public boolean isCallbackOrderingPrereq(OFType type, String name) {
-		return (type.equals(OFType.PACKET_IN) &&
-				(name.equals("topology") ||
-						name.equals("devicemanager")));
+		return (type.equals(OFType.PACKET_IN) && (name.equals("topology") || name.equals("devicemanager")));
 	}
 
 	@Override
diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java b/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
index 02779e0488b8960fea5d5f24eb52d6cc733a4bfc..bc9df880fd08a4a72f98d9104d09f7245edabfc0 100644
--- a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
+++ b/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java
@@ -60,7 +60,7 @@ public interface IRoutingDecision {
     public List<SwitchPort> getMulticastInterfaces();
     public void setMulticastInterfaces(List<SwitchPort> lspt);
     public Match getMatch();
-    public void setMatch(Match wildcards);
+    public void setMatch(Match match);
     public short getHardTimeout();
     public void setHardTimeout(short hardTimeout);
 }
diff --git a/src/main/java/net/floodlightcontroller/util/MatchMaskUtils.java b/src/main/java/net/floodlightcontroller/util/MatchMaskUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4620e5aed250128c3d54572a5b215941c141ae7
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/util/MatchMaskUtils.java
@@ -0,0 +1,41 @@
+package net.floodlightcontroller.util;
+
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.protocol.match.MatchField;
+
+/**
+ * Apply certain, routine masks to existing matches.
+ *
+ * @author Ryan Izard <ryan.izard@bigswitch.com, rizard@g.clemson.edu>
+ */
+public class MatchMaskUtils {
+	/**
+	 * Create a point-to-point match for two devices at the IP layer.
+	 * Takes an existing match (e.g. from a PACKET_IN), and masks all
+	 * MatchFields leaving behind:
+	 * 		IN_PORT
+	 * 		VLAN_VID
+	 * 		ETH_SRC
+	 * 		ETH_DST
+	 * 		IPV4_SRC
+	 * 		IPV4_DST
+	 * 
+	 * @param m The match to remove all L4+ MatchFields from
+	 * @return A new Match object with all MatchFields masked/wildcared
+	 * except for those listed above.
+	 */
+	public static Match maskL4AndUp(Match m) {
+		// cannot create builder from existing match; will retain all MatchFields set
+		Match.Builder mb = OFFactories.getFactory(m.getVersion()).buildMatch(); 
+		return mb.setExact(MatchField.IN_PORT, m.get(MatchField.IN_PORT))
+		.setExact(MatchField.VLAN_VID, m.get(MatchField.VLAN_VID))
+		.setExact(MatchField.ETH_SRC, m.get(MatchField.ETH_SRC))
+		.setExact(MatchField.ETH_DST, m.get(MatchField.ETH_DST))
+		.setExact(MatchField.IPV4_SRC, m.get(MatchField.IPV4_SRC))
+		.setExact(MatchField.IPV4_DST, m.get(MatchField.IPV4_DST))
+		.build();
+	}
+	
+	
+}
diff --git a/src/main/java/net/floodlightcontroller/util/MatchString.java b/src/main/java/net/floodlightcontroller/util/MatchString.java
index 26603ce8d18492a5e4b75c1813478bb99069bdc2..fb71e3cd1fb3cf6c108f37c94fe750e471df221f 100644
--- a/src/main/java/net/floodlightcontroller/util/MatchString.java
+++ b/src/main/java/net/floodlightcontroller/util/MatchString.java
@@ -25,20 +25,19 @@ import org.projectfloodlight.openflow.types.VlanPcp;
  * 
  */
 public class MatchString {
-	
     /* List of Strings for marshalling and unmarshalling to human readable forms */
-    final public static String STR_IN_PORT = "in_port";
-    final public static String STR_DL_DST = "dl_dst";
-    final public static String STR_DL_SRC = "dl_src";
-    final public static String STR_DL_TYPE = "dl_type";
-    final public static String STR_DL_VLAN = "dl_vlan";
-    final public static String STR_DL_VLAN_PCP = "dl_vpcp";
-    final public static String STR_NW_DST = "nw_dst";
-    final public static String STR_NW_SRC = "nw_src";
-    final public static String STR_NW_PROTO = "nw_proto";
-    final public static String STR_NW_TOS = "nw_tos";
-    final public static String STR_TP_DST = "tp_dst";
-    final public static String STR_TP_SRC = "tp_src";
+    final private static String STR_IN_PORT = "in_port";
+    final private static String STR_DL_DST = "dl_dst";
+    final private static String STR_DL_SRC = "dl_src";
+    final private static String STR_DL_TYPE = "dl_type";
+    final private static String STR_DL_VLAN = "dl_vlan";
+    final private static String STR_DL_VLAN_PCP = "dl_vpcp";
+    final private static String STR_NW_DST = "nw_dst";
+    final private static String STR_NW_SRC = "nw_src";
+    final private static String STR_NW_PROTO = "nw_proto";
+    final private static String STR_NW_TOS = "nw_tos";
+    final private static String STR_TP_DST = "tp_dst";
+    final private static String STR_TP_SRC = "tp_src";
 
     /**
      * Output a dpctl-styled string, i.e., only list the elements that are not
diff --git a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
index eb4c368e80b4131d8eff36879cbb5b86564f2ae9..ba4f01d3ac64a6b96d9856e489ab46e8c521aad2 100644
--- a/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
+++ b/src/main/java/net/floodlightcontroller/util/OFMessageDamper.java
@@ -116,8 +116,7 @@ public class OFMessageDamper {
      * the message was dampened. 
      * @throws IOException
      */
-    public boolean write(IOFSwitch sw, OFMessage msg, FloodlightContext cntx)
-                    throws IOException {
+    public boolean write(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) throws IOException {
         return write(sw, msg, cntx, false);
     }
     
@@ -131,9 +130,7 @@ public class OFMessageDamper {
      * the message was dampened. 
      * @throws IOException
      */
-    public boolean write(IOFSwitch sw, OFMessage msg,
-                        FloodlightContext cntx, boolean flush) 
-            throws IOException {
+    public boolean write(IOFSwitch sw, OFMessage msg, FloodlightContext cntx, boolean flush) throws IOException {
         if (! msgTypesToCache.contains(msg.getType())) {
             sw.write(msg, LogicalOFMessageCategory.MAIN);
             if (flush) {