/// <summary>
        /// The Topological Sorting algorithm
        /// </summary>
        public static IEnumerable <T> Sort <T>(IGraph <T> Graph) where T : IComparable <T>
        {
            // If the graph is either null or is not a DAG, throw exception.
            if (Graph == null)
            {
                throw new ArgumentNullException();
            }
            else if (!Graph.IsDirected || CyclesDetector.IsCyclic <T>(Graph))
            {
                throw new Exception("The graph is not a DAG.");
            }

            var visited       = new HashSet <T>();
            var topoSortStack = new DataStructures.Lists.Stack <T>();

            foreach (var vertex in Graph.Vertices)
            {
                if (!visited.Contains(vertex))
                {
                    _topoSortHelper <T>(Graph, vertex, ref topoSortStack, ref visited);
                }
            }

            return(topoSortStack);
        }
        /// <summary>
        /// Returns an enumerable collection of nodes that specify the shortest path from the source vertex to the destination vertex.
        /// </summary>
        public IEnumerable <T> ShortestPathTo(T destinationVertex)
        {
            if (!_nodesToIndices.ContainsKey(destinationVertex))
            {
                throw new Exception("Graph doesn't have the specified vertex.");
            }
            else if (!HasPathTo(destinationVertex))
            {
                return(null);
            }

            int indexOfDest = _nodesToIndices[destinationVertex];

            var stack = new DataStructures.Lists.Stack <T>();

            int index;

            for (index = indexOfDest; _distances[index] != 0; index = _predecessors[index])
            {
                stack.Push(_indicesToNodes[index]);
            }

            // Push the source vertex
            stack.Push(_indicesToNodes[index]);

            return(stack);
        }
        /// <summary>
        /// Private recursive helper.
        /// </summary>
        private static void _topoSortHelper <T>(IGraph <T> graph, T source, ref DataStructures.Lists.Stack <T> topoSortStack, ref HashSet <T> visited) where T : IComparable <T>
        {
            visited.Add(source);

            foreach (var adjacent in graph.Neighbours(source))
            {
                if (!visited.Contains(adjacent))
                {
                    _topoSortHelper <T>(graph, adjacent, ref topoSortStack, ref visited);
                }
            }

            topoSortStack.Push(source);
        }
        /// <summary>
        /// A depth first search traversal of the graph, starting from a specified vertex.
        /// Returns the visited vertices of the graph.
        /// </summary>
        public virtual IEnumerable <T> DepthFirstWalk(T source)
        {
            // Check for existence of source
            if (VerticesCount == 0)
            {
                return(new ArrayList <T>(0));
            }
            else if (!HasVertex(source))
            {
                throw new KeyNotFoundException("The source vertex doesn't exist.");
            }

            var visited     = new HashSet <T>();
            var stack       = new DataStructures.Lists.Stack <T>();
            var listOfNodes = new ArrayList <T>(VerticesCount);

            stack.Push(source);

            while (!stack.IsEmpty)
            {
                var current = stack.Pop();

                if (!visited.Contains(current))
                {
                    listOfNodes.Add(current);
                    visited.Add(current);

                    foreach (var adjacent in Neighbours(current))
                    {
                        if (!visited.Contains(adjacent))
                        {
                            stack.Push(adjacent);
                        }
                    }
                }
            }

            return(listOfNodes);
        }