Merge pull request #215 from sbstp/dot-escape

Support more escape codes inside labels 
diff --git a/.travis.yml b/.travis.yml
index ee1d3fd..3d19f3d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,16 +2,10 @@
 sudo: false
 matrix:
   include:
-    - rust: 1.12.0
-      before_script:
-        # rand 0.4.2 requires rust 1.15, and rand-0.3.22 requires rand-0.4  :/
-        # manually hacking the lockfile due to the limitations of cargo#2773
-        - cargo generate-lockfile
-        - sed -i -e 's/"rand 0.[34].[0-9]\+/"rand 0.3.20/' Cargo.lock
-        - sed -i -e '/^name = "rand"/,/^$/s/version = "0.3.[0-9]\+"/version = "0.3.20"/' Cargo.lock
+    - rust: 1.15.0
       env:
       - ALL=' '
-    - rust: 1.15.0
+    - rust: 1.25.0
       env:
       - ALL=' '
     - rust: stable
diff --git a/Cargo.toml b/Cargo.toml
index 0e72c8c..04be09d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 
 name = "petgraph"
-version = "0.4.11"
+version = "0.4.13"
 license = "MIT/Apache-2.0"
 authors = [
 "bluss",
@@ -27,20 +27,20 @@
 
 [dependencies]
 fixedbitset = { version = "0.1.4" }
-quickcheck = { optional = true, version = "0.4", default-features = false }
-ordermap = { version = "0.3.0", optional = true }
+quickcheck = { optional = true, version = "0.7.1", default-features = false }
+indexmap = { version = "1.0.2", optional = true }
 serde = { version = "1.0", optional = true }
 serde_derive = { version = "1.0", optional = true }
 
 [dev-dependencies]
-rand = "0.3"
+rand = "0.5.5"
 odds = { version = "0.2.19" }
 defmac = "0.1"
 itertools = { version = "0.7.0", default-features = false }
 
 [features]
 default = ["graphmap", "stable_graph"]
-graphmap = ["ordermap"]
+graphmap = ["indexmap"]
 serde-1 = ["serde", "serde_derive"]
 stable_graph = []
 
diff --git a/README.rst b/README.rst
index 3ccd7ca..383a709 100644
--- a/README.rst
+++ b/README.rst
@@ -26,6 +26,17 @@
 Recent Changes
 --------------
 
+- 0.4.13
+
+  - Fix clippy warnings by @jonasbb
+  - Add docs for ``Csr`` by @ksadorf
+  - Fix conflict with new stable method ``find_map`` in new Rust
+
+- 0.4.12
+
+  - Newtype ``Time`` now also implements ``Hash``
+  - Documentation updates for ``Frozen``.
+
 - 0.4.11
 
   - Fix ``petgraph::graph::NodeReferences`` to be publically visible
@@ -187,7 +198,7 @@
   - ``GraphMap`` can now have directed edges. ``GraphMap::new`` is now generic
     in the edge type. ``DiGraphMap`` and ``UnGraphMap`` are new type aliases.
   - Add type aliases ``DiGraph, UnGraph, StableDiGraph, StableUnGraph``
-  - ``GraphMap`` is based on the ordermap crate. Deterministic iteration
+  - ``GraphMap`` is based on the indexmap crate. Deterministic iteration
     order, faster iteration, no side tables needed to convert to ``Graph``.
   - Improved docs for a lot of types and functions.
   - Add graph visitor ``DfsPostOrder``
@@ -297,7 +308,7 @@
   - Add Graph::capacity(), GraphMap::capacity()
   - Fix bug in Graph::reverse()
   - Graph and GraphMap have `quickcheck::Arbitrary` implementations,
-    if optional feature `quickcheck` is enabled.
+    if optional feature `check` is enabled.
 
 - 0.1.16
 
diff --git a/serialization-tests/Cargo.toml b/serialization-tests/Cargo.toml
index 8837c0d..063fd44 100644
--- a/serialization-tests/Cargo.toml
+++ b/serialization-tests/Cargo.toml
@@ -19,6 +19,6 @@
 
 [dev-dependencies]
 serde_json = "1.0"
-quickcheck = { version = "0.4", default-features = false }
-bincode = { version = "0.9" }
+quickcheck = { version = "0.7.1", default-features = false }
+bincode = "1.0.1"
 defmac = "0.1"
diff --git a/serialization-tests/tests/serialization.rs b/serialization-tests/tests/serialization.rs
index 069304f..a82ff88 100644
--- a/serialization-tests/tests/serialization.rs
+++ b/serialization-tests/tests/serialization.rs
@@ -352,7 +352,7 @@
 
 
 // bincode macros
-defmac!(encode ref g => bincode::serialize(g, bincode::Infinite).unwrap());
+defmac!(encode ref g => bincode::serialize(g).unwrap());
 defmac!(decode ref data => bincode::deserialize(data).unwrap());
 defmac!(recode ref g => decode!(encode!(g)));
 
diff --git a/src/algo/dominators.rs b/src/algo/dominators.rs
index 6d08f61..80380af 100644
--- a/src/algo/dominators.rs
+++ b/src/algo/dominators.rs
@@ -213,7 +213,7 @@
                         .map(|p| *node_to_post_order_idx.get(&p).unwrap())
                         .collect()
                 })
