class ResourceProfile implements Serializable, Comparable<ResourceProfile> {

	public ResourceProfile subtract(ResourceProfile other) {
		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() == 0 ? null : resultResource;
			});
		});

		return new ResourceProfile(
			subtractDoublesConsideringInf(cpuCores, other.cpuCores),
			subtractIntegersConsideringInf(heapMemoryInMB, other.heapMemoryInMB),
			subtractIntegersConsideringInf(directMemoryInMB, other.directMemoryInMB),
			subtractIntegersConsideringInf(nativeMemoryInMB, other.nativeMemoryInMB),
			subtractIntegersConsideringInf(networkMemoryInMB, other.networkMemoryInMB),
			subtractIntegersConsideringInf(managedMemoryInMB, other.managedMemoryInMB),
			resultExtendedResource
		);
	}

	public  ResourceProfile(
			double cpuCores,
			int heapMemoryInMB,
			int directMemoryInMB,
			int nativeMemoryInMB,
			int networkMemoryInMB,
			int managedMemoryInMB,
			Map<String, Resource> extendedResources);
	public  ResourceProfile(double cpuCores, int heapMemoryInMB);
	private  ResourceProfile();
	public  ResourceProfile(ResourceProfile other);

}