public TType Apply(TType source, IDiff <TType> patch)
        {
            if (this.aIdAccessor == null)
            {
                this.aIdAccessor    = IdHelpers.CreateIdAccessor <TItemType, TIdType>(this.aIdProperty);
                this.aApplyItemDiff = this.aMergerImplementation.Partial.Algorithms.GetApplyPatchAlgorithm <TItemType>();
                this.aConvertor     = this.CompileConvertor();
            }

            return(this.ApplyInternal((IEnumerable <TItemType>)source, patch));
        }
        public IDiff <TType> Compute(TType @base, TType changed)
        {
            if (this.aIdAccessor == null)
            {
                this.aIdAccessor   = IdHelpers.CreateIdAccessor <TItemType, TIdType>(this.aIdProperty);
                this.aItemDiff     = this.aMergerImplementation.Partial.Algorithms.GetDiffAlgorithm <TItemType>();
                this.aItemComparer = EqualityComparer <TItemType> .Default;
            }

            return(this.ComputeInternal((IEnumerable <TItemType>)@base, (IEnumerable <TItemType>)changed));
        }
        public IDiff <TType> MergeDiffs(IDiff <TType> left, IDiff <TType> right, IConflictContainer conflicts)
        {
            if (this.aIdAccessor == null)
            {
                if (this.aIdProperty == null)
                {
                    ParameterExpression obj = Expression.Parameter(typeof(TItemType), "obj");

                    Expression <Func <TItemType, TIdType> > identityFunction = Expression.Lambda <Func <TItemType, TIdType> >(
                        obj, obj
                        );

                    this.aIdAccessor = identityFunction.Compile();
                }
                else
                {
                    this.aIdAccessor = IdHelpers.CreateIdAccessor <TItemType, TIdType>(this.aIdProperty);
                }

                this.aMergeItemsDiffs = this.aMergerImplementation.Partial.Algorithms.GetMergeDiffsAlgorithm <TItemType>();
            }

            Dictionary <TIdType, IDiffUnorderedCollectionItem> rightIndex = new Dictionary <TIdType, IDiffUnorderedCollectionItem>(right.Count);

            foreach (IDiffItem item in right)
            {
                rightIndex[this.GetID(item)] = (IDiffUnorderedCollectionItem)item;
            }

            List <IDiffItem> ret = new List <IDiffItem>(left.Count + right.Count);

            foreach (var leftItem in left.Cast <IDiffUnorderedCollectionItem>())
            {
                IDiffUnorderedCollectionItem rightItem;

                TIdType id = this.GetID(leftItem);

                if (rightIndex.TryGetValue(id, out rightItem))
                {
                    rightIndex.Remove(id);

                    this.ProcessConflict(id, leftItem, rightItem, ret, conflicts);
                }
                else
                {
                    ret.Add(leftItem);
                }
            }

            ret.AddRange(rightIndex.Values);

            return(new Diff <TType>(ret));
        }