reinstating the key field in FilterObjectives

Change-Id: I25f7d105edd562785cb213f747e7d9e0650f2635
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index 5164e45..29bb2f7 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -375,6 +375,10 @@
         return new OpticalSignalTypeCriterion(sigType, Type.OCH_SIGTYPE);
     }
 
+    public static Criterion dummy() {
+        return new DummyCriterion();
+    }
+
     /**
      * Implementation of input port criterion.
      */
@@ -1729,4 +1733,15 @@
             return false;
         }
     }
+
+    /**
+     * Dummy Criterion used with @see{FilteringObjective}.
+     */
+    private static class DummyCriterion implements Criterion {
+
+        @Override
+        public Type type() {
+            return Type.DUMMY;
+        }
+    }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
index 25764d4..b42376d 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
@@ -124,7 +124,12 @@
         /** Optical channel signal ID (lambda). */
         OCH_SIGID,
         /** Optical channel signal type (fixed or flexible). */
-        OCH_SIGTYPE
+        OCH_SIGTYPE,
+
+        /**
+         * An empty criterion.
+         */
+        DUMMY
     }
 
     /**
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java b/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
index da92b80..33b8f5a 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/DefaultFilteringObjective.java
@@ -17,6 +17,7 @@
 
 import com.google.common.collect.ImmutableList;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
 
 import java.util.Collection;
@@ -37,13 +38,15 @@
     private final int timeout;
     private final ApplicationId appId;
     private final int priority;
+    private final Criterion key;
     private final List<Criterion> conditions;
     private final int id;
     private final Operation op;
 
     private DefaultFilteringObjective(Type type, boolean permanent, int timeout,
-                                      ApplicationId appId, int priority,
+                                      ApplicationId appId, int priority, Criterion key,
                                       List<Criterion> conditions, Operation op) {
+        this.key = key;
         this.type = type;
         this.permanent = permanent;
         this.timeout = timeout;
@@ -52,11 +55,16 @@
         this.conditions = conditions;
         this.op = op;
 
-        this.id = Objects.hash(type, conditions, permanent,
+        this.id = Objects.hash(type, key, conditions, permanent,
                                timeout, appId, priority);
     }
 
     @Override
+    public Criterion key() {
+        return key;
+    }
+
+    @Override
     public Type type() {
         return this.type;
     }
@@ -115,6 +123,13 @@
         private int timeout = DEFAULT_TIMEOUT;
         private ApplicationId appId;
         private int priority = DEFAULT_PRIORITY;
+        private Criterion key = Criteria.dummy();
+
+        @Override
+        public Builder withKey(Criterion key) {
+            this.key = key;
+            return this;
+        }
 
         @Override
         public Builder addCondition(Criterion criterion) {
@@ -167,7 +182,7 @@
             checkNotNull(appId, "Must supply an application id");
 
             return new DefaultFilteringObjective(type, permanent, timeout,
-                                                appId, priority, conditions,
+                                                appId, priority, key, conditions,
                                                 Operation.ADD);
 
         }
@@ -179,8 +194,9 @@
             checkArgument(!conditions.isEmpty(), "Must have at least one condition.");
             checkNotNull(appId, "Must supply an application id");
 
+
             return new DefaultFilteringObjective(type, permanent, timeout,
-                                                 appId, priority, conditions,
+                                                 appId, priority, key, conditions,
                                                  Operation.REMOVE);
 
         }
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
index 24ca2dc..d892a97 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjective.java
@@ -41,6 +41,13 @@
     }
 
     /**
+     * Obtain the key for this filter.
+     *
+     * @return a criterion
+     */
+    public Criterion key();
+
+    /**
      * Obtain this filtering type.
      * @return the type
      */
@@ -59,6 +66,14 @@
     public interface Builder extends Objective.Builder {
 
         /**
+         * Specify the key for the filter.
+         *
+         * @param key a criterion
+         * @return a filter objective builder
+         */
+        public Builder withKey(Criterion key);
+
+        /**
          * Add a filtering condition.
          *
          * @param criterion new criterion