diff --git a/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java b/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java
new file mode 100644
index 0000000..b62d3b2
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java
@@ -0,0 +1,128 @@
+/*
+ * 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 java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+
+public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Path<V, E> {
+    public Path<V, E> path1, path2;
+    boolean usingPath1 = true;
+
+    /**
+     * Creates a Disjoint Path Pair from two paths.
+     *
+     * @param p1    first path
+     * @param p2    second path
+     */
+    public DisjointPathPair(Path<V, E> p1, Path<V, E> p2) {
+        path1 = p1;
+        path2 = p2;
+    }
+
+    @Override
+    public V src() {
+        return path1.src();
+    }
+
+    @Override
+    public V dst() {
+        return path1.dst();
+    }
+
+    @Override
+    public double cost() {
+        if (!hasBackup()) {
+            return path1.cost();
+        }
+        return path1.cost() + path2.cost();
+    }
+
+    @Override
+    public List<E> edges() {
+        if (usingPath1 || !hasBackup()) {
+            return path1.edges();
+        } else {
+            return path2.edges();
+        }
+    }
+
+    /**
+     * Checks if this path pair contains a backup/secondary path.
+     *
+     * @return boolean representing whether it has backup
+     */
+    public boolean hasBackup() {
+        return path2 != null && path2.edges() != null;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("src", src())
+                .add("dst", dst())
+                .add("cost", cost())
+                .add("edges", edges())
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        Set<Path<V, E>> paths;
+        if (!hasBackup()) {
+            paths = of(path1);
+        } else {
+            paths = of(path1, path2);
+        }
+        return Objects.hash(paths);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DisjointPathPair) {
+            final DisjointPathPair other = (DisjointPathPair) obj;
+            return Objects.equals(this.src(), other.src()) &&
+                    Objects.equals(this.dst(), other.dst()) &&
+                    (Objects.equals(this.path1, other.path1) &&
+                            Objects.equals(this.path2, other.path2)) ||
+                    (Objects.equals(this.path1, other.path2) &&
+                            Objects.equals(this.path2, other.path1));
+        }
+        return false;
+    }
+
+    /**
+     * Returns number of paths inside this path pair object.
+     *
+     * @return number of paths
+     */
+    public int size() {
+        if (hasBackup()) {
+            return 2;
+        }
+        return 1;
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java.orig b/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java.orig
new file mode 100644
index 0000000..1cf22b6
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/DisjointPathPair.java.orig
@@ -0,0 +1,169 @@
+/*
+ * 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 java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+
+public class DisjointPathPair<V extends Vertex, E extends Edge<V>> implements Path<V, E> {
+    public Path<V, E> path1, path2;
+    boolean usingPath1 = true;
+
+<<<<<<< HEAD
+    /**
+     * Creates a Disjoint Path Pair from two paths.
+     *
+     * @param p1    first path
+     * @param p2    second path
+     */
+=======
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public DisjointPathPair(Path<V, E> p1, Path<V, E> p2) {
+        path1 = p1;
+        path2 = p2;
+    }
+<<<<<<< HEAD
+
+    @Override
+=======
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public V src() {
+        return path1.src();
+    }
+
+<<<<<<< HEAD
+    @Override
+    public V dst() {
+        return path1.dst();
+    }
+
+    @Override
+=======
+    public V dst() {
+        return path1.dst();
+    }
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public double cost() {
+        if (!hasBackup()) {
+            return path1.cost();
+        }
+        return path1.cost() + path2.cost();
+    }
+<<<<<<< HEAD
+
+    @Override
+=======
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public List<E> edges() {
+        if (usingPath1 || !hasBackup()) {
+            return path1.edges();
+        } else {
+            return path2.edges();
+        }
+    }
+<<<<<<< HEAD
+
+    /**
+     * Checks if this path pair contains a backup/secondary path.
+     *
+     * @return boolean representing whether it has backup
+     */
+    public boolean hasBackup() {
+        return path2 != null && path2.edges() != null;
+    }
+
+    /**
+     * Switches this disjoint path pair to using its backup path, instead of
+     * using its primary.
+     */
+    public void useBackup() {
+        usingPath1 = !usingPath1;
+    }
+
+    @Override
+=======
+    public boolean hasBackup() {
+        return path2 != null && path2.edges() != null;
+    }
+    public void useBackup() {
+        usingPath1 = !usingPath1;
+    }
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public String toString() {
+        return toStringHelper(this)
+                .add("src", src())
+                .add("dst", dst())
+                .add("cost", cost())
+                .add("edges", edges())
+                .toString();
+    }
+<<<<<<< HEAD
+
+    @Override
+=======
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public int hashCode() {
+        Set<Path<V, E>> paths;
+        if (!hasBackup()) {
+            paths = of(path1);
+        } else {
+            paths = of(path1, path2);
+        }
+        return Objects.hash(paths);
+    }
+<<<<<<< HEAD
+
+    @Override
+=======
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DisjointPathPair) {
+            final DisjointPathPair other = (DisjointPathPair) obj;
+            return Objects.equals(this.src(), other.src()) &&
+                    Objects.equals(this.dst(), other.dst()) &&
+                    (Objects.equals(this.path1, other.path1) &&
+                            Objects.equals(this.path2, other.path2)) ||
+                    (Objects.equals(this.path1, other.path2) &&
+                            Objects.equals(this.path2, other.path1));
+        }
+        return false;
+    }
+<<<<<<< HEAD
+
+    /**
+     * Returns number of paths inside this path pair object.
+     *
+     * @return number of paths
+     */
+=======
+>>>>>>> Disjoint Path Pairs (Suurballe) utils
+    public int size() {
+        if (hasBackup()) {
+            return 2;
+        }
+        return 1;
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java b/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java
new file mode 100644
index 0000000..230609f
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/GAOrganism.java
@@ -0,0 +1,38 @@
+package org.onlab.graph;
+
+/**
+ * Interface representing an "organism": a specific solution
+ * to a problem where solutions can be evaluated in terms
+ * of fitness. These organisms can be used to represent any
+ * class of problem that genetic algorithms can be run on.
+ */
+interface GAOrganism {
+    /**
+     * A fitness function that determines how
+     * optimal a given organism is.
+     *
+     * @return fitness of organism
+     */
+    double fitness();
+
+    /**
+     * A method that slightly mutates an organism.
+     */
+    void mutate();
+
+    /**
+     * Creates a new random organism.
+     *
+     * @return  random GAOrganism
+     */
+    GAOrganism random();
+
+    /**
+     * Returns a child organism that is the result
+     * of "crossing" this organism with another.
+     *
+     * @param other Other organism to cross with
+     * @return child organism
+     */
+    GAOrganism crossWith(GAOrganism other);
+}
diff --git a/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java b/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java
new file mode 100644
index 0000000..ae7f182
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/GAPopulation.java
@@ -0,0 +1,75 @@
+package org.onlab.graph;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Represents a population of GAOrganisms. This class can be used
+ * to run a genetic algorithm on the population and return the fittest solutions.
+ */
+class GAPopulation<Organism extends GAOrganism> extends ArrayList<Organism> {
+    Random r = new Random();
+
+    /**
+     * Steps the population through one generation. The 75% least fit
+     * organisms are killed off and replaced with the children of the
+     * 25% (as well as some "random" newcomers).
+     */
+    void step() {
+        Collections.sort(this, (org1, org2) -> {
+            double d = org1.fitness() - org2.fitness();
+            if (d < 0) {
+                return -1;
+            } else if (d == 0) {
+                return 0;
+            }
+            return 1;
+        });
+        int maxSize = size();
+        for (int i = size() - 1; i > maxSize / 4; i--) {
+            remove(i);
+        }
+        for (Organism org: this) {
+            if (r.nextBoolean()) {
+                org.mutate();
+            }
+        }
+        while (size() < maxSize * 4 / 5) {
+            Organism org1 = get(r.nextInt(size()));
+            Organism org2 = get(r.nextInt(size()));
+            add((Organism) org1.crossWith(org2));
+        }
+
+        while (size() < maxSize) {
+            Organism org1 = get(r.nextInt(size()));
+            add((Organism) org1.random());
+        }
+    }
+
+    /**
+     * Runs GA for the specified number of iterations, and returns
+     * a sample of the resulting population of solutions.
+     *
+     * @param generations   Number of generations to run GA for
+     * @param populationSize    Population size of GA
+     * @param sample        Number of solutions to ask for
+     * @param template      Template GAOrganism to seed the population with
+     * @return  ArrayList containing sample number of organisms
+     */
+    List<Organism> runGA(int generations, int populationSize, int sample, Organism template) {
+        for (int i = 0; i < populationSize; i++) {
+            add((Organism) template.random());
+        }
+
+        for (int i = 0; i < generations; i++) {
+            step();
+        }
+        for (int i = size() - 1; i >= sample; i--) {
+            remove(i);
+        }
+        return new ArrayList<>(this);
+    }
+}
+
diff --git a/utils/misc/src/main/java/org/onlab/graph/SRLGGraphSearch.java b/utils/misc/src/main/java/org/onlab/graph/SRLGGraphSearch.java
new file mode 100644
index 0000000..21f687a
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/SRLGGraphSearch.java
@@ -0,0 +1,253 @@
+/*
+ * 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 java.util.Map;
+import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Random;
+
+
+/**
+ * SRLG Graph Search finds a pair of paths with disjoint risk groups; i.e
+ * if one path goes through an edge in risk group 1, the other path will go
+ * through no edges in risk group 1.
+ */
+public class SRLGGraphSearch<V extends Vertex, E extends Edge<V>>
+        extends AbstractGraphPathSearch<V, E> {
+
+    static final int ITERATIONS = 100;
+    static final int POPSIZE = 50;
+
+    boolean useSuurballe = false;
+
+    static final double INF = 100000000.0;
+
+    int numGroups;
+    Map<E, Integer> riskGrouping;
+
+    Graph<V, E> orig;
+    V src, dst;
+    EdgeWeight<V, E> weight;
+
+    /**
+     * Creates an SRLG graph search object with the given number
+     * of groups and given risk mapping.
+     *
+     * @param   groups      the number of disjoint risk groups
+     * @param   grouping    map linking edges to integral group assignments
+     */
+    public SRLGGraphSearch(int groups, Map<E, Integer> grouping) {
+        numGroups = groups;
+        riskGrouping = grouping;
+    }
+
+    /**
+     * Creates an SRLG graph search object from a map, inferring
+     * the number of groups and creating an integral mapping.
+     *
+     * @param   grouping    map linking edges to object group assignments,
+     *                      with same-group status linked to equality
+     */
+    public SRLGGraphSearch(Map<E, Object> grouping) {
+        if (grouping == null) {
+            useSuurballe = true;
+            return;
+        }
+        numGroups = 0;
+        HashMap<Object, Integer> tmpMap = new HashMap<>();
+        riskGrouping = new HashMap<>();
+        for (E key: grouping.keySet()) {
+            Object value = grouping.get(key);
+            if (!tmpMap.containsKey(value)) {
+                tmpMap.put(value, numGroups);
+                numGroups++;
+            }
+            riskGrouping.put(key, tmpMap.get(value));
+        }
+    }
+
+    @Override
+    public Result<V, E> search(Graph<V, E> graph, V src, V dst,
+                               EdgeWeight<V, E> weight, int maxPaths) {
+        if (maxPaths == ALL_PATHS) {
+            maxPaths = POPSIZE;
+        }
+        if (useSuurballe) {
+            return new SuurballeGraphSearch<V, E>().search(graph, src, dst, weight, ALL_PATHS);
+        }
+        if (weight == null) {
+            weight = edge -> 1;
+        }
+        checkArguments(graph, src, dst);
+        orig = graph;
+        this.src = src;
+        this.dst = dst;
+        this.weight = weight;
+        List<Subset> best = new GAPopulation<Subset>()
+                .runGA(ITERATIONS, POPSIZE, maxPaths, new Subset(new boolean[numGroups]));
+        Set<DisjointPathPair> dpps = new HashSet<DisjointPathPair>();
+        for (Subset s: best) {
+            dpps.addAll(s.buildPaths());
+        }
+        Result<V, E> firstDijkstra = new DijkstraGraphSearch<V, E>()
+                .search(orig, src, dst, weight, 1);
+        return new Result<V, E>() {
+            final DefaultResult search = (DefaultResult) firstDijkstra;
+
+            public V src() {
+                return src;
+            }
+            public V dst() {
+                return dst;
+
+            }
+            public Set<Path<V, E>> paths() {
+                Set<Path<V, E>> pathsD = new HashSet<>();
+                for (DisjointPathPair<V, E> path: dpps) {
+                    pathsD.add(path);
+                }
+                return pathsD;
+            }
+            public Map<V, Double> costs() {
+                return search.costs();
+
+            }
+            public Map<V, Set<E>> parents() {
+                return search.parents();
+
+            }
+        };
+    }
+
+    //finds the shortest path in the graph given a subset of edge types to use
+    private Result<V, E> findShortestPathFromSubset(boolean[] subset) {
+        Graph<V, E> graph = orig;
+        EdgeWeight<V, E> modified = new EdgeWeight<V, E>() {
+            final boolean[] subsetF = subset;
+
+            @Override
+            public double weight(E edge) {
+                if (subsetF[riskGrouping.get(edge)]) {
+                    return weight.weight(edge);
+                }
+                return INF;
+            }
+        };
+
+        Result<V, E> res = new DijkstraGraphSearch<V, E>().search(graph, src, dst, modified, 1);
+        return res;
+    }
+    /**
+     * A subset is a type of GA organism that represents a subset of allowed shortest
+     * paths (and its complement). Its fitness is determined by the sum of the weights
+     * of the first two shortest paths.
+     */
+    class Subset implements GAOrganism {
+
+        boolean[] subset;
+        boolean[] not;
+        Random r = new Random();
+
+        /**
+         * Creates a Subset from the given subset array.
+         *
+         * @param sub   subset array
+         */
+        public Subset(boolean[] sub) {
+            subset = sub.clone();
+            not = new boolean[subset.length];
+            for (int i = 0; i < subset.length; i++) {
+                not[i] = !subset[i];
+            }
+        }
+
+        @Override
+        public double fitness() {
+            Set<Path<V, E>> paths1 = findShortestPathFromSubset(subset).paths();
+            Set<Path<V, E>> paths2 = findShortestPathFromSubset(not).paths();
+            if (paths1.size() == 0 || paths2.size() == 0) {
+                return INF;
+            }
+            return paths1.iterator().next().cost() + paths2.iterator().next().cost();
+        }
+
+        @Override
+        public void mutate() {
+            int turns = r.nextInt((int) Math.sqrt(subset.length));
+            while (turns > 0) {
+                int choose = r.nextInt(subset.length);
+                subset[choose] = !subset[choose];
+                not[choose] = !not[choose];
+                turns--;
+            }
+        }
+
+        @Override
+        public GAOrganism crossWith(GAOrganism org) {
+            if (!(org.getClass().equals(getClass()))) {
+                return this;
+            }
+            Subset other = (Subset) (org);
+            boolean[] sub = new boolean[subset.length];
+            for (int i = 0; i < subset.length; i++) {
+                sub[i] = subset[i];
+                if (r.nextBoolean()) {
+                    sub[i] = other.subset[i];
+                }
+            }
+            return new Subset(sub);
+        }
+
+        @Override
+        public GAOrganism random() {
+            boolean[] sub = new boolean[subset.length];
+            for (int i = 0; i < sub.length; i++) {
+                sub[i] = r.nextBoolean();
+            }
+            return new Subset(sub);
+        }
+
+        /**
+         * Builds the set of disjoint path pairs for a given subset
+         * using Dijkstra's algorithm on both the subset and complement
+         * and returning all pairs with one from each set.
+         *
+         * @return all shortest disjoint paths given this subset
+         */
+        public Set<DisjointPathPair> buildPaths() {
+            Set<DisjointPathPair> dpps = new HashSet<>();
+            for (Path<V, E> path1: findShortestPathFromSubset(subset).paths()) {
+                if (path1.cost() >= INF) {
+                    continue;
+                }
+                for (Path<V, E> path2: findShortestPathFromSubset(not).paths()) {
+                    if (path2.cost() >= INF) {
+                        continue;
+                    }
+                    DisjointPathPair<V, E> dpp = new DisjointPathPair<>(path1, path2);
+                    dpps.add(dpp);
+                }
+            }
+            return dpps;
+        }
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/graph/SuurballeGraphSearch.java b/utils/misc/src/main/java/org/onlab/graph/SuurballeGraphSearch.java
new file mode 100644
index 0000000..76591c8
--- /dev/null
+++ b/utils/misc/src/main/java/org/onlab/graph/SuurballeGraphSearch.java
@@ -0,0 +1,193 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Set;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.stream.Collectors;
+
+/**
+ * Suurballe shortest-path graph search algorithm capable of finding both
+ * a shortest path, as well as a backup shortest path, between a source and a destination
+ * such that the sum of the path lengths is minimized.
+ */
+public class SuurballeGraphSearch<V extends Vertex, E extends Edge<V>> extends DijkstraGraphSearch<V, E> {
+
+    @Override
+    public Result<V, E> search(Graph<V, E> graph, V src, V dst,
+                               EdgeWeight<V, E> weight, int maxPaths) {
+
+        if (weight == null) {
+            weight = edge -> 1;
+        }
+
+        List<DisjointPathPair<V, E>> dpps = new ArrayList<>();
+
+        final EdgeWeight weightf = weight;
+        DefaultResult firstDijkstraS = (DefaultResult) super.search(graph, src, dst, weight, ALL_PATHS);
+        DefaultResult firstDijkstra = (DefaultResult) super.search(graph, src, null, weight, ALL_PATHS);
+
+        //choose an arbitrary shortest path to run Suurballe on
+        Path<V, E> shortPath = null;
+        if (firstDijkstraS.paths().size() == 0) {
+            return firstDijkstraS;
+        }
+        for (Path p: firstDijkstraS.paths()) {
+            shortPath = p;
+            //transforms the graph so tree edges have 0 weight
+            EdgeWeight<V, Edge<V>> modified = edge -> {
+                if (classE().isInstance(edge)) {
+                    return weightf.weight((E) (edge)) + firstDijkstra.cost(edge.src())
+                            - firstDijkstra.cost(edge.dst());
+                }
+                return 0;
+            };
+            EdgeWeight<V, E> modified2 = edge ->
+                    weightf.weight(edge) + firstDijkstra.cost(edge.src()) - firstDijkstra.cost(edge.dst());
+
+            //create a residual graph g' by removing all src vertices and reversing 0 length path edges
+            MutableGraph<V, Edge<V>> gt = mutableCopy(graph);
+
+            Map<Edge<V>, E> revToEdge = new HashMap<>();
+            graph.getEdgesTo(src).forEach(gt::removeEdge);
+            for (E edge: shortPath.edges()) {
+                gt.removeEdge(edge);
+                Edge<V> reverse = new Edge<V>() {
+                    final Edge<V> orig = edge;
+                    public V src() {
+                        return orig.dst();
+                    }
+                    public V dst() {
+                        return orig.src();
+                    }
+                    public String toString() {
+                        return "ReversedEdge " + "src=" + src() + " dst=" + dst();
+                    }
+                };
+                revToEdge.put(reverse, edge);
+                gt.addEdge(reverse);
+            }
+
+            //rerun dijkstra on the temporary graph to get a second path
+            Result<V, Edge<V>> secondDijkstra;
+            secondDijkstra = new DijkstraGraphSearch<V, Edge<V>>().search(gt, src, dst, modified, ALL_PATHS);
+
+            Path<V, Edge<V>> residualShortPath = null;
+            if (secondDijkstra.paths().size() == 0) {
+                dpps.add(new DisjointPathPair<V, E>(shortPath, null));
+                continue;
+            }
+
+            for (Path p2: secondDijkstra.paths()) {
+                residualShortPath = p2;
+
+                MutableGraph<V, E> roundTrip = mutableCopy(graph);
+
+                List<E> tmp = roundTrip.getEdges().stream().collect(Collectors.toList());
+
+                tmp.forEach(roundTrip::removeEdge);
+
+                shortPath.edges().forEach(roundTrip::addEdge);
+
+                if (residualShortPath != null) {
+                    for (Edge<V> edge: residualShortPath.edges()) {
+                        if (classE().isInstance(edge)) {
+                            roundTrip.addEdge((E) edge);
+                        } else {
+                            roundTrip.removeEdge(revToEdge.get(edge));
+                        }
+                    }
+                }
+                //Actually build the final result
+                DefaultResult lastSearch = (DefaultResult) super.search(roundTrip, src, dst, weight, ALL_PATHS);
+                Path<V, E> path1 = lastSearch.paths().iterator().next();
+                path1.edges().forEach(roundTrip::removeEdge);
+
+                Set<Path<V, E>> bckpaths = super.search(roundTrip, src, dst, weight, ALL_PATHS).paths();
+                Path<V, E> backup = null;
+                if (bckpaths.size() != 0) {
+                    backup = bckpaths.iterator().next();
+                }
+
+                dpps.add(new DisjointPathPair<>(path1, backup));
+            }
+        }
+
+        for (int i = dpps.size() - 1; i > 0; i--) {
+            if (dpps.get(i).size() <= 1) {
+                dpps.remove(i);
+            }
+        }
+
+        return new Result<V, E>() {
+            final DefaultResult search = firstDijkstra;
+
+            public V src() {
+                return src;
+            }
+            public V dst() {
+                return dst;
+            }
+            public Set<Path<V, E>> paths() {
+                Set<Path<V, E>> pathsD = new HashSet<>();
+                int paths = 0;
+                for (DisjointPathPair<V, E> path: dpps) {
+                    pathsD.add((Path<V, E>) path);
+                    paths++;
+                    if (paths == maxPaths) {
+                        break;
+                    }
+                }
+                return pathsD;
+            }
+            public Map<V, Double> costs() {
+                return search.costs();
+            }
+            public Map<V, Set<E>> parents() {
+                return search.parents();
+            }
+        };
+    }
+
+    private Class<?> clazzV;
+
+    public Class<?> classV() {
+        return clazzV;
+    }
+
+    private Class<?> clazzE;
+
+    public Class<?> classE() {
+        return clazzE;
+    }
+    /**
+     * Creates a mutable copy of an immutable graph.
+     *
+     * @param graph   immutable graph
+     * @return mutable copy
+     */
+    public MutableGraph mutableCopy(Graph<V, E> graph) {
+        clazzV = graph.getVertexes().iterator().next().getClass();
+        clazzE = graph.getEdges().iterator().next().getClass();
+        return new MutableAdjacencyListsGraph<V, E>(graph.getVertexes(), graph.getEdges());
+    }
+}
+
diff --git a/utils/misc/src/test/java/org/onlab/graph/SRLGGraphSearchTest.java b/utils/misc/src/test/java/org/onlab/graph/SRLGGraphSearchTest.java
new file mode 100644
index 0000000..885fbe5
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/graph/SRLGGraphSearchTest.java
@@ -0,0 +1,183 @@
+/*
+ * 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 org.junit.Test;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static org.junit.Assert.assertTrue;
+
+
+
+/**
+ * Test of the Suurballe backup path algorithm.
+ */
+public class SRLGGraphSearchTest extends BreadthFirstSearchTest {
+    @Override
+    protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
+        return new SRLGGraphSearch<TestVertex, TestEdge>(null);
+    }
+
+    public void setWeights() {
+        weight = new EdgeWeight<TestVertex, TestEdge>() {
+            @Override
+            public double weight(TestEdge edge) {
+                return edge.weight();
+            }
+        };
+    }
+    public void setDefaultWeights() {
+        weight = null;
+    }
+    @Override
+    public void defaultGraphTest() {
+
+    }
+
+    @Override
+    public void defaultHopCountWeight() {
+
+    }
+
+    @Test
+    public void onePathPair() {
+        setDefaultWeights();
+        TestEdge aB = new TestEdge(A, B, 1);
+        TestEdge bC = new TestEdge(B, C, 1);
+        TestEdge aD = new TestEdge(A, D, 1);
+        TestEdge dC = new TestEdge(D, C, 1);
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
+                                                                      of(aB, bC, aD, dC));
+        Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
+        riskProfile.put(aB, 0);
+        riskProfile.put(bC, 0);
+        riskProfile.put(aD, 1);
+        riskProfile.put(dC, 1);
+        SRLGGraphSearch<TestVertex, TestEdge> search =
+                new SRLGGraphSearch<TestVertex, TestEdge>(2, riskProfile);
+        Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, GraphPathSearch.ALL_PATHS).paths();
+        System.out.println("\n\n\n" + paths + "\n\n\n");
+        assertTrue("one disjoint path pair found", paths.size() == 1);
+        checkIsDisjoint(paths.iterator().next(), riskProfile);
+    }
+    public void checkIsDisjoint(Path<TestVertex, TestEdge> p, Map<TestEdge, Integer> risks) {
+        assertTrue("The path is not a DisjointPathPair", (p instanceof DisjointPathPair));
+        DisjointPathPair<TestVertex, TestEdge> q = (DisjointPathPair) p;
+        Set<Integer> p1Risks = new HashSet<Integer>();
+        Set<Integer> p2Risks = new HashSet<Integer>();
+        for (TestEdge e: q.edges()) {
+            p1Risks.add(risks.get(e));
+        }
+        if (!q.hasBackup()) {
+            return;
+        }
+        Path<TestVertex, TestEdge> pq = q.path2;
+        for (TestEdge e: pq.edges()) {
+            assertTrue("The paths are not disjoint", !p1Risks.contains(risks.get(e)));
+        }
+    }
+    @Test
+    public void complexGraphTest() {
+        setDefaultWeights();
+        TestEdge aB = new TestEdge(A, B, 1);
+        TestEdge bC = new TestEdge(B, C, 1);
+        TestEdge aD = new TestEdge(A, D, 1);
+        TestEdge dC = new TestEdge(D, C, 1);
+        TestEdge cE = new TestEdge(C, E, 1);
+        TestEdge bE = new TestEdge(B, E, 1);
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
+                                                                      of(aB, bC, aD, dC, cE, bE));
+        Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
+        riskProfile.put(aB, 0);
+        riskProfile.put(bC, 0);
+        riskProfile.put(aD, 1);
+        riskProfile.put(dC, 1);
+        riskProfile.put(cE, 2);
+        riskProfile.put(bE, 3);
+        SRLGGraphSearch<TestVertex, TestEdge> search =
+                new SRLGGraphSearch<TestVertex, TestEdge>(4, riskProfile);
+        Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, GraphPathSearch.ALL_PATHS).paths();
+    }
+
+    @Test
+    public void multiplePathGraphTest() {
+        setDefaultWeights();
+        TestEdge aB = new TestEdge(A, B, 1);
+        TestEdge bE = new TestEdge(B, E, 1);
+        TestEdge aD = new TestEdge(A, D, 1);
+        TestEdge dE = new TestEdge(D, E, 1);
+        TestEdge aC = new TestEdge(A, C, 1);
+        TestEdge cE = new TestEdge(C, E, 1);
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
+                                                                      of(aB, bE, aD, dE, aC, cE));
+        Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
+        riskProfile.put(aB, 0);
+        riskProfile.put(bE, 1);
+        riskProfile.put(aD, 2);
+        riskProfile.put(dE, 3);
+        riskProfile.put(aC, 4);
+        riskProfile.put(cE, 5);
+        SRLGGraphSearch<TestVertex, TestEdge> search =
+                new SRLGGraphSearch<TestVertex, TestEdge>(6, riskProfile);
+        Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, GraphPathSearch.ALL_PATHS).paths();
+        assertTrue("> one disjoint path pair found", paths.size() >= 1);
+        checkIsDisjoint(paths.iterator().next(), riskProfile);
+    }
+    @Test
+    public void onePath() {
+        setDefaultWeights();
+        TestEdge aB = new TestEdge(A, B, 1);
+        TestEdge bC = new TestEdge(B, C, 1);
+        TestEdge aD = new TestEdge(A, D, 1);
+        TestEdge dC = new TestEdge(D, C, 1);
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
+                                                                      of(aB, bC, aD, dC));
+        Map<TestEdge, Integer> riskProfile = new HashMap<TestEdge, Integer>();
+        riskProfile.put(aB, 0);
+        riskProfile.put(bC, 0);
+        riskProfile.put(aD, 1);
+        riskProfile.put(dC, 0);
+        SRLGGraphSearch<TestVertex, TestEdge> search =
+                new SRLGGraphSearch<TestVertex, TestEdge>(2, riskProfile);
+        Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, C, weight, GraphPathSearch.ALL_PATHS).paths();
+        System.out.println(paths);
+        assertTrue("no disjoint path pairs found", paths.size() == 0);
+    }
+    @Test
+    public void noPath() {
+        setDefaultWeights();
+        TestEdge aB = new TestEdge(A, B, 1);
+        TestEdge bC = new TestEdge(B, C, 1);
+        TestEdge aD = new TestEdge(A, D, 1);
+        TestEdge dC = new TestEdge(D, C, 1);
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
+                                                                      of(aB, bC, aD, dC));
+        Map<TestEdge, Integer> riskProfile = new HashMap<>();
+        riskProfile.put(aB, 0);
+        riskProfile.put(bC, 0);
+        riskProfile.put(aD, 1);
+        riskProfile.put(dC, 0);
+        SRLGGraphSearch<TestVertex, TestEdge> search =
+                new SRLGGraphSearch<>(2, riskProfile);
+        Set<Path<TestVertex, TestEdge>> paths = search.search(graph, A, E, weight, GraphPathSearch.ALL_PATHS).paths();
+        assertTrue("no disjoint path pairs found", paths.size() == 0);
+    }
+}
diff --git a/utils/misc/src/test/java/org/onlab/graph/SuurballeGraphSearchTest.java b/utils/misc/src/test/java/org/onlab/graph/SuurballeGraphSearchTest.java
new file mode 100644
index 0000000..0d2d13b
--- /dev/null
+++ b/utils/misc/src/test/java/org/onlab/graph/SuurballeGraphSearchTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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 org.junit.Test;
+import java.util.Set;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static org.junit.Assert.assertEquals;
+//import static org.junit.Assert.assertTrue;
+
+
+
+/**
+ * Test of the Suurballe backup path algorithm.
+ */
+public class SuurballeGraphSearchTest extends BreadthFirstSearchTest {
+
+    @Override
+    protected AbstractGraphPathSearch<TestVertex, TestEdge> graphSearch() {
+        return new SuurballeGraphSearch<>();
+    }
+
+    public void setWeights() {
+        weight = new EdgeWeight<TestVertex, TestEdge>() {
+            @Override
+            public double weight(TestEdge edge) {
+                return edge.weight();
+            }
+        };
+    }
+    public void setDefaultWeights() {
+        weight = null;
+    }
+    @Override
+    public void defaultGraphTest() {
+
+    }
+
+    @Override
+    public void defaultHopCountWeight() {
+
+    }
+
+    @Test
+    public void basicGraphTest() {
+        setDefaultWeights();
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
+                                                                      of(new TestEdge(A, B, 1),
+                                                                         new TestEdge(B, C, 1),
+                                                                         new TestEdge(A, D, 1),
+                                                                         new TestEdge(D, C, 1)));
+        executeSearch(graphSearch(), graph, A, C, weight, 1, 4.0);
+    }
+
+    @Test
+    public void multiplePathOnePairGraphTest() {
+        setWeights();
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
+                                                                      of(new TestEdge(A, B, 1),
+                                                                         new TestEdge(B, C, 1),
+                                                                         new TestEdge(A, D, 1),
+                                                                         new TestEdge(D, C, 1),
+                                                                         new TestEdge(B, E, 2),
+                                                                         new TestEdge(C, E, 1)));
+        executeSearch(graphSearch(), graph, A, E, weight, 1, 6.0);
+    }
+
+    @Test
+    public void multiplePathsMultiplePairs() {
+        setWeights();
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
+                                                                      of(new TestEdge(A, B, 1),
+                                                                         new TestEdge(B, E, 1),
+                                                                         new TestEdge(A, C, 1),
+                                                                         new TestEdge(C, E, 1),
+                                                                         new TestEdge(A, D, 1),
+                                                                         new TestEdge(D, E, 1),
+                                                                         new TestEdge(A, E, 2)));
+        GraphPathSearch.Result<TestVertex, TestEdge> result =
+                graphSearch().search(graph, A, E, weight, GraphPathSearch.ALL_PATHS);
+        Set<Path<TestVertex, TestEdge>> paths = result.paths();
+        System.out.println("\n\n" + paths + "\n\n\ndone\n");
+        assertEquals("incorrect paths count", 3, paths.size());
+        DisjointPathPair<TestVertex, TestEdge> dpp = (DisjointPathPair<TestVertex, TestEdge>) paths.iterator().next();
+        assertEquals("incorrect disjoint paths per path", 2, dpp.size());
+    }
+
+    @Test
+    public void differingPrimaryAndBackupPathLengths() {
+        setWeights();
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D, E),
+                                                                      of(new TestEdge(A, B, 1),
+                                                                         new TestEdge(B, C, 1),
+                                                                         new TestEdge(A, D, 1),
+                                                                         new TestEdge(D, C, 1),
+                                                                         new TestEdge(B, E, 1),
+                                                                         new TestEdge(C, E, 1)));
+        executeSearch(graphSearch(), graph, A, E, weight, 1, 5.0);
+    }
+
+    @Test
+    public void onePath() {
+        setWeights();
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
+                                                                      of(new TestEdge(A, B, 1),
+                                                                         new TestEdge(B, C, 1),
+                                                                         new TestEdge(A, C, 4),
+                                                                         new TestEdge(C, D, 1)));
+        GraphPathSearch.Result<TestVertex, TestEdge> result =
+                graphSearch().search(graph, A, D, weight, GraphPathSearch.ALL_PATHS);
+        Set<Path<TestVertex, TestEdge>> paths = result.paths();
+        assertEquals("incorrect paths count", 1, paths.size());
+        DisjointPathPair<TestVertex, TestEdge> dpp = (DisjointPathPair<TestVertex, TestEdge>) paths.iterator().next();
+        assertEquals("incorrect disjoint paths count", 1, dpp.size());
+    }
+
+    @Test
+    public void noPath() {
+        setWeights();
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
+                                                                      of(new TestEdge(A, B, 1),
+                                                                         new TestEdge(B, C, 1),
+                                                                         new TestEdge(A, C, 4)));
+        GraphPathSearch.Result<TestVertex, TestEdge> result =
+                graphSearch().search(graph, A, D, weight, GraphPathSearch.ALL_PATHS);
+        Set<Path<TestVertex, TestEdge>> paths = result.paths();
+        assertEquals("incorrect paths count", paths.size(), 0);
+    }
+
+    @Test
+    public void disconnected() {
+        setWeights();
+        Graph<TestVertex, TestEdge> graph = new AdjacencyListsGraph<>(of(A, B, C, D),
+                                                                      of());
+        GraphPathSearch.Result<TestVertex, TestEdge> result =
+                graphSearch().search(graph, A, D, weight, GraphPathSearch.ALL_PATHS);
+        Set<Path<TestVertex, TestEdge>> paths = result.paths();
+        assertEquals("incorrect paths count", 0, paths.size());
+    }
+}
