private Optional<Node> tryAllocateNodes(List<Node> nodes,
                                            List<Node> hosts,
                                            Map<Node, AllocationResources> availableResources,
                                            Map<Node, List<Allocation>> containedAllocations, boolean withHistory) {
        for (var node : nodes) {
            var newParent = tryAllocateNode(node, hosts, availableResources, containedAllocations);
            if (newParent.isEmpty()) {
                if (withHistory) allocationHistory.addEntry(node, null, 0);
                return Optional.of(node);
            }
            if (withHistory) {
                long eligibleParents =
                    hosts.stream().filter(h ->
                            !violatesParentHostPolicy(node, h, containedAllocations)
                                && availableResources.get(h).satisfies(AllocationResources.from(node.resources()))).count();
                allocationHistory.addEntry(node, newParent.get(), eligibleParents + 1);
            }
        }
        return Optional.empty();
    }
Attempts to allocate the listed nodes to a new host, mutating availableResources and containedAllocations,
optionally returning the first node to fail, if one does.
node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityChecker.java