/// <summary>
        /// Subtracts another resource spec from this one.
        /// </summary>
        /// <param name="other">The other resource spec to subtract.</param>
        /// <returns>The subtracted resource spec.</returns>
        public ResourceSpec Subtract(ResourceSpec other)
        {
            Preconditions.CheckNotNull(other, "Cannot subtract null resources");

            if (Equals(Unknown) || other.Equals(Unknown))
            {
                return(Unknown);
            }

            Preconditions.CheckArgument(other.LessThanOrEqual(this), "Cannot subtract a larger ResourceSpec from this one.");

            var target = new ResourceSpec(
                CpuCores.Merge(other.CpuCores),
                TaskHeapMemory.Subtract(other.TaskHeapMemory),
                TaskOffHeapMemory.Subtract(other.TaskOffHeapMemory),
                OnHeapManagedMemory.Subtract(other.OnHeapManagedMemory),
                OffHeapManagedMemory.Subtract(other.OffHeapManagedMemory));

            foreach (var(key, value) in ExtendedResources)
            {
                target.ExtendedResources.Add(key, value);
            }

            foreach (var resource in other.ExtendedResources.Values)
            {
                var temp       = target.ExtendedResources[resource.Name];
                var subtracted = temp.Subtract(resource);

                target.ExtendedResources.Add(temp.Name, subtracted);
            }

            return(target);
        }
        /// <summary>
        /// Used by system internally to merge the other resources of chained operators when generating the job graph.
        /// </summary>
        /// <param name="other">Reference to resource to merge in.</param>
        /// <returns>The new resource with merged values.</returns>
        public ResourceSpec Merge(ResourceSpec other)
        {
            Preconditions.CheckNotNull(other, "Cannot merge with null resources");

            if (Equals(Unknown) || other.Equals(Unknown))
            {
                return(Unknown);
            }

            var target = new ResourceSpec(
                CpuCores.Merge(other.CpuCores),
                TaskHeapMemory.Add(other.TaskHeapMemory),
                TaskOffHeapMemory.Add(other.TaskOffHeapMemory),
                OnHeapManagedMemory.Add(other.OnHeapManagedMemory),
                OffHeapManagedMemory.Add(other.OffHeapManagedMemory));

            foreach (var(key, value) in ExtendedResources)
            {
                target.ExtendedResources.Add(key, value);
            }

            foreach (var resource in other.ExtendedResources.Values)
            {
                var temp   = target.ExtendedResources[resource.Name];
                var merged = temp.Merge(resource);

                target.ExtendedResources.Add(temp.Name, merged);
            }

            return(target);
        }