avoid other OF listeners overwriting the priority of another listener
diff --git a/core/api/src/main/java/org/onlab/onos/net/PortNumber.java b/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
index 93ec91d..56e15a2 100644
--- a/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
+++ b/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
@@ -13,12 +13,13 @@
 
     private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
 
-    public static final PortNumber FLOOD = new PortNumber(-1);
-    public static final PortNumber IN_PORT = new PortNumber(-2);
-    public static final PortNumber TABLE = new PortNumber(-3);
-    public static final PortNumber NORMAL = new PortNumber(-4);
+
+    public static final PortNumber IN_PORT = new PortNumber(-8);
+    public static final PortNumber TABLE = new PortNumber(-7);
+    public static final PortNumber NORMAL = new PortNumber(-6);
+    public static final PortNumber FLOOD = new PortNumber(-5);
     public static final PortNumber ALL = new PortNumber(-4);
-    public static final PortNumber LOCAL = new PortNumber(-5);
+    public static final PortNumber LOCAL = new PortNumber(-2);
 
     private final long number;
 
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultPacketContext.java b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultPacketContext.java
index 923f168..3c2b0ea 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultPacketContext.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultPacketContext.java
@@ -1,5 +1,7 @@
 package org.onlab.onos.net.packet;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
 import org.onlab.onos.net.flow.DefaultTrafficTreatment;
 import org.onlab.onos.net.flow.TrafficTreatment;
 import org.onlab.onos.net.flow.TrafficTreatment.Builder;
@@ -12,7 +14,7 @@
     private final OutboundPacket outPkt;
     private final TrafficTreatment.Builder builder;
 
-    private boolean block = false;
+    private final AtomicBoolean block;
 
 
     protected DefaultPacketContext(long time, InboundPacket inPkt,
@@ -21,7 +23,7 @@
         this.time = time;
         this.inPkt = inPkt;
         this.outPkt = outPkt;
-        this.block = block;
+        this.block = new AtomicBoolean(block);
         this.builder = new DefaultTrafficTreatment.Builder();
     }
 
@@ -49,13 +51,12 @@
     public abstract void send();
 
     @Override
-    public void block() {
-        this.block = true;
+    public boolean blocked() {
+        return this.block.getAndSet(true);
     }
 
     @Override
     public boolean isHandled() {
-        return this.block;
+        return this.block.get();
     }
-
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
index b77635b..ce08fde 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
@@ -43,14 +43,13 @@
 
     /**
      * Blocks the outbound packet from being sent from this point onward.
+     * @return whether the outbound packet is blocked.
      */
-    void block();
+    boolean blocked();
 
     /**
-     * Indicates whether the packet has already been handled, i.e. sent or
-     * blocked.
-     *
-     * @return true if sent or blocked
+     * Check whether the outbound packet is blocked.
+     * @return
      */
     boolean isHandled();
 
diff --git a/core/api/src/test/java/org/onlab/onos/net/device/DeviceEventTest.java b/core/api/src/test/java/org/onlab/onos/net/device/DeviceEventTest.java
index 6f1219a..7175308 100644
--- a/core/api/src/test/java/org/onlab/onos/net/device/DeviceEventTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/device/DeviceEventTest.java
@@ -1,5 +1,8 @@
 package org.onlab.onos.net.device;
 
+import static org.junit.Assert.assertEquals;
+import static org.onlab.onos.net.DeviceId.deviceId;
+
 import org.junit.Test;
 import org.onlab.onos.event.AbstractEventTest;
 import org.onlab.onos.net.DefaultDevice;
@@ -9,9 +12,6 @@
 import org.onlab.onos.net.PortNumber;
 import org.onlab.onos.net.provider.ProviderId;
 
-import static org.junit.Assert.assertEquals;
-import static org.onlab.onos.net.DeviceId.deviceId;
-
 /**
  * Tests of the device event.
  */
@@ -19,23 +19,25 @@
 
     private Device createDevice() {
         return new DefaultDevice(new ProviderId("foo"), deviceId("of:foo"),
-                                 Device.Type.SWITCH, "box", "hw", "sw", "sn");
+                Device.Type.SWITCH, "box", "hw", "sw", "sn");
     }
 
+    @Override
     @Test
     public void withTime() {
         Device device = createDevice();
-        Port port = new DefaultPort(device, PortNumber.portNumber(123L), true);
+        Port port = new DefaultPort(device, PortNumber.portNumber(123), true);
         DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED,
-                                            device, port, 123L);
+                device, port, 123L);
         validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L);
         assertEquals("incorrect port", port, event.port());
     }
 
+    @Override
     @Test
     public void withoutTime() {
         Device device = createDevice();
-        Port port = new DefaultPort(device, PortNumber.portNumber(123L), true);
+        Port port = new DefaultPort(device, PortNumber.portNumber(123), true);
         long before = System.currentTimeMillis();
         DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
         long after = System.currentTimeMillis();
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/DefaultOpenFlowPacketContext.java b/of/api/src/main/java/org/onlab/onos/of/controller/DefaultOpenFlowPacketContext.java
index d8cd715..529bc02 100644
--- a/of/api/src/main/java/org/onlab/onos/of/controller/DefaultOpenFlowPacketContext.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/DefaultOpenFlowPacketContext.java
@@ -3,6 +3,7 @@
 import static org.slf4j.LoggerFactory.getLogger;
 
 import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.onlab.packet.Ethernet;
 import org.projectfloodlight.openflow.protocol.OFPacketIn;
@@ -18,7 +19,7 @@
 
     private final Logger log = getLogger(getClass());
 
-    private boolean free = true;
+    private final AtomicBoolean free = new AtomicBoolean(true);
     private boolean isBuilt = false;
     private final OpenFlowSwitch sw;
     private final OFPacketIn pktin;
@@ -30,14 +31,8 @@
     }
 
     @Override
