public static IReadOnlyList <object> Deserialize(this DbContext context, IEntityEntryReader reader, ResolveConflict?resolveConflict = null)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var finder       = new EntityEntryFinder(context);
            var synchronizer = new TemporaryIdentitySynchronizer( );
            var entities     = new List <object> ( );
            var properties   = new Dictionary <IProperty, object?> ( );
            var collections  = new List <CollectionEntry> ( );

            while (reader.ReadEntry( ))
            {
                var entityType  = reader.ReadEntityType(context.Model);
                var entityState = reader.ReadEntityState( );

                properties.Clear( );
                while (reader.ReadProperty(out var property, out var value))
                {
                    properties [property] = value;
                }

                var entityEntry = finder.FindOrCreate(entityType, properties);
                var conflict    = resolveConflict != null &&
                                  entityEntry.State != EntityState.Detached ? resolveConflict(entityEntry, entityState, properties) :
                                  ConflictResolution.OverwriteExistingEntry;

                if (conflict == ConflictResolution.KeepExistingEntry)
                {
                    while (reader.ReadModifiedProperty(out _, out _))
                    {
                        ;
                    }
                    while (reader.ReadNavigationState(out _))
                    {
                        ;
                    }

                    entities.Add(entityEntry.Entity);

                    continue;
                }

                foreach (var entry in properties)
                {
                    var propertyEntry = entityEntry.SetProperty(entry.Key, entry.Value);

                    if (propertyEntry.Metadata.IsConcurrencyToken)
                    {
                        // TODO: Check original version...
                    }

                    if (entityState != EntityState.Unchanged)
                    {
                        synchronizer.SynchronizeTemporaryIdentity(propertyEntry);
                    }
                }

                entityEntry.SetState(entityState);

                while (reader.ReadModifiedProperty(out var property, out var value))
                {
                    entityEntry.SetModifiedProperty(property, value);
                }

                while (reader.ReadNavigationState(out var navigation))
                {
                    var collection = entityEntry.Collection(navigation);
                    if (!collection.IsLoaded)
                    {
                        collections.Add(collection);
                    }
                }

                entities.Add(entityEntry.Entity);
            }

            foreach (var collection in collections)
            {
                if (collection.CurrentValue == null)
                {
                    collection.CurrentValue = (IEnumerable)collection.Metadata.GetCollectionAccessor( ).Create( );
                }

                collection.IsLoaded = true;
            }

            return(entities.AsReadOnly( ));
        }
        public static void AcceptChanges(this DbContext context, IEntityEntryReader reader)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            var finder     = new EntityEntryFinder(context);
            var properties = new Dictionary <IProperty, object?> ( );

            while (reader.ReadEntry( ))
            {
                var entityType  = reader.ReadEntityType(context.Model);
                var entityState = reader.ReadEntityState( );

                properties.Clear( );
                while (reader.ReadProperty(out var property, out var value))
                {
                    properties [property] = value;
                }

                var entityEntry = finder.Find(entityType, properties);
                if (entityEntry != null)
                {
                    while (reader.ReadModifiedProperty(out var property, out var value))
                    {
                        entityEntry.SetProperty(property, value);
                    }
                }
                else
                {
                    var modifiedProperties = new List <(IProperty Property, object?Value)> ( );
                    while (reader.ReadModifiedProperty(out var property, out var value))
                    {
                        modifiedProperties.Add((property, value));
                        properties [property] = value;
                    }

                    entityEntry = finder.Find(entityType, properties);
                    if (entityEntry != null)
                    {
                        foreach (var modified in modifiedProperties)
                        {
                            entityEntry.SetProperty(modified.Property, modified.Value);
                        }
                    }
                    else
                    {
                        // TODO: Log entries not found
                    }
                }

                while (reader.ReadNavigationState(out var navigation))
                {
                    ;
                }
            }

            context.ChangeTracker.AcceptAllChanges( );
        }