very basic broken reactive forwarding; nit yet using treatments, but rather defaulting to flood for everything

generates a ton of duplicates for now
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
new file mode 100644
index 0000000..d206c97
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
@@ -0,0 +1,77 @@
+package org.onlab.onos.net.flow;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.onlab.onos.net.PortNumber;
+import org.slf4j.Logger;
+
+@SuppressWarnings("rawtypes")
+public class DefaultTrafficTreatment implements TrafficTreatment {
+
+    private final List<Instruction> instructions;
+
+    public DefaultTrafficTreatment(List<Instruction> instructions) {
+        this.instructions = Collections.unmodifiableList(instructions);
+    }
+
+    @Override
+    public List<Instruction> instructions() {
+        return instructions;
+    }
+
+    /**
+     * Builds a list of treatments following the following order.
+     * Modifications -> Group -> Output (including drop)
+     *
+     */
+
+    public static class Builder implements TrafficTreatment.Builder {
+
+        private final Logger log = getLogger(getClass());
+
+        List<Instruction<PortNumber>> outputs = new LinkedList<>();
+
+        // TODO: should be a list of instructions based on group objects
+        List<Instruction<Object>> groups = new LinkedList<>();
+
+        // TODO: should be a list of instructions based on modification objects
+        List<Instruction<Object>> modifications = new LinkedList<>();
+
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Builder add(Instruction instruction) {
+            switch (instruction.type()) {
+            case OUTPUT:
+            case DROP:
+                // TODO: should check that there is only one drop instruction.
+                outputs.add(instruction);
+                break;
+            case MODIFICATION:
+                // TODO: enforce modification order if any
+                modifications.add(instruction);
+            case GROUP:
+                groups.add(instruction);
+            default:
+                log.warn("Unknown instruction type {}", instruction.type());
+            }
+            return this;
+        }
+
+        @Override
+        public TrafficTreatment build() {
+            List<Instruction> instructions = new LinkedList<Instruction>();
+            instructions.addAll(modifications);
+            instructions.addAll(groups);
+            instructions.addAll(outputs);
+
+            return new DefaultTrafficTreatment(instructions);
+        }
+
+    }
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/Instruction.java b/core/api/src/main/java/org/onlab/onos/net/flow/Instruction.java
index 9fc1489..e9ea35b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/Instruction.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Instruction.java
@@ -2,8 +2,9 @@
 
 /**
  * Abstraction of a single traffic treatment step.
+ * @param <T> the type parameter for the instruction
  */
-public interface Instruction {
+public interface Instruction<T> {
 
     /**
      * Represents the type of traffic treatment.
@@ -33,4 +34,17 @@
     // TODO: Create factory class 'Instructions' that will have various factory
     // to create specific instructions.
 
+    /**
+     * Returns the type of instruction not to be confused
+     * with the instruction's java type.
+     * @return type of instruction
+     */
+    public Type type();
+
+    /**
+     * Returns the actual value of the instruction.
+     * @return the value for this instruction
+     */
+    public T instruction();
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/Instructions.java b/core/api/src/main/java/org/onlab/onos/net/flow/Instructions.java
index 13114c3..f72b07e 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/Instructions.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Instructions.java
@@ -8,8 +8,7 @@
 public final class Instructions {
 
     // Ban construction
-    private Instructions() {
-    }
+    private Instructions() {}
 
     /**
      * Creates an output instruction using the specified port number. This can
@@ -18,8 +17,20 @@
      * @param number port number
      * @return output instruction
      */
-    public static Instruction createOutput(PortNumber number) {
-        return null;
+    public static Instruction<PortNumber> createOutput(final PortNumber number) {
+        return new Instruction<PortNumber>() {
+
+            @Override
+            public Instruction.Type type() {
+                return Type.OUTPUT;
+            }
+
+            @Override
+            public PortNumber instruction() {
+                return number;
+            }
+
+        };
     }
 
     // TODO: add create methods
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
index 8c2495c..8f49602 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
@@ -1,10 +1,11 @@
 package org.onlab.onos.net.packet;
 
-import com.google.common.base.MoreObjects;
+import java.nio.ByteBuffer;
+
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.flow.TrafficTreatment;
 
-import java.nio.ByteBuffer;
+import com.google.common.base.MoreObjects;
 
 /**
  * Default implementation of an immutable outbound packet.
@@ -22,7 +23,7 @@
      * @param data        raw packet data
      */
     public DefaultOutboundPacket(DeviceId sendThrough,
-                                 TrafficTreatment treatment, ByteBuffer data) {
+            TrafficTreatment treatment, ByteBuffer data) {
         this.sendThrough = sendThrough;
         this.treatment = treatment;
         this.data = data;
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 6b77225..923f168 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,13 +1,20 @@
 package org.onlab.onos.net.packet;
 
+import org.onlab.onos.net.flow.DefaultTrafficTreatment;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.flow.TrafficTreatment.Builder;
+
 
 public abstract class DefaultPacketContext implements PacketContext {
 
     private final long time;
     private final InboundPacket inPkt;
     private final OutboundPacket outPkt;
+    private final TrafficTreatment.Builder builder;
+
     private boolean block = false;
 
+
     protected DefaultPacketContext(long time, InboundPacket inPkt,
             OutboundPacket outPkt, boolean block) {
         super();
@@ -15,6 +22,7 @@
         this.inPkt = inPkt;
         this.outPkt = outPkt;
         this.block = block;
+        this.builder = new DefaultTrafficTreatment.Builder();
     }
 
     @Override
@@ -33,6 +41,11 @@
     }
 
     @Override
+    public Builder treatmentBuilder() {
+        return builder;
+    }
+
+    @Override
     public abstract void send();
 
     @Override
diff --git a/core/trivial/src/main/java/org/onlab/onos/net/trivial/packet/impl/ReactivePacketProcessor.java b/core/trivial/src/main/java/org/onlab/onos/net/trivial/packet/impl/ReactivePacketProcessor.java
index 5e0a39b..bc5d30a 100644
--- a/core/trivial/src/main/java/org/onlab/onos/net/trivial/packet/impl/ReactivePacketProcessor.java
+++ b/core/trivial/src/main/java/org/onlab/onos/net/trivial/packet/impl/ReactivePacketProcessor.java
@@ -2,6 +2,8 @@
 
 import static org.slf4j.LoggerFactory.getLogger;
 
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.flow.Instructions;
 import org.onlab.onos.net.packet.PacketContext;
 import org.onlab.onos.net.packet.PacketProcessor;
 import org.slf4j.Logger;
@@ -12,7 +14,8 @@
 
     @Override
     public void process(PacketContext context) {
-        log.info("Packet reveived {}", context.inPacket());
+        context.treatmentBuilder().add(Instructions.createOutput(PortNumber.FLOOD));
+        context.send();
     }
 
 }
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 d0b1f13..d8cd715 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
@@ -1,5 +1,7 @@
 package org.onlab.onos.of.controller;
 
+import static org.slf4j.LoggerFactory.getLogger;
+
 import java.util.Collections;
 
 import org.onlab.packet.Ethernet;
@@ -10,9 +12,12 @@
 import org.projectfloodlight.openflow.protocol.match.MatchField;
 import org.projectfloodlight.openflow.types.OFBufferId;
 import org.projectfloodlight.openflow.types.OFPort;
+import org.slf4j.Logger;
 
 public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
 
+    private final Logger log = getLogger(getClass());
+
     private boolean free = true;
     private boolean isBuilt = false;
     private final OpenFlowSwitch sw;
@@ -32,8 +37,8 @@
     @Override
     public void send() {
         if (free && isBuilt) {
-            sw.sendMsg(pktout);
             block();
+            sw.sendMsg(pktout);
         }
     }
 
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 eceeb6c..cdbba2b 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
@@ -15,6 +15,7 @@
 import org.onlab.onos.of.controller.DefaultOpenFlowPacketContext;
 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.PacketListener;
@@ -106,7 +107,7 @@
 
     @Override
     public void removePacketListener(PacketListener listener) {
-        ofPacketListener.remove(listener);
+        ofPacketListener.values().remove(listener);
     }
 
     @Override
@@ -123,10 +124,11 @@
             }
             break;
         case PACKET_IN:
+            OpenFlowPacketContext pktCtx = DefaultOpenFlowPacketContext
+            .packetContextFromPacketIn(this.getSwitch(dpid),
+                    (OFPacketIn) msg);
             for (PacketListener p : ofPacketListener.values()) {
-                p.handlePacket(DefaultOpenFlowPacketContext
-                        .packetContextFromPacketIn(this.getSwitch(dpid),
-                                (OFPacketIn) msg));
+                p.handlePacket(pktCtx);
             }
             break;
         default:
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
new file mode 100644
index 0000000..aeb9542
--- /dev/null
+++ b/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowCorePacketContext.java
@@ -0,0 +1,41 @@
+package org.onlab.onos.provider.of.packet.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.onlab.onos.net.packet.DefaultPacketContext;
+import org.onlab.onos.net.packet.InboundPacket;
+import org.onlab.onos.net.packet.OutboundPacket;
+import org.onlab.onos.of.controller.OpenFlowPacketContext;
+import org.onlab.packet.Ethernet;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.slf4j.Logger;
+
+public class OpenFlowCorePacketContext extends DefaultPacketContext {
+
+    private final Logger log = getLogger(getClass());
+
+    private final OpenFlowPacketContext ofPktCtx;
+
+    protected OpenFlowCorePacketContext(long time, InboundPacket inPkt,
+            OutboundPacket outPkt, boolean block, OpenFlowPacketContext ofPktCtx) {
+        super(time, inPkt, outPkt, block);
+        this.ofPktCtx = ofPktCtx;
+    }
+
+    @Override
+    public void send() {
+        if (!this.isHandled()) {
+            block();
+            if (outPacket() == null) {
+                ofPktCtx.build(OFPort.FLOOD);
+            } else {
+                Ethernet eth = new Ethernet();
+                eth.deserialize(outPacket().data().array(), 0,
+                        outPacket().data().array().length);
+                ofPktCtx.build(eth, OFPort.FLOOD);
+            }
+            ofPktCtx.send();
+        }
+    }
+
+}
diff --git a/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java b/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java
index 44a3a58..96208fc 100644
--- a/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java
+++ b/providers/of/packet/src/main/java/org/onlab/onos/provider/of/packet/impl/OpenFlowPacketProvider.java
@@ -78,7 +78,6 @@
      */
     private class InternalPacketProvider implements PacketListener {
 
-
         @Override
         public void handlePacket(OpenFlowPacketContext pktCtx) {
             DeviceId id = DeviceId.deviceId(Dpid.uri(pktCtx.dpid().value()));
@@ -88,8 +87,7 @@
                     pktCtx.parsed(), ByteBuffer.wrap(pktCtx.unparsed()));
 
             OpenFlowCorePacketContext corePktCtx =
-                    new OpenFlowCorePacketContext(0, inPkt, null, false, pktCtx,
-                            controller.getSwitch(pktCtx.dpid()));
+                    new OpenFlowCorePacketContext(0, inPkt, null, false, pktCtx);
             providerService.processPacket(corePktCtx);
         }