Implement flow objective queue command

- View flow objecitve queus and caches
- Refactor flow objecitve service and remove deprecated method

Change-Id: I6bbd209a351e0d87c5ee518038b33f72dcb3058a
diff --git a/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveQueueClearCommand.java b/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveQueueClearCommand.java
new file mode 100644
index 0000000..d15ac87
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveQueueClearCommand.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.osgi.ServiceNotFoundException;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+
+/**
+ * Clear flow objective that are waiting for the completion of previous objective with the same key.
+ */
+@Command(scope = "onos", name = "obj-clear-queues",
+        description = "Force empty flow objective queues and invalidate flow objective caches")
+public class FlowObjectiveQueueClearCommand extends AbstractShellCommand {
+
+    private static final String CONFIRM_PHRASE = "please";
+    @Argument(name = "confirm", description = "Confirmation phrase")
+    private String please = null;
+
+    @Override
+    protected void execute() {
+        if (please == null || !please.equals(CONFIRM_PHRASE)) {
+            print("WARNING: System may enter an unpredictable state if the flow obj queues are force emptied." +
+                    "Enter confirmation phrase to continue.");
+            return;
+        }
+
+        try {
+            FlowObjectiveService service = get(FlowObjectiveService.class);
+            service.clearQueue();
+        } catch (ServiceNotFoundException e) {
+            print("FlowObjectiveService unavailable");
+        }
+    }
+
+}
diff --git a/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveQueueListCommand.java b/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveQueueListCommand.java
new file mode 100644
index 0000000..46f6122
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveQueueListCommand.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.cli.net;
+
+import com.google.common.collect.ListMultimap;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onlab.osgi.ServiceNotFoundException;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.flowobjective.FilteringObjQueueKey;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjQueueKey;
+import org.onosproject.net.flowobjective.NextObjQueueKey;
+import org.onosproject.net.flowobjective.Objective;
+
+import java.util.Map;
+
+/**
+ * Displays flow objective that are waiting for the completion of previous objective with the same key.
+ */
+@Command(scope = "onos", name = "obj-queues",
+        description = "Display flow objective queues")
+public class FlowObjectiveQueueListCommand extends AbstractShellCommand {
+
+    @Option(name = "-s", aliases = "--size",
+            description = "Print queue size only",
+            required = false, multiValued = false)
+    private boolean sizeOnly = false;
+
+    @Option(name = "-c", aliases = "--cache",
+            description = "Print cache",
+            required = false, multiValued = false)
+    private boolean cache = false;
+
+    @Override
+    protected void execute() {
+        try {
+            FlowObjectiveService service = get(FlowObjectiveService.class);
+            ListMultimap<FilteringObjQueueKey, Objective> filtObjQueue = service.getFilteringObjQueue();
+            ListMultimap<ForwardingObjQueueKey, Objective> fwdObjQueue = service.getForwardingObjQueue();
+            ListMultimap<NextObjQueueKey, Objective> nextObjQueue = service.getNextObjQueue();
+            Map<FilteringObjQueueKey, Objective> filtObjQueueHead = service.getFilteringObjQueueHead();
+            Map<ForwardingObjQueueKey, Objective> fwdObjQueueHead = service.getForwardingObjQueueHead();
+            Map<NextObjQueueKey, Objective> nextObjQueueHead = service.getNextObjQueueHead();
+
+            if (cache) {
+                printMap("Filtering objective cache", filtObjQueueHead, sizeOnly);
+                printMap("Forwarding objective cache", fwdObjQueueHead, sizeOnly);
+                printMap("Next objective cache", nextObjQueueHead, sizeOnly);
+            } else {
+                printMap("Filtering objective queue", filtObjQueue.asMap(), sizeOnly);
+                printMap("Forwarding objective queue", fwdObjQueue.asMap(), sizeOnly);
+                printMap("Next objective queue", nextObjQueue.asMap(), sizeOnly);
+            }
+        } catch (ServiceNotFoundException e) {
+            print("FlowObjectiveService unavailable");
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void printMap(String mapName, Map map, boolean sizeOnly) {
+        print("%s size = %d", mapName, map.size());
+        if (!sizeOnly) {
+            map.forEach((k, v) -> print("%s -> %s", k, v));
+        }
+    }
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 3fab2f9..6ca9c5a 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -53,6 +53,14 @@
         </command>
 
         <command>
+            <action class="org.onosproject.cli.net.FlowObjectiveQueueListCommand"/>
+        </command>
+
+        <command>
+            <action class="org.onosproject.cli.net.FlowObjectiveQueueClearCommand"/>
+        </command>
+
+        <command>
             <action class="org.onosproject.cli.net.FlowObjectiveCompositionCommand"/>
         </command>
 
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjQueueKey.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjQueueKey.java
new file mode 100644
index 0000000..8ec1bce3
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FilteringObjQueueKey.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.flowobjective;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.criteria.Criterion;
+
+import java.util.Objects;
+
+/**
+ * Filtering objective queue key.
+ */
+public class FilteringObjQueueKey {
+    private DeviceId deviceId;
+    private int priority;
+    private Criterion key;
+
+    public FilteringObjQueueKey(DeviceId deviceId, int priority, Criterion key) {
+        this.deviceId = deviceId;
+        this.priority = priority;
+        this.key = key;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(deviceId, priority, key);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof FilteringObjQueueKey)) {
+            return false;
+        }
+        FilteringObjQueueKey that = (FilteringObjQueueKey) other;
+        return Objects.equals(this.deviceId, that.deviceId) &&
+                Objects.equals(this.priority, that.priority) &&
+                Objects.equals(this.key, that.key);
+    }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
index cb7b1e0..103691c 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
@@ -18,7 +18,12 @@
 import com.google.common.annotations.Beta;
 
 import java.util.List;
+import java.util.Map;
 
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.NotImplementedException;
 import org.onosproject.net.DeviceId;
 
 /**
@@ -111,14 +116,48 @@
     List<String> getPendingFlowObjectives();
 
     /**
-     * Retrieve all nextObjectives that are waiting to hear back from device
-     * drivers, and the forwarding-objectives or next-objectives that are waiting
-     * on the successful completion of the original next-objectives.
+     * Returns all filtering objective that are waiting for the completion of previous objective
+     * with the same FilteringObjQueueKey.
      *
-     * @return a list of strings preformatted by the device-drivers to provide
-     *         information on next-id to group-id mapping.
+     * @return Filtering objective queue as map
      */
-    @Deprecated
-    List<String> getPendingNexts();
+    default ListMultimap<FilteringObjQueueKey, Objective> getFilteringObjQueue() {
+        return ArrayListMultimap.create();
+    }
 
+    /**
+     * Returns all forwarding objective that are waiting for the completion of previous objective
+     * with the same ForwardingObjQueueKey.
+     *
+     * @return Forwarding objective queue as map
+     */
+    default ListMultimap<ForwardingObjQueueKey, Objective> getForwardingObjQueue() {
+        return ArrayListMultimap.create();
+    }
+
+    /**
+     * Returns all next objective that are waiting for the completion of previous objective
+     * with the same NextObjQueueKey.
+     *
+     * @return Next objective queue as map
+     */
+    default ListMultimap<NextObjQueueKey, Objective> getNextObjQueue() {
+        return ArrayListMultimap.create();
+    }
+
+    default Map<FilteringObjQueueKey, Objective> getFilteringObjQueueHead() {
+        return Maps.newHashMap();
+    }
+
+    default Map<ForwardingObjQueueKey, Objective> getForwardingObjQueueHead() {
+        return Maps.newHashMap();
+    }
+
+    default Map<NextObjQueueKey, Objective> getNextObjQueueHead() {
+        return Maps.newHashMap();
+    }
+
+    default void clearQueue() {
+        throw new NotImplementedException("clearQueue is not implemented");
+    }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/ForwardingObjQueueKey.java b/core/api/src/main/java/org/onosproject/net/flowobjective/ForwardingObjQueueKey.java
new file mode 100644
index 0000000..d963d8a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/ForwardingObjQueueKey.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.flowobjective;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.TrafficSelector;
+
+import java.util.Objects;
+
+/**
+ * Forwarding objective queue key.
+ */
+public class ForwardingObjQueueKey {
+    private DeviceId deviceId;
+    private int priority;
+    private TrafficSelector selector;
+
+    public ForwardingObjQueueKey(DeviceId deviceId, int priority, TrafficSelector selector) {
+        this.deviceId = deviceId;
+        this.priority = priority;
+        this.selector = selector;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(deviceId, priority, selector);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof ForwardingObjQueueKey)) {
+            return false;
+        }
+        ForwardingObjQueueKey that = (ForwardingObjQueueKey) other;
+        return Objects.equals(this.deviceId, that.deviceId) &&
+                Objects.equals(this.priority, that.priority) &&
+                Objects.equals(this.selector, that.selector);
+    }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjQueueKey.java b/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjQueueKey.java
new file mode 100644
index 0000000..a2d9c64
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/NextObjQueueKey.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.flowobjective;
+
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+/**
+ * Next objective queue key.
+ */
+public class NextObjQueueKey {
+    private DeviceId deviceId;
+    private int id;
+
+    public NextObjQueueKey(DeviceId deviceId, int id) {
+        this.deviceId = deviceId;
+        this.id = id;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(deviceId, id);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof NextObjQueueKey)) {
+            return false;
+        }
+        NextObjQueueKey that = (NextObjQueueKey) other;
+        return Objects.equals(this.deviceId, that.deviceId) &&
+                Objects.equals(this.id, that.id);
+    }
+}
\ No newline at end of file
diff --git a/core/api/src/test/java/org/onosproject/net/flowobjective/FlowObjectiveServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/flowobjective/FlowObjectiveServiceAdapter.java
index 0b37ccd..360c1f2 100644
--- a/core/api/src/test/java/org/onosproject/net/flowobjective/FlowObjectiveServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/flowobjective/FlowObjectiveServiceAdapter.java
@@ -65,9 +65,4 @@
     public List<String> getPendingFlowObjectives() {
         return ImmutableList.of();
     }