-                .unwrap_or(vec![])
+                .unwrap_or_else(Vec::new)
         })
         .collect()
 }
diff --git a/src/astar.rs b/src/astar.rs
index 565953d..794f1c0 100644
--- a/src/astar.rs
+++ b/src/astar.rs
@@ -157,13 +157,9 @@
         let mut path = vec![last];
 
         let mut current = last;
-        loop {
-            if let Some(&previous) = self.came_from.get(&current) {
-                path.push(previous);
-                current = previous;
-            } else {
-                break
-            }
+        while let Some(&previous) = self.came_from.get(&current) {
+            path.push(previous);
+            current = previous;
         }
 
         path.reverse();
diff --git a/src/csr.rs b/src/csr.rs
index 1a237bb..1ce87cc 100644
--- a/src/csr.rs
+++ b/src/csr.rs
@@ -341,7 +341,7 @@
 
     fn neighbors_range(&self, a: NodeIndex<Ix>) -> Range<usize> {
         let index = self.row[a.index()];
-        let end = self.row.get(a.index() + 1).cloned().unwrap_or(self.column.len());
+        let end = self.row.get(a.index() + 1).cloned().unwrap_or_else(|| self.column.len());
         index..end
     }
 
diff --git a/src/graph_impl/stable_graph/mod.rs b/src/graph_impl/stable_graph/mod.rs
index fda91c1..20582a5 100644
--- a/src/graph_impl/stable_graph/mod.rs
+++ b/src/graph_impl/stable_graph/mod.rs
@@ -685,6 +685,22 @@
         }
     }
 
+    /// Return an iterator over either the nodes without edges to them
+    /// (`Incoming`) or from them (`Outgoing`).
+    ///
+    /// An *internal* node has both incoming and outgoing edges.
+    /// The nodes in `.externals(Incoming)` are the source nodes and
+    /// `.externals(Outgoing)` are the sinks of the graph.
+    ///
+    /// For a graph with undirected edges, both the sinks and the sources are
+    /// just the nodes without edges.
+    ///
+    /// The whole iteration computes in **O(|V|)** time.
+    pub fn externals(&self, dir: Direction) -> Externals<N, Ty, Ix>
+    {
+        Externals { iter: self.raw_nodes().iter().enumerate(), dir: dir, ty: PhantomData }
+    }
+
     /// Index the `StableGraph` by two indices, any combination of
     /// node or edge indices is fine.
     ///
