class OrganizationResourcesDistributor {

  public void capResources(String suborganizationId, List<? extends Resource> resourcesCaps)
      throws NotFoundException, ConflictException, ServerException {
    requireNonNull(suborganizationId, "Required non-null suborganization id");
    requireNonNull(resourcesCaps, "Required non-null resources to capResources");
    checkIsSuborganization(suborganizationId);

    // remove caps with amount -1
    resourcesCaps = resourcesCaps.stream().filter(res -> res.getAmount() != -1).collect(toList());

    // locking resources by suborganization should lock resources whole organization tree
    // so we can check resource availability for suborganization organization
    try (@SuppressWarnings("unused")
        Unlocker u = resourcesLocks.lock(suborganizationId)) {
      if (resourcesCaps.isEmpty()) {
        organizationDistributedResourcesDao.remove(suborganizationId);
      } else {
        checkResourcesAvailability(suborganizationId, resourcesCaps);

        organizationDistributedResourcesDao.store(
            new OrganizationDistributedResourcesImpl(suborganizationId, resourcesCaps));
      }
    }
  }

  @Inject public  OrganizationResourcesDistributor(
      OrganizationDistributedResourcesDao organizationDistributedResourcesDao,
      OrganizationManager organizationManager,
      ResourcesLocks resourcesLocks,
      ResourceManager resourceManager,
      ResourceAggregator resourceAggregator);

}