private NodesSpecification(ClusterResources min,
                               ClusterResources max,
                               IntRange groupSize,
                               boolean dedicated, Version version,
                               boolean required, boolean canFail, boolean exclusive,
                               Optional<DockerImage> dockerImageRepo,
                               Optional<String> combinedId,
                               Optional<CloudAccount> cloudAccount,
                               boolean hasCountAttribute) {
        if (max.smallerThan(min))
            throw new IllegalArgumentException("Max resources must be larger or equal to min resources, but " +
                                               max + " is smaller than " + min);
        if (min.nodes() < 1)
            throw new IllegalArgumentException("Min node count cannot be less than 1, but is " + min.nodes());

        // Non-scaled resources must be equal
        if ( ! min.nodeResources().justNonNumbers().equals(max.nodeResources().justNonNumbers()))
            throw new IllegalArgumentException("Min and max resources must have the same non-numeric settings, but " +
                                               "min is " + min + " and max " + max);
        if (min.nodeResources().bandwidthGbps() != max.nodeResources().bandwidthGbps())
            throw new IllegalArgumentException("Min and max resources must have the same bandwidth, but " +
                                               "min is " + min + " and max " + max);

        this.min = min;
        this.max = max;
        this.groupSize = groupSize;
        this.dedicated = dedicated;
        this.version = version;
        this.required = required;
        this.canFail = canFail;
        this.exclusive = exclusive;
        this.dockerImageRepo = dockerImageRepo;
        this.combinedId = combinedId;
        this.cloudAccount = cloudAccount;
        this.hasCountAttribute = hasCountAttribute;
    }
@Test
    void invalidResources() {
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources vcpu='-1' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources vcpu='' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources memory='-1' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources memory='1x' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources memory='' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources vcpu='[-1,]' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources vcpu='[1,0.5]' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources memory='[,-1b]' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources memory='[1mb,999kb]' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources memory='b' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes><resources memory='Yb' /></nodes>"));
        assertThrows(IllegalArgumentException.class,
                     () -> nodesSpecification("<nodes count='[0, 1]'></nodes>"));
    }