/**
   * Returns <code>true</code> if the given <code>version</code> is in the range of valid versions,
   * <code>false</code> otherwise.
   *
   * @param version the version to check for validity.
   * @return <code>true</code> if the given <code>version</code> is in the range of valid versions,
   *     <code>false</code> otherwise.
   */
  public boolean matches(Version version) {
    boolean lowerBoundHolds = false;
    if (min.getEndPoint().compareTo(version) < 0
        || min.getEndPoint().compareTo(version) == 0 && min.isInclusive()) lowerBoundHolds = true;

    boolean upperBoundHolds = false;
    if (max.getEndPoint().compareTo(version) > 0
        || max.getEndPoint().compareTo(version) == 0 && max.isInclusive()) upperBoundHolds = true;

    return lowerBoundHolds & upperBoundHolds;
  }
  /**
   * Returns the upper bound of valid versions given a minimum version and a {@link MatchRule}.
   *
   * @param min the minimum Version, the lower bound of the valid version range.
   * @param rule the {@link MatchRule} to use for determining the upper bound (<code>max</code>).
   * @return the upper bound of valid versions given a minimum version and a {@link MatchRule}.
   */
  private static VersionRangeEndPoint getUpperBoundForRule(
      VersionRangeEndPoint min, MatchRule rule) {
    VersionRangeEndPoint max = min.changeLocation(EndPointLocation.UPPER);
    if (!max.isInclusive()) max = max.changeInclusive(true);

    Version upperEndPoint = max.getEndPoint();
    boolean changed = false;
    switch (rule) {
      case GreaterOrEqual:
        upperEndPoint = upperEndPoint.changeMajor(Integer.MAX_VALUE);
      case Equivalent:
        upperEndPoint = upperEndPoint.changeMinor(Integer.MAX_VALUE);
      case Compatible:
        upperEndPoint = upperEndPoint.changeRelease(Integer.MAX_VALUE);
        upperEndPoint = upperEndPoint.changePatchLevel(Integer.MAX_VALUE);
        changed = true;
      case Perfect:
        if (changed) max = max.changeVersion(upperEndPoint);
        return max;

      default:
        throw new RuntimeException(
            "The MatchRule enum has been extended but the "
                + "'getUpperBoundForRule' method hasn't been updated!");
    }
  }