private static int comparePrerelease(@Nullable String pre1, @Nullable String pre2) {
    if (pre1 == null) {
      return pre2 == null ? 0 : 1;
    }
    else if (pre2 == null) {
      return -1;
    }
    int length1 = pre1.length();
    int length2 = pre2.length();

    if (length1 == length2 && pre1.equals(pre2)) return 0;

    int start1 = 0;
    int start2 = 0;
    int diff;

    // compare each segment separately
    do {
      int end1 = pre1.indexOf('.', start1);
      int end2 = pre2.indexOf('.', start2);

      if (end1 < 0) end1 = length1;
      if (end2 < 0) end2 = length2;


      CharSequence segment1 = new CharSequenceSubSequence(pre1, start1, end1);
      CharSequence segment2 = new CharSequenceSubSequence(pre2, start2, end2);
      if (Strings.isNotNegativeNumber(segment1)) {
        if (!Strings.isNotNegativeNumber(segment2)) {
          // According to SemVer specification numeric segments has lower precedence
          // than non-numeric segments
          return -1;
        }
        diff = compareNumeric(segment1, segment2);
      }
      else if (Strings.isNotNegativeNumber(segment2)) {
        return 1;
      }
      else {
        diff = Strings.compare(segment1, segment2, false);
      }
      start1 = end1 + 1;
      start2 = end2 + 1;
    }
    while (diff == 0 && start1 < length1 && start2 < length2);

    if (diff != 0) return diff;

    return start1 < length1 ? 1 : -1;
  }
private static int comparePrerelease(@Nullable String pre1, @Nullable String pre2)