public void TryGetOutEdges()
        {
            var graph = new TransitionFactoryImplicitGraph <CloneableTestVertex, Edge <CloneableTestVertex> >();

            var vertex0 = new CloneableTestVertex("0");
            var vertex1 = new CloneableTestVertex("1");
            var vertex2 = new CloneableTestVertex("2");
            var vertex3 = new CloneableTestVertex("3");
            var vertex4 = new CloneableTestVertex("4");
            var vertex5 = new CloneableTestVertex("5");

            var edge1 = new Edge <CloneableTestVertex>(vertex1, vertex2);
            var edge2 = new Edge <CloneableTestVertex>(vertex1, vertex2);
            var edge3 = new Edge <CloneableTestVertex>(vertex1, vertex3);
            var edge4 = new Edge <CloneableTestVertex>(vertex2, vertex2);
            var edge5 = new Edge <CloneableTestVertex>(vertex2, vertex4);
            var edge6 = new Edge <CloneableTestVertex>(vertex3, vertex1);
            var edge7 = new Edge <CloneableTestVertex>(vertex4, vertex5);

            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(vertex1, Enumerable.Empty <Edge <CloneableTestVertex> >()));
            AssertNoOutEdge(graph, vertex1);

            graph.ClearTransitionFactories();
            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(new[]
            {
                new TestTransitionFactory <CloneableTestVertex> .VertexEdgesSet(vertex1, new[] { edge1, edge2, edge3 }),
                new TestTransitionFactory <CloneableTestVertex> .VertexEdgesSet(vertex2, new[] { edge4 }),
                new TestTransitionFactory <CloneableTestVertex> .VertexEdgesSet(vertex3, new[] { edge6 }),
            }));

            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(vertex2, new[] { edge5 }));
            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(vertex4, new[] { edge7 }));

            Assert.IsFalse(graph.TryGetOutEdges(vertex0, out _));

            Assert.IsFalse(graph.TryGetOutEdges(vertex5, out _));   // Vertex5 was not discovered

            Assert.IsTrue(graph.TryGetOutEdges(vertex3, out IEnumerable <Edge <CloneableTestVertex> > gotEdges));
            CollectionAssert.AreEqual(new[] { edge6 }, gotEdges);

            Assert.IsTrue(graph.TryGetOutEdges(vertex1, out gotEdges));
            CollectionAssert.AreEqual(new[] { edge1, edge2, edge3 }, gotEdges);

            // Trigger discover of vertex5
            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            graph.OutEdges(vertex4);

            Assert.IsTrue(graph.TryGetOutEdges(vertex5, out gotEdges));
            CollectionAssert.IsEmpty(gotEdges);
        }
        public void TryGetOutEdges_WithFilter()
        {
            var graph = new TransitionFactoryImplicitGraph <CloneableTestVertex, Edge <CloneableTestVertex> >();

            var vertex1 = new CloneableTestVertex("1");
            var vertex2 = new CloneableTestVertex("2");
            var vertex3 = new CloneableTestVertex("3");
            var vertex4 = new CloneableTestVertex("4");
            var vertex5 = new CloneableTestVertex("5");

            var edge1 = new Edge <CloneableTestVertex>(vertex1, vertex2);
            var edge2 = new Edge <CloneableTestVertex>(vertex1, vertex2);
            var edge3 = new Edge <CloneableTestVertex>(vertex1, vertex3);
            var edge4 = new Edge <CloneableTestVertex>(vertex2, vertex2);
            var edge5 = new Edge <CloneableTestVertex>(vertex2, vertex4);
            var edge6 = new Edge <CloneableTestVertex>(vertex3, vertex1);
            var edge7 = new Edge <CloneableTestVertex>(vertex4, vertex5);

            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(vertex1, Enumerable.Empty <Edge <CloneableTestVertex> >()));
            AssertNoOutEdge(graph, vertex1);

            graph.ClearTransitionFactories();
            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(new[]
            {
                new TestTransitionFactory <CloneableTestVertex> .VertexEdgesSet(vertex1, new[] { edge1, edge2, edge3 }),
                new TestTransitionFactory <CloneableTestVertex> .VertexEdgesSet(vertex2, new[] { edge4 }),
                new TestTransitionFactory <CloneableTestVertex> .VertexEdgesSet(vertex3, new[] { edge6 }),
            }));

            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(vertex2, new[] { edge5 }));
            graph.AddTransitionFactory(
                new TestTransitionFactory <CloneableTestVertex>(vertex4, new[] { edge7 }));

            graph.SuccessorVertexPredicate = vertex => vertex != vertex4;
            graph.SuccessorEdgePredicate   = edge => edge.Source != edge.Target;

            Assert.IsTrue(graph.TryGetOutEdges(vertex2, out IEnumerable <Edge <CloneableTestVertex> > gotEdges));
            CollectionAssert.IsEmpty(gotEdges); // Both edges filtered by the 2 filters combined

            // Restore no filter
            graph.SuccessorVertexPredicate = vertex => true;
            graph.SuccessorEdgePredicate   = edge => true;

            Assert.IsTrue(graph.TryGetOutEdges(vertex2, out gotEdges));
            CollectionAssert.AreEqual(new[] { edge4, edge5 }, gotEdges);
        }