<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def model_to_dict(instance, **options):
    "Takes a model instance and converts it into a dict."

    options = _defaults(options)
    attrs = {}

    if options['prehook']:
        if isinstance(options['prehook'], collections.Callable):
            instance = options['prehook'](instance)
            if instance is None:
                return attrs

    # Items in the `fields` list are the output aliases, not the raw
    # accessors (field, method, property names)
    for alias in options['fields']:

        # Get the accessor for the object
        accessor = options['aliases'].get(alias, alias)

        # Create the key that will be used in the output dict
        key = options['prefix'] + alias

        # Optionally camelcase the key
        if options['camelcase']:
            key = convert_to_camel(key)

        # Get the field value. Use the mapped value to the actually property or
        # method name. `value` may be a number of things, so the various types
        # are checked below.
        value = get_field_value(instance, accessor,
                                allow_missing=options['allow_missing'])

        # Related objects, perform some checks on their options
        if isinstance(value, (models.Model, QuerySet)):
            _options = _defaults(options['related'].get(accessor, {}))

            # If the `prefix` follows the below template, generate the
            # `prefix` for the related object
            if '%(accessor)s' in _options['prefix']:
                _options['prefix'] = _options['prefix'] % {'accessor': alias}

            if isinstance(value, models.Model):
                if len(_options['fields']) == 1 and _options['flat'] \
                        and not _options['merge']:
                    value = list(serialize(value, **_options).values())[0]
                else:
                    # Recurse, get the dict representation
                    _attrs = serialize(value, **_options)

                    # Check if this object should be merged into the parent,
                    # otherwise nest it under the accessor name
                    if _options['merge']:
                        attrs.update(_attrs)
                        continue

                    value = _attrs
            else:
                value = serialize(value, **_options)

        attrs[key] = value

    # Apply post-hook to serialized attributes
    if options['posthook']:
        attrs = options['posthook'](instance, attrs)

    return attrs