'Updates an existing image with the registry.
:param request: The WSGI/Webob Request object
:param id: The opaque image identifier
:returns: Returns the updated image information as a mapping'

@utils.mutating
def update(self, req, id, image_meta, image_data):

    self._enforce(req, 'modify_image')
    is_public = image_meta.get('is_public')
    if is_public:
        self._enforce(req, 'publicize_image')
    if Controller._copy_from(req):
        self._enforce(req, 'copy_from')
    if (image_data or Controller._copy_from(req)):
        self._enforce(req, 'upload_image')
    orig_image_meta = self.get_image_meta_or_404(req, id)
    orig_status = orig_image_meta['status']
    if (orig_status == 'deleted'):
        msg = _('Forbidden    to    update    deleted    image.')
        raise HTTPForbidden(explanation=msg, request=req, content_type='text/plain')
    if (req.context.is_admin is False):
        for key in ACTIVE_IMMUTABLE:
            if (((orig_status == 'active') or (orig_status == 'deactivated')) and (key in image_meta) and (image_meta.get(key) != orig_image_meta.get(key))):
                msg = (_("Forbidden    to    modify    '%(key)s'    of    %(status)s    image.") % {'key': key, 'status': orig_status})
                raise HTTPForbidden(explanation=msg, request=req, content_type='text/plain')
    for key in IMMUTABLE:
        if ((key in image_meta) and (image_meta.get(key) != orig_image_meta.get(key))):
            msg = (_("Forbidden    to    modify    '%s'    of    image.") % key)
            raise HTTPForbidden(explanation=msg, request=req, content_type='text/plain')
    purge_props = req.headers.get('x-glance-registry-purge-props', True)
    purge_props = (strutils.bool_from_string(purge_props) and (image_data is None))
    if ((image_data is not None) and (orig_status != 'queued')):
        raise HTTPConflict(_('Cannot    upload    to    an    unqueued    image'))
    location = self._external_source(image_meta, req)
    reactivating = ((orig_status != 'queued') and location)
    activating = ((orig_status == 'queued') and (location or image_data))
    orig_or_updated_loc = (location or orig_image_meta.get('location'))
    if orig_or_updated_loc:
        try:
            if ((is_public is not None) or (location is not None)):
                self.update_store_acls(req, id, orig_or_updated_loc, public=is_public)
        except store.BadStoreUri:
            msg = (_('Invalid    location:    %s') % location)
            LOG.warn(msg)
            raise HTTPBadRequest(explanation=msg, request=req, content_type='text/plain')
    if reactivating:
        msg = _('Attempted    to    update    Location    field    for    an    image    not    in    queued    status.')
        raise HTTPBadRequest(explanation=msg, request=req, content_type='text/plain')
    orig_keys = set(orig_image_meta['properties'])
    new_keys = set(image_meta['properties'])
    self._enforce_update_protected_props(orig_keys.intersection(new_keys), image_meta, orig_image_meta, req)
    self._enforce_create_protected_props(new_keys.difference(orig_keys), req)
    if purge_props:
        self._enforce_delete_protected_props(orig_keys.difference(new_keys), image_meta, orig_image_meta, req)
    self._enforce_image_property_quota(image_meta, orig_image_meta=orig_image_meta, purge_props=purge_props, req=req)
    try:
        if location:
            image_meta['size'] = self._get_size(req.context, image_meta, location)
        image_meta = registry.update_image_metadata(req.context, id, image_meta, purge_props)
        if activating:
            image_meta = self._handle_source(req, id, image_meta, image_data)
    except exception.Invalid as e:
        msg = (_('Failed    to    update    image    metadata.    Got    error:    %s') % encodeutils.exception_to_unicode(e))
        LOG.warn(msg)
        raise HTTPBadRequest(explanation=msg, request=req, content_type='text/plain')
    except exception.ImageNotFound as e:
        msg = (_('Failed    to    find    image    to    update:    %s') % encodeutils.exception_to_unicode(e))
        LOG.warn(msg)
        raise HTTPNotFound(explanation=msg, request=req, content_type='text/plain')
    except exception.Forbidden as e:
        msg = (_('Forbidden    to    update    image:    %s') % encodeutils.exception_to_unicode(e))
        LOG.warn(msg)
        raise HTTPForbidden(explanation=msg, request=req, content_type='text/plain')
    except (exception.Conflict, exception.Duplicate) as e:
        LOG.warn(encodeutils.exception_to_unicode(e))
        raise HTTPConflict(body=_('Image    operation    conflicts'), request=req, content_type='text/plain')
    else:
        self.notifier.info('image.update', redact_loc(image_meta))
    image_meta = redact_loc(image_meta)
    self._enforce_read_protected_props(image_meta, req)
    return {'image_meta': image_meta}
