class ResourceAggregator {

  public List<? extends Resource> excess(
      List<? extends Resource> sourceResources, List<? extends Resource> resourcesToCompare) {
    checkSupporting(sourceResources);
    checkSupporting(resourcesToCompare);

    final Map<String, Resource> result =
        sourceResources.stream().collect(Collectors.toMap(Resource::getType, Function.identity()));
    for (Resource toCompare : resourcesToCompare) {
      String resourceType = toCompare.getType();
      final Resource sourceResource = result.get(resourceType);
      if (sourceResource != null) {
        if (sourceResource.getAmount() == toCompare.getAmount()) {
          // source resource doesn't have excessive amount
          result.remove(resourceType);
          continue;
        }
        try {
          Resource excess = deduct(sourceResource, toCompare);
          if (excess.getAmount() == 0) {
            // source resource doesn't have excessive amount
            result.remove(resourceType);
          } else {
            result.put(resourceType, excess);
          }
        } catch (NoEnoughResourcesException e) {
          // source resource doesn't have excessive amount
          result.remove(resourceType);
        }
      }
    }

    return new ArrayList<>(result.values());
  }

  @Inject public  ResourceAggregator(Set<ResourceType> resourcesTypes);

}