diff --git a/graphmod.cabal b/graphmod.cabal
--- a/graphmod.cabal
+++ b/graphmod.cabal
@@ -1,12 +1,12 @@
 name:           graphmod
-version:        1.2.6
+version:        1.2.7
 license:        BSD3
 license-file:   LICENSE
 author:         Iavor S. Diatchki
 maintainer:     iavor.diatchki@gmail.com
 homepage:       http://github.com/yav/graphmod/wiki
 build-type:     Simple
-cabal-version:  >= 1.2
+cabal-version:  >= 1.6
 synopsis:       Present the module dependencies of a program as a "dot" graph.
 description:    This package contains a program that computes "dot" graphs
                 from the dependencies of a number of Haskell modules.
@@ -19,3 +19,7 @@
                      haskell-lexer, containers
     hs-source-dirs:  src
     ghc-options:     -Wall -O2
+
+source-repository head
+  type:     git
+  location: git://github.com/yav/graphmod
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -28,7 +28,7 @@
 
                | otherwise ->
                   do g <- graph (add_current opts) (map to_input ms)
-                     putStrLn (make_dot (graph_size opts) (color_scheme opts)
+                     putStr (make_dot (graph_size opts) (color_scheme opts)
                                                       (use_clusters opts) g)
               where opts = foldr ($) default_opts fs
 
@@ -48,6 +48,8 @@
 
 -- type Nodes    = Trie.Trie String [(String,Int)]
 type NodesC   = Trie.Trie String [((NodeT,String),Int)]
+                    -- Maps a path to:   ((node, label), nodeId)
+
 type Edges    = IMap.IntMap Set.IntSet
 
 
@@ -105,29 +107,30 @@
   maybePrune (es,ns) = if prune_edges opts then (pruneEdges es, ns)
                                            else (es,ns)
 
+
+
+
 pruneEdges :: Edges -> Edges
-pruneEdges es = fmap (prune [] . Set.toList) es
+pruneEdges es = foldr checkEdges es (IMap.toList es)
   where
-  -- add nodes that are reachable in one more step than the given set
-  step :: Set.IntSet -> Set.IntSet
-  step      = Set.unions . mapMaybe (`IMap.lookup` es) . Set.toList
+  reachIn _ _ _ [] = False
+  reachIn g tgt visited (x : xs)
+    | x `Set.member` visited  = reachIn g tgt visited xs
+    | x == tgt                = True
+    | otherwise = let vs = neighbours g x
+                  in reachIn g tgt (Set.insert x visited) (vs ++ xs)
 
-  -- compute closure using a naive fix-point
-  reach g   = let g' = fmap (\ns -> Set.union ns (step ns)) g
-              in if g == g' then g else reach g'
-  reachable = reach es
+  neighbours g x = Set.toList (IMap.findWithDefault Set.empty x g)
 
-  x `reachableFrom` y = case IMap.lookup y reachable of
-                          Just rs -> x `Set.member` rs
-                          Nothing -> False
+  reachableIn g x y = reachIn g y Set.empty [x]
 
-  x `reachableFromOneOf` ys = any (x `reachableFrom`) ys
+  rmEdge x y g = IMap.adjust (Set.delete y) x g
 
-  prune done []                   = Set.fromList done
-  prune done (x : xs)
-    | x `reachableFromOneOf` done = prune done xs
-    | x `reachableFromOneOf` xs   = prune done xs
-    | otherwise                   = prune (x : done) xs
+  checkEdge x y g = let g1 = rmEdge x y g
+                    in if reachableIn g1 x y then g1 else g
+
+  checkEdges (x,vs) g = foldr (checkEdge x) g (Set.toList vs)
+
 
 isIgnored :: IgnoreSet -> ModName -> Bool
 isIgnored (Trie.Sub _ (Just IgnoreAll))       _        = True
