'Check values (usage + desired delta) against quota limits.
For limits--this method checks that a set of
proposed values are permitted by the limit restriction.
This method will raise a QuotaResourceUnknown exception if a
given resource is unknown or if it is not a simple limit
resource.
If any of the proposed values is over the defined quota, an
OverQuota exception will be raised with the sorted list of the
resources which are too high.  Otherwise, the method returns
nothing.
:param context: The request context, for access checks
:param resources: A dictionary of the registered resources
:param project_values: Optional dict containing the resource values to
check against project quota,
e.g. {\'instances\': 1, \'cores\': 2, \'memory_mb\': 512}
:param user_values: Optional dict containing the resource values to
check against user quota,
e.g. {\'instances\': 1, \'cores\': 2, \'memory_mb\': 512}
:param project_id: Optional project_id for scoping the limit check to a
different project than in the context
:param user_id: Optional user_id for scoping the limit check to a
different user than in the context'

def limit_check_project_and_user(self, context, resources, project_values=None, user_values=None, project_id=None, user_id=None):

    if (project_values is None):
        project_values = {}
    if (user_values is None):
        user_values = {}
    _valid_method_call_check_resources(project_values, 'check', resources)
    _valid_method_call_check_resources(user_values, 'check', resources)
    if (not any([project_values, user_values])):
        raise exception.Invalid('Must    specify    at    least    one    of    project_values    or    user_values    for    the    limit    check.')
    for vals in (project_values, user_values):
        unders = [key for (key, val) in vals.items() if (val < 0)]
        if unders:
            raise exception.InvalidQuotaValue(unders=sorted(unders))
    all_keys = set(project_values).union(user_values)
    keys_to_merge = set(project_values).symmetric_difference(user_values)
    merged_values = {}
    for key in keys_to_merge:
        merged_values[key] = (project_values.get(key, 0) or user_values.get(key, 0))
        project_values.pop(key, None)
        user_values.pop(key, None)
    if (project_id is None):
        project_id = context.project_id
    if (user_id is None):
        user_id = context.user_id
    project_quotas = objects.Quotas.get_all_by_project(context, project_id)
    quotas = self._get_quotas(context, resources, all_keys, project_id=project_id, project_quotas=project_quotas)
    user_quotas = self._get_quotas(context, resources, all_keys, project_id=project_id, user_id=user_id, project_quotas=project_quotas)
    if merged_values:
        merged_quotas = copy.deepcopy(quotas)
        for (k, v) in user_quotas.items():
            if (k in merged_quotas):
                merged_quotas[k] = min(merged_quotas[k], v)
            else:
                merged_quotas[k] = v
        overs = [key for (key, val) in merged_values.items() if ((merged_quotas[key] >= 0) and (merged_quotas[key] < val))]
        if overs:
            headroom = {}
            for key in overs:
                headroom[key] = merged_quotas[key]
            raise exception.OverQuota(overs=sorted(overs), quotas=merged_quotas, usages={}, headroom=headroom)
    over_user_quota = False
    overs = []
    for key in user_values.keys():
        if ((quotas[key] >= 0) and (quotas[key] < project_values[key])):
            overs.append(key)
        elif ((user_quotas[key] >= 0) and (user_quotas[key] < user_values[key])):
            overs.append(key)
            over_user_quota = True
    if overs:
        quotas_exceeded = (user_quotas if over_user_quota else quotas)
        headroom = {}
        for key in overs:
            headroom[key] = quotas_exceeded[key]
        raise exception.OverQuota(overs=sorted(overs), quotas=quotas_exceeded, usages={}, headroom=headroom)
