'Deletes all the records referenced by the ir.model.data entries
``ids`` along with their corresponding database backed (including
dropping tables, columns, FKs, etc, as long as there is no other
ir.model.data entry holding a reference to them (which indicates that
they are still owned by another module).
Attempts to perform the deletion in an appropriate order to maximize
the chance of gracefully deleting all records.
This step is performed as part of the full uninstallation of a module.'

@api.model
def _module_data_uninstall(self, modules_to_remove):

    if (not ((self._uid == SUPERUSER_ID) or self.env.user.has_group('base.group_system'))):
        raise AccessError(_('Administrator    access    is    required    to    uninstall    a    module'))
    self = self.with_context(**{MODULE_UNINSTALL_FLAG: True})
    datas = self.search([('module', 'in', modules_to_remove)])
    wkf_todo = []
    to_unlink = tools.OrderedSet()
    undeletable = self.browse([])
    for data in datas.sorted(key='id', reverse=True):
        model = data.model
        res_id = data.res_id
        to_unlink.add((model, res_id))
        if (model == 'workflow.activity'):
            self._cr.execute('SELECT    res_type,    res_id    FROM    wkf_instance    WHERE    id    IN    (SELECT    inst_id    FROM    wkf_workitem    WHERE    act_id=%s)', (res_id,))
            wkf_todo.extend(self._cr.fetchall())
            self._cr.execute("UPDATE    wkf_transition    SET    condition='True',    group_id=NULL,    signal=NULL,    act_to=act_from,    act_from=%s    WHERE    act_to=%s", (res_id, res_id))
            self.invalidate_cache()
    for (model, res_id) in wkf_todo:
        try:
            record = self.env[model].browse(res_id)
            record.step_workflow()
        except Exception:
            _logger.info('Unable    to    force    processing    of    workflow    for    item    %s@%s    in    order    to    leave    activity    to    be    deleted', res_id, model, exc_info=True)
    def unlink_if_refcount(to_unlink):
        undeletable = self.browse()
        for (model, res_id) in to_unlink:
            external_ids = self.search([('model', '=', model), ('res_id', '=', res_id)])
            if (external_ids - datas):
                continue
            if (model == 'ir.model.fields'):
                field = self.env[model].browse(res_id)
                if (not field.exists()):
                    _logger.info('Deleting    orphan    external_ids    %s', external_ids)
                    external_ids.unlink()
                    continue
                if ((field.name in models.LOG_ACCESS_COLUMNS) and (field.model in self.env) and self.env[field.model]._log_access):
                    continue
                if (field.name == 'id'):
                    continue
            _logger.info('Deleting    %s@%s', res_id, model)
            try:
                self._cr.execute('SAVEPOINT    record_unlink_save')
                self.env[model].browse(res_id).unlink()
            except Exception:
                _logger.info('Unable    to    delete    %s@%s', res_id, model, exc_info=True)
                undeletable += external_ids
                self._cr.execute('ROLLBACK    TO    SAVEPOINT    record_unlink_save')
            else:
                self._cr.execute('RELEASE    SAVEPOINT    record_unlink_save')
        return undeletable
    undeletable += unlink_if_refcount((item for item in to_unlink if (item[0] not in ('ir.model', 'ir.model.fields', 'ir.model.constraint'))))
    undeletable += unlink_if_refcount((item for item in to_unlink if (item[0] == 'ir.model.constraint')))
    modules = self.env['ir.module.module'].search([('name', 'in', modules_to_remove)])
    constraints = self.env['ir.model.constraint'].search([('module', 'in', modules.ids)])
    constraints._module_data_uninstall()
    undeletable += unlink_if_refcount((item for item in to_unlink if (item[0] == 'ir.model.fields')))
    relations = self.env['ir.model.relation'].search([('module', 'in', modules.ids)])
    relations._module_data_uninstall()
    undeletable += unlink_if_refcount((item for item in to_unlink if (item[0] == 'ir.model')))
    (datas - undeletable).unlink()
