Merge remote-tracking branch 'origin/master'
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/Criteria.java b/core/api/src/main/java/org/onlab/onos/net/flow/Criteria.java
index 9595797..4717cc4 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/Criteria.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Criteria.java
@@ -20,6 +20,18 @@
         return null;
     }
 
+    /**
+     * Creates a match on ETH_DST field using the specified value. This value
+     * may be a wildcard mask.
+     *
+     * @param macValue MAC address value or wildcard mask
+     * @return match criterion
+     */
+    public static Criterion matchEthDst(MACValue macValue) {
+        return null;
+    }
+
+
     // Dummy to illustrate the concept for now; delete ASAP
     private static class MACValue { }
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
index 7204745..5f44630 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
@@ -2,14 +2,14 @@
 
 import org.onlab.onos.net.DeviceId;
 
-import java.util.List;
-
 /**
  * Represents a generalized match & action pair to be applied to
  * an infrastucture device.
  */
 public interface FlowRule {
 
+    //TODO: build cookie value
+
     /**
      * Returns the flow rule priority given in natural order; higher numbers
      * mean higher priorities.
@@ -38,6 +38,6 @@
      *
      * @return traffic treatment
      */
-    List<Treatment> treatments();
+    TrafficTreatment treatment();
 
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
index 76689c2..661b195 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
@@ -22,4 +22,11 @@
      */
     void flowMissing(FlowRule flowRule);
 
+    /**
+     * Signals that a flow rule was indeed added.
+     *
+     * @param flowRule the added flow rule
+     */
+    void flowAdded(FlowRule flowRule);
+
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
index ccb6a51..724051f 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
@@ -26,6 +26,15 @@
     void applyFlowRules(FlowRule... flowRules);
 
     /**
+     * Removes the specified flow rules from their respective devices.
+     *
+     * @param flowRules one or more flow rules
+     * throws SomeKindOfException that indicates which ones were removed and
+     *                  which ones failed
+     */
+    void removeFlowRules(FlowRule... flowRules);
+
+    /**
      * Adds the specified flow rule listener.
      *
      * @param listener flow rule listener
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
index c024e9c..9678dc1 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
@@ -24,8 +24,9 @@
          * already been added, it will be replaced by this one.
          *
          * @param criterion new criterion
+         * @return self
          */
-        void add(Criterion criterion);
+        Builder add(Criterion criterion);
 
         /**
          * Builds an immutable traffic selector.
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
index 0eb5299..b8b9c10 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
@@ -25,7 +25,7 @@
          *
          * @param instruction new instruction
          */
-        void add(Instruction instruction);
+        Builder add(Instruction instruction);
 
         /**
          * Builds an immutable traffic treatment descriptor.
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
new file mode 100644
index 0000000..6b77225
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultPacketContext.java
@@ -0,0 +1,48 @@
+package org.onlab.onos.net.packet;
+
+
+public abstract class DefaultPacketContext implements PacketContext {
+
+    private final long time;
+    private final InboundPacket inPkt;
+    private final OutboundPacket outPkt;
+    private boolean block = false;
+
+    protected DefaultPacketContext(long time, InboundPacket inPkt,
+            OutboundPacket outPkt, boolean block) {
+        super();
+        this.time = time;
+        this.inPkt = inPkt;
+        this.outPkt = outPkt;
+        this.block = block;
+    }
+
+    @Override
+    public long time() {
+        return time;
+    }
+
+    @Override
+    public InboundPacket inPacket() {
+        return inPkt;
+    }
+
+    @Override
+    public OutboundPacket outPacket() {
+        return outPkt;
+    }
+
+    @Override
+    public abstract void send();
+
+    @Override
+    public void block() {
+        this.block = true;
+    }
+
+    @Override
+    public boolean isHandled() {
+        return this.block;
+    }
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProcessor.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProcessor.java
index a53a08c..aef5568 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProcessor.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProcessor.java
@@ -1,10 +1,16 @@
 package org.onlab.onos.net.packet;
 
+
+
 /**
  * Abstraction of an inbound packet processor.
  */
 public interface PacketProcessor {
 
+    public static final int ADVISOR_MAX = Integer.MAX_VALUE / 3;
+    public static final int DIRECTOR_MAX = (Integer.MAX_VALUE / 3) * 2;
+    public static final int OBSERVER_MAX = Integer.MAX_VALUE;
+
     /**
      * Processes the inbound packet as specified in the given context.
      *
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProvider.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProvider.java
index 14597ee..4ffdd6fd 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProvider.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProvider.java
@@ -1,9 +1,11 @@
 package org.onlab.onos.net.packet;
 
+import org.onlab.onos.net.provider.Provider;
+
 /**
  * Abstraction of a packet provider capable of emitting packets.
  */
-public interface PacketProvider {
+public interface PacketProvider extends Provider {
 
     /**
      * Emits the specified outbound packet onto the network.
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderRegistry.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderRegistry.java
new file mode 100644
index 0000000..86df510
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderRegistry.java
@@ -0,0 +1,10 @@
+package org.onlab.onos.net.packet;
+
+import org.onlab.onos.net.provider.ProviderRegistry;
+
+/**
+ * Abstraction of an infrastructure packet provider registry.
+ */
+public interface PacketProviderRegistry
+extends ProviderRegistry<PacketProvider, PacketProviderService> {
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderService.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderService.java
index 1b58f3e..6615386 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderService.java
@@ -1,9 +1,11 @@
 package org.onlab.onos.net.packet;
 
+import org.onlab.onos.net.provider.ProviderService;
+
 /**
  * Entity capable of processing inbound packets.
  */
-public interface PacketProviderService {
+public interface PacketProviderService extends ProviderService<PacketProvider> {
 
     /**
      * Submits inbound packet context for processing. This processing will be
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketService.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketService.java
index 5debf1b..d2db536 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/PacketService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketService.java
@@ -18,7 +18,7 @@
      * @throws java.lang.IllegalArgumentException if a processor with the
      *                                            given priority already exists
      */
-    void addProcessor(PacketProcessor processor, long priority);
+    void addProcessor(PacketProcessor processor, int priority);
 
     /**
      * Removes the specified processor from the processing pipeline.
diff --git a/core/api/src/test/java/org/onlab/onos/net/DefaultHostTest.java b/core/api/src/test/java/org/onlab/onos/net/DefaultHostTest.java
new file mode 100644
index 0000000..4f23231
--- /dev/null
+++ b/core/api/src/test/java/org/onlab/onos/net/DefaultHostTest.java
@@ -0,0 +1,36 @@
+package org.onlab.onos.net;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+public class DefaultHostTest extends  TestDeviceParams {
+
+    @Test
+    public void testEquality() {
+        Host h1 = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1, IPSET1);
+        Host h2 = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1, IPSET1);
+        Host h3 = new DefaultHost(PID, HID2, MAC2, VLAN2, LOC2, IPSET2);
+        Host h4 = new DefaultHost(PID, HID2, MAC2, VLAN2, LOC2, IPSET2);
+        Host h5 = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC2, IPSET1);
+
+        new EqualsTester().addEqualityGroup(h1, h2)
+                .addEqualityGroup(h3, h4)
+                .addEqualityGroup(h5)
+                .testEquals();
+    }
+
+    @Test
+    public void basics() {
+        Host host = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1, IPSET1);
+        assertEquals("incorrect provider", PID, host.providerId());
+        assertEquals("incorrect id", HID1, host.id());
+        assertEquals("incorrect type", MAC1, host.mac());
+        assertEquals("incorrect VLAN", VLAN1, host.vlan());
+        assertEquals("incorrect location", LOC1, host.location());
+        assertEquals("incorrect IP's", IPSET1, host.ipAddresses());
+    }
+
+}
diff --git a/core/api/src/test/java/org/onlab/onos/net/HostIdTest.java b/core/api/src/test/java/org/onlab/onos/net/HostIdTest.java
index 3adcabc..fefc499 100644
--- a/core/api/src/test/java/org/onlab/onos/net/HostIdTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/HostIdTest.java
@@ -1,21 +1,30 @@
 package org.onlab.onos.net;
 
 import com.google.common.testing.EqualsTester;
+
 import org.junit.Test;
+import org.onlab.packet.MACAddress;
+import org.onlab.packet.VLANID;
 
 import static org.onlab.onos.net.HostId.hostId;
 
 /**
- * Test of the host identifier.
+ * Test for the host identifier.
  */
 public class HostIdTest extends ElementIdTest {
 
+    private static final MACAddress MAC1 = MACAddress.valueOf("00:11:00:00:00:01");
+    private static final MACAddress MAC2 = MACAddress.valueOf("00:22:00:00:00:02");
+    private static final VLANID VLAN1 = VLANID.vlanId((short) 11);
+    private static final VLANID VLAN2 = VLANID.vlanId((short) 22);
+
+    @Override
     @Test
     public void basics() {
         new EqualsTester()
-                .addEqualityGroup(hostId("nic:foo"),
-                                  hostId("nic:foo"))
-                .addEqualityGroup(hostId("nic:bar"))
+                .addEqualityGroup(hostId("nic:00:11:00:00:00:01/11"),
+                                  hostId(MAC1, VLAN1))
+                .addEqualityGroup(hostId(MAC2, VLAN2))
                 .testEquals();
     }
 
diff --git a/core/api/src/test/java/org/onlab/onos/net/TestDeviceParams.java b/core/api/src/test/java/org/onlab/onos/net/TestDeviceParams.java
new file mode 100644
index 0000000..930cb3b
--- /dev/null
+++ b/core/api/src/test/java/org/onlab/onos/net/TestDeviceParams.java
@@ -0,0 +1,40 @@
+package org.onlab.onos.net;
+
+import static org.onlab.onos.net.DeviceId.deviceId;
+
+import java.util.Set;
+
+import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.packet.IPAddress;
+import org.onlab.packet.MACAddress;
+import org.onlab.packet.VLANID;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Provides a set of test DefaultDevice parameters for use with Host-
+ * related tests.
+ */
+public abstract class TestDeviceParams {
+
+    protected static final ProviderId PID = new ProviderId("foo");
+    protected static final DeviceId DID1 = deviceId("of:foo");
+    protected static final DeviceId DID2 = deviceId("of:bar");
+    protected static final MACAddress MAC1 = MACAddress.valueOf("00:11:00:00:00:01");
+    protected static final MACAddress MAC2 = MACAddress.valueOf("00:22:00:00:00:02");
+    protected static final VLANID VLAN1 = VLANID.vlanId((short) 11);
+    protected static final VLANID VLAN2 = VLANID.vlanId((short) 22);
+    protected static final IPAddress IP1 = IPAddress.valueOf("10.0.0.1");
+    protected static final IPAddress IP2 = IPAddress.valueOf("10.0.0.2");
+    protected static final IPAddress IP3 = IPAddress.valueOf("10.0.0.3");
+
+    protected static final PortNumber P1 = PortNumber.portNumber(100);
+    protected static final PortNumber P2 = PortNumber.portNumber(200);
+    protected static final HostId HID1 = HostId.hostId(MAC1, VLAN1);
+    protected static final HostId HID2 = HostId.hostId(MAC2, VLAN2);
+    protected static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
+    protected static final HostLocation LOC2 = new HostLocation(DID2, P2, 123L);
+    protected static final Set<IPAddress> IPSET1 = Sets.newHashSet(IP1, IP2);
+    protected static final Set<IPAddress> IPSET2 = Sets.newHashSet(IP1, IP3);
+
+}
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/DefaultPacketContext.java b/of/api/src/main/java/org/onlab/onos/of/controller/DefaultOpenFlowPacketContext.java
similarity index 89%
rename from of/api/src/main/java/org/onlab/onos/of/controller/DefaultPacketContext.java
rename to of/api/src/main/java/org/onlab/onos/of/controller/DefaultOpenFlowPacketContext.java
index 60580db..f05a7ff 100644
--- a/of/api/src/main/java/org/onlab/onos/of/controller/DefaultPacketContext.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/DefaultOpenFlowPacketContext.java
@@ -11,7 +11,7 @@
 import org.projectfloodlight.openflow.types.OFBufferId;
 import org.projectfloodlight.openflow.types.OFPort;
 
-public final class DefaultPacketContext implements PacketContext {
+public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
 
     private boolean free = true;
     private boolean isBuilt = false;
@@ -19,7 +19,7 @@
     private final OFPacketIn pktin;
     private OFPacketOut pktout = null;
 
-    private DefaultPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
+    private DefaultOpenFlowPacketContext(OpenFlowSwitch s, OFPacketIn pkt) {
         this.sw = s;
         this.pktin = pkt;
     }
@@ -78,8 +78,8 @@
         return new Dpid(sw.getId());
     }
 
-    public static PacketContext packetContextFromPacketIn(OpenFlowSwitch s, OFPacketIn pkt) {
-        return new DefaultPacketContext(s, pkt);
+    public static OpenFlowPacketContext packetContextFromPacketIn(OpenFlowSwitch s, OFPacketIn pkt) {
+        return new DefaultOpenFlowPacketContext(s, pkt);
     }
 
     @Override
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowPacketContext.java
similarity index 97%
rename from of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java
rename to of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowPacketContext.java
index 536dd7f..73365e7 100644
--- a/of/api/src/main/java/org/onlab/onos/of/controller/PacketContext.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/OpenFlowPacketContext.java
@@ -8,7 +8,7 @@
  * to view the packet in event but may block the response to the
  * event if blocked has been called.
  */
-public interface PacketContext {
+public interface OpenFlowPacketContext {
 
     //TODO: may want to support sending packet out other switches than
     // the one it came in on.
diff --git a/of/api/src/main/java/org/onlab/onos/of/controller/PacketListener.java b/of/api/src/main/java/org/onlab/onos/of/controller/PacketListener.java
index a14f9e1..6bd39b8 100644
--- a/of/api/src/main/java/org/onlab/onos/of/controller/PacketListener.java
+++ b/of/api/src/main/java/org/onlab/onos/of/controller/PacketListener.java
@@ -10,5 +10,5 @@
      *
      * @param pktCtx the packet context
      */
-    public void handlePacket(PacketContext pktCtx);
+    public void handlePacket(OpenFlowPacketContext pktCtx);
 }
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 bade605..f1ff6cc 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
@@ -12,7 +12,7 @@
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Service;
-import org.onlab.onos.of.controller.DefaultPacketContext;
+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.OpenFlowSwitch;
@@ -124,7 +124,7 @@
             break;
         case PACKET_IN:
             for (PacketListener p : ofPacketListener) {
-                p.handlePacket(DefaultPacketContext
+                p.handlePacket(DefaultOpenFlowPacketContext
                         .packetContextFromPacketIn(this.getSwitch(dpid),
                                 (OFPacketIn) msg));
             }
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 02239ab..8f6c612 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
@@ -15,7 +15,7 @@
 import org.onlab.onos.of.controller.OpenFlowController;
 import org.onlab.onos.of.controller.OpenFlowSwitch;
 import org.onlab.onos.of.controller.OpenFlowSwitchListener;
-import org.onlab.onos.of.controller.PacketContext;
+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;
@@ -87,7 +87,7 @@
 
 
         @Override
-        public void handlePacket(PacketContext pktCtx) {
+        public void handlePacket(OpenFlowPacketContext pktCtx) {
             LinkDiscovery ld = discoverers.get(pktCtx.dpid());
             if (ld == null) {
                 return;
diff --git a/utils/misc/src/main/java/org/onlab/packet/IPAddress.java b/utils/misc/src/main/java/org/onlab/packet/IPAddress.java
index 94c2d54..4e898f4 100644
--- a/utils/misc/src/main/java/org/onlab/packet/IPAddress.java
+++ b/utils/misc/src/main/java/org/onlab/packet/IPAddress.java
@@ -57,7 +57,7 @@
      * @return an IP address
      */
     public static IPAddress valueOf(String address) {
-        final String [] parts = address.split(".");
+        final String [] parts = address.split("\\.");
         if (parts.length != INET_LEN) {
             throw new IllegalArgumentException("Malformed IP address string; "
                     + "Addres must have four decimal values separated by dots (.)");
@@ -119,7 +119,9 @@
             return true;
         }
         if (obj instanceof IPAddress) {
+
             IPAddress other = (IPAddress) obj;
+
             if (!(this.version.equals(other.version))) {
                 return false;
             }
diff --git a/utils/misc/src/main/java/org/onlab/packet/VLANID.java b/utils/misc/src/main/java/org/onlab/packet/VLANID.java
index 31cdecb..5b26d04 100644
--- a/utils/misc/src/main/java/org/onlab/packet/VLANID.java
+++ b/utils/misc/src/main/java/org/onlab/packet/VLANID.java
@@ -37,12 +37,12 @@
         }
 
         if (obj instanceof VLANID) {
-            return true;
-        }
 
-        VLANID other = (VLANID) obj;
-        if (this.value == other.value) {
-            return true;
+            VLANID other = (VLANID) obj;
+
+             if (this.value == other.value) {
+                return true;
+            }
         }
 
         return false;