-    public void block() {
-        free = false;
-    }
-
-    @Override
     public void send() {
-        if (free && isBuilt) {
-            block();
+        if (blocked() && isBuilt) {
             sw.sendMsg(pktout);
         }
     }
@@ -111,4 +106,9 @@
         return act;
     }
 
+    @Override
+    public boolean blocked() {
+        return free.getAndSet(false);
+    }
+
 }
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowPacketContext.java b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowPacketContext.java
index 73365e7..e1360e2 100644
--- a/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowPacketContext.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowPacketContext.java
@@ -16,7 +16,7 @@
      * Blocks further responses (ie. send() calls) on this
      * packet in event.
      */
-    public void block();
+    public boolean blocked();
 
     /**
      * Provided build has been called send the packet
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
index cdbba2b..a8b0673 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
@@ -1,9 +1,7 @@
 package org.onlab.onos.of.controller.impl;
 
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
-import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
@@ -27,6 +25,9 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+
 @Component(immediate = true)
 @Service
 public class OpenFlowControllerImpl implements OpenFlowController {
@@ -44,7 +45,9 @@
     protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
     protected Set<OpenFlowSwitchListener> ofEventListener = new HashSet<>();
 
-    protected Map<Integer, PacketListener> ofPacketListener = new TreeMap<>();
+    protected Multimap<Integer, PacketListener> ofPacketListener =
+            ArrayListMultimap.create();
+
 
     private final Controller ctrl = new Controller();
 
diff --git a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
index 8f6c612..ff9a996 100644
--- a/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
+++ b/providers/of/link/src/main/java/org/onlab/onos/provider/of/link/impl/OpenFlowLinkProvider.java
@@ -1,5 +1,10 @@
 package org.onlab.onos.provider.of.link.impl;
 
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -13,9 +18,9 @@
 import org.onlab.onos.net.provider.ProviderId;
 import org.onlab.onos.of.controller.Dpid;
 import org.onlab.onos.of.controller.OpenFlowController;
+import org.onlab.onos.of.controller.OpenFlowPacketContext;
 import org.onlab.onos.of.controller.OpenFlowSwitch;
 import org.onlab.onos.of.controller.OpenFlowSwitchListener;
-import org.onlab.onos.of.controller.OpenFlowPacketContext;
 import org.onlab.onos.of.controller.PacketListener;
 import org.projectfloodlight.openflow.protocol.OFPortConfig;
 import org.projectfloodlight.openflow.protocol.OFPortDesc;
@@ -23,11 +28,6 @@
 import org.projectfloodlight.openflow.protocol.OFPortStatus;
 import org.slf4j.Logger;
 
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
 /**
  * Provider which uses an OpenFlow controller to detect network
  * infrastructure links.
@@ -93,7 +93,7 @@
                 return;
             }
             if (ld.handleLLDP(pktCtx.unparsed(), pktCtx.inPort())) {
-                pktCtx.block();
+                pktCtx.blocked();
             }
 
         }
@@ -101,7 +101,7 @@
         @Override
         public void switchAdded(Dpid dpid) {
             discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
-                                                    controller, providerService, useBDDP));
+                    controller, providerService, useBDDP));
 
         }
 
diff --git a/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java b/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java
index aeb9542..55476d0 100644
--- a/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java
+++ b/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java
@@ -2,6 +2,11 @@
 
 import static org.slf4j.LoggerFactory.getLogger;
 
+import java.util.List;
+
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.flow.Instruction;
+import org.onlab.onos.net.flow.Instruction.Type;
 import org.onlab.onos.net.packet.DefaultPacketContext;
 import org.onlab.onos.net.packet.InboundPacket;
 import org.onlab.onos.net.packet.OutboundPacket;
@@ -24,18 +29,36 @@
 
     @Override
     public void send() {
-        if (!this.isHandled()) {
-            block();
+        if (!this.blocked()) {
             if (outPacket() == null) {
-                ofPktCtx.build(OFPort.FLOOD);
+                sendBufferedPacket();
             } else {
                 Ethernet eth = new Ethernet();
                 eth.deserialize(outPacket().data().array(), 0,
                         outPacket().data().array().length);
                 ofPktCtx.build(eth, OFPort.FLOOD);
             }
-            ofPktCtx.send();
+
         }
     }
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private void sendBufferedPacket() {
+        List<Instruction> ins = treatmentBuilder().build().instructions();
+        OFPort p = null;
+        //TODO: support arbitrary list of treatments
+        for (Instruction i : ins) {
+            if (i.type() == Type.OUTPUT) {
+                p = buildPort(((Instruction<PortNumber>) i).instruction());
+                break; //for now...
+            }
+        }
+        ofPktCtx.build(p);
+        ofPktCtx.send();
+    }
+
+    private OFPort buildPort(PortNumber port) {
+        return OFPort.of((int) port.toLong());
+    }
+
 }