/// <summary>
        /// Update existing object from encoded values
        /// </summary>
        public static object UpdateInstance(object instance, Entry encoded, ICustomSerialization customSerialization)
        {
            var filtered = customSerialization.WriteFilter(instance.GetType(), encoded.SubEntries);

            foreach (var mapped in filtered)
            {
                var property            = mapped.Property;
                var propertyType        = mapped.Property.PropertyType;
                var doNotUpdateProperty = false;

                // Do not operate on faulty properties or read-only properties
                // For security reasons read the flag from the property again
                if (mapped.Entry?.Value.Type == EntryValueType.Exception || property.GetCustomAttribute <ReadOnlyAttribute>()?.IsReadOnly == true)
                {
                    continue;
                }

                // Try to assign value to the property
                var currentValue = mapped.Property.GetValue(instance);
                var value        = mapped.Entry == null
                    ? customSerialization.DefaultValue(property, currentValue)
                    : customSerialization.ConvertValue(propertyType, property, mapped.Entry, currentValue);

                // Value types, strings and streams do not need recursion
                if (ValueOrStringType(propertyType) || typeof(Stream).IsAssignableFrom(propertyType))
                {
                }
                // Update collection from entry
                else if (IsCollection(propertyType) && mapped.Entry != null)
                {
                    // Pick collection strategy
                    var strategy = CreateStrategy(value, currentValue, propertyType, customSerialization, mapped.Property, instance);
                    UpdateCollection(currentValue, mapped.Property.PropertyType, mapped.Property, mapped.Entry, strategy, customSerialization);
                    if (strategy is ArrayIListStrategy)
                    {
                        doNotUpdateProperty = true;
                    }
                }
                // Update class
                else if (propertyType.IsClass)
                {
                    UpdateInstance(value, mapped.Entry ?? new Entry(), customSerialization);
                }
                else
                {
                    throw new SerializationException($"Unsupported property {property.Name} on {instance.GetType().Name}!");
                }

                // Write new value to property
                if (property.CanWrite && !doNotUpdateProperty)
                {
                    mapped.Property.SetValue(instance, value);
                }
            }

            return(instance);
        }