public ReindexedDataResult <GraphConnectivityDefinition <TEdgeData> > CreateCompacted <TEdgeData>(
            GraphConnectivityDefinition <TEdgeData> source,
            IVertexAdjacencyFactory <TEdgeData> verticesFactory,
            bool sharedVerticesInstances,
            IEqualityComparer <VertexAdjacency <TEdgeData> > vertexEqualityComparer = null)
        {
            var oldVertices = source.ToArray();

            var map = oldVertices.SortWithReindexingResult(VertexAdjacencyComparer <TEdgeData> .DefaultWithHighestNumberOfEdgesFirst);

            var cloned = Create(oldVertices,
                                new ReindexedVertexAdjacencyFactoryWrapper <TEdgeData>(map, verticesFactory ?? new VertexAdjacencyFactory <TEdgeData>()), d => d,
                                sharedVerticesInstances, vertexEqualityComparer);

            return(map.ToReindexedDataResult(cloned));
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="ReindexedVertexAdjacencyFactoryWrapper{TEdgeData}" /> class.
 /// </summary>
 /// <param name="translator">The index translator used to convert old vertices indexes to new ones.</param>
 /// <param name="wrapped">The wrapped factory.</param>
 public ReindexedVertexAdjacencyFactoryWrapper(IIndexTranslator translator, IVertexAdjacencyFactory <TEdgeData> wrapped)
 {
     _translator = translator;
     _wrapped    = wrapped;
 }
 /// <summary>
 ///     Initializes a new instance of the <see cref="EdgeDataCloningVertexAdjacencyFactoryWrapper{TEdgeData}" /> class.
 /// </summary>
 /// <param name="wrapped">The wrapped.</param>
 /// <param name="copyEdgeDataCallback">The copy edge data callback.</param>
 public EdgeDataCloningVertexAdjacencyFactoryWrapper(IVertexAdjacencyFactory <TEdgeData> wrapped,
                                                     Func <AdjacentEdge <TEdgeData>, TEdgeData> copyEdgeDataCallback)
 {
     _wrapped = wrapped;
     _copyEdgeDataCallback = copyEdgeDataCallback;
 }
 /// <summary>
 ///     Initializes a new instance of the <see cref="EdgeDataCloningVertexAdjacencyFactoryWrapper{TEdgeData}" /> class.
 /// </summary>
 /// <param name="wrapped">The wrapped.</param>
 /// <param name="copyEdgeDataCallback">The copy edge data callback.</param>
 public EdgeDataCloningVertexAdjacencyFactoryWrapper(IVertexAdjacencyFactory <TEdgeData> wrapped,
                                                     Func <TEdgeData, TEdgeData> copyEdgeDataCallback)
 {
     _wrapped = wrapped;
     _copyEdgeDataCallback = adj => copyEdgeDataCallback(adj.Data);
 }
        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));
        }
 /// <summary>
 ///     Gets the new instance of vertex initialized with specified edges.
 /// </summary>
 /// <param name="source">The source of extension.</param>
 /// <param name="edgesTo">The collection with edges..</param>
 /// <returns>Vertex instance.</returns>
 public static VertexAdjacency <TEdgeData> GetInstance <TEdgeData>(this IVertexAdjacencyFactory <TEdgeData> source,
                                                                   IReadOnlyCollection <AdjacentEdge <TEdgeData> > edgesTo)
 {
     return(source.GetInstance(edgesTo, edgesTo.Count));
 }