code: @Override
  	public int compareTo(Costs o) {
  		// check the network cost. if we have actual costs on both, use them, otherwise use the heuristic costs.
  		if (this.networkCost != UNKNOWN && o.networkCost != UNKNOWN) {
  			if (this.networkCost != o.networkCost) {
  				return this.networkCost < o.networkCost ? -1 : 1;
  			}
  		} else if (this.heuristicNetworkCost < o.heuristicNetworkCost) {
  			return -1;
  		} else if (this.heuristicNetworkCost > o.heuristicNetworkCost) {
  			return 1;
  		}
  		
  		// next, check the disk cost. again, if we have actual costs on both, use them, otherwise use the heuristic costs.
  		if (this.diskCost != UNKNOWN && o.diskCost != UNKNOWN) {
  			if (this.diskCost != o.diskCost) {
  				return this.diskCost < o.diskCost ? -1 : 1;
  			}
  		} else if (this.heuristicDiskCost < o.heuristicDiskCost) {
  			return -1;
  		} else if (this.heuristicDiskCost > o.heuristicDiskCost) {
  			return 1;
  		}
  		
  		// next, check the CPU cost. again, if we have actual costs on both, use them, otherwise use the heuristic costs.
  		if (this.cpuCost != UNKNOWN && o.cpuCost != UNKNOWN) {
  			return this.cpuCost < o.cpuCost ? -1 : this.cpuCost > o.cpuCost ? 1 : 0;
  		} else if (this.heuristicCpuCost < o.heuristicCpuCost) {
  			return -1;
  		} else if (this.heuristicCpuCost > o.heuristicCpuCost) {
  			return 1;
  		} else {
  			return 0;
  		}
  	}
docs: The order of comparison is: network first, then disk, then CPU. The comparison here happens each time
  primarily after the heuristic costs, then after the quantifiable costs.
  
  @see java.lang.Comparable#compareTo(java.lang.Object)