'Given a list of services waiting of each constraint set, and active nodes of each constraint set, return the
number of slots needed of each constraint set if the maximum wait thresholds have been reached, constrained by
the configured limits.'

def slots_needed(self, waiting_services, active_nodes):

    rval = {}
    services_constraints = set(waiting_services.keys())
    nodes_constraints = set(active_nodes.keys())
    limits_constraints = set(self._limits.keys())
    all_constraints = services_constraints.union(nodes_constraints).union(limits_constraints)
    if ((not all_constraints) and (self._conf.slots_min_spare or self._conf.slots_min_limit)):
        if (self._service_create_image_constraint or self._service_create_cpus_constraint):
            raise Exception("Global    'slots_min_limit'    and/or    'slots_min_spare'    are    set    and    'service_create_image_constraint'    and/or    'service_create_cpus_constraint'    are    set    but    constraint-specific    limits    are    unset,    minimum    nodes    cannot    be    started    since    the    constraints    are    not    known    until    service    creation    time.    Either    disable    'service_create_*_constraint'    or    create    constraint-specific    limits    in    the    'limits'    section    of    'manager_conf'    in    containers_conf.yml")
        all_constraints.add(DockerServiceConstraints.from_constraint_string_list([]))
    for constraints in all_constraints:
        services = waiting_services.get(constraints, [])
        nodes = active_nodes.get(constraints, [])
        services = [s for s in services if (s not in self._handled_services)]
        (slots_needed, total_slots) = self.slots_delta(constraints, services, nodes)
        if (services and (constraints not in self._waiting_since)):
            self._waiting_since[constraints] = time.time()
        elif ((not services) and (constraints in self._waiting_since)):
            del self._waiting_since[constraints]
        rval[constraints] = {'services': services, 'nodes': nodes, 'slots_needed': slots_needed}
    return rval
