From e63291850fd0795c5700e25e67e5dee89ba54c5f Mon Sep 17 00:00:00 2001
From: Ashlee Young <ashlee@wildernessvoice.com>
Date: Tue, 1 Dec 2015 05:49:27 -0800
Subject: onos commit hash c2999f30c69e50df905a9d175ef80b3f23a98514

Change-Id: I2bb8562c4942b6d6a6d60b663db2e17540477b81
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
---
 .../org/onosproject/net/EncapsulationType.java     |  30 +++++
 .../java/org/onosproject/net/TributarySlot.java    |  73 ++++++++++
 .../net/behaviour/ExtensionResolver.java           |  40 ------
 .../net/behaviour/ExtensionTreatmentResolver.java  |  40 ++++++
 .../onosproject/net/behaviour/TunnelConfig.java    |   1 +
 .../java/org/onosproject/net/config/Config.java    |  20 +++
 .../net/config/basics/BasicFeatureConfig.java      |  54 ++++++++
 .../net/flow/DefaultTrafficSelector.java           |   7 +-
 .../net/flow/DefaultTrafficTreatment.java          |   4 +-
 .../org/onosproject/net/flow/TrafficSelector.java  |   8 ++
 .../org/onosproject/net/flow/TrafficTreatment.java |   4 +-
 .../net/flow/criteria/ArpOpCriterion.java          |  78 +++++++++++
 .../onosproject/net/flow/criteria/Criteria.java    |  32 ++++-
 .../onosproject/net/flow/criteria/Criterion.java   |  90 ++++++++++++-
 .../net/flow/criteria/MplsTcCriterion.java         |  75 +++++++++++
 .../net/flow/criteria/TcpFlagsCriterion.java       |  75 +++++++++++
 .../instructions/AbstractExtensionInstruction.java |  71 ----------
 .../instructions/AbstractExtensionTreatment.java   |  71 ++++++++++
 .../flow/instructions/ExtensionInstruction.java    |  78 -----------
 .../net/flow/instructions/ExtensionTreatment.java  |  78 +++++++++++
 .../flow/instructions/ExtensionTreatmentType.java  |  95 +++++++++++++
 .../net/flow/instructions/ExtensionType.java       |  93 -------------
 .../net/flow/instructions/Instructions.java        |  18 +--
 .../flowobjective/DefaultForwardingObjective.java  |  48 +++++++
 .../net/flowobjective/DefaultNextObjective.java    |  65 +++++++++
 .../net/flowobjective/NextObjective.java           |  55 +++++++-
 .../onosproject/net/flowobjective/Objective.java   |  25 +++-
 .../org/onosproject/net/group/DefaultGroupKey.java |  17 +++
 .../onosproject/net/intent/HostToHostIntent.java   |   2 +
 .../net/intent/constraint/BandwidthConstraint.java |  12 +-
 .../intent/constraint/EncapsulationConstraint.java |  83 ++++++++++++
 .../net/intent/constraint/LambdaConstraint.java    |   8 +-
 .../net/newresource/ResourceAdminService.java      |  38 +++---
 .../onosproject/net/newresource/ResourcePath.java  |  19 +++
 .../resource/link/DefaultLinkResourceRequest.java  |   2 +-
 .../org/onosproject/net/config/ConfigTest.java     | 141 +++++++++++++++++++
 .../net/flow/criteria/CriteriaTest.java            | 149 +++++++++++++--------
 .../net/intent/LinkCollectionIntentTest.java       |   4 +-
 .../intent/constraint/ConstraintObjectsTest.java   |  30 ++---
 39 files changed, 1416 insertions(+), 417 deletions(-)
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java
 delete mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java
 delete mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java
 delete mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
 delete mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
 create mode 100644 framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java
 create mode 100644 framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java

(limited to 'framework/src/onos/core/api')

diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java
new file mode 100644
index 00000000..63ff46d3
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/EncapsulationType.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net;
+
+public enum EncapsulationType {
+    /**
+     * Indicates an MPLS encapsulation.
+     */
+    MPLS,
+    /**
+     * Indicates a VLAN encapsulation.
+     */
+    VLAN,
+};
+
+
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java
new file mode 100644
index 00000000..d8a10c81
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/TributarySlot.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implementation of ODU Tributary Slot simply designated by an index number of slot.
+ */
+public class TributarySlot {
+
+    private final long index;
+
+    /**
+     * Creates an instance representing the TributarySlot specified by the given index number.
+     *
+     * @param index index number of wavelength
+     */
+    public TributarySlot(long index) {
+        this.index = index;
+    }
+
+    public static TributarySlot of(long index) {
+        return new TributarySlot(index);
+    }
+
+    /**
+     * Returns the index number of TributarySlot.
+     *
+     * @return the index number of TributarySlot
+     */
+    public long index() {
+        return index;
+    }
+
+    @Override
+    public int hashCode() {
+        return Long.hashCode(index);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof TributarySlot)) {
+            return false;
+        }
+
+        final TributarySlot that = (TributarySlot) obj;
+        return this.index == that.index;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("index", index)
+                .toString();
+    }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java
deleted file mode 100644
index 54cbc7ac..00000000
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionResolver.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 org.onosproject.net.behaviour;
-
-import com.google.common.annotations.Beta;
-import org.onosproject.net.driver.HandlerBehaviour;
-import org.onosproject.net.flow.instructions.ExtensionInstruction;
-import org.onosproject.net.flow.instructions.ExtensionType;
-
-/**
- * Provides access to the extension implemented by this driver.
- */
-@Beta
-public interface ExtensionResolver extends HandlerBehaviour {
-
-    /**
-     * Gets an extension instruction instance of the specified type, if supported
-     * by the driver.
-     *
-     * @param type type of extension to get
-     * @return extension instruction
-     * @throws UnsupportedOperationException if the extension type is not
-     * supported by this driver
-     */
-    ExtensionInstruction getExtensionInstruction(ExtensionType type);
-}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java
new file mode 100644
index 00000000..85f0216d
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionTreatmentResolver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+
+/**
+ * Provides access to the extension implemented by this driver.
+ */
+@Beta
+public interface ExtensionTreatmentResolver extends HandlerBehaviour {
+
+    /**
+     * Gets an extension instruction instance of the specified type, if supported
+     * by the driver.
+     *
+     * @param type type of extension to get
+     * @return extension instruction
+     * @throws UnsupportedOperationException if the extension type is not
+     * supported by this driver
+     */
+    ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type);
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java
index e3b4c198..a1b97ffd 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/TunnelConfig.java
@@ -29,6 +29,7 @@ public interface TunnelConfig extends HandlerBehaviour {
      *
      * @param tunnel tunnel descriptor
      */
+    @Deprecated
     void createTunnel(TunnelDescription tunnel);
 
     /**
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
index 3757d327..5f2c9f3a 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
@@ -332,6 +332,26 @@ public abstract class Config<S> {
         return list;
     }
 
+    /**
+     * Gets the specified array property as a list of items.
+     *
+     * @param name     property name
+     * @param function mapper from string to item
+     * @param defaultValue default value if property not set
+     * @param <T>      type of item
+     * @return list of items
+     */
+    protected <T> List<T> getList(String name, Function<String, T> function, List<T> defaultValue) {
+        List<T> list = Lists.newArrayList();
+        JsonNode jsonNode = object.path(name);
+        if (jsonNode.isMissingNode()) {
+            return defaultValue;
+        }
+        ArrayNode arrayNode = (ArrayNode) jsonNode;
+        arrayNode.forEach(i -> list.add(function.apply(i.asText())));
+        return list;
+    }
+
     /**
      * Sets the specified property as an array of items in a given collection or
      * clears it if null is given.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java
new file mode 100644
index 00000000..fcf24bc6
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/basics/BasicFeatureConfig.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.config.basics;
+
+import org.onosproject.net.config.Config;
+
+/**
+ * Base abstraction for configuring feature on subject.
+ *
+ * @param <S> Subject type
+ */
+public abstract class BasicFeatureConfig<S> extends Config<S> {
+
+    private static final String ENABLED = "enabled";
+
+    private final boolean defaultValue;
+
+    protected BasicFeatureConfig(boolean defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    /**
+     * Indicates whether the feature for the subject is enabled.
+     *
+     * @return true if feature is enabled
+     */
+    public boolean enabled() {
+        return get(ENABLED, defaultValue);
+    }
+
+    /**
+     * Specifies whether the feature for the subject is to be enabled.
+     *
+     * @param enabled true to enable; false to disable; null to clear
+     * @return self
+     */
+    public BasicFeatureConfig<S> enabled(Boolean enabled) {
+        return (BasicFeatureConfig<S>) setOrClear(ENABLED, enabled);
+    }
+
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
index a842d600..d3c2449c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
@@ -340,7 +340,7 @@ public final class DefaultTrafficSelector implements TrafficSelector {
 
         @Override
         public Builder matchMplsBos(boolean mplsBos) {
-            return add(Criteria.matchMplsLabel(mplsBos));
+            return add(Criteria.matchMplsBos(mplsBos));
         }
 
         @Override
@@ -373,6 +373,11 @@ public final class DefaultTrafficSelector implements TrafficSelector {
             return add(Criteria.matchArpSha(addr));
         }
 
+        @Override
+        public Builder matchArpOp(int arpOp) {
+            return add(Criteria.matchArpOp(arpOp));
+        }
+
         @Override
         public TrafficSelector build() {
             return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
index 4615a82b..22bff7dd 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
@@ -30,7 +30,7 @@ import org.onosproject.core.GroupId;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.IndexedLambda;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.instructions.ExtensionInstruction;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.net.meter.MeterId;
@@ -489,7 +489,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
         }
 
         @Override
-        public TrafficTreatment.Builder extension(ExtensionInstruction extension,
+        public TrafficTreatment.Builder extension(ExtensionTreatment extension,
                                                   DeviceId deviceId) {
             return add(Instructions.extension(extension, deviceId));
         }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
index 9fe88d5a..b92281f5 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
@@ -418,6 +418,14 @@ public interface TrafficSelector {
          */
         Builder matchArpSha(MacAddress addr);
 
+        /**
+         * Matches a arp operation type.
+         *
+         * @param arpOp a arp operation type
+         * @return a selection builder
+         */
+        Builder matchArpOp(int arpOp);
+
         /**
          * Builds an immutable traffic selector.
          *
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
index f1a676ab..06b6ffa0 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
@@ -26,7 +26,7 @@ import org.onlab.packet.VlanId;
 import org.onosproject.core.GroupId;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.instructions.ExtensionInstruction;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.net.meter.MeterId;
@@ -430,7 +430,7 @@ public interface TrafficTreatment {
          * @param deviceId device ID
          * @return a treatment builder
          */
-        Builder extension(ExtensionInstruction extension, DeviceId deviceId);
+        Builder extension(ExtensionTreatment extension, DeviceId deviceId);
 
         /**
          * Builds an immutable traffic treatment descriptor.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java
new file mode 100644
index 00000000..8c5398c6
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpOpCriterion.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.flow.criteria;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Implementation of arp operation type criterion.
+ */
+public final class ArpOpCriterion implements Criterion {
+    private final int arpOp;
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param arpOp the arp operation type to match.
+     * @param type the match type. Should be the following:
+     * Type.ARP_OP
+     */
+    ArpOpCriterion(int arpOp, Type type) {
+        this.arpOp = arpOp;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the arp operation type to match.
+     *
+     * @return the arp operation type to match
+     */
+    public int arpOp() {
+        return this.arpOp;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("arpOp", arpOp).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type().ordinal(), arpOp);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ArpOpCriterion) {
+            ArpOpCriterion that = (ArpOpCriterion) obj;
+            return Objects.equals(arpOp, that.arpOp) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index 554b8e74..a28a4ab9 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -229,6 +229,16 @@ public final class Criteria {
         return new TcpPortCriterion(tcpPort, Type.TCP_DST);
     }
 
+    /**
+     * Creates a match on TCP flags using the specified value.
+     *
+     * @param flags TCP flags
+     * @return match criterion
+     */
+    public static Criterion matchTcpFlags(int flags) {
+        return new TcpFlagsCriterion(flags);
+    }
+
     /**
      * Creates a match on UDP source port field using the specified value.
      *
@@ -438,10 +448,20 @@ public final class Criteria {
      * @param mplsBos boolean value indicating true (BOS=1) or false (BOS=0)
      * @return match criterion
      */
-    public static Criterion matchMplsLabel(boolean mplsBos) {
+    public static Criterion matchMplsBos(boolean mplsBos) {
         return new MplsBosCriterion(mplsBos);
     }
 
+    /**
+     * Creates a match on MPLS TC.
+     *
+     * @param mplsTc MPLS TC (3 bits)
+     * @return match criterion
+     */
+    public static Criterion matchMplsTc(byte mplsTc) {
+        return new MplsTcCriterion(mplsTc);
+    }
+
     /**
      * Creates a match on Tunnel ID.
      *
@@ -549,6 +569,16 @@ public final class Criteria {
         return new ArpHaCriterion(mac, Type.ARP_SHA);
     }
 
+    /**
+     * Creates a match on arp operation type field using the specified value.
+     *
+     * @param arpOp arp operation type value
+     * @return match criterion
+     */
+    public static Criterion matchArpOp(int arpOp) {
+        return new ArpOpCriterion(arpOp, Type.ARP_OP);
+    }
+
     public static Criterion dummy() {
         return new DummyCriterion();
     }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
index 10cb629f..26665246 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
@@ -28,92 +28,136 @@ public interface Criterion {
     enum Type {
         /** Switch input port. */
         IN_PORT,
+
         /** Switch physical input port. */
         IN_PHY_PORT,
+
         /** Metadata passed between tables. */
         METADATA,
+
         /** Ethernet destination address. */
         ETH_DST,
+
         /** Ethernet source address. */
         ETH_SRC,
+
         /** Ethernet frame type. */
         ETH_TYPE,
+
         /** VLAN id. */
         VLAN_VID,
+
         /** VLAN priority. */
         VLAN_PCP,
+
         /** IP DSCP (6 bits in ToS field). */
         IP_DSCP,
+
         /** IP ECN (2 bits in ToS field). */
         IP_ECN,
+
         /** IP protocol. */
         IP_PROTO,
+
         /** IPv4 source address. */
         IPV4_SRC,
+
         /** IPv4 destination address. */
         IPV4_DST,
+
         /** TCP source port. */
         TCP_SRC,
+
         /** TCP destination port. */
         TCP_DST,
+
         /** UDP source port. */
         UDP_SRC,
+
         /** UDP destination port. */
         UDP_DST,
+
         /** SCTP source port. */
         SCTP_SRC,
+
         /** SCTP destination port. */
         SCTP_DST,
+
         /** ICMP type. */
         ICMPV4_TYPE,
+
         /** ICMP code. */
         ICMPV4_CODE,
+
         /** ARP opcode. */
         ARP_OP,
+
         /** ARP source IPv4 address. */
         ARP_SPA,
+
         /** ARP target IPv4 address. */
         ARP_TPA,
+
         /** ARP source hardware address. */
         ARP_SHA,
+
         /** ARP target hardware address. */
         ARP_THA,
+
         /** IPv6 source address. */
         IPV6_SRC,
+
         /** IPv6 destination address. */
         IPV6_DST,
+
         /** IPv6 Flow Label. */
         IPV6_FLABEL,
+
         /** ICMPv6 type. */
         ICMPV6_TYPE,
+
         /** ICMPv6 code. */
         ICMPV6_CODE,
+
         /** Target address for ND. */
         IPV6_ND_TARGET,
+
         /** Source link-layer for ND. */
         IPV6_ND_SLL,
+
         /** Target link-layer for ND. */
         IPV6_ND_TLL,
+
         /** MPLS label. */
         MPLS_LABEL,
+
         /** MPLS TC. */
         MPLS_TC,
-        /** MPLS BoS bit. */
+
+        /**  MPLS BoS bit. */
         MPLS_BOS,
+
         /** PBB I-SID. */
         PBB_ISID,
+
         /** Logical Port Metadata. */
         TUNNEL_ID,
+
         /** IPv6 Extension Header pseudo-field. */
         IPV6_EXTHDR,
+
         /** Unassigned value: 40. */
         UNASSIGNED_40,
+
         /** PBB UCA header field. */
         PBB_UCA,
+
         /** TCP flags. */
         TCP_FLAGS,
+
         /** Output port from action set metadata. */
         ACTSET_OUTPUT,
+
         /** Packet type value. */
         PACKET_TYPE,
 
@@ -123,16 +167,17 @@ public interface Criterion {
         //
         /** Optical channel signal ID (lambda). */
         OCH_SIGID,
+
         /** Optical channel signal type (fixed or flexible). */
         OCH_SIGTYPE,
+
         /** ODU (Optical channel Data Unit) signal ID. */
         ODU_SIGID,
+
         /** ODU (Optical channel Data Unit) signal type. */
         ODU_SIGTYPE,
 
-        /**
-         * An empty criterion.
-         */
+        /** An empty criterion. */
         DUMMY
     }
 
@@ -182,4 +227,41 @@ public interface Criterion {
             return this.value;
         }
     }
+
+    enum TCPFlags {
+
+        /** ECN-nonce concealment protection. */
+        NS((short) (1 << 0)),
+        /** Congestion Window Reduced. */
+        CWR((short) (1 << 1)),
+        /** ECN-Echo. **/
+        ECE((short) (1 << 2)),
+        /** Urgent pointer field is significant. */
+        URG((short) (1 << 3)),
+        /** Acknowledgment field is significant. */
+        ACK((short) (1 << 4)),
+        /** Push the buffered data to the receiving application. */
+        PSH((short) (1 << 5)),
+        /** Reset the connection. */
+        RST((short) (1 << 6)),
+        /** Synchronize sequence numbers. */
+        SYN((short) (1 << 7)),
+        /** No more data from sender. */
+        FIN((short) (1 << 8));
+
+        private short value;
+
+        TCPFlags(short value) {
+            this.value = value;
+        }
+
+        /**
+         * Gets the value as an integer.
+         *
+         * @return the value as an integer
+         */
+        public short getValue() {
+            return this.value;
+        }
+    }
 }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java
new file mode 100644
index 00000000..8ad62358
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsTcCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of MPLS TC criterion (3 bits).
+ */
+public final class MplsTcCriterion implements Criterion {
+    private static final byte MASK = 0x7;
+    private final byte mplsTc;
+
+    /**
+     * Constructor.
+     *
+     * @param mplsTc the MPLS TC to match (3 bits)
+     */
+    MplsTcCriterion(byte mplsTc) {
+        this.mplsTc = (byte) (mplsTc & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.MPLS_TC;
+    }
+
+    /**
+     * Gets the MPLS TC to match.
+     *
+     * @return the MPLS TC to match (3 bits)
+     */
+    public byte tc() {
+        return mplsTc;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("tc", Long.toHexString(mplsTc)).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type().ordinal(), mplsTc);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MplsTcCriterion) {
+            MplsTcCriterion that = (MplsTcCriterion) obj;
+            return Objects.equals(mplsTc, that.mplsTc) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java
new file mode 100644
index 00000000..e0b53958
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpFlagsCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of TCP flags criterion (12 bits unsigned integer).
+ */
+public final class TcpFlagsCriterion implements Criterion {
+    private static final int MASK = 0xfffff;
+    private final int flags;            // TCP flags: 12 bits
+
+    /**
+     * Constructor.
+     *
+     * @param flags the TCP flags to match (12 bits)
+     */
+    TcpFlagsCriterion(int flags) {
+        this.flags = flags & MASK;
+    }
+
+    @Override
+    public Type type() {
+        return Type.TCP_FLAGS;
+    }
+
+    /**
+     * Gets the TCP flags to match.
+     *
+     * @return the TCP flags to match (12 bits)
+     */
+    public int flags() {
+        return flags;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("flags", Long.toHexString(flags)).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type().ordinal(), flags);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TcpFlagsCriterion) {
+            TcpFlagsCriterion that = (TcpFlagsCriterion) obj;
+            return Objects.equals(flags, that.flags) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java
deleted file mode 100644
index 9f22f888..00000000
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionInstruction.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 org.onosproject.net.flow.instructions;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Abstract implementation of the set/get property methods of ExtensionInstruction.
- */
-public abstract class AbstractExtensionInstruction implements ExtensionInstruction {
-
-    private static final String INVALID_KEY = "Invalid property key: ";
-    private static final String INVALID_TYPE = "Given type does not match field type: ";
-
-    @Override
-    public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
-        Class<?> clazz = this.getClass();
-        try {
-            Field field = clazz.getDeclaredField(key);
-            field.setAccessible(true);
-            field.set(this, value);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new ExtensionPropertyException(INVALID_KEY + key);
-        }
-    }
-
-    @Override
-    public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
-        Class<?> clazz = this.getClass();
-        try {
-            Field field = clazz.getDeclaredField(key);
-            field.setAccessible(true);
-            @SuppressWarnings("unchecked")
-            T result = (T) field.get(this);
-            return result;
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new ExtensionPropertyException(INVALID_KEY + key);
-        } catch (ClassCastException e) {
-            throw new ExtensionPropertyException(INVALID_TYPE + key);
-        }
-    }
-
-    @Override
-    public List<String> getProperties() {
-        Class<?> clazz = this.getClass();
-
-        List<String> fields = new ArrayList<>();
-
-        for (Field field : clazz.getDeclaredFields()) {
-            fields.add(field.getName());
-        }
-
-        return fields;
-    }
-}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java
new file mode 100644
index 00000000..ac7c771f
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.flow.instructions;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Abstract implementation of the set/get property methods of ExtensionInstruction.
+ */
+public abstract class AbstractExtensionTreatment implements ExtensionTreatment {
+
+    private static final String INVALID_KEY = "Invalid property key: ";
+    private static final String INVALID_TYPE = "Given type does not match field type: ";
+
+    @Override
+    public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+        Class<?> clazz = this.getClass();
+        try {
+            Field field = clazz.getDeclaredField(key);
+            field.setAccessible(true);
+            field.set(this, value);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExtensionPropertyException(INVALID_KEY + key);
+        }
+    }
+
+    @Override
+    public <T> T getPropertyValue(String key) throws ExtensionPropertyException {
+        Class<?> clazz = this.getClass();
+        try {
+            Field field = clazz.getDeclaredField(key);
+            field.setAccessible(true);
+            @SuppressWarnings("unchecked")
+            T result = (T) field.get(this);
+            return result;
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new ExtensionPropertyException(INVALID_KEY + key);
+        } catch (ClassCastException e) {
+            throw new ExtensionPropertyException(INVALID_TYPE + key);
+        }
+    }
+
+    @Override
+    public List<String> getProperties() {
+        Class<?> clazz = this.getClass();
+
+        List<String> fields = new ArrayList<>();
+
+        for (Field field : clazz.getDeclaredFields()) {
+            fields.add(field.getName());
+        }
+
+        return fields;
+    }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java
deleted file mode 100644
index 89e0cc5e..00000000
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionInstruction.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 org.onosproject.net.flow.instructions;
-
-import java.util.List;
-
-/**
- * An extensible instruction type.
- */
-public interface ExtensionInstruction {
-
-    /**
-     * Gets the type of the extension instruction.
-     *
-     * @return type
-     */
-    ExtensionType type();
-
-    /**
-     * Sets a property on the extension instruction.
-     *
-     * @param key property key
-     * @param value value to set for the given key
-     * @param <T> class of the value
-     * @throws ExtensionPropertyException if the given key is not a valid
-     * property on this extension instruction
-     */
-    <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
-
-    /**
-     * Gets a property value of an extension instruction.
-     *
-     * @param key property key
-     * @param <T> class of the value
-     * @return value of the property
-     * @throws ExtensionPropertyException if the given key is not a valid
-     * property on this extension instruction
-     */
-    <T> T getPropertyValue(String key) throws ExtensionPropertyException;
-
-    /**
-     * Gets a list of all properties on the extension instruction.
-     *
-     * @return list of properties
-     */
-    List<String> getProperties();
-
-    /**
-     * Serialize the extension instruction to a byte array.
-     *
-     * @return byte array
-     */
-    byte[] serialize();
-
-    /**
-     * Deserialize the extension instruction from a byte array. The properties
-     * of this object will be overwritten with the data in the byte array.
-     *
-     * @param data input byte array
-     */
-    void deserialize(byte[] data);
-
-
-}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
new file mode 100644
index 00000000..0e8885ed
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.flow.instructions;
+
+import java.util.List;
+
+/**
+ * An extensible instruction type.
+ */
+public interface ExtensionTreatment {
+
+    /**
+     * Gets the type of the extension instruction.
+     *
+     * @return type
+     */
+    ExtensionTreatmentType type();
+
+    /**
+     * Sets a property on the extension instruction.
+     *
+     * @param key property key
+     * @param value value to set for the given key
+     * @param <T> class of the value
+     * @throws ExtensionPropertyException if the given key is not a valid
+     * property on this extension instruction
+     */
+    <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
+
+    /**
+     * Gets a property value of an extension instruction.
+     *
+     * @param key property key
+     * @param <T> class of the value
+     * @return value of the property
+     * @throws ExtensionPropertyException if the given key is not a valid
+     * property on this extension instruction
+     */
+    <T> T getPropertyValue(String key) throws ExtensionPropertyException;
+
+    /**
+     * Gets a list of all properties on the extension instruction.
+     *
+     * @return list of properties
+     */
+    List<String> getProperties();
+
+    /**
+     * Serialize the extension instruction to a byte array.
+     *
+     * @return byte array
+     */
+    byte[] serialize();
+
+    /**
+     * Deserialize the extension instruction from a byte array. The properties
+     * of this object will be overwritten with the data in the byte array.
+     *
+     * @param data input byte array
+     */
+    void deserialize(byte[] data);
+
+
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
new file mode 100644
index 00000000..38fbc279
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.flow.instructions;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Type of extension instructions.
+ */
+@Beta
+public final class ExtensionTreatmentType {
+
+    /**
+     * A list of well-known named extension instruction type codes.
+     * These numbers have no impact on the actual OF type id.
+     */
+    public enum ExtensionTreatmentTypes {
+        // TODO fix type numbers to include experimenter id
+        NICIRA_SET_TUNNEL_DST(0),
+        NICIRA_RESUBMIT(1),
+        NICIRA_SET_NSH_SPI(32);
+
+        private ExtensionTreatmentType type;
+
+        /**
+         * Creates a new named extension instruction type.
+         *
+         * @param type type code
+         */
+        ExtensionTreatmentTypes(int type) {
+            this.type = new ExtensionTreatmentType(type);
+        }
+
+        /**
+         * Gets the extension type object for this named type code.
+         *
+         * @return extension type object
+         */
+        public ExtensionTreatmentType type() {
+            return type;
+        }
+    }
+
+    private final int type;
+
+    /**
+     * Creates an extension type with the given int type code.
+     *
+     * @param type type code
+     */
+    public ExtensionTreatmentType(int type) {
+        this.type = type;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ExtensionTreatmentType) {
+            final ExtensionTreatmentType that = (ExtensionTreatmentType) obj;
+            return this.type == that.type;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(ExtensionTreatmentType.class)
+                .add("type", type)
+                .toString();
+    }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
deleted file mode 100644
index 3e1cb75c..00000000
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 org.onosproject.net.flow.instructions;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects;
-
-import java.util.Objects;
-
-/**
- * Type of extension instructions.
- */
-@Beta
-public final class ExtensionType {
-
-    /**
-     * A list of well-known named extension instruction type codes.
-     */
-    public enum ExtensionTypes {
-        // TODO fix type numbers to include experimenter id
-        NICIRA_SET_TUNNEL_DST(31),
-        NICIRA_RESUBMIT(32);
-
-        private ExtensionType type;
-
-        /**
-         * Creates a new named extension instruction type.
-         *
-         * @param type type code
-         */
-        ExtensionTypes(int type) {
-            this.type = new ExtensionType(type);
-        }
-
-        /**
-         * Gets the extension type object for this named type code.
-         *
-         * @return extension type object
-         */
-        public ExtensionType type() {
-            return type;
-        }
-    }
-
-    private final int type;
-
-    /**
-     * Creates an extension type with the given int type code.
-     *
-     * @param type type code
-     */
-    public ExtensionType(int type) {
-        this.type = type;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(type);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof ExtensionType) {
-            final ExtensionType that = (ExtensionType) obj;
-            return this.type == that.type;
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(ExtensionType.class)
-                .add("type", type)
-                .toString();
-    }
-}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index 126e722e..4643b315 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -489,7 +489,7 @@ public final class Instructions {
      * @param deviceId device ID
      * @return extension instruction
      */
-    public static ExtensionInstructionWrapper extension(ExtensionInstruction extension,
+    public static ExtensionInstructionWrapper extension(ExtensionTreatment extension,
                                                         DeviceId deviceId) {
         checkNotNull(extension, "Extension instruction cannot be null");
         checkNotNull(deviceId, "Device ID cannot be null");
@@ -858,16 +858,16 @@ public final class Instructions {
      *  Extension instruction.
      */
     public static class ExtensionInstructionWrapper implements Instruction {
-        private final ExtensionInstruction extensionInstruction;
+        private final ExtensionTreatment extensionTreatment;
         private final DeviceId deviceId;
 
-        ExtensionInstructionWrapper(ExtensionInstruction extension, DeviceId deviceId) {
-            extensionInstruction = extension;
+        ExtensionInstructionWrapper(ExtensionTreatment extension, DeviceId deviceId) {
+            extensionTreatment = extension;
             this.deviceId = deviceId;
         }
 
-        public ExtensionInstruction extensionInstruction() {
-            return extensionInstruction;
+        public ExtensionTreatment extensionInstruction() {
+            return extensionTreatment;
         }
 
         public DeviceId deviceId() {
@@ -882,14 +882,14 @@ public final class Instructions {
         @Override
         public String toString() {
             return toStringHelper(type().toString())
-                    .add("extension", extensionInstruction)
+                    .add("extension", extensionTreatment)
                     .add("deviceId", deviceId)
                     .toString();
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(type().ordinal(), extensionInstruction, deviceId);
+            return Objects.hash(type().ordinal(), extensionTreatment, deviceId);
         }
 
         @Override
@@ -899,7 +899,7 @@ public final class Instructions {
             }
             if (obj instanceof ExtensionInstructionWrapper) {
                 ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj;
-                return Objects.equals(extensionInstruction, that.extensionInstruction)
+                return Objects.equals(extensionTreatment, that.extensionTreatment)
                         && Objects.equals(deviceId, that.deviceId);
 
             }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java
index 0abf5abe..af481805 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultForwardingObjective.java
@@ -16,6 +16,7 @@
 package org.onosproject.net.flowobjective;
 
 import com.google.common.annotations.Beta;
+
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
@@ -119,6 +120,53 @@ public final class DefaultForwardingObjective implements ForwardingObjective {
         return context;
     }
 
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(selector, flag, permanent,
+                            timeout, appId, priority, nextId,
+                            treatment, op);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof DefaultForwardingObjective)) {
+            return false;
+        }
+        final DefaultForwardingObjective other = (DefaultForwardingObjective) obj;
+        boolean nextEq = false, treatmentEq = false;
+        if (this.selector.equals(other.selector) &&
+                this.flag == other.flag &&
+                this.permanent == other.permanent &&
+                this.timeout == other.timeout &&
+                this.appId.equals(other.appId) &&
+                this.priority == other.priority &&
+                this.op == other.op) {
+            if (this.nextId != null && other.nextId != null) {
+                nextEq = this.nextId == other.nextId;
+            }
+            if (this.treatment != null && other.treatment != null) {
+                treatmentEq = this.treatment.equals(other.treatment);
+            }
+            if (nextEq && treatmentEq) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Returns a new builder.
      *
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java
index 20e89295..4701589f 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultNextObjective.java
@@ -18,6 +18,7 @@ package org.onosproject.net.flowobjective;
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 
 import java.util.Collection;
@@ -39,6 +40,7 @@ public final class DefaultNextObjective implements NextObjective {
     private final Integer id;
     private final Operation op;
     private final Optional<ObjectiveContext> context;
+    private final TrafficSelector meta;
 
     private DefaultNextObjective(Builder builder) {
         this.treatments = builder.treatments;
@@ -47,6 +49,7 @@ public final class DefaultNextObjective implements NextObjective {
         this.id = builder.id;
         this.op = builder.op;
         this.context = Optional.ofNullable(builder.context);
+        this.meta = builder.meta;
     }
 
     @Override
@@ -94,6 +97,11 @@ public final class DefaultNextObjective implements NextObjective {
         return context;
     }
 
+    @Override
+    public TrafficSelector meta() {
+        return meta;
+    }
+
     /**
      * Returns a new builder.
      *
@@ -111,6 +119,7 @@ public final class DefaultNextObjective implements NextObjective {
         private List<TrafficTreatment> treatments;
         private Operation op;
         private ObjectiveContext context;
+        private TrafficSelector meta;
 
         private final ImmutableList.Builder<TrafficTreatment> listBuilder
                 = ImmutableList.builder();
@@ -171,6 +180,12 @@ public final class DefaultNextObjective implements NextObjective {
             return this;
         }
 
+        @Override
+        public Builder setMeta(TrafficSelector meta) {
+            this.meta = meta;
+            return this;
+        }
+
         @Override
         public NextObjective add() {
             treatments = listBuilder.build();
@@ -218,5 +233,55 @@ public final class DefaultNextObjective implements NextObjective {
 
             return new DefaultNextObjective(this);
         }
+
+        @Override
+        public NextObjective addToExisting() {
+            treatments = listBuilder.build();
+            op = Operation.ADD_TO_EXISTING;
+            checkNotNull(appId, "Must supply an application id");
+            checkNotNull(id, "id cannot be null");
+            checkNotNull(type, "The type cannot be null");
+            checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
+
+            return new DefaultNextObjective(this);
+        }
+
+        @Override
+        public NextObjective removeFromExisting() {
+            treatments = listBuilder.build();
+            op = Operation.REMOVE_FROM_EXISTING;
+            checkNotNull(appId, "Must supply an application id");
+            checkNotNull(id, "id cannot be null");
+            checkNotNull(type, "The type cannot be null");
+
+            return new DefaultNextObjective(this);
+        }
+
+        @Override
+        public NextObjective addToExisting(ObjectiveContext context) {
+            treatments = listBuilder.build();
+            op = Operation.ADD_TO_EXISTING;
+            this.context = context;
+            checkNotNull(appId, "Must supply an application id");
+            checkNotNull(id, "id cannot be null");
+            checkNotNull(type, "The type cannot be null");
+            checkArgument(!treatments.isEmpty(), "Must have at least one treatment");
+
+            return new DefaultNextObjective(this);
+        }
+
+        @Override
+        public NextObjective removeFromExisting(ObjectiveContext context) {
+            treatments = listBuilder.build();
+            op = Operation.REMOVE_FROM_EXISTING;
+            this.context = context;
+            checkNotNull(appId, "Must supply an application id");
+            checkNotNull(id, "id cannot be null");
+            checkNotNull(type, "The type cannot be null");
+
+            return new DefaultNextObjective(this);
+        }
+
     }
+
 }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java
index 1350d7a1..08916eb2 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjective.java
@@ -17,6 +17,7 @@ package org.onosproject.net.flowobjective;
 
 import com.google.common.annotations.Beta;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 
 import java.util.Collection;
@@ -34,7 +35,7 @@ import java.util.Collection;
  * - Failover
  * - Simple
  *
- * These types will indicate to the driver what the intended behaviour is.
+ * These types will indicate to the driver what the intended behavior is.
  * For example, a broadcast next objective with a collection of output
  * treatments will indicate to a driver that all output actions are expected
  * to be executed simultaneously. The driver is then free to implement this
@@ -83,6 +84,16 @@ public interface NextObjective extends Objective {
      */
     Type type();
 
+    /**
+     * Auxiliary optional information provided to the device-driver.Typically
+     * conveys information about selectors (matches) that are intended to
+     * use this Next Objective.
+     *
+     * @return a selector intended to pass meta information to the device driver.
+     *         Value may be null if no meta information is provided.
+     */
+    TrafficSelector meta();
+
     /**
      * A next step builder.
      */
@@ -130,6 +141,14 @@ public interface NextObjective extends Objective {
         @Override
         Builder withPriority(int priority);
 
+        /**
+         * Set meta information related to this next objective.
+         *
+         * @param selector match conditions
+         * @return an objective builder
+         */
+        Builder setMeta(TrafficSelector selector);
+
         /**
          * Builds the next objective that will be added.
          *
@@ -162,6 +181,40 @@ public interface NextObjective extends Objective {
          */
         NextObjective remove(ObjectiveContext context);
 
+        /**
+         * Build the next objective that will be added, with {@link Operation}
+         * ADD_TO_EXISTING.
+         *
+         * @return a next objective
+         */
+        NextObjective addToExisting();
+
+        /**
+         * Build the next objective that will be removed, with {@link Operation}
+         * REMOVE_FROM_EXISTING.
+         *
+         * @return a next objective
+         */
+        NextObjective removeFromExisting();
+
+        /**
+         * Builds the next objective that will be added, with {@link Operation}
+         * ADD_TO_EXISTING. The context will be used to notify the calling application.
+         *
+         * @param context an objective context
+         * @return a next objective
+         */
+        NextObjective addToExisting(ObjectiveContext context);
+
+        /**
+         * Builds the next objective that will be removed, with {@link Operation}
+         * REMOVE_FROM_EXISTING. The context will be used to notify the calling application.
+         *
+         * @param context an objective context
+         * @return a next objective
+         */
+        NextObjective removeFromExisting(ObjectiveContext context);
+
     }
 
 }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java
index 6ac7a7a2..b1d73a7c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flowobjective/Objective.java
@@ -21,7 +21,7 @@ import org.onosproject.core.ApplicationId;
 import java.util.Optional;
 
 /**
- * Base representation of an flow description.
+ * Base representation of a flow-objective description.
  */
 @Beta
 public interface Objective {
@@ -35,14 +35,30 @@ public interface Objective {
      */
     enum Operation {
         /**
-         * Adds the objective.
+         * Adds the objective. Can be used for any flow objective. For forwarding
+         * and filtering objectives, existing objectives with identical selector
+         * and priority fields (but different treatments or next) will be replaced.
+         * For next objectives, if modification is desired, ADD will not
+         * do anything - use ADD_TO_EXISTING.
          */
         ADD,
 
         /**
-         * Removes the objective.
+         * Removes the objective. Can be used for any flow objective.
          */
-        REMOVE
+        REMOVE,
+
+        /**
+         * Add to an existing Next Objective. Should not be used for any other
+         * objective.
+         */
+        ADD_TO_EXISTING,
+
+        /**
+         * Remove from an existing Next Objective. Should not be used for any
+         * other objective.
+         */
+        REMOVE_FROM_EXISTING
     }
 
     /**
@@ -129,6 +145,7 @@ public interface Objective {
          * @return an objective builder
          */
         Builder withPriority(int priority);
+
     }
 
 }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java
index 7f00ae70..e1eacd1e 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroupKey.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
 public class DefaultGroupKey implements GroupKey {
 
     private final byte[] key;
+    protected static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
 
     public DefaultGroupKey(byte[] key) {
         this.key = checkNotNull(key);
@@ -52,4 +53,20 @@ public class DefaultGroupKey implements GroupKey {
         return Arrays.hashCode(this.key);
     }
 
+    /**
+     * Returns a hex string representation of the byte array that is used
+     * as a group key. This solution was adapted from
+     * http://stackoverflow.com/questions/9655181/
+     */
+    @Override
+    public String toString() {
+        char[] hexChars = new char[key.length * 2];
+        for (int j = 0; j < key.length; j++) {
+            int v = key[j] & 0xFF;
+            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
+            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
+        }
+        return "GroupKey:0x" + new String(hexChars);
+    }
+
 }
\ No newline at end of file
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java
index c1467241..306597b3 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java
@@ -114,6 +114,8 @@ public final class HostToHostIntent extends ConnectivityIntent {
             return this;
         }
 
+
+
         /**
          * Builds a host to host intent from the accumulated parameters.
          *
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java
index 444feee4..1b4a2600 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java
@@ -17,9 +17,9 @@ package org.onosproject.net.intent.constraint;
 
 import com.google.common.annotations.Beta;
 
+import org.onlab.util.Bandwidth;
 import org.onlab.util.DataRateUnit;
 import org.onosproject.net.Link;
-import org.onosproject.net.resource.link.BandwidthResource;
 import org.onosproject.net.resource.link.BandwidthResourceRequest;
 import org.onosproject.net.resource.link.LinkResourceService;
 import org.onosproject.net.resource.ResourceRequest;
@@ -36,14 +36,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
 @Beta
 public final class BandwidthConstraint extends BooleanConstraint {
 
-    private final BandwidthResource bandwidth;
+    private final Bandwidth bandwidth;
 
     /**
      * Creates a new bandwidth constraint.
      *
      * @param bandwidth required bandwidth
      */
-    public BandwidthConstraint(BandwidthResource bandwidth) {
+    public BandwidthConstraint(Bandwidth bandwidth) {
         this.bandwidth = checkNotNull(bandwidth, "Bandwidth cannot be null");
     }
 
@@ -55,7 +55,7 @@ public final class BandwidthConstraint extends BooleanConstraint {
      * @return  {@link BandwidthConstraint} instance with given bandwidth requirement
      */
     public static BandwidthConstraint of(double v, DataRateUnit unit) {
-        return new BandwidthConstraint(BandwidthResource.of(v, unit));
+        return new BandwidthConstraint(Bandwidth.of(v, unit));
     }
 
     // Constructor for serialization
@@ -68,7 +68,7 @@ public final class BandwidthConstraint extends BooleanConstraint {
         for (ResourceRequest request : resourceService.getAvailableResources(link)) {
             if (request.type() == ResourceType.BANDWIDTH) {
                 BandwidthResourceRequest brr = (BandwidthResourceRequest) request;
-                if (brr.bandwidth().toDouble() >= bandwidth.toDouble()) {
+                if (brr.bandwidth().toDouble() >= bandwidth.bps()) {
                     return true;
                 }
             }
@@ -81,7 +81,7 @@ public final class BandwidthConstraint extends BooleanConstraint {
      *
      * @return required bandwidth
      */
-    public BandwidthResource bandwidth() {
+    public Bandwidth bandwidth() {
         return bandwidth;
     }
 
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java
new file mode 100644
index 00000000..e8539398
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/EncapsulationConstraint.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.intent.constraint;
+
+
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Link;
+import org.onosproject.net.resource.link.LinkResourceService;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Encapsulation to manage core transportation.
+ */
+public class EncapsulationConstraint extends BooleanConstraint {
+
+    private EncapsulationType encapType;
+
+    /**
+     * Creates a new encapsulation constraint.
+     *
+     * @param encapType the encapsulation type {@link EncapsulationType}
+     */
+    public EncapsulationConstraint(EncapsulationType encapType) {
+        checkNotNull(encapType, "EncapsulationType cannot be null");
+        this.encapType = encapType;
+    }
+
+
+    @Override
+    public boolean isValid(Link link, LinkResourceService resourceService) {
+        //TODO: validate the availability of the resources for each link in the path.
+        //e.g., availability of MPLSlabels, VLANID
+
+        return true;
+    }
+
+    /**
+     * Returns the encapsulation type required by this constraint.
+     *
+     * @return encapType
+     */
+    public EncapsulationType encapType() {
+        return encapType;
+    }
+
+    @Override
+    public int hashCode() {
+        return encapType.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        final EncapsulationConstraint other = (EncapsulationConstraint) obj;
+        return this.encapType() == other.encapType();
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("encapType", encapType).toString();
+    }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java
index 7811a004..eba28984 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java
@@ -16,8 +16,8 @@
 package org.onosproject.net.intent.constraint;
 
 import com.google.common.annotations.Beta;
+import org.onosproject.net.IndexedLambda;
 import org.onosproject.net.Link;
-import org.onosproject.net.resource.link.LambdaResource;
 import org.onosproject.net.resource.link.LinkResourceService;
 import org.onosproject.net.resource.ResourceRequest;
 import org.onosproject.net.resource.ResourceType;
@@ -32,14 +32,14 @@ import static com.google.common.base.MoreObjects.toStringHelper;
 @Beta
 public class LambdaConstraint extends BooleanConstraint {
 
-    private final LambdaResource lambda;
+    private final IndexedLambda lambda;
 
     /**
      * Creates a new optical lambda constraint.
      *
      * @param lambda optional lambda to indicate a specific lambda
      */
-    public LambdaConstraint(LambdaResource lambda) {
+    public LambdaConstraint(IndexedLambda lambda) {
         this.lambda = lambda;
     }
 
@@ -63,7 +63,7 @@ public class LambdaConstraint extends BooleanConstraint {
      *
      * @return required lambda
      */
-    public LambdaResource lambda() {
+    public IndexedLambda lambda() {
         return lambda;
     }
 
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
index cdcd4072..28c429bd 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
@@ -16,8 +16,8 @@
 package org.onosproject.net.newresource;
 
 import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
 
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -26,50 +26,42 @@ import java.util.List;
 @Beta
 public interface ResourceAdminService {
     /**
-     * Registers resources as the children of the parent resource path.
+     * Registers the specified resources.
      *
-     * @param parent parent resource path under which the resource are registered
-     * @param children resources to be registered as the children of the parent
-     * @param <T> type of resources
+     * @param resources resources to be registered
      * @return true if registration is successfully done, false otherwise. Registration
      * succeeds when each resource is not registered or unallocated.
      */
-    default <T> boolean registerResources(ResourcePath parent, T... children) {
-        return registerResources(parent, Arrays.asList(children));
+    default boolean registerResources(ResourcePath... resources) {
+        return registerResources(ImmutableList.copyOf(resources));
     }
 
     /**
-     * Registers resources as the children of the parent resource path.
+     * Registers the specified resources.
      *
-     * @param parent parent resource path under which the resource are registered
-     * @param children resources to be registered as the children of the parent
-     * @param <T> type of resources
+     * @param resources resources to be registered
      * @return true if registration is successfully done, false otherwise. Registration
      * succeeds when each resource is not registered or unallocated.
      */
-    <T> boolean registerResources(ResourcePath parent, List<T> children);
+    boolean registerResources(List<ResourcePath> resources);
 
     /**
-     * Unregisters resources as the children of the parent resource path.
+     * Unregisters the specified resources.
      *
-     * @param parent parent resource path under which the resource are unregistered
-     * @param children resources to be unregistered as the children of the parent
-     * @param <T> type of resources
+     * @param resources resources to be unregistered
      * @return true if unregistration is successfully done, false otherwise. Unregistration
      * succeeds when each resource is not registered or unallocated.
      */
-    default <T> boolean unregisterResources(ResourcePath parent, T... children) {
-        return unregisterResources(parent, Arrays.asList(children));
+    default boolean unregisterResources(ResourcePath... resources) {
+        return unregisterResources(ImmutableList.copyOf(resources));
     }
 
     /**
-     * Unregisters resources as the children of the parent resource path.
+     * Unregisters the specified resources.
      *
-     * @param parent parent resource path under which the resource are unregistered
-     * @param children resources to be unregistered as the children of the parent
-     * @param <T> type of resources
+     * @param resources resources to be unregistered
      * @return true if unregistration is successfully done, false otherwise. Unregistration
      * succeeds when each resource is not registered or unallocated.
      */
-    <T> boolean unregisterResources(ResourcePath parent, List<T> children);
+    boolean unregisterResources(List<ResourcePath> resources);
 }
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
index d87682a9..c0c4e34f 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
@@ -56,6 +56,7 @@ public abstract class ResourcePath {
      * Creates an resource path which represents a discrete-type resource from the specified components.
      *
      * @param components components of the path. The order represents hierarchical structure of the resource.
+     * @return resource path instance
      */
     public static ResourcePath discrete(Object... components) {
         if (components.length == 0) {
@@ -70,6 +71,7 @@ public abstract class ResourcePath {
      *
      * @param value amount of the resource
      * @param components components of the path. The order represents hierarchical structure of the resource.
+     * @return resource path instance
      */
     public static ResourcePath continuous(double value, Object... components) {
         return new Continuous(ImmutableList.copyOf(components), value);
@@ -141,12 +143,27 @@ public abstract class ResourcePath {
         return Optional.ofNullable(parent);
     }
 
+    /**
+     * Returns a child resource path of this instance with specifying the child object.
+     * The child resource path is discrete-type.
+     *
+     * @param child child object
+     * @return a child resource path
+     */
     public ResourcePath child(Object child) {
         checkState(this instanceof Discrete);
 
         return new Discrete((Discrete) this, child);
     }
 
+    /**
+     * Returns a child resource path of this instance with specifying a child object and
+     * value. The child resource path is continuous-type.
+     *
+     * @param child child object
+     * @param value value
+     * @return a child resource path
+     */
     public ResourcePath child(Object child, double value) {
         checkState(this instanceof Discrete);
 
@@ -197,6 +214,7 @@ public abstract class ResourcePath {
      * implementation only. It is not for resource API user.
      * </p>
      */
+    @Beta
     public static final class Discrete extends ResourcePath {
         private Discrete() {
             super();
@@ -218,6 +236,7 @@ public abstract class ResourcePath {
      * Note: This class is exposed to the public, but intended to be used in the resource API
      * implementation only. It is not for resource API user.
      */
+    @Beta
     public static final class Continuous extends ResourcePath {
         // Note: value is not taken into account for equality
         private final double value;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
index b57465f2..583570f5 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
@@ -201,7 +201,7 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest {
                 return addLambdaRequest();
             } else if (constraint instanceof BandwidthConstraint) {
                 BandwidthConstraint bw = (BandwidthConstraint) constraint;
-                return addBandwidthRequest(bw.bandwidth().toDouble());
+                return addBandwidthRequest(bw.bandwidth().bps());
             }
             return this;
         }
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java
new file mode 100644
index 00000000..34b0fe7b
--- /dev/null
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/config/ConfigTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * 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 org.onosproject.net.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
+import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;
+
+/**
+ * Test of the base network config class.
+ */
+public class ConfigTest {
+
+    private static final String SUBJECT = "subject";
+    private static final String KEY = "key";
+
+    private static final String TEXT = "text";
+    private static final String LONG = "long";
+    private static final String DOUBLE = "double";
+    private static final String MAC = "mac";
+    private static final String IP = "ip";
+
+    private final ObjectMapper mapper = new ObjectMapper();
+    private final ConfigApplyDelegate delegate = new TestDelegate();
+
+    private Config<String> cfg;
+    private JsonNode json;
+
+    @Before
+    public void setUp() {
+        json = new ObjectMapper().createObjectNode()
+                .put(TEXT, "foo").put(LONG, 5).put(DOUBLE, 0.5)
+                .put(MAC, "ab:cd:ef:ca:fe:ed").put(IP, "12.34.56.78");
+        cfg = new TestConfig();
+        cfg.init(SUBJECT, KEY, json, mapper, delegate);
+    }
+
+    @Test
+    public void hasOnlyFields() {
+        assertTrue("has unexpected fields", cfg.hasOnlyFields(TEXT, LONG, DOUBLE, MAC, IP));
+        assertFalse("did not detect unexpected fields", cfg.hasOnlyFields(TEXT, LONG, DOUBLE, MAC));
+        assertTrue("is not proper text", cfg.isString(TEXT, MANDATORY));
+    }
+
+    @Test
+    public void isString() {
+        assertTrue("is not proper text", cfg.isString(TEXT, MANDATORY));
+        assertTrue("is not proper text", cfg.isString(TEXT, MANDATORY, "^f.*"));
+        assertTrue("is not proper text", cfg.isString(TEXT, OPTIONAL, "^f.*"));
+        assertTrue("is not proper text", cfg.isString(TEXT, OPTIONAL));
+        assertTrue("is not proper text", cfg.isString("none", OPTIONAL));
+        assertFalse("did not detect missing field", cfg.isString("none", MANDATORY));
+    }
+
+    @Test
+    public void isNumber() {
+        assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY));
+        assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY, 0));
+        assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY, 0, 10));
+        assertTrue("is not proper number", cfg.isNumber(LONG, MANDATORY, 5, 6));
+        assertFalse("is not in range", cfg.isNumber(LONG, MANDATORY, 6, 10));
+        assertFalse("is not in range", cfg.isNumber(LONG, MANDATORY, 4, 5));
+        assertTrue("is not proper number", cfg.isNumber(LONG, OPTIONAL, 0, 10));
+        assertTrue("is not proper number", cfg.isNumber(LONG, OPTIONAL));
+        assertTrue("is not proper number", cfg.isNumber("none", OPTIONAL));
+        assertFalse("did not detect missing field", cfg.isNumber("none", MANDATORY));
+    }
+
+    @Test
+    public void isDecimal() {
+        assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY));
+        assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY, 0.0));
+        assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY, 0.0, 1.0));
+        assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, MANDATORY, 0.5, 0.6));
+        assertFalse("is not in range", cfg.isDecimal(DOUBLE, MANDATORY, 0.6, 1.0));
+        assertFalse("is not in range", cfg.isDecimal(DOUBLE, MANDATORY, 0.4, 0.5));
+        assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, OPTIONAL, 0.0, 1.0));
+        assertTrue("is not proper decimal", cfg.isDecimal(DOUBLE, OPTIONAL));
+        assertTrue("is not proper decimal", cfg.isDecimal("none", OPTIONAL));
+        assertFalse("did not detect missing field", cfg.isDecimal("none", MANDATORY));
+    }
+
+    @Test
+    public void isMacAddress() {
+        assertTrue("is not proper mac", cfg.isMacAddress(MAC, MANDATORY));
+        assertTrue("is not proper mac", cfg.isMacAddress(MAC, OPTIONAL));
+        assertTrue("is not proper mac", cfg.isMacAddress("none", OPTIONAL));
+        assertFalse("did not detect missing field", cfg.isMacAddress("none", MANDATORY));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void badMacAddress() {
+        assertTrue("is not proper mac", cfg.isMacAddress(TEXT, MANDATORY));
+    }
+
+
+    @Test
+    public void isIpAddress() {
+        assertTrue("is not proper ip", cfg.isIpAddress(IP, MANDATORY));
+        assertTrue("is not proper ip", cfg.isIpAddress(IP, OPTIONAL));
+        assertTrue("is not proper ip", cfg.isIpAddress("none", OPTIONAL));
+        assertFalse("did not detect missing field", cfg.isMacAddress("none", MANDATORY));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void badIpAddress() {
+        assertTrue("is not proper ip", cfg.isIpAddress(TEXT, MANDATORY));
+    }
+
+
+    // TODO: Add tests for other helper methods
+
+    private class TestConfig extends Config<String> {
+    }
+
+    private class TestDelegate implements ConfigApplyDelegate {
+        @Override
+        public void onApply(Config config) {
+        }
+    }
+}
\ No newline at end of file
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
index d86744df..56a6ff63 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
@@ -42,6 +42,7 @@ import org.onosproject.net.OduSignalType;
 import org.onosproject.net.PortNumber;
 
 import com.google.common.testing.EqualsTester;
+
 /**
  * Unit tests for the Criteria class and its subclasses.
  */
@@ -135,6 +136,24 @@ public class CriteriaTest {
     Criterion sameAsMatchUdpPort1 = Criteria.matchUdpSrc(tpPort1);
     Criterion matchUdpPort2 = Criteria.matchUdpDst(tpPort2);
 
+
+    int tcpFlags1 =
+        Criterion.TCPFlags.NS.getValue() |
+        Criterion.TCPFlags.CWR.getValue() |
+        Criterion.TCPFlags.ECE.getValue() |
+        Criterion.TCPFlags.URG.getValue() |
+        Criterion.TCPFlags.ACK.getValue() |
+        Criterion.TCPFlags.PSH.getValue() |
+        Criterion.TCPFlags.RST.getValue() |
+        Criterion.TCPFlags.SYN.getValue();
+
+    int tcpFlags2 = tcpFlags1 |
+        Criterion.TCPFlags.FIN.getValue();
+
+    Criterion matchTcpFlags1 = Criteria.matchTcpFlags(tcpFlags1);
+    Criterion sameAsmatchTcpFlags1 = Criteria.matchTcpFlags(tcpFlags1);
+    Criterion matchTcpFlags2 = Criteria.matchTcpFlags(tcpFlags2);
+
     Criterion matchSctpPort1 = Criteria.matchSctpSrc(tpPort1);
     Criterion sameAsMatchSctpPort1 = Criteria.matchSctpSrc(tpPort1);
     Criterion matchSctpPort2 = Criteria.matchSctpDst(tpPort2);
@@ -174,28 +193,28 @@ public class CriteriaTest {
     private Ip6Address ip6TargetAddress1 = Ip6Address.valueOf(IPV6_ADDR1);
     private Ip6Address ip6TargetAddress2 = Ip6Address.valueOf(IPV6_ADDR2);
     Criterion matchIpv6TargetAddr1 =
-        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
+            Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
     Criterion sameAsMatchIpv6TargetAddr1 =
-        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
+            Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
     Criterion matchIpv6TargetAddr2 =
-        Criteria.matchIPv6NDTargetAddress(ip6TargetAddress2);
+            Criteria.matchIPv6NDTargetAddress(ip6TargetAddress2);
 
     private static final String LL_MAC1 = "00:00:00:00:00:01";
     private static final String LL_MAC2 = "00:00:00:00:00:02";
     private MacAddress llMac1 = MacAddress.valueOf(LL_MAC1);
     private MacAddress llMac2 = MacAddress.valueOf(LL_MAC2);
     Criterion matchSrcLlAddr1 =
-        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
+            Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
     Criterion sameAsMatchSrcLlAddr1 =
-        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
+            Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
     Criterion matchSrcLlAddr2 =
-        Criteria.matchIPv6NDSourceLinkLayerAddress(llMac2);
+            Criteria.matchIPv6NDSourceLinkLayerAddress(llMac2);
     Criterion matchTargetLlAddr1 =
-        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
+            Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
     Criterion sameAsMatchTargetLlAddr1 =
-        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
+            Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
     Criterion matchTargetLlAddr2 =
-        Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2);
+            Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2);
 
     MplsLabel mpls1 = MplsLabel.mplsLabel(1);
     MplsLabel mpls2 = MplsLabel.mplsLabel(2);
@@ -219,13 +238,13 @@ public class CriteriaTest {
         Criterion.IPv6ExthdrFlags.HOP.getValue() |
         Criterion.IPv6ExthdrFlags.UNREP.getValue();
     int ipv6ExthdrFlags2 = ipv6ExthdrFlags1 |
-        Criterion.IPv6ExthdrFlags.UNSEQ.getValue();
+            Criterion.IPv6ExthdrFlags.UNSEQ.getValue();
     Criterion matchIpv6ExthdrFlags1 =
-        Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
+            Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
     Criterion sameAsMatchIpv6ExthdrFlags1 =
-        Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
+            Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
     Criterion matchIpv6ExthdrFlags2 =
-        Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags2);
+            Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags2);
 
     Criterion matchOchSignalType1 = Criteria.matchOchSignalType(OchSignalType.FIXED_GRID);
     Criterion sameAsMatchOchSignalType1 = Criteria.matchOchSignalType(OchSignalType.FIXED_GRID);
@@ -242,8 +261,8 @@ public class CriteriaTest {
     Criterion matchOchSignal2 =
             Criteria.matchLambda(Lambda.ochSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 4, 8));
 
-    final OduSignalId odu1 = oduSignalId(1, 80, new byte [] {1, 1, 2, 2, 1, 2, 2, 1, 2, 2});
-    final OduSignalId odu2 = oduSignalId(3, 8, new byte [] {1, 0, 0, 0, 0, 0, 0, 0, 0, 0});
+    final OduSignalId odu1 = oduSignalId(1, 80, new byte[]{1, 1, 2, 2, 1, 2, 2, 1, 2, 2});
+    final OduSignalId odu2 = oduSignalId(3, 8, new byte[]{1, 0, 0, 0, 0, 0, 0, 0, 0, 0});
     Criterion matchOduSignalId1 = Criteria.matchOduSignalId(odu1);
     Criterion sameAsMatchOduSignalId1 = Criteria.matchOduSignalId(odu1);
     Criterion matchOduSignalId2 = Criteria.matchOduSignalId(odu2);
@@ -259,9 +278,9 @@ public class CriteriaTest {
      * it to the proper type.
      *
      * @param criterion Criterion object to convert
-     * @param type Enumerated type value for the Criterion class
-     * @param clazz Desired Criterion class
-     * @param <T> The type the caller wants returned
+     * @param type      Enumerated type value for the Criterion class
+     * @param clazz     Desired Criterion class
+     * @param <T>       The type the caller wants returned
      * @return converted object
      */
     @SuppressWarnings("unchecked")
@@ -297,6 +316,7 @@ public class CriteriaTest {
         assertThatClassIsImmutable(IPCriterion.class);
         assertThatClassIsImmutable(TcpPortCriterion.class);
         assertThatClassIsImmutable(UdpPortCriterion.class);
+        assertThatClassIsImmutable(TcpFlagsCriterion.class);
         assertThatClassIsImmutable(SctpPortCriterion.class);
         assertThatClassIsImmutable(IcmpTypeCriterion.class);
         assertThatClassIsImmutable(IcmpCodeCriterion.class);
@@ -395,8 +415,8 @@ public class CriteriaTest {
         Criterion matchEthDst = Criteria.matchEthDst(mac1);
         EthCriterion ethCriterion =
                 checkAndConvert(matchEthDst,
-                        Criterion.Type.ETH_DST,
-                        EthCriterion.class);
+                                Criterion.Type.ETH_DST,
+                                EthCriterion.class);
         assertThat(ethCriterion.mac(), is(equalTo(mac1)));
     }
 
@@ -461,8 +481,8 @@ public class CriteriaTest {
         Criterion matchVlanId = Criteria.matchVlanId(vlanId1);
         VlanIdCriterion vlanIdCriterion =
                 checkAndConvert(matchVlanId,
-                        Criterion.Type.VLAN_VID,
-                        VlanIdCriterion.class);
+                                Criterion.Type.VLAN_VID,
+                                VlanIdCriterion.class);
         assertThat(vlanIdCriterion.vlanId(), is(equalTo(vlanId1)));
     }
 
@@ -487,8 +507,8 @@ public class CriteriaTest {
         Criterion matchVlanPcp = Criteria.matchVlanPcp(vlanPcp1);
         VlanPcpCriterion vlanPcpCriterion =
                 checkAndConvert(matchVlanPcp,
-                        Criterion.Type.VLAN_PCP,
-                        VlanPcpCriterion.class);
+                                Criterion.Type.VLAN_PCP,
+                                VlanPcpCriterion.class);
         assertThat(vlanPcpCriterion.priority(), is(equalTo(vlanPcp1)));
     }
 
@@ -513,8 +533,8 @@ public class CriteriaTest {
         Criterion matchIPDscp = Criteria.matchIPDscp(ipDscp1);
         IPDscpCriterion ipDscpCriterion =
                 checkAndConvert(matchIPDscp,
-                        Criterion.Type.IP_DSCP,
-                        IPDscpCriterion.class);
+                                Criterion.Type.IP_DSCP,
+                                IPDscpCriterion.class);
         assertThat(ipDscpCriterion.ipDscp(), is(equalTo(ipDscp1)));
     }
 
@@ -539,8 +559,8 @@ public class CriteriaTest {
         Criterion matchIPEcn = Criteria.matchIPEcn(ipEcn1);
         IPEcnCriterion ipEcnCriterion =
                 checkAndConvert(matchIPEcn,
-                        Criterion.Type.IP_ECN,
-                        IPEcnCriterion.class);
+                                Criterion.Type.IP_ECN,
+                                IPEcnCriterion.class);
         assertThat(ipEcnCriterion.ipEcn(), is(equalTo(ipEcn1)));
     }
 
@@ -565,8 +585,8 @@ public class CriteriaTest {
         Criterion matchIPProtocol = Criteria.matchIPProtocol(protocol1);
         IPProtocolCriterion ipProtocolCriterion =
                 checkAndConvert(matchIPProtocol,
-                        Criterion.Type.IP_PROTO,
-                        IPProtocolCriterion.class);
+                                Criterion.Type.IP_PROTO,
+                                IPProtocolCriterion.class);
         assertThat(ipProtocolCriterion.protocol(), is(equalTo(protocol1)));
     }
 
@@ -604,8 +624,8 @@ public class CriteriaTest {
         Criterion matchIPDst = Criteria.matchIPDst(ip1);
         IPCriterion ipCriterion =
                 checkAndConvert(matchIPDst,
-                        Criterion.Type.IPV4_DST,
-                        IPCriterion.class);
+                                Criterion.Type.IPV4_DST,
+                                IPCriterion.class);
         assertThat(ipCriterion.ip(), is(equalTo(ip1)));
     }
 
@@ -617,8 +637,8 @@ public class CriteriaTest {
         Criterion matchIpv6Src = Criteria.matchIPv6Src(ipv61);
         IPCriterion ipCriterion =
                 checkAndConvert(matchIpv6Src,
-                        Criterion.Type.IPV6_SRC,
-                        IPCriterion.class);
+                                Criterion.Type.IPV6_SRC,
+                                IPCriterion.class);
         assertThat(ipCriterion.ip(), is(ipv61));
     }
 
@@ -630,8 +650,8 @@ public class CriteriaTest {
         Criterion matchIPv6Dst = Criteria.matchIPv6Dst(ipv61);
         IPCriterion ipCriterion =
                 checkAndConvert(matchIPv6Dst,
-                        Criterion.Type.IPV6_DST,
-                        IPCriterion.class);
+                                Criterion.Type.IPV6_DST,
+                                IPCriterion.class);
         assertThat(ipCriterion.ip(), is(equalTo(ipv61)));
     }
 
@@ -674,8 +694,8 @@ public class CriteriaTest {
         Criterion matchTcpDst = Criteria.matchTcpDst(tpPort1);
         TcpPortCriterion tcpPortCriterion =
                 checkAndConvert(matchTcpDst,
-                        Criterion.Type.TCP_DST,
-                        TcpPortCriterion.class);
+                                Criterion.Type.TCP_DST,
+                                TcpPortCriterion.class);
         assertThat(tcpPortCriterion.tcpPort(), is(equalTo(tpPort1)));
     }
 
@@ -713,8 +733,8 @@ public class CriteriaTest {
         Criterion matchUdpDst = Criteria.matchUdpDst(tpPort1);
         UdpPortCriterion udpPortCriterion =
                 checkAndConvert(matchUdpDst,
-                        Criterion.Type.UDP_DST,
-                        UdpPortCriterion.class);
+                                Criterion.Type.UDP_DST,
+                                UdpPortCriterion.class);
         assertThat(udpPortCriterion.udpPort(), is(equalTo(tpPort1)));
     }
 
@@ -729,6 +749,19 @@ public class CriteriaTest {
                 .testEquals();
     }
 
+    // TcpFlagsCriterion class
+
+    /**
+     * Test the equals() method of the TcpFlagsCriterion class.
+     */
+    @Test
+    public void testTcpFlagsCriterionEquals() {
+        new EqualsTester()
+                .addEqualityGroup(matchTcpFlags1, sameAsmatchTcpFlags1)
+                .addEqualityGroup(matchTcpFlags2)
+                .testEquals();
+    }
+
     // SctpPortCriterion class
 
     /**
@@ -752,8 +785,8 @@ public class CriteriaTest {
         Criterion matchSctpDst = Criteria.matchSctpDst(tpPort1);
         SctpPortCriterion sctpPortCriterion =
                 checkAndConvert(matchSctpDst,
-                        Criterion.Type.SCTP_DST,
-                        SctpPortCriterion.class);
+                                Criterion.Type.SCTP_DST,
+                                SctpPortCriterion.class);
         assertThat(sctpPortCriterion.sctpPort(), is(equalTo(tpPort1)));
     }
 
@@ -911,7 +944,7 @@ public class CriteriaTest {
     @Test
     public void testMatchIPv6NDTargetAddressMethod() {
         Criterion matchTargetAddress =
-            Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
+                Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
         IPv6NDTargetAddressCriterion targetAddressCriterion =
                 checkAndConvert(matchTargetAddress,
                                 Criterion.Type.IPV6_ND_TARGET,
@@ -940,11 +973,11 @@ public class CriteriaTest {
     @Test
     public void testMatchIPv6NDSourceLinkLayerAddressMethod() {
         Criterion matchSrcLlAddr =
-            Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
+                Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
         IPv6NDLinkLayerAddressCriterion srcLlCriterion =
                 checkAndConvert(matchSrcLlAddr,
-                        Criterion.Type.IPV6_ND_SLL,
-                        IPv6NDLinkLayerAddressCriterion.class);
+                                Criterion.Type.IPV6_ND_SLL,
+                                IPv6NDLinkLayerAddressCriterion.class);
         assertThat(srcLlCriterion.mac(), is(equalTo(llMac1)));
     }
 
@@ -954,11 +987,11 @@ public class CriteriaTest {
     @Test
     public void testMatchIPv6NDTargetLinkLayerAddressMethod() {
         Criterion matchTargetLlAddr =
-            Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
+                Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
         IPv6NDLinkLayerAddressCriterion targetLlCriterion =
                 checkAndConvert(matchTargetLlAddr,
-                        Criterion.Type.IPV6_ND_TLL,
-                        IPv6NDLinkLayerAddressCriterion.class);
+                                Criterion.Type.IPV6_ND_TLL,
+                                IPv6NDLinkLayerAddressCriterion.class);
         assertThat(targetLlCriterion.mac(), is(equalTo(llMac1)));
     }
 
@@ -988,8 +1021,8 @@ public class CriteriaTest {
         Criterion matchMplsLabel = Criteria.matchMplsLabel(mpls1);
         MplsCriterion mplsCriterion =
                 checkAndConvert(matchMplsLabel,
-                        Criterion.Type.MPLS_LABEL,
-                        MplsCriterion.class);
+                                Criterion.Type.MPLS_LABEL,
+                                MplsCriterion.class);
         assertThat(mplsCriterion.label(), is(equalTo(mpls1)));
     }
 
@@ -1025,10 +1058,10 @@ public class CriteriaTest {
      */
     @Test
     public void testTunnelIdCriterionEquals() {
-       new EqualsTester()
-               .addEqualityGroup(matchTunnelId1, sameAsMatchTunnelId1)
-               .addEqualityGroup(matchTunnelId2)
-               .testEquals();
+        new EqualsTester()
+                .addEqualityGroup(matchTunnelId1, sameAsMatchTunnelId1)
+                .addEqualityGroup(matchTunnelId2)
+                .testEquals();
     }
 
     // IPv6ExthdrFlagsCriterion class
@@ -1039,11 +1072,11 @@ public class CriteriaTest {
     @Test
     public void testMatchIPv6ExthdrFlagsMethod() {
         Criterion matchExthdrFlags =
-            Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
+                Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
         IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
                 checkAndConvert(matchExthdrFlags,
-                        Criterion.Type.IPV6_EXTHDR,
-                        IPv6ExthdrFlagsCriterion.class);
+                                Criterion.Type.IPV6_EXTHDR,
+                                IPv6ExthdrFlagsCriterion.class);
         assertThat(exthdrFlagsCriterion.exthdrFlags(),
                    is(equalTo(ipv6ExthdrFlags1)));
     }
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java
index 88fa7f4f..dd371c15 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/LinkCollectionIntentTest.java
@@ -22,11 +22,11 @@ import java.util.Set;
 
 import org.junit.Test;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.IndexedLambda;
 import org.onosproject.net.Link;
 import org.onosproject.net.NetTestTools;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.intent.constraint.LambdaConstraint;
-import org.onosproject.net.resource.link.LambdaResource;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.testing.EqualsTester;
@@ -132,7 +132,7 @@ public class LinkCollectionIntentTest extends IntentTest {
         final LinkedList<Constraint> constraints = new LinkedList<>();
 
         links1.add(link("src", 1, "dst", 2));
-        constraints.add(new LambdaConstraint(LambdaResource.valueOf(23)));
+        constraints.add(new LambdaConstraint(new IndexedLambda(23)));
         final LinkCollectionIntent collectionIntent =
                 LinkCollectionIntent.builder()
                         .appId(APP_ID)
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java
index 743fc252..d2e99400 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/constraint/ConstraintObjectsTest.java
@@ -17,9 +17,8 @@ package org.onosproject.net.intent.constraint;
 
 import org.junit.Test;
 import org.onlab.util.Bandwidth;
+import org.onosproject.net.IndexedLambda;
 import org.onosproject.net.Link;
-import org.onosproject.net.resource.link.BandwidthResource;
-import org.onosproject.net.resource.link.LambdaResource;
 
 import com.google.common.testing.EqualsTester;
 
@@ -39,21 +38,18 @@ public class ConstraintObjectsTest {
     private final Bandwidth sameAsBandwidth1 = Bandwidth.bps(100.0);
     private final Bandwidth bandwidth2 = Bandwidth.bps(200.0);
 
-    final BandwidthConstraint bandwidthConstraint1 =
-            new BandwidthConstraint(new BandwidthResource(bandwidth1));
-    final BandwidthConstraint bandwidthConstraintSameAs1 =
-            new BandwidthConstraint(new BandwidthResource(sameAsBandwidth1));
-    final BandwidthConstraint bandwidthConstraint2 =
-            new BandwidthConstraint(new BandwidthResource(bandwidth2));
+    final BandwidthConstraint bandwidthConstraint1 = new BandwidthConstraint(bandwidth1);
+    final BandwidthConstraint bandwidthConstraintSameAs1 = new BandwidthConstraint(sameAsBandwidth1);
+    final BandwidthConstraint bandwidthConstraint2 = new BandwidthConstraint(bandwidth2);
 
     /**
      * Checks that the objects were created properly.
      */
     @Test
     public void testBandwidthConstraintCreation() {
-        assertThat(bandwidthConstraint1.bandwidth().toDouble(), is(equalTo(100.0)));
-        assertThat(bandwidthConstraintSameAs1.bandwidth().toDouble(), is(equalTo(100.0)));
-        assertThat(bandwidthConstraint2.bandwidth().toDouble(), is(equalTo(200.0)));
+        assertThat(bandwidthConstraint1.bandwidth().bps(), is(equalTo(100.0)));
+        assertThat(bandwidthConstraintSameAs1.bandwidth().bps(), is(equalTo(100.0)));
+        assertThat(bandwidthConstraint2.bandwidth().bps(), is(equalTo(200.0)));
     }
 
     /**
@@ -70,20 +66,20 @@ public class ConstraintObjectsTest {
     // Lambda Constraint
 
     final LambdaConstraint lambdaConstraint1 =
-            new LambdaConstraint(LambdaResource.valueOf(100));
+            new LambdaConstraint(new IndexedLambda(100));
     final LambdaConstraint lambdaConstraintSameAs1 =
-            new LambdaConstraint(LambdaResource.valueOf(100));
+            new LambdaConstraint(new IndexedLambda(100));
     final LambdaConstraint lambdaConstraint2 =
-            new LambdaConstraint(LambdaResource.valueOf(200));
+            new LambdaConstraint(new IndexedLambda(200));
 
     /**
      * Checks that the objects were created properly.
      */
     @Test
     public void testLambdaConstraintCreation() {
-        assertThat(lambdaConstraint1.lambda().toInt(), is(equalTo(100)));
-        assertThat(lambdaConstraintSameAs1.lambda().toInt(), is(equalTo(100)));
-        assertThat(lambdaConstraint2.lambda().toInt(), is(equalTo(200)));
+        assertThat(lambdaConstraint1.lambda().index(), is(equalTo(100L)));
+        assertThat(lambdaConstraintSameAs1.lambda().index(), is(equalTo(100L)));
+        assertThat(lambdaConstraint2.lambda().index(), is(equalTo(200L)));
     }
 
     /**
-- 
cgit