/// <summary>
        /// The actual crawler routine. It visits the specified vertex over the edge used. If the vertex is visitable over multiple edges from the last visited vertex,
        /// the routine is called multiple times.
        /// </summary>
        /// <param name="vertex">The vertex.</param>
        /// <param name="verticesProcessed">The vertices processed.</param>
        /// <param name="edges">The edges usable to visit the vertex.</param>
        private void Visit(TVertex vertex, IDictionary <TVertex, VertexColor> verticesProcessed, HashSet <TEdge> edges)
        {
            if (_abortCrawl)
            {
                return;
            }
            if (!verticesProcessed.ContainsKey(vertex))
            {
                verticesProcessed.Add(vertex, VertexColor.NotVisited);
            }
            if (verticesProcessed[vertex] == VertexColor.Visiting)
            {
                // check if we ran into a cycle, in the case of a directed graph
                if (_graphToCrawl.IsDirected)
                {
                    if (_detectCycles)
                    {
                        // cycle detected, as we're reaching a vertex (via recursion) which is still in progress. It depends on the CycleDetected routine if we may
                        // proceed.
                        bool continueTraverse = CycleDetected(vertex, edges);
                        if (!continueTraverse)
                        {
                            // simply break off traversal.
                            return;
                        }
                    }
                }
                else
                {
                    // as the crawler visits vertices over all the edges at once, in an undirected graph there is no such situation where the visited vertex
                    // has more edges to the previous vertex as the previous vertex has to the currently visited vertex.
                    // break off traversal
                    return;
                }
            }
            if (verticesProcessed[vertex] == VertexColor.Visited)
            {
                // vertex has already been processed
                return;
            }
            verticesProcessed[vertex] = VertexColor.Visiting;

            MultiValueDictionary <TVertex, TEdge> adjacencyList = _graphToCrawl.GetAdjacencyListForVertex(vertex);

            OnVisiting(vertex, edges);

            // crawl to all this vertex' related vertices, if they've not yet been processed.
            foreach (KeyValuePair <TVertex, HashSet <TEdge> > relatedVertexEdgesTuple in adjacencyList)
            {
                if (_abortCrawl)
                {
                    break;
                }
                // recurse to the related vertex, over the edges in the list of edges. We simply pass the whole hashset as it doesn't matter which edge is picked
                // to crawl the graph, but an algorithm might want to know which edges to pick from, so it's better to pass them as a whole than to pass them one by
                // one in a non-sequential order (through backtracking)
                Visit(relatedVertexEdgesTuple.Key, verticesProcessed, relatedVertexEdgesTuple.Value);
            }

            OnVisited(vertex, edges);
            verticesProcessed[vertex] = VertexColor.Visited;
        }