private void Visit([NotNull] TVertex u, int depth)
        {
            Debug.Assert(u != null);

            if (depth > MaxDepth)
            {
                return;
            }

            VertexColors[u] = GraphColor.Gray;
            OnDiscoverVertex(u);

            ICancelManager cancelManager = Services.CancelManager;

            foreach (TEdge edge in VisitedGraph.OutEdges(u))
            {
                if (cancelManager.IsCancelling)
                {
                    return;
                }

                OnExamineEdge(edge);
                TVertex v = edge.Target;

                if (!VertexColors.TryGetValue(v, out GraphColor vColor))
                {
                    OnTreeEdge(edge);
                    Visit(v, depth + 1);
                }
                else
                {
                    if (vColor == GraphColor.Gray)
                    {
                        OnBackEdge(edge);
                    }
                    else
                    {
                        OnForwardOrCrossEdge(edge);
                    }
                }
            }

            VertexColors[u] = GraphColor.Black;
            OnVertexFinished(u);
        }