class ResourceProfile implements Serializable {

	public ResourceProfile subtract(final ResourceProfile other) {
		checkNotNull(other, "Cannot subtract with null resources");

		if (equals(ANY) || other.equals(ANY)) {
			return ANY;
		}

		if (this.equals(UNKNOWN) || other.equals(UNKNOWN)) {
			return UNKNOWN;
		}

		checkArgument(isMatching(other), "Try to subtract an unmatched resource profile from this one.");

		Map<String, Resource> resultExtendedResource = new HashMap<>(extendedResources);

		other.extendedResources.forEach((String name, Resource resource) -> {
			resultExtendedResource.compute(name, (ignored, oldResource) -> {
				Resource resultResource = oldResource.subtract(resource);
				return resultResource.getValue().compareTo(BigDecimal.ZERO) == 0 ? null : resultResource;
			});
		});

		return new ResourceProfile(
			cpuCores.subtract(other.cpuCores),
			taskHeapMemory.subtract(other.taskHeapMemory),
			taskOffHeapMemory.subtract(other.taskOffHeapMemory),
			managedMemory.subtract(other.managedMemory),
			networkMemory.subtract(other.networkMemory),
			resultExtendedResource
		);
	}

	private  ResourceProfile(
			final Resource cpuCores,
			final MemorySize taskHeapMemory,
			final MemorySize taskOffHeapMemory,
			final MemorySize managedMemory,
			final MemorySize networkMemory,
			final Map<String, Resource> extendedResources);
	private  ResourceProfile();

}