-
-    @Override
-    public List<String> getPendingNexts() {
-        return ImmutableList.of();
-    }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
index 20e55a5..1e3b2a8 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
@@ -684,9 +684,4 @@
 
         return pendingFlowObjectives;
     }
-
-    @Override
-    public List<String> getPendingNexts() {
-        return getPendingFlowObjectives();
-    }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java
index f32bb6c..5eb3ac0 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/InOrderFlowObjectiveManager.java
@@ -29,11 +29,12 @@
 import org.onlab.util.Tools;
 import org.onlab.util.Tools.LogLevel;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flowobjective.FilteringObjQueueKey;
 import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
+import org.onosproject.net.flowobjective.ForwardingObjQueueKey;
 import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjQueueKey;
 import org.onosproject.net.flowobjective.NextObjective;
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveContext;
@@ -43,7 +44,7 @@
 import org.slf4j.LoggerFactory;
 
 import java.util.List;
-import java.util.Objects;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ScheduledExecutorService;
@@ -60,14 +61,14 @@
     // TODO Make queue timeout configurable
     static final int OBJ_TIMEOUT_MS = 5000;
 
-    private Cache<FiltObjQueueKey, Objective> filtObjQueueHead;
-    private Cache<FwdObjQueueKey, Objective> fwdObjQueueHead;
+    private Cache<FilteringObjQueueKey, Objective> filtObjQueueHead;
+    private Cache<ForwardingObjQueueKey, Objective> fwdObjQueueHead;
     private Cache<NextObjQueueKey, Objective> nextObjQueueHead;
     private ScheduledExecutorService cacheCleaner;
 
