diff --git a/utils/misc/src/main/java/org/onlab/graph/KShortestPathsSearch.java b/utils/misc/src/main/java/org/onlab/graph/KShortestPathsSearch.java
new file mode 100644
index 0000000..1c4d9aa
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/KShortestPathsSearch.java
@@ -0,0 +1,194 @@
+/*
+ * 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.onlab.graph;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Runs K shortest paths algorithm on a provided directed graph.  Returns results in the form of an
+ * InnerOrderedResult so iteration through the returned paths will return paths in ascending order according to the
+ * provided EdgeWeight.
+ */
+public class KShortestPathsSearch<V extends Vertex, E extends Edge<V>> extends AbstractGraphPathSearch<V, E> {
+
+    private final Logger log = getLogger(getClass());
+
+    @Override
+    public Result<V, E> search(Graph<V, E> graph, V src, V dst, EdgeWeight<V, E> weight, int maxPaths) {
+        checkNotNull(src);
+        checkNotNull(dst);
+        //The modified edge weight removes any need to modify the original graph
+        InnerEdgeWeighter modifiedWeighter = new InnerEdgeWeighter(checkNotNull(weight));
+        checkArgument(maxPaths > 0);
+        Graph<V, E> originalGraph = checkNotNull(graph);
+        //the result contains the set of eventual results
+        InnerOrderedResult result = new InnerOrderedResult(src, dst, maxPaths);
+        ArrayList<Path<V, E>> resultPaths = new ArrayList<>(maxPaths);
+        ArrayList<Path<V, E>> potentialPaths = Lists.newArrayList();
+
+        DijkstraGraphSearch<V, E> dijkstraSearch = new DijkstraGraphSearch<>();
+        Set<Path<V, E>> dijkstraResults = dijkstraSearch.search(originalGraph, src, dst, modifiedWeighter, 1).paths();
+        //Checks if the dst was reachable
+        if (dijkstraResults.size() == 0) {
+            log.warn("No path was found.");
+            return result;
+        }
+        //If it was reachable adds the first shortest path to the set of results
+        resultPaths.add(dijkstraResults.iterator().next());
+
+        for (int k = 1; k < maxPaths; k++) {
+
+            for (int i = 0; i < (resultPaths.get(k - 1).edges().size() - 1); i++) {
+                V spurNode = resultPaths.get(k - 1).edges().get(i).src();
+                List<E> rootPathEdgeList = resultPaths.get(k - 1).edges().subList(0, i);
+
+                for (Path<V, E> path : resultPaths) {
+                    if (edgeListsAreEqual(rootPathEdgeList, path.edges().subList(0, i))) {
+                        modifiedWeighter.removedEdges.add(path.edges().get(i));
+                    }
+                }
+
+                //Effectively remove all nodes from the source path
+                for (E edge : rootPathEdgeList) {
+                    originalGraph.getEdgesFrom(edge.src()).forEach(e -> modifiedWeighter.removedEdges.add(e));
+                    originalGraph.getEdgesTo(edge.src()).forEach(e -> modifiedWeighter.removedEdges.add(e));
+                }
+
+                dijkstraResults = dijkstraSearch.search(originalGraph, spurNode, dst, modifiedWeighter, 1).paths();
+                if (dijkstraResults.size() != 0) {
+                    Path<V, E> spurPath = dijkstraResults.iterator().next();
+                    List<E> totalPath = new ArrayList<>(rootPathEdgeList);
+                    spurPath.edges().forEach(e -> totalPath.add(e));
+                    //The following line must use the original weighter not the modified weighter because the modified
+                    //weighter will count -1 values used for modifying the graph and return an inaccurate cost.
+                    potentialPaths.add(new DefaultPath<V, E>(totalPath,
+                                                             calculatePathCost(weight, totalPath)));
+                }
+
+                //Restore all removed paths and nodes
+                modifiedWeighter.removedEdges.clear();
+            }
+            if (potentialPaths.isEmpty()) {
+                break;
+            }
+            potentialPaths.sort(new InnerPathComparator());
+            resultPaths.add(potentialPaths.get(0));
+            potentialPaths.remove(0);
+        }
+        result.pathSet.addAll(resultPaths);
+
+        return result;
+    }
+    //Edge list equality is judges by shared endpoints, and shared endpoints should be the same
+    private boolean edgeListsAreEqual(List<E> edgeListOne, List<E> edgeListTwo) {
+        if (edgeListOne.size() != edgeListTwo.size()) {
+            return false;
+        }
+        E edgeOne;
+        E edgeTwo;
+        for (int i = 0; i < edgeListOne.size(); i++) {
+            edgeOne = edgeListOne.get(i);
+            edgeTwo = edgeListTwo.get(i);
+            if (!edgeOne.equals(edgeTwo)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private Double calculatePathCost(EdgeWeight<V, E> weighter, List<E> edges) {
+        Double totalCost = 0.0;
+        for (E edge : edges) {
+            totalCost += weighter.weight(edge);
+        }
+        return totalCost;
+    }
+
+    /**
+     * Weights edges to make them inaccessible if set, otherwise returns the result of the original EdgeWeight.
+     */
+    private class InnerEdgeWeighter implements EdgeWeight<V, E> {
+
+        private Set<E> removedEdges = Sets.newConcurrentHashSet();
+        private EdgeWeight<V, E> innerEdgeWeight;
+
+        public InnerEdgeWeighter(EdgeWeight<V, E> weight) {
+            this.innerEdgeWeight = weight;
+        }
+
+        @Override
+        public double weight(E edge) {
+            if (removedEdges.contains(edge)) {
+                //THIS RELIES ON THE LOCAL DIJKSTRA ALGORITHM AVOIDING NEGATIVES
+                return -1;
+            } else {
+                return innerEdgeWeight.weight(edge);
+            }
+        }
+    }
+
+    /**
+     * A result modified to return paths ordered according to the provided comparator.
+     */
+    protected class InnerOrderedResult extends DefaultResult {
+
+        private TreeSet<Path<V, E>> pathSet = new TreeSet<>(new InnerPathComparator());
+
+        public InnerOrderedResult(V src, V dst) {
+            super(src, dst);
+        }
+
+        public InnerOrderedResult(V src, V dst, int maxPaths) {
+            super(src, dst, maxPaths);
+        }
+
+        @Override
+        public Set<Path<V, E>> paths() {
+            return ImmutableSet.copyOf(pathSet);
+        }
+    }
+
+    /**
+     * Provides a comparator to order the set of paths.
+     */
+    private class InnerPathComparator implements Comparator<Path<V, E>> {
+
+        @Override
+        public int compare(Path<V, E> pathOne, Path<V, E> pathTwo) {
+            int comparisonValue = Double.compare(pathOne.cost(), pathTwo.cost());
+            if  (comparisonValue != 0) {
+                return comparisonValue;
+            } else if (edgeListsAreEqual(pathOne.edges(), pathTwo.edges())) {
+                return 0;
+            } else {
+                return 1;
+            }
+        }
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java b/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java
deleted file mode 100644
index 820e912..0000000
--- a/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * 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.onlab.graph;
-
-import java.util.ArrayList;
-//import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-//import java.util.Map;
-//import java.util.PriorityQueue;
-import java.util.Set;
-
-import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
-
-/**
- * K-shortest-path graph search algorithm capable of finding not just one,
- * but K shortest paths with ascending order between the source and destinations.
- */
-
-public class KshortestPathSearch<V extends Vertex, E extends Edge<V>> {
-
-    // Define class variables.
-    private Graph<V, E> immutableGraph;
-    private MutableGraph<V, E> mutableGraph;
-    private List<List<E>> pathResults = new ArrayList<List<E>>();
-    private List<List<E>> pathCandidates = new ArrayList<List<E>>();
-    private V source;
-    private V sink;
-    private int numK = 0;
-    private EdgeWeight<V, E> weight =  null;
-    // private PriorityQueue<List<E>> pathCandidates = new PriorityQueue<List<E>>();
-
-    // Initialize the graph.
-    public KshortestPathSearch(Graph<V, E> graph) {
-        immutableGraph = graph;
-        mutableGraph = new MutableAdjacencyListsGraph<>(graph.getVertexes(),
-                graph.getEdges());
-    }
-
-    public List<List<E>> search(V src,
-            V dst,
-            EdgeWeight<V, E> wei,
-            int k) {
-
-        weight = wei;
-        source = src;
-        sink = dst;
-        numK = k;
-        // pathCandidates = new PriorityQueue<List<E>>();
-
-        pathResults.clear();
-        pathCandidates.clear();
-
-        // Double check the parameters
-        checkArguments(immutableGraph, src, dst, numK);
-
-        // DefaultResult result = new DefaultResult(src, dst);
-
-        searchKShortestPaths();
-
-        return pathResults;
-    }
-
-    private void checkArguments(Graph<V, E> graph, V src, V dst, int k) {
-            if (graph == null) {
-                throw new NullPointerException("graph is null");
-            }
-            if (!graph.getVertexes().contains(src)) {
-                throw new NullPointerException("source node does not exist");
-            }
-            if (!graph.getVertexes().contains(dst)) {
-                throw new NullPointerException("target node does not exist");
-            }
-            if (k <= 0) {
-                throw new NullPointerException("K is negative or 0");
-            }
-            if (weight == null) {
-                throw new NullPointerException("the cost matrix is null");
-            }
-    }
-
-    private void searchKShortestPaths() {
-            // Step 1: find the shortest path.
-            List<E> shortestPath = searchShortestPath(immutableGraph, source, sink);
-            // no path exists, exit.
-            if (shortestPath == null) {
-                return;
-            }
-
-            // Step 2: update the results.
-            pathResults.add(shortestPath);
-            // pathCandidates.add(shortestPath);
-
-            // Step 3: find the other K-1 paths.
-            while (/*pathCandidates.size() > 0 &&*/pathResults.size() < numK) {
-                // 3.1 the spur node ranges from the first node to the last node in the previous k-shortest path.
-                List<E> lastPath = pathResults.get(pathResults.size() - 1);
-                for (int i = 0; i < lastPath.size(); i++) {
-                    // 3.1.1 convert the graph into mutable.
-                    convertGraph();
-                    // 3.1.2 transform the graph.
-                    List<E> rootPath = createSpurNode(lastPath, i);
-                    transformGraph(rootPath);
-                    // 3.1.3 find the deviation node.
-                    V devNode;
-                    devNode = getDevNode(rootPath);
-                    List<E> spurPath;
-                    // 3.1.4 find the shortest path in the transformed graph.
-                    spurPath = searchShortestPath(mutableGraph, devNode, sink);
-                    // 3.1.5 update the path candidates.
-                    if (spurPath != null) {
-                        // totalPath = rootPath + spurPath;
-                        rootPath.addAll(spurPath);
-                        pathCandidates.add(rootPath);
-                    }
-                }
-                // 3.2 if there is no spur path, exit.
-                if (pathCandidates.size() == 0) {
-                    break;
-                }
-                 // 3.3 add the path into the results.
-                addPathResult();
-            }
-        }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    private List<E> searchShortestPath(Graph<V, E> graph, V src, V dst) {
-        // Determine the shortest path from the source to the destination by using the Dijkstra algorithm.
-        DijkstraGraphSearch dijkstraAlg = new DijkstraGraphSearch();
-        Set<Path> paths =  dijkstraAlg.search(graph, src, dst, weight, ALL_PATHS).paths();
-        Iterator<Path> itr = paths.iterator();
-        if (!itr.hasNext()) {
-            return null;
-        }
-        // return the first shortest path only.
-        return (List<E>) itr.next().edges();
-    }
-
-    private void convertGraph() {
-        // clear the mutableGraph first
-        if (mutableGraph != null) {
-            ((MutableAdjacencyListsGraph) mutableGraph).clear();
-        }
-
-        // create a immutableGraph
-        Set<E> copyEa = immutableGraph.getEdges();
-        Set<V> copyVa = immutableGraph.getVertexes();
-        for (V vertex : copyVa) {
-            mutableGraph.addVertex(vertex);
-            }
-        for (E edge : copyEa) {
-            mutableGraph.addEdge(edge);
-            }
-    }
-
-    private V getDevNode(List<E> path) {
-            V srcA;
-            V dstB;
-
-            if (path.size() == 0) {
-                return source;
-            }
-
-            E temp1 = path.get(path.size() - 1);
-            srcA = temp1.src();
-            dstB = temp1.dst();
-
-            if (path.size() == 1) {
-                if (srcA.equals(source)) {
-                    return dstB;
-                } else {
-                    return srcA;
-                }
-            } else {
-                E temp2 = path.get(path.size() - 2);
-                if (srcA.equals(temp2.src()) || srcA.equals(temp2.dst())) {
-                    return dstB;
-                } else {
-                    return srcA;
-                }
-            }
-          }
-
-     private List<E> createSpurNode(List<E> path, int n) {
-            List<E> root = new ArrayList<E>();
-
-            for (int i = 0; i < n; i++) {
-                root.add(path.get(i));
-            }
-            return root;
-        }
-
-        private void transformGraph(List<E> rootPath) {
-            List<E> prePath;
-            //remove edges
-            for (int i = 0; i < pathResults.size(); i++) {
-                prePath = pathResults.get(i);
-                if (prePath.size() == 1) {
-                    mutableGraph.removeEdge(prePath.get(0));
-                } else if (comparePath(rootPath, prePath)) {
-                    for (int j = 0; j <= rootPath.size(); j++) {
-                        mutableGraph.removeEdge(prePath.get(j));
-                    }
-                }
-            }
-            for (int i = 0; i < pathCandidates.size(); i++) {
-                prePath = pathCandidates.get(i);
-                if (prePath.size() == 1) {
-                    mutableGraph.removeEdge(prePath.get(0));
-                } else if (comparePath(rootPath, prePath)) {
-                    for (int j = 0; j <= rootPath.size(); j++) {
-                        mutableGraph.removeEdge(prePath.get(j));
-                    }
-                }
-            }
-
-            if (rootPath.size() == 0) {
-                return;
-            }
-
-            //remove nodes
-            List<V> nodes = new ArrayList<V>();
-            nodes.add(source);
-            V pre = source;
-            V srcA;
-            V dstB;
-            for (int i = 0; i < rootPath.size() - 1; i++) {
-                E temp = rootPath.get(i);
-                srcA = temp.src();
-                dstB = temp.dst();
-
-                if (srcA.equals(pre)) {
-                    nodes.add(dstB);
-                    pre = dstB;
-                } else {
-                    nodes.add(srcA);
-                    pre = srcA;
-                }
-            }
-            for (int i = 0; i < nodes.size(); i++) {
-                mutableGraph.removeVertex(nodes.get(i));
-            }
-        }
-
-        private boolean comparePath(List<E> path1, List<E> path2) {
-            if (path1.size() > path2.size()) {
-                return false;
-            }
-            if (path1.size() == 0) {
-                return true;
-            }
-            for (int i = 0; i < path1.size(); i++) {
-                if (path1.get(i) != path2.get(i)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private void addPathResult() {
-            List<E> sp;
-            sp = pathCandidates.get(0);
-            for (int i = 1; i < pathCandidates.size(); i++) {
-                if (sp.size() > pathCandidates.get(i).size()) {
-                    sp = pathCandidates.get(i);
-                }
-            }
-            pathResults.add(sp);
-            // Log.info(sp.toString());
-            pathCandidates.remove(sp);
-        }
-
-}
diff --git a/utils/misc/src/test/java/org/onlab/graph/KShortestPathsSearchTest.java b/utils/misc/src/test/java/org/onlab/graph/KShortestPathsSearchTest.java
new file mode 100644
index 0000000..b27a5de
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/graph/KShortestPathsSearchTest.java
@@ -0,0 +1,144 @@
+package org.onlab.graph;
+
+import com.google.common.collect.Lists;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Class for test KshortestPathsSearch.
+ */
+public class KShortestPathsSearchTest<V extends Vertex, E extends Edge<V>> extends GraphTest {
+    private KShortestPathsSearch<TestVertex, TestEdge> kShortestPathsSearch = new KShortestPathsSearch<>();
+    private GraphPathSearch.Result<TestVertex, TestEdge> result;
+
+    @Before
+    public void setUp() {
+        graph = new AdjacencyListsGraph<>(vertexes(), edges());
+    }
+    @Test
+    public void noPath() {
+        graph = new AdjacencyListsGraph<>(of(A, B, C, D),
+                                          of(new TestEdge(A, B, 1),
+                                             new TestEdge(B, A, 1),
+                                             new TestEdge(C, D, 1),
+                                             new TestEdge(D, C, 1)));
+        KShortestPathsSearch<TestVertex, TestEdge> kShortestPathsSearch = new KShortestPathsSearch<>();
+        GraphPathSearch.Result<TestVertex, TestEdge> result = kShortestPathsSearch.search(graph, A, D, weight, 1);
+        Set<Path<TestVertex, TestEdge>> resultPathSet = result.paths();
+        assertTrue("There should not be any paths.", resultPathSet.isEmpty());
+    }
+
+    @Test
+    public void testSinglePath() {
+        //Tests that there is only a single path possible between A and B
+        graph = new AdjacencyListsGraph<>(vertexes(), edges());
+        this.result = kShortestPathsSearch.search(graph, A, B, weight, 2);
+        Iterator<Path<TestVertex, TestEdge>> itr = result.paths().iterator();
+        assertEquals("incorrect paths count", 1, result.paths().size());
+        List<TestEdge> correctEdgeList = Lists.newArrayList();
+        correctEdgeList.add(new TestEdge(A, B, 1));
+        assertTrue("That wrong path was returned.",
+                   edgeListsAreEqual(correctEdgeList, result.paths().iterator().next().edges()));
+    }
+
+    @Test
+    public void testTwoPath() {
+        //Tests that there are only two paths between A and C and that they are returned in the correct order
+        result = kShortestPathsSearch.search(graph, A, C, weight, 3);
+        assertTrue("There are an unexpected number of paths.", result.paths().size() == 2);
+        Iterator<Path<TestVertex, TestEdge>> edgeListIterator = result.paths().iterator();
+        List<TestEdge> correctEdgeList = Lists.newArrayList();
+        correctEdgeList.add(new TestEdge(A, B, 1));
+        correctEdgeList.add(new TestEdge(B, C, 1));
+        assertTrue("The first path from A to C was incorrect.",
+                   edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
+        correctEdgeList.clear();
+        correctEdgeList.add(new TestEdge(A, C, 3));
+        assertTrue("The second path from A to C was incorrect.",
+                   edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
+    }
+
+    @Test
+    public void testFourPath() {
+        //Tests that there are only four paths between A and E and that they are returned in the correct order
+        //Also tests the special case where some correct solutions are equal
+        result = kShortestPathsSearch.search(graph, A, E, weight, 5);
+        assertTrue("There are an unexpected number of paths.", result.paths().size() == 4);
+        Iterator<Path<TestVertex, TestEdge>> edgeListIterator = result.paths().iterator();
+        List<TestEdge> correctEdgeList = Lists.newArrayList();
+        correctEdgeList.add(new TestEdge(A, B, 1));
+        correctEdgeList.add(new TestEdge(B, C, 1));
+        correctEdgeList.add(new TestEdge(C, E, 1));
+        assertTrue("The first path from A to E was incorrect.",
+                   edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
+        correctEdgeList.clear();
+        //There are two paths of equal length that should hold positions two and three
+        List<TestEdge> alternateCorrectEdgeList = Lists.newArrayList();
+        correctEdgeList.add(new TestEdge(A, C, 3));
+        correctEdgeList.add(new TestEdge(C, E, 1));
+        alternateCorrectEdgeList.add(new TestEdge(A, B, 1));
+        alternateCorrectEdgeList.add(new TestEdge(B, D, 2));
+        alternateCorrectEdgeList.add(new TestEdge(D, E, 1));
+        List<TestEdge> candidateOne = edgeListIterator.next().edges();
+        List<TestEdge> candidateTwo = edgeListIterator.next().edges();
+        if (candidateOne.size() == 2) {
+            assertTrue("The second path from A to E was incorrect.",
+                       edgeListsAreEqual(candidateOne, correctEdgeList));
+            assertTrue("The third path from A to E was incorrect.",
+                       edgeListsAreEqual(candidateTwo, alternateCorrectEdgeList));
+        } else {
+            assertTrue("The second path from A to E was incorrect.",
+                       edgeListsAreEqual(candidateOne, alternateCorrectEdgeList));
+            assertTrue("The third path from A to E was incorrect.",
+                       edgeListsAreEqual(candidateTwo, correctEdgeList));
+        }
+        correctEdgeList.clear();
+        correctEdgeList.add(new TestEdge(A, B, 1));
+        correctEdgeList.add(new TestEdge(B, E, 4));
+        assertTrue("The fourth path rom A to E was incorrect",
+                   edgeListsAreEqual(edgeListIterator.next().edges(), correctEdgeList));
+
+    }
+
+    @Test
+    public void testPathsFromSink() {
+        //H is a sink in this topology, insure there are no paths from it to any other location
+        for (TestVertex vertex : vertexes()) {
+            assertTrue("There should be no paths from vertex H to any other node.",
+                       kShortestPathsSearch.search(graph, H, vertex, weight, 1).paths().size() == 0);
+        }
+    }
+
+    @Test
+    public void testLimitPathSetSize() {
+        //Checks to make sure that no more than K paths are returned
+        result = kShortestPathsSearch.search(graph, A, E, weight, 3);
+        assertTrue("There are an unexpected number of paths.", result.paths().size() == 3);
+        result = kShortestPathsSearch.search(graph, A, G, weight, 1);
+        assertTrue("There are an unexpected number of paths.", result.paths().size() == 1);
+    }
+
+    private boolean edgeListsAreEqual(List<TestEdge> edgeListOne, List<TestEdge> edgeListTwo) {
+        if (edgeListOne.size() != edgeListTwo.size()) {
+            return false;
+        }
+        TestEdge edgeOne;
+        TestEdge edgeTwo;
+        for (int i = 0; i < edgeListOne.size(); i++) {
+            edgeOne = edgeListOne.get(i);
+            edgeTwo = edgeListTwo.get(i);
+            if (!edgeOne.equals(edgeTwo)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java b/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java
deleted file mode 100644
index 3e8900b..0000000
--- a/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2014 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.onlab.graph;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.junit.Assert.*;
-
-import java.io.ByteArrayOutputStream;
-//import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class KshortestPathSearchTest extends BreadthFirstSearchTest {
-
-    private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
-
-    @Test
-    public void noPath() {
-        graph = new AdjacencyListsGraph<>(of(A, B, C, D),
-                                          of(new TestEdge(A, B, 1),
-                                             new TestEdge(B, A, 1),
-                                             new TestEdge(C, D, 1),
-                                             new TestEdge(D, C, 1)));
-        KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
-        List<List<TestEdge>> result = gs.search(A, D, weight, 1);
-        List<Path> paths = new ArrayList<>();
-        Iterator<List<TestEdge>> itr = result.iterator();
-        while (itr.hasNext()) {
-            System.out.println(itr.next().toString());
-        }
-        assertEquals("incorrect paths count", 0, result.size());
-    }
-
-    @Test
-    public void test2Path() {
-        graph = new AdjacencyListsGraph<>(of(A, B, C, D),
-                                          of(new TestEdge(A, B, 1),
-                                             new TestEdge(B, A, 1),
-                                             new TestEdge(B, D, 1),
-                                             new TestEdge(D, B, 1),
-                                             new TestEdge(A, C, 1),
-                                             new TestEdge(C, A, 1),
-                                             new TestEdge(C, D, 1),
-                                             new TestEdge(D, C, 1)));
-        KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
-        List<List<TestEdge>> result = gs.search(A, D, weight, 2);
-        List<Path> paths = new ArrayList<>();
-        Iterator<List<TestEdge>> itr = result.iterator();
-        while (itr.hasNext()) {
-            System.out.println(itr.next().toString());
-        }
-        assertEquals("incorrect paths count", 2, result.size());
-        // assertEquals("printing the paths", outContent.toString());
-    }
-
-    @Test
-    public void test3Path() {
-        graph = new AdjacencyListsGraph<>(of(A, B, C, D),
-                                          of(new TestEdge(A, B, 1),
-                                             new TestEdge(B, A, 1),
-                                             new TestEdge(A, D, 1),
-                                             new TestEdge(D, A, 1),
-                                             new TestEdge(B, D, 1),
-                                             new TestEdge(D, B, 1),
-                                             new TestEdge(A, C, 1),
-                                             new TestEdge(C, A, 1),
-                                             new TestEdge(C, D, 1),
-                                             new TestEdge(D, C, 1)));
-        KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
-        List<List<TestEdge>> result = gs.search(A, D, weight, 3);
-        List<Path> paths = new ArrayList<>();
-        Iterator<List<TestEdge>> itr = result.iterator();
-        while (itr.hasNext()) {
-            System.out.println(itr.next().toString());
-        }
-        assertEquals("incorrect paths count", 3, result.size());
-        // assertEquals("printing the paths", outContent.toString());
-    }
-
-    @Test
-    public void test4Path() {
-        graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F),
-                                          of(new TestEdge(A, B, 1),
-                                             new TestEdge(B, A, 1),
-                                             new TestEdge(A, C, 1),
-                                             new TestEdge(C, A, 1),
-                                             new TestEdge(B, D, 1),
-                                             new TestEdge(D, B, 1),
-                                             new TestEdge(C, E, 1),
-                                             new TestEdge(E, C, 1),
-                                             new TestEdge(D, F, 1),
-                                             new TestEdge(F, D, 1),
-                                             new TestEdge(F, E, 1),
-                                             new TestEdge(E, F, 1),
-                                             new TestEdge(C, D, 1),
-                                             new TestEdge(D, C, 1)));
-        KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
-        List<List<TestEdge>> result = gs.search(A, F, weight, 4);
-        List<Path> paths = new ArrayList<>();
-        Iterator<List<TestEdge>> itr = result.iterator();
-        while (itr.hasNext()) {
-            System.out.println(itr.next().toString());
-        }
-        assertEquals("incorrect paths count", 4, result.size());
-        // assertEquals("printing the paths", outContent.toString());
-    }
-
-    @Test
-    public void test6Path() {
-        graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F),
-                                          of(new TestEdge(A, B, 1),
-                                             new TestEdge(B, A, 1),
-                                             new TestEdge(A, C, 1),
-                                             new TestEdge(C, A, 1),
-                                             new TestEdge(B, D, 1),
-                                             new TestEdge(D, B, 1),
-                                             new TestEdge(B, C, 1),
-                                             new TestEdge(C, B, 1),
-                                             new TestEdge(D, E, 1),
-                                             new TestEdge(E, D, 1),
-                                             new TestEdge(C, E, 1),
-                                             new TestEdge(E, C, 1),
-                                             new TestEdge(D, F, 1),
-                                             new TestEdge(F, D, 1),
-                                             new TestEdge(E, F, 1),
-                                             new TestEdge(F, E, 1)));
-        KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
-        List<List<TestEdge>> result = gs.search(A, F, weight, 6);
-        List<Path> paths = new ArrayList<>();
-        Iterator<List<TestEdge>> itr = result.iterator();
-        while (itr.hasNext()) {
-            System.out.println(itr.next().toString());
-        }
-        assertEquals("incorrect paths count", 6, result.size());
-        // assertEquals("printing the paths", outContent.toString());
-    }
-
-    @Test
-    public void dualEdgePath() {
-        graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G, H),
-                                          of(new TestEdge(A, B, 1), new TestEdge(A, C, 3),
-                                             new TestEdge(B, D, 2), new TestEdge(B, C, 1),
-                                             new TestEdge(B, E, 4), new TestEdge(C, E, 1),
-                                             new TestEdge(D, H, 5), new TestEdge(D, E, 1),
-                                             new TestEdge(E, F, 1), new TestEdge(F, D, 1),
-                                             new TestEdge(F, G, 1), new TestEdge(F, H, 1),
-                                             new TestEdge(A, E, 3), new TestEdge(B, D, 1)));
-        KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
-        List<List<TestEdge>> result = gs.search(A, G, weight, 6);
-        List<Path> paths = new ArrayList<>();
-        Iterator<List<TestEdge>> itr = result.iterator();
-        while (itr.hasNext()) {
-            System.out.println(itr.next().toString());
-        }
-        assertEquals("incorrect paths count", 6, result.size());
-        // assertEquals("printing the paths", outContent.toString());
-    }
-
-    @BeforeClass
-    public static void setUpBeforeClass() throws Exception {
-    }
-
-    @AfterClass
-    public static void tearDownAfterClass() throws Exception {
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        // System.setOut(new PrintStream(outContent));
-    }
-
-    @After
-    public void tearDown() throws Exception {
-         // System.setOut(null);
-    }
-
-}
