<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def create_image_metadata(data):
 """Generate metadata dict for a new image from a given form data."""


    # Default metadata
    meta = {'protected': data.get('protected', False),
            'disk_format': data.get('disk_format', 'raw'),
            'container_format': data.get('container_format', 'bare'),
            'min_disk': data.get('min_disk') or 0,
            'min_ram': data.get('min_ram') or 0,
            'name': data.get('name', '')}

    # Glance does not really do anything with container_format at the
    # moment. It requires it is set to the same disk_format for the three
    # Amazon image types, otherwise it just treats them as 'bare.' As such
    # we will just set that to be that here instead of bothering the user
    # with asking them for information we can already determine.
    if meta['disk_format'] in ('ami', 'aki', 'ari',):
        meta['container_format'] = meta['disk_format']
    elif meta['disk_format'] == 'docker':
        # To support docker containers we allow the user to specify
        # 'docker' as the format. In that case we really want to use
        # 'raw' as the disk format and 'docker' as the container format.
        meta['disk_format'] = 'raw'
        meta['container_format'] = 'docker'
    elif meta['disk_format'] == 'ova':
        # If the user wishes to upload an OVA using Horizon, then
        # 'ova' must be the container format and 'vmdk' must be the disk
        # format.
        meta['container_format'] = 'ova'
        meta['disk_format'] = 'vmdk'

    properties = {}

    for prop, key in [('description', 'description'),
                      ('kernel_id', 'kernel'),
                      ('ramdisk_id', 'ramdisk'),
                      ('architecture', 'architecture')]:
        if data.get(key):
            properties[prop] = data[key]

    _handle_unknown_properties(data, properties)

    if ('visibility' in data and
            data['visibility'] not in ['public', 'private', 'community',
                                       'shared']):
        raise KeyError('invalid visibility option: %s' % data['visibility'])
    _normalize_is_public_filter(data)

    if VERSIONS.active < 2:
        meta['properties'] = properties
        meta['is_public'] = data.get('is_public', False)
    else:
        meta['visibility'] = data.get('visibility', 'private')
        meta.update(properties)

    return meta