private bool IsIncluded(AdjacentEdge <TEdgeData> adj) => _owner.SelectEdgePredicate.Invoke(adj.ToEdge(_currentIndex));
        public GraphConnectivityDefinition <TTargetEdgeData> Create <TSrcEdgeData, TTargetEdgeData>(
            IReadOnlyList <VertexAdjacency <TSrcEdgeData> > sourceAdjacency,
            IVertexAdjacencyFactory <TTargetEdgeData> verticesFactory   = null,
            Func <TSrcEdgeData, TTargetEdgeData> targetEdgeDataSelector = null,
            bool sharedVerticesInstances = false,
            IEqualityComparer <VertexAdjacency <TSrcEdgeData> > vertexEqualityComparer = null)
        {
            if (sourceAdjacency == null || sourceAdjacency.Count <= 0)
            {
                return(GetEmpty <TTargetEdgeData>());
            }

            if (verticesFactory == null)
            {
                verticesFactory = new VertexAdjacencyFactory <TTargetEdgeData>();
            }

            if (targetEdgeDataSelector == null)
            {
                if (EmptyValue.IsEmptyValueType <TTargetEdgeData>())
                {
                    targetEdgeDataSelector = _ => (TTargetEdgeData)(object)EmptyValue.Value;
                }
                else
                {
                    if (!typeof(TTargetEdgeData).IsAssignableFrom(typeof(TSrcEdgeData)))
                    {
                        throw new ArgumentNullException(nameof(targetEdgeDataSelector),
                                                        "Edge data selector can't be evaluated for specified types and must be defined.");
                    }

                    targetEdgeDataSelector = prev => (TTargetEdgeData)(object)prev;
                }
            }

            var oldVertices = sourceAdjacency;

            var destItemsCount = oldVertices.GetIndexOfLastNotEmptyVertex() + 1;

            var newVertices = new VertexAdjacency <TTargetEdgeData> [destItemsCount];

            var oldToNewVertexInstanceMap = sharedVerticesInstances
                                ? new Dictionary <VertexAdjacency <TSrcEdgeData>, VertexAdjacency <TTargetEdgeData> >(
                vertexEqualityComparer ?? VertexAdjacencyComparer <TSrcEdgeData> .DefaultWithHighestNumberOfEdgesFirst)
                                : null;

            for (var idx = 0; idx < destItemsCount; idx++)
            {
                var oldVertex = oldVertices[idx];

                VertexAdjacency <TTargetEdgeData> newVertex;

                if (oldToNewVertexInstanceMap != null)
                {
                    if (!oldToNewVertexInstanceMap.TryGetValue(oldVertex, out newVertex))
                    {
                        newVertex = verticesFactory.GetInstance(
                            oldVertex.Select(e => AdjacentEdge.Create(e.Destination, targetEdgeDataSelector.Invoke(e.Data))),
                            oldVertex.Count);

                        oldToNewVertexInstanceMap.Add(oldVertex, newVertex);
                    }
                }
                else
                {
                    newVertex = verticesFactory.GetInstance(
                        oldVertex.Select(e => AdjacentEdge.Create(e.Destination, targetEdgeDataSelector.Invoke(e.Data))),
                        oldVertex.Count);
                }

                newVertices[idx] = newVertex;
            }

            return(CreateEmptyTailWrapperOf(newVertices, oldVertices.Count));
        }