@@ -1168,7 +1184,7 @@
     type Item = (NodeIndex<Ix>, &'a N);
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.iter.find_map(|(i, node)| {
+        self.iter.ex_find_map(|(i, node)| {
             node.weight.as_ref().map(move |w| (node_index(i), w))
         })
     }
@@ -1183,7 +1199,7 @@
     where Ix: IndexType
 {
     fn next_back(&mut self) -> Option<Self::Item> {
-        self.iter.rfind_map(|(i, node)| {
+        self.iter.ex_rfind_map(|(i, node)| {
             node.weight.as_ref().map(move |w| (node_index(i), w))
         })
     }
@@ -1360,7 +1376,7 @@
     type Item = EdgeReference<'a, E, Ix>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.iter.find_map(|(i, edge)|
+        self.iter.ex_find_map(|(i, edge)|
             edge.weight.as_ref().map(move |weight| {
                 EdgeReference {
                     index: edge_index(i),
@@ -1375,7 +1391,7 @@
     where Ix: IndexType
 {
     fn next_back(&mut self) -> Option<Self::Item> {
-        self.iter.rfind_map(|(i, edge)|
+        self.iter.ex_rfind_map(|(i, edge)|
             edge.weight.as_ref().map(move |weight| {
                 EdgeReference {
                     index: edge_index(i),
@@ -1386,6 +1402,38 @@
     }
 }
 
+/// An iterator over either the nodes without edges to them or from them.
+pub struct Externals<'a, N: 'a, Ty, Ix: IndexType = DefaultIx> {
+    iter: iter::Enumerate<slice::Iter<'a, Node<Option<N>, Ix>>>,
+    dir: Direction,
+    ty: PhantomData<Ty>,
+}
+
+impl<'a, N: 'a, Ty, Ix> Iterator for Externals<'a, N, Ty, Ix> where
+    Ty: EdgeType,
+    Ix: IndexType,
+{
+    type Item = NodeIndex<Ix>;
+    fn next(&mut self) -> Option<NodeIndex<Ix>>
+    {
+        let k = self.dir.index();
+        loop {
+            match self.iter.next() {
+                None => return None,
+                Some((index, node)) => {
+                    if node.weight.is_some() &&
+                        node.next[k] == EdgeIndex::end() &&
+                        (Ty::is_directed() ||
+                         node.next[1-k] == EdgeIndex::end()) {
+                        return Some(NodeIndex::new(index))
+                    } else {
+                        continue
+                    }
+                },
+            }
+        }
+    }
+}
 
 /// Iterator over the neighbors of a node.
 ///
@@ -1524,7 +1572,7 @@
     type Item = NodeIndex<Ix>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.iter.find_map(|(i, node)| {
+        self.iter.ex_find_map(|(i, node)| {
             if node.weight.is_some() {
                 Some(node_index(i))
             } else { None }
@@ -1539,7 +1587,7 @@
 
 impl<'a, N, Ix: IndexType> DoubleEndedIterator for NodeIndices<'a, N, Ix> {
     fn next_back(&mut self) -> Option<Self::Item> {
-        self.iter.rfind_map(|(i, node)| {
+        self.iter.ex_rfind_map(|(i, node)| {
             if node.weight.is_some() {
                 Some(node_index(i))
             } else { None }
@@ -1570,7 +1618,7 @@
     type Item = EdgeIndex<Ix>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.iter.find_map(|(i, node)| {
+        self.iter.ex_find_map(|(i, node)| {
             if node.weight.is_some() {
                 Some(edge_index(i))
             } else { None }
@@ -1585,7 +1633,7 @@
 
 impl<'a, E, Ix: IndexType> DoubleEndedIterator for EdgeIndices<'a, E, Ix> {
     fn next_back(&mut self) -> Option<Self::Item> {
-        self.iter.rfind_map(|(i, node)| {
+        self.iter.ex_rfind_map(|(i, node)| {
             if node.weight.is_some() {
                 Some(edge_index(i))
             } else { None }
diff --git a/src/graphmap.rs b/src/graphmap.rs
index 945abe0..6b6cab4 100644
--- a/src/graphmap.rs
+++ b/src/graphmap.rs
@@ -14,11 +14,11 @@
 use std::ops::{Index, IndexMut, Deref};
 use std::iter::FromIterator;
 use std::marker::PhantomData;
-use ordermap::OrderMap;
-use ordermap::{
-    Iter as OrderMapIter, IterMut as OrderMapIterMut
+use indexmap::IndexMap;
+use indexmap::map::{
+    Iter as IndexMapIter, IterMut as IndexMapIterMut
 };
-use ordermap::Keys;
+use indexmap::map::Keys;
 
 use {
     EdgeType,
@@ -72,8 +72,8 @@
 /// Depends on crate feature `graphmap` (default).
 #[derive(Clone)]
 pub struct GraphMap<N, E, Ty> {
-    nodes: OrderMap<N, Vec<(N, CompactDirection)>>,
-    edges: OrderMap<(N, N), E>,
+    nodes: IndexMap<N, Vec<(N, CompactDirection)>>,
+    edges: IndexMap<(N, N), E>,
     ty: PhantomData<Ty>,
 }
 
@@ -121,8 +121,8 @@
     /// Create a new `GraphMap` with estimated capacity.
     pub fn with_capacity(nodes: usize, edges: usize) -> Self {
         GraphMap {
-            nodes: OrderMap::with_capacity(nodes),
-            edges: OrderMap::with_capacity(edges),
+            nodes: IndexMap::with_capacity(nodes),
+            edges: IndexMap::with_capacity(edges),
             ty: PhantomData,
         }
     }
@@ -559,7 +559,7 @@
           Ty: EdgeType
 {
     from: N,
-    edges: &'a OrderMap<(N, N), E>,
+    edges: &'a IndexMap<(N, N), E>,
     iter: Neighbors<'a, N, Ty>,
 }
 
@@ -596,7 +596,7 @@
 }
 
 pub struct AllEdges<'a, N, E: 'a, Ty> where N: 'a + NodeTrait {
-    inner: OrderMapIter<'a, (N, N), E>,
+    inner: IndexMapIter<'a, (N, N), E>,
     ty: PhantomData<Ty>,
 }
 
@@ -640,7 +640,7 @@
 }
 
 pub struct AllEdgesMut<'a, N, E: 'a, Ty> where N: 'a + NodeTrait {
-    inner: OrderMapIterMut<'a, (N, N), E>,
+    inner: IndexMapIterMut<'a, (N, N), E>,
     ty: PhantomData<Ty>,
 }
 
@@ -815,7 +815,7 @@
 }
 
 pub struct NodeIdentifiers<'a, N, E: 'a, Ty> where N: 'a + NodeTrait {
-    iter: OrderMapIter<'a, N, Vec<(N, CompactDirection)>>,
+    iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
     ty: PhantomData<Ty>,
     edge_ty: PhantomData<E>,
 }
@@ -847,7 +847,7 @@
 }
 
 pub struct NodeReferences<'a, N, E: 'a, Ty> where N: 'a + NodeTrait {
-    iter: OrderMapIter<'a, N, Vec<(N, CompactDirection)>>,
+    iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
     ty: PhantomData<Ty>,
     edge_ty: PhantomData<E>,
 }
diff --git a/src/iter_utils.rs b/src/iter_utils.rs
index 62a0183..30db2d5 100644
--- a/src/iter_utils.rs
+++ b/src/iter_utils.rs
@@ -2,10 +2,10 @@
 pub trait IterUtilsExt : Iterator {
     /// Return the first element that maps to `Some(_)`, or None if the iterator
     /// was exhausted.
-    fn find_map<F, R>(&mut self, mut f: F) -> Option<R>
+    fn ex_find_map<F, R>(&mut self, mut f: F) -> Option<R>
         where F: FnMut(Self::Item) -> Option<R>
     {
-        while let Some(elt) = self.next() {
+        for elt in self {
             if let result @ Some(_) = f(elt) {
                 return result;
             }
@@ -15,7 +15,7 @@
 
     /// Return the last element from the back that maps to `Some(_)`, or
     /// None if the iterator was exhausted.
-    fn rfind_map<F, R>(&mut self, mut f: F) -> Option<R>
+    fn ex_rfind_map<F, R>(&mut self, mut f: F) -> Option<R>
         where F: FnMut(Self::Item) -> Option<R>,
               Self: DoubleEndedIterator,
     {
diff --git a/src/lib.rs b/src/lib.rs
index 6523894..7554774 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,7 +19,7 @@
 
 extern crate fixedbitset;
 #[cfg(feature = "graphmap")]
-extern crate ordermap;
+extern crate indexmap;
 
 #[cfg(feature = "serde-1")]
 extern crate serde;
diff --git a/src/quickcheck.rs b/src/quickcheck.rs
index 18d40c7..bda1594 100644
--- a/src/quickcheck.rs
+++ b/src/quickcheck.rs
@@ -1,5 +1,4 @@
 extern crate quickcheck;
-
 use self::quickcheck::{Gen, Arbitrary};
 
 use {
@@ -20,6 +19,15 @@
 };
 use visit::NodeIndexable;
 
+/// Return a random float in the range [0, 1.)
+fn random_01<G: Gen>(g: &mut G) -> f64 {
+    // from rand
+    let bits = 53;
+    let scale = 1. / ((1u64 << bits) as f64);
+    let x = g.next_u64();
+    (x >> (64 - bits)) as f64 * scale
+}
+
 /// `Arbitrary` for `Graph` creates a graph by selecting a node count
 /// and a probability for each possible edge to exist.
 ///
@@ -41,7 +49,7 @@
             return Graph::with_capacity(0, 0);
         }
         // use X² for edge probability (bias towards lower)
-        let edge_prob = g.gen_range(0., 1.) * g.gen_range(0., 1.);
+        let edge_prob = random_01(g) * random_01(g);
         let edges = ((nodes as f64).powi(2) * edge_prob) as usize;
         let mut gr = Graph::with_capacity(nodes, edges);
         for _ in 0..nodes {
@@ -52,7 +60,7 @@
                 if !gr.is_directed() && i > j {
                     continue;
                 }
-                let p: f64 = g.gen();
+                let p: f64 = random_01(g);
                 if p <= edge_prob {
                     gr.add_edge(i, j, E::arbitrary(g));
                 }
@@ -107,7 +115,7 @@
             return StableGraph::with_capacity(0, 0);
         }
         // use X² for edge probability (bias towards lower)
-        let edge_prob = g.gen_range(0., 1.) * g.gen_range(0., 1.);
+        let edge_prob = random_01(g) * random_01(g);
         let edges = ((nodes as f64).powi(2) * edge_prob) as usize;
         let mut gr = StableGraph::with_capacity(nodes, edges);
         for _ in 0..nodes {
@@ -120,7 +128,7 @@
                 if !gr.is_directed() && i > j {
                     continue;
                 }
-                let p: f64 = g.gen();
+                let p: f64 = random_01(g);
                 if p <= edge_prob {
                     gr.add_edge(i, j, E::arbitrary(g));
                 }
@@ -188,7 +196,7 @@
         nodes.dedup();
 
         // use X² for edge probability (bias towards lower)
-        let edge_prob = g.gen_range(0., 1.) * g.gen_range(0., 1.);
+        let edge_prob = random_01(g) * random_01(g);
         let edges = ((nodes.len() as f64).powi(2) * edge_prob) as usize;
         let mut gr = GraphMap::with_capacity(nodes.len(), edges);
         for &node in &nodes {
@@ -197,7 +205,7 @@
         for (index, &i) in nodes.iter().enumerate() {
             let js = if Ty::is_directed() { &nodes[..] } else { &nodes[index..] };
             for &j in js {
-                let p: f64 = g.gen();
+                let p: f64 = random_01(g);
                 if p <= edge_prob {
                     gr.add_edge(i, j, E::arbitrary(g));
                 }
diff --git a/src/visit/dfsvisit.rs b/src/visit/dfsvisit.rs
index 91ea1b2..4e8a57b 100644
--- a/src/visit/dfsvisit.rs
+++ b/src/visit/dfsvisit.rs
@@ -78,7 +78,7 @@
 impl<E> ControlFlow for Result<(), E> {
     fn continuing() -> Self { Ok(()) }
     fn should_break(&self) -> bool {
-        if let Err(_) = *self { true } else { false }
+        self.is_err()
     }
 }
 
diff --git a/src/visit/filter.rs b/src/visit/filter.rs
index 07b3ae9..cb64c79 100644
--- a/src/visit/filter.rs
+++ b/src/visit/filter.rs
@@ -10,6 +10,7 @@
     GraphProp,
     IntoEdgeReferences,
     IntoEdges,
+    IntoEdgesDirected,
     IntoNeighbors,
     IntoNeighborsDirected,
     IntoNodeIdentifiers,
@@ -337,6 +338,21 @@
     }
 }
 
+impl<'a, G, F> IntoNeighborsDirected for &'a EdgeFiltered<G, F>
+where
+    G: IntoEdgesDirected,
+    F: FilterEdge<G::EdgeRef>,
+{
+    type NeighborsDirected = EdgeFilteredNeighborsDirected<'a, G, F>;
+    fn neighbors_directed(self, n: G::NodeId, dir: Direction) -> Self::NeighborsDirected {
+        EdgeFilteredNeighborsDirected {
+            iter: self.0.edges_directed(n, dir),
+            f: &self.1,
+            from: n,
+        }
+    }
+}
+
 /// A filtered neighbors iterator.
 pub struct EdgeFilteredNeighbors<'a, G, F: 'a>
     where G: IntoEdges,
@@ -409,6 +425,41 @@
     }
 }
 
+/// A filtered neighbors-directed iterator.
+pub struct EdgeFilteredNeighborsDirected<'a, G, F: 'a>
+where
+    G: IntoEdgesDirected,
+{
+    iter: G::EdgesDirected,
+    f: &'a F,
+    from: G::NodeId,
+}
+
+impl<'a, G, F> Iterator for EdgeFilteredNeighborsDirected<'a, G, F>
+where
+    F: FilterEdge<G::EdgeRef>,
+    G: IntoEdgesDirected,
+{
+    type Item = G::NodeId;
+    fn next(&mut self) -> Option<Self::Item> {
+        let f = self.f;
+        let from = self.from;
+        (&mut self.iter)
+            .filter_map(move |edge| {
+                if f.include_edge(edge) {
+                    if edge.source() != from {
+                        Some(edge.source())
+                    } else {
+                        Some(edge.target()) // includes case where from == source == target
+                    }
+                } else {
+                    None
+                }
+            })
+            .next()
+    }
+}
+
 Data!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
 GraphProp!{delegate_impl [[G, F], G, EdgeFiltered<G, F>, access0]}
 IntoNodeIdentifiers!{delegate_impl [['a, G, F], G, &'a EdgeFiltered<G, F>, access0]}
diff --git a/src/visit/traversal.rs b/src/visit/traversal.rs
index 9aa6f93..cc17f82 100644
--- a/src/visit/traversal.rs
+++ b/src/visit/traversal.rs
@@ -95,7 +95,7 @@
     pub fn next<G>(&mut self, graph: G) -> Option<N>
         where G: IntoNeighbors<NodeId=N>,
     {
-        while let Some(node) = self.stack.pop() {
+        if let Some(node) = self.stack.pop() {
             for succ in graph.neighbors(node) {
                 if self.discovered.visit(succ) {
                     self.stack.push(succ);
@@ -251,7 +251,7 @@
     pub fn next<G>(&mut self, graph: G) -> Option<N>
         where G: IntoNeighbors<NodeId=N>
     {
-        while let Some(node) = self.stack.pop_front() {
+        if let Some(node) = self.stack.pop_front() {
             for succ in graph.neighbors(node) {
                 if self.discovered.visit(succ) {
                     self.stack.push_back(succ);
diff --git a/tests/graph.rs b/tests/graph.rs
index d16e176..04de259 100644
--- a/tests/graph.rs
+++ b/tests/graph.rs
@@ -1463,7 +1463,145 @@
     assert_eq!(set(po), set(g.node_identifiers().filter(|n| (filt.1)(*n))));
 }
 
+#[test]
+fn filtered_edge_reverse() {
+    use petgraph::visit::EdgeFiltered;
+    #[derive(Eq, PartialEq)]
+    enum E {
+        A,
+        B,
+    }
 
+    // Start with single node graph with loop
+    let mut g = Graph::new();
+    let a = g.add_node("A");
+    g.add_edge(a, a, E::A);
+    let ef_a = EdgeFiltered::from_fn(&g, |edge| *edge.weight() == E::A);
+    let mut po = Vec::new();
+    let mut dfs = Dfs::new(&ef_a, a);
+    while let Some(next_n_ix) = dfs.next(&ef_a) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![a]));
+
+    // Check in reverse
+    let mut po = Vec::new();
+    let mut dfs = Dfs::new(&Reversed(&ef_a), a);
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_a)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![a]));
+
+
+    let mut g = Graph::new();
+    let a = g.add_node("A");
+    let b = g.add_node("B");
+    let c = g.add_node("C");
+    let d = g.add_node("D");
+    let e = g.add_node("E");
+    let f = g.add_node("F");
+    let h = g.add_node("H");
+    let i = g.add_node("I");
+    let j = g.add_node("J");
+
+    g.add_edge(a, b, E::A);
+    g.add_edge(b, c, E::A);
+    g.add_edge(c, d, E::B);
+    g.add_edge(d, e, E::A);
+    g.add_edge(e, f, E::A);
+    g.add_edge(e, h, E::A);
+    g.add_edge(e, i, E::A);
+    g.add_edge(i, j, E::A);
+
+    let ef_a = EdgeFiltered::from_fn(&g, |edge| *edge.weight() == E::A);
+    let ef_b = EdgeFiltered::from_fn(&g, |edge| *edge.weight() == E::B);
+
+    // DFS down from a, filtered by E::A.
+    let mut po = Vec::new();
+    let mut dfs = Dfs::new(&ef_a, a);
+    while let Some(next_n_ix) = dfs.next(&ef_a) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![a, b, c]));
+
+    // Reversed DFS from f, filtered by E::A.
+    let mut dfs = Dfs::new(&Reversed(&ef_a), f);
+    let mut po = Vec::new();
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_a)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![d, e, f]));
+
+    // Reversed DFS from j, filtered by E::A.
+    let mut dfs = Dfs::new(&Reversed(&ef_a), j);
+    let mut po = Vec::new();
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_a)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![d, e, i, j]));
+
+    // Reversed DFS from c, filtered by E::A.
+    let mut dfs = Dfs::new(&Reversed(&ef_a), c);
+    let mut po = Vec::new();
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_a)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![a, b, c]));
+
+    // Reversed DFS from c, filtered by E::B.
+    let mut dfs = Dfs::new(&Reversed(&ef_b), c);
+    let mut po = Vec::new();
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_b)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![c]));
+
+    // Reversed DFS from d, filtered by E::B.
+    let mut dfs = Dfs::new(&Reversed(&ef_b), d);
+    let mut po = Vec::new();
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_b)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![c, d]));
+
+    // Now let's test the same graph but undirected
+    
+    let mut g = Graph::new_undirected();
+    let a = g.add_node("A");
+    let b = g.add_node("B");
+    let c = g.add_node("C");
+    let d = g.add_node("D");
+    let e = g.add_node("E");
+    let f = g.add_node("F");
+    let h = g.add_node("H");
+    let i = g.add_node("I");
+    let j = g.add_node("J");
+
+    g.add_edge(a, b, E::A);
+    g.add_edge(b, c, E::A);
+    g.add_edge(c, d, E::B);
+    g.add_edge(d, e, E::A);
+    g.add_edge(e, f, E::A);
+    g.add_edge(e, h, E::A);
+    g.add_edge(e, i, E::A);
+    g.add_edge(i, j, E::A);
+
+    let ef_a = EdgeFiltered::from_fn(&g, |edge| *edge.weight() == E::A);
+    let ef_b = EdgeFiltered::from_fn(&g, |edge| *edge.weight() == E::B);
+    let mut po = Vec::new();
+    let mut dfs = Dfs::new(&Reversed(&ef_b), d);
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_b)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![c, d]));
+
+    let mut po = Vec::new();
+    let mut dfs = Dfs::new(&Reversed(&ef_a), h);
+    while let Some(next_n_ix) = dfs.next(&Reversed(&ef_a)) {
+        po.push(next_n_ix);
+    }
+    assert_eq!(set(po), set(vec![d, e, f, h, i, j]));
+}
 
 #[test]
 fn dfs_visit() {
diff --git a/tests/unionfind.rs b/tests/unionfind.rs
index f5e2bcf..ba3bdc5 100644
--- a/tests/unionfind.rs
+++ b/tests/unionfind.rs
@@ -1,7 +1,7 @@
 extern crate rand;
 extern crate petgraph;
 
-use rand::{Rng, thread_rng, ChaChaRng};
+use rand::{Rng, thread_rng, ChaChaRng, SeedableRng};
 use std::collections::HashSet;
 use petgraph::unionfind::UnionFind;
 
@@ -36,7 +36,7 @@
 #[test]
 fn uf_rand() {
     let n = 1 << 14;
-    let mut rng: ChaChaRng = thread_rng().gen();
+    let mut rng = ChaChaRng::from_rng(thread_rng()).unwrap();
     let mut u = UnionFind::new(n);
     for _ in 0..100 {
         let a = rng.gen_range(0, n);
@@ -50,7 +50,7 @@
 #[test]
 fn uf_u8() {
     let n = 256;
-    let mut rng: ChaChaRng = thread_rng().gen();
+    let mut rng = ChaChaRng::from_rng(thread_rng()).unwrap();
     let mut u = UnionFind::<u8>::new(n);
     for _ in 0..(n * 8) {
         let a = rng.gen();