diff --git a/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java b/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java
new file mode 100644
index 0000000..bcbe941
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/KshortestPathSearch.java
@@ -0,0 +1,289 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.commons.lang3.tuple.Pair;
+//import org.onlab.graph.AbstractGraphPathSearch.DefaultResult;
+
+/**
+ * K-shortest-path graph search algorithm capable of finding not just one,
+ * but K shortest paths with descending 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++) {
+                    // 4.1 convert the graph into mutable.
+                    convertGraph();
+                    // 4.2 transform the graph.
+                    List<E> rootPath = createSpurNode(lastPath, i);
+                    transformGraph(rootPath);
+                    // 4.3 find the deviation node.
+                    V devNode;
+                    devNode = getDevNode(rootPath);
+                    List<E> spurPath;
+                    // 4.4 find the shortest path in the transformed graph.
+                    spurPath = searchShortestPath(mutableGraph, devNode, sink);
+                    // 4.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();
+            }
+        }
+
+    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).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/main/java/org/onlab/graph/MutableAdjacencyListsGraph.java b/utils/misc/src/main/java/org/onlab/graph/MutableAdjacencyListsGraph.java
new file mode 100644
index 0000000..e107f5f
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/MutableAdjacencyListsGraph.java
@@ -0,0 +1,147 @@
+package org.onlab.graph;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
+
+public class MutableAdjacencyListsGraph<V extends Vertex, E extends Edge<V>>
+implements MutableGraph<V, E> {
+    private Set<V> vertexes = new HashSet<V>();
+    private Set<E> edges = new HashSet<E>();
+
+    private SetMultimap<V, E> sources = HashMultimap.create();
+    private SetMultimap<V, E> destinations = HashMultimap.create();
+
+    /**
+     * Creates a graph comprising of the specified vertexes and edges.
+     *
+     * @param vertexes set of graph vertexes
+     * @param edges    set of graph edges
+     */
+    public MutableAdjacencyListsGraph(Set<V> vertex, Set<E> edge) {
+        vertexes.addAll(vertex);
+        edges.addAll(edge);
+        for (E e : edge) {
+            sources.put(e.src(), e);
+            vertexes.add(e.src());
+            destinations.put(e.dst(), e);
+            vertexes.add(e.dst());
+        }
+    }
+
+    @Override
+    public Set<V> getVertexes() {
+        return vertexes;
+    }
+
+    @Override
+    public Set<E> getEdges() {
+        return edges;
+    }
+
+    @Override
+    public Set<E> getEdgesFrom(V src) {
+        return sources.get(src);
+    }
+
+    @Override
+    public Set<E> getEdgesTo(V dst) {
+        return destinations.get(dst);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MutableAdjacencyListsGraph) {
+            MutableAdjacencyListsGraph that = (MutableAdjacencyListsGraph) obj;
+            return this.getClass() == that.getClass() &&
+                    Objects.equals(this.vertexes, that.vertexes) &&
+                    Objects.equals(this.edges, that.edges);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(vertexes, edges);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("vertexes", vertexes)
+                .add("edges", edges)
+                .toString();
+    }
+
+
+    @Override
+    public void addVertex(V vertex) {
+        if (vertexes != null) {
+              if (!vertexes.contains(vertex)) {
+                    vertexes.add(vertex);
+                }
+        }
+    }
+
+    @Override
+    public void removeVertex(V vertex) {
+        // TODO Auto-generated method stub
+        if (vertexes != null && edges != null) {
+            if (vertexes.contains(vertex)) {
+                vertexes.remove(vertex);
+                Set<E> srcEdgesList = sources.get(vertex);
+                Set<E> dstEdgesList = destinations.get(vertex);
+                edges.removeAll(srcEdgesList);
+                edges.removeAll(dstEdgesList);
+                sources.remove(vertex, srcEdgesList);
+                sources.remove(vertex, dstEdgesList);
+            }
+        }
+    }
+
+    @Override
+    public void addEdge(E edge) {
+        if (edges != null) {
+                if (!edges.contains(edge)) {
+                    edges.add(edge);
+                    sources.put(edge.src(), edge);
+                    destinations.put(edge.dst(), edge);
+                }
+        }
+    }
+
+    @Override
+    public void removeEdge(E edge) {
+        if (edges != null) {
+            if (edges.contains(edge)) {
+                edges.remove(edge);
+                sources.remove(edge.src(), edge);
+                destinations.remove(edge.dst(), edge);
+            }
+        }
+    }
+
+    @Override
+    public Graph<V, E> toImmutable() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    /**
+     * Clear the graph.
+     */
+    public void clear() {
+        edges.clear();
+        vertexes.clear();
+        sources.clear();
+        destinations.clear();
+    }
+}
diff --git a/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java b/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java
new file mode 100644
index 0000000..3ef2fcf
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/graph/KshortestPathSearchTest.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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);
+    }
+
+}
