class PowerSetPartitionMap implements PartitionMap<T> {

    @Override
    public List<T> add(final PartitionAttributes partition) {
        final int partitionSize = partition.size();
        if (partitionSize <= 0 || partitionSize > MAX_PARTITION_ATTRIBUTE_SIZE) {
            throw new IllegalArgumentException("attribute size: " + partitionSize + " must be in the range [0," +
                    MAX_PARTITION_ATTRIBUTE_SIZE + ")");
        }

        // Make a copy of the current wildCardToValueMap because we will copy/swap
        Map<PartitionAttributes, ValueHolder<T>> newWildCardToAttributes = new HashMap<>(wildCardToValueMap);

        // Calculate all combinations of attributes from the new absoluteAttributes map
        // This involves first putting the elements into a fixed array, and then iterate over that array
        // and select all unique subsets to make all combinations.
        List<Object> entries = new ArrayList<>(partitionSize << 1);
        partition.forEach((key, value) -> {
            entries.add(key);
            entries.add(value);
        });

        final int numCombinations = 1 << partitionSize;
        final List<T> effectedPartitions = new ArrayList<>(numCombinations);
        for (int i = 1; i < numCombinations; ++i) {
            // wildCardAttributesBuilder will represent the current combination of attributes
            PartitionAttributesBuilder wildCardAttributesBuilder = partitionAttributesBuilderFunc.apply(bitCount(i));
            int remainingBits = i;
            do {
                int entriesIndex = numberOfTrailingZeros(remainingBits);
                remainingBits &= ~(1 << entriesIndex);
                wildCardAttributesBuilder.add((PartitionAttributes.Key) entries.get(entriesIndex << 1),
                        entries.get((entriesIndex << 1) + 1));
            } while (remainingBits != 0);

            PartitionAttributes wildCardAttributes = wildCardAttributesBuilder.build();

            // Update the new wild card attribute index
            ValueHolder<T> valueHolder = newWildCardToAttributes.get(wildCardAttributes);
            if (valueHolder != null) {
                ++valueHolder.refCount;
            } else {
                valueHolder = new ValueHolder<>(valueFactory.apply(wildCardAttributes));
                newWildCardToAttributes.put(wildCardAttributes, valueHolder);
            }
            // Update the absolute to wild card index ... this makes removal/replacement of entries easier later.
            absoluteToWildCardIndexMap.computeIfAbsent(partition,
                    attributes -> new HashSet<>(2)).add(wildCardAttributes);
            effectedPartitions.add(valueHolder.value);
        }

        wildCardToValueMap = newWildCardToAttributes;

        // It is likely/possible that we generated new objects above, and so we must ensure that these are closed.
        if (closed > 0) {
            closeAllValues(newWildCardToAttributes, closed == CLOSED_GRACEFULLY).subscribe();
        }

        return effectedPartitions;
    }

      PowerSetPartitionMap(Function<PartitionAttributes, T> valueFactory);
    public  PowerSetPartitionMap(Function<PartitionAttributes, T> valueFactory,
                                IntFunction<PartitionAttributesBuilder> partitionAttributesBuilderFunc);

}