protected static IEnumerable <T> GetPath(IMutableBidirectionalGraph <T, IEdge <T> > graph)
        {
            var result     = new LinkedList <T>();
            var candidates = new HashSet <T>(graph.Vertices.Where(graph.IsOutEdgesEmpty), new IdentityComparer <T>());

            while (candidates.Count > 0)
            {
                var component = candidates.First();
                candidates.Remove(component);

                result.AddFirst(component);

                var inEdges = graph.InEdges(component).ToList();
                graph.RemoveVertex(component);

                foreach (var inEdge in inEdges)
                {
                    if (graph.IsOutEdgesEmpty(inEdge.Source))
                    {
                        candidates.Add(inEdge.Source);
                    }
                }
            }

            return(result);
        }
        public static void DeleteVerticesAndMergeEdges <TVertex, TEdge>
            (this IMutableBidirectionalGraph <TVertex, TEdge> graph, TVertex vertexToDelete,
            Func <TEdge, TEdge, TEdge> mergeFunc)
            where TEdge : IEdge <TVertex>
        {
            if (graph.IsInEdgesEmpty(vertexToDelete) || graph.IsOutEdgesEmpty(vertexToDelete))
            {
                //simple case
                graph.RemoveVertex(vertexToDelete);
            }
            else
            {
                //need to keep connections
                var newEdges = from e1 in graph.InEdges(vertexToDelete)
                               from e2 in graph.OutEdges(vertexToDelete)
                               select mergeFunc(e1, e2);

                //create edges
                var newEdgesList = newEdges.ToList();

                graph.AddEdgeRange(newEdgesList);
                graph.RemoveVertex(vertexToDelete);
            }
        }