-    private ListMultimap<FiltObjQueueKey, Objective> filtObjQueue =
+    private ListMultimap<FilteringObjQueueKey, Objective> filtObjQueue =
             Multimaps.synchronizedListMultimap(ArrayListMultimap.create());
-    private ListMultimap<FwdObjQueueKey, Objective> fwdObjQueue =
+    private ListMultimap<ForwardingObjQueueKey, Objective> fwdObjQueue =
             Multimaps.synchronizedListMultimap(ArrayListMultimap.create());
     private ListMultimap<NextObjQueueKey, Objective> nextObjQueue =
             Multimaps.synchronizedListMultimap(ArrayListMultimap.create());
@@ -81,7 +82,7 @@
         // TODO Clean up duplicated code
         filtObjQueueHead = CacheBuilder.newBuilder()
                 .expireAfterWrite(OBJ_TIMEOUT_MS, TimeUnit.MILLISECONDS)
-                .removalListener((RemovalNotification<FiltObjQueueKey, Objective> notification) -> {
+                .removalListener((RemovalNotification<FilteringObjQueueKey, Objective> notification) -> {
                     Objective obj = notification.getValue();
                     switch (notification.getCause()) {
                         case EXPIRED:
@@ -97,7 +98,7 @@
                 }).build();
         fwdObjQueueHead = CacheBuilder.newBuilder()
                 .expireAfterWrite(OBJ_TIMEOUT_MS, TimeUnit.MILLISECONDS)
-                .removalListener((RemovalNotification<FwdObjQueueKey, Objective> notification) -> {
+                .removalListener((RemovalNotification<ForwardingObjQueueKey, Objective> notification) -> {
                     Objective obj = notification.getValue();
                     switch (notification.getCause()) {
                         case EXPIRED:
@@ -144,9 +145,7 @@
     @Deactivate
     protected void deactivate() {
         cacheCleaner.shutdown();
-        filtObjQueueHead.invalidateAll();
-        fwdObjQueueHead.invalidateAll();
-        nextObjQueueHead.invalidateAll();
+        clearQueue();
 
         super.deactivate();
     }
@@ -221,6 +220,51 @@
         process(deviceId, nextObjective);
     }
 
+    @Override
+    public ListMultimap<FilteringObjQueueKey, Objective> getFilteringObjQueue() {
+        return filtObjQueue;
+    }
+
+    @Override
+    public ListMultimap<ForwardingObjQueueKey, Objective> getForwardingObjQueue() {
+        return fwdObjQueue;
+    }
+
+    @Override
+    public ListMultimap<NextObjQueueKey, Objective> getNextObjQueue() {
+        return nextObjQueue;
+    }
+
+    @Override
+    public Map<FilteringObjQueueKey, Objective> getFilteringObjQueueHead() {
+        return filtObjQueueHead.asMap();
+    }
+
+    @Override
+    public Map<ForwardingObjQueueKey, Objective> getForwardingObjQueueHead() {
+        return fwdObjQueueHead.asMap();
+    }
+
+    @Override
+    public Map<NextObjQueueKey, Objective> getNextObjQueueHead() {
+        return nextObjQueueHead.asMap();
+    }
+
+    @Override
+    public void clearQueue() {
+        filtObjQueueHead.invalidateAll();
+        fwdObjQueueHead.invalidateAll();
+        nextObjQueueHead.invalidateAll();
+
+        filtObjQueueHead.cleanUp();
+        fwdObjQueueHead.cleanUp();
+        nextObjQueueHead.cleanUp();
+
+        filtObjQueue.clear();
+        fwdObjQueue.clear();
+        nextObjQueue.clear();
+    }
+
     /**
      * Enqueue flow objective. Execute the flow objective if there is no pending objective ahead.
      *
@@ -235,11 +279,12 @@
         Tools.log(log, logLevel, "Enqueue {}", obj);
 
         if (obj instanceof FilteringObjective) {
-            FiltObjQueueKey k = new FiltObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
+            FilteringObjQueueKey k = new FilteringObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
             filtObjQueue.put(k, obj);
             queueSize = filtObjQueue.get(k).size();
         } else if (obj instanceof ForwardingObjective) {
-            FwdObjQueueKey k = new FwdObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
+            ForwardingObjQueueKey k =
+                    new ForwardingObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
             fwdObjQueue.put(k, obj);
             queueSize = fwdObjQueue.get(k).size();
         } else if (obj instanceof NextObjective) {
@@ -272,12 +317,13 @@
         Tools.log(log, logLevel, "Dequeue {}", obj);
 
         if (obj instanceof FilteringObjective) {
-            FiltObjQueueKey k = new FiltObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
+            FilteringObjQueueKey k = new FilteringObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
             filtObjQueueHead.invalidate(k);
             filtObjQueue.remove(k, obj);
             remaining = filtObjQueue.get(k);
         } else if (obj instanceof ForwardingObjective) {
-            FwdObjQueueKey k = new FwdObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
+            ForwardingObjQueueKey k =
+                    new ForwardingObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
             fwdObjQueueHead.invalidate(k);
             fwdObjQueue.remove(k, obj);
             remaining = fwdObjQueue.get(k);
@@ -311,11 +357,12 @@
 
         int priority = obj.priority();
         if (obj instanceof FilteringObjective) {
-            FiltObjQueueKey k = new FiltObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
+            FilteringObjQueueKey k = new FilteringObjQueueKey(deviceId, priority, ((FilteringObjective) obj).key());
             filtObjQueueHead.put(k, obj);
             super.filter(deviceId, (FilteringObjective) obj);
         } else if (obj instanceof ForwardingObjective) {
-            FwdObjQueueKey k = new FwdObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
+            ForwardingObjQueueKey k =
+                    new ForwardingObjQueueKey(deviceId, priority, ((ForwardingObjective) obj).selector());
             fwdObjQueueHead.put(k, obj);
             super.forward(deviceId, (ForwardingObjective) obj);
         } else if (obj instanceof NextObjective) {
@@ -368,94 +415,4 @@
             }
         }
     }
-
-    private static class FiltObjQueueKey {
-        private DeviceId deviceId;
-        private int priority;
-        private Criterion key;
-
-        FiltObjQueueKey(DeviceId deviceId, int priority, Criterion key) {
-            this.deviceId = deviceId;
-            this.priority = priority;
-            this.key = key;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(deviceId, priority, key);
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (!(other instanceof FiltObjQueueKey)) {
-                return false;
-            }
-            FiltObjQueueKey that = (FiltObjQueueKey) other;
-            return Objects.equals(this.deviceId, that.deviceId) &&
-                    Objects.equals(this.priority, that.priority) &&
-                    Objects.equals(this.key, that.key);
-        }
-    }
-
-    private static class FwdObjQueueKey {
-        private DeviceId deviceId;
-        private int priority;
-        private TrafficSelector selector;
-
-        FwdObjQueueKey(DeviceId deviceId, int priority, TrafficSelector selector) {
-            this.deviceId = deviceId;
-            this.priority = priority;
-            this.selector = selector;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(deviceId, priority, selector);
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (!(other instanceof FwdObjQueueKey)) {
-                return false;
-            }
-            FwdObjQueueKey that = (FwdObjQueueKey) other;
-            return Objects.equals(this.deviceId, that.deviceId) &&
-                    Objects.equals(this.priority, that.priority) &&
-                    Objects.equals(this.selector, that.selector);
-        }
-    }
-
-    private static class NextObjQueueKey {
-        private DeviceId deviceId;
-        private int id;
-
-        NextObjQueueKey(DeviceId deviceId, int id) {
-            this.deviceId = deviceId;
-            this.id = id;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(deviceId, id);
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (this == other) {
-                return true;
-            }
-            if (!(other instanceof NextObjQueueKey)) {
-                return false;
-            }
-            NextObjQueueKey that = (NextObjQueueKey) other;
-            return Objects.equals(this.deviceId, that.deviceId) &&
-                    Objects.equals(this.id, that.id);
-        }
-    }
 }
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
index a765648..21f8ddc 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
@@ -436,9 +436,4 @@
         // TODO Implementation deferred as this is an experimental component.
         return ImmutableList.of();
     }
-
-    @Override
-    public List<String> getPendingNexts() {
-        return ImmutableList.of();
-    }
 }
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManager.java
index 2a5bc26..84ce3eb 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkFlowObjectiveManager.java
@@ -241,11 +241,6 @@
         return pendingFlowObjectives;
     }
 
-    @Override
-    public List<String> getPendingNexts() {
-        return getPendingFlowObjectives();
-    }
-
     private boolean queueFwdObjective(DeviceId deviceId, ForwardingObjective fwd) {
         boolean queued = false;
         synchronized (pendingForwards) {