
...24import java.util.function.Function;25import java.util.stream.Collector;26import java.util.stream.Collectors;27import java.util.stream.Stream;28public class PersistentCapabilities implements Capabilities {29  private final ImmutableCapabilities caps;30  private final ImmutableCapabilities overrides;31  public PersistentCapabilities() {32    this(new ImmutableCapabilities());33  }34  public PersistentCapabilities(Capabilities source) {35    this(source, new ImmutableCapabilities());36  }37  private PersistentCapabilities(Capabilities previousValues, Capabilities newValues) {38    Require.nonNull("Source capabilities", previousValues, "may be empty, but must be set.");39    Require.nonNull("Additional capabilities", newValues, "may be empty, but must be set.");40    this.caps = ImmutableCapabilities.copyOf(previousValues);41    this.overrides = ImmutableCapabilities.copyOf(newValues);42  }43  public PersistentCapabilities setCapability(String name, Object value) {44    Require.nonNull("Name", name);45    Require.nonNull("Value", value);46    return new PersistentCapabilities(caps, new ImmutableCapabilities(name, value));47  }48  @Override49  public Map<String, Object> asMap() {50    return getCapabilityNames().stream()51      .collect(toUnmodifiableMap(Function.identity(), this::getCapability));52  }53  @Override54  public Object getCapability(String capabilityName) {55    Require.nonNull("Capability name", capabilityName);56    Object capability = overrides.getCapability(capabilityName);57    if (capability != null) {58      return capability;59    }60    return caps.getCapability(capabilityName);61  }62  @Override63  public Capabilities merge(Capabilities other) {64    Require.nonNull("Other capabilities", other, "may be empty, but must be set.");65    return new PersistentCapabilities(this, other);66  }67  @Override68  public Set<String> getCapabilityNames() {69    return Stream.concat(caps.getCapabilityNames().stream(), overrides.getCapabilityNames().stream())70      .collect(toUnmodifiableSet());71  }72  // Needed, since we're dependent on Java 8 as a minimum version73  private <T, K, U> Collector<T, ?, Map<K, U>> toUnmodifiableMap(74    Function<? super T, ? extends K> keyMapper,75    Function<? super T, ? extends U> valueMapper) {76    return Collectors.collectingAndThen(Collectors.toMap(keyMapper, valueMapper), Collections::unmodifiableMap);77  }78  // Needed, since we're dependent on Java 8 as a minimum version79  private <T> Collector<T, ?, Set<T>> toUnmodifiableSet() {...
