public static double computeResourceUtilizationBalanceThreshold(double avgUtilizationPercentage,
                                                                  Resource resource,
                                                                  BalancingConstraint balancingConstraint,
                                                                  boolean isTriggeredByGoalViolation,
                                                                  double balanceMargin,
                                                                  boolean isLowerThreshold) {

    if (balanceMargin >= 1) {
      throw new IllegalArgumentException("Balance margin must be less than 1.0. Got: " + balanceMargin);
    }
    boolean isLowUtilization = avgUtilizationPercentage <= balancingConstraint.lowUtilizationThreshold(resource);

    if (isLowerThreshold) {
      if (isLowUtilization) {
        return 0.0;
      }
      double balancePercentageWithMargin =
          balancePercentageWithMargin(isTriggeredByGoalViolation, balancingConstraint, resource, balanceMargin);
      return avgUtilizationPercentage * Math.max(0, (1 - balancePercentageWithMargin));

    } else {
      double balancePercentageWithMargin =
          balancePercentageWithMargin(isTriggeredByGoalViolation, balancingConstraint, resource, balanceMargin);
      double resourceBalanceThreshold = avgUtilizationPercentage * (1 + balancePercentageWithMargin);
      if (isLowUtilization) {
        return Math.max(resourceBalanceThreshold, balancingConstraint.lowUtilizationThreshold(resource) * balanceMargin);
      }
      return resourceBalanceThreshold;
    }
  }
@Test
  public void testComputeResourceUtilizationBalanceThreshold() {
    Resource resource = Resource.CPU;

    // Verify case 1: Low utilization and compute balance threshold lower bound
    verifyComputingResourceUtilizationBalanceThreshold(resource, true, 0.4, 0.0);

    // Verify case 2: Low utilization. The average utilization percentage * resource balance threshold > low resource utilization percentage
    double expectedComputedBalanceUpperLimit = 0.3 * (1 + ((1.3 * 1.2) - 1) * ResourceDistributionGoal.BALANCE_MARGIN);
    verifyComputingResourceUtilizationBalanceThreshold(resource, false, 0.4, expectedComputedBalanceUpperLimit);

    // Verify case 3: Low utilization. The average utilization percentage * resource balance threshold < low resource utilization percentage
    double lowUtilizationThreshold = 0.6;
    expectedComputedBalanceUpperLimit = lowUtilizationThreshold * ResourceDistributionGoal.BALANCE_MARGIN;
    verifyComputingResourceUtilizationBalanceThreshold(resource, false, lowUtilizationThreshold, expectedComputedBalanceUpperLimit);

    // Verify case 4: Not low utilization and compute balance threshold lower bound
    verifyComputingResourceUtilizationBalanceThreshold(resource, true, 0.2, 0.3 * (1 - ((1.3 * 1.2) - 1) * ResourceDistributionGoal.BALANCE_MARGIN));

    // Verify case 5: Not low utilization and compute balance threshold upper bound
    verifyComputingResourceUtilizationBalanceThreshold(resource, false, 0.2, 0.3 * (1 + ((1.3 * 1.2) - 1) * ResourceDistributionGoal.BALANCE_MARGIN));
  }