class JobScopedResourceTracker {

	public void notifyLostResource(ResourceProfile resourceProfile) {
		Preconditions.checkNotNull(resourceProfile);
		if (excessResources.getResourceCount(resourceProfile) > 0) {
			LOG.trace("Job {} lost excess resource {}.", jobId, resourceProfile);
			excessResources.decrementCount(resourceProfile, 1);
			return;
		}

		Set<ResourceProfile> fulfilledRequirements = resourceToRequirementMapping.getRequirementsFulfilledBy(resourceProfile).keySet();

		if (!fulfilledRequirements.isEmpty()) {
			// deduct the resource from any requirement
			// from a correctness standpoint the choice is arbitrary
			// from a resource utilization standpoint it could make sense to search for the requirement with the largest
			// distance to the resource profile (i.e., the smallest requirement), but it may not matter since we are
			// likely to get back a similarly-sized resource later on
			ResourceProfile assignedRequirement = fulfilledRequirements.iterator().next();

			resourceToRequirementMapping.decrementCount(assignedRequirement, resourceProfile, 1);

			tryAssigningExcessSlots();
		} else {
			throw new IllegalStateException(String.format("Job %s lost a resource %s but no such resource was tracked.", jobId, resourceProfile));
		}
	}

	  JobScopedResourceTracker(JobID jobId);

}