code: public static Version parseVersion(String versionString) {
      requireNonNull(versionString, "versionString");
  
      Matcher matcher = VERSION_PATTERN.matcher(versionString);
      if (matcher.matches() && matcher.groupCount() == 3) {
        int major = Integer.parseInt(matcher.group(1));
        int minor = matcher.group(2) != null ? Integer.parseInt(matcher.group(2)) : 0;
        int patch = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 0;
        return new Version(major, minor, patch);
      } else {
        throw new IllegalArgumentException(
            "Expected a version string starting with X[.Y[.Z]], was " + versionString);
      }
    }
docs: Parses a {@link String} into a {@link Version}. This expects a version string in the form of
  "X[.Y[.Z]][anything]". That is a major number, followed optionally by a minor only or a minor + a patch revision,
  everything after that being completely ignored.
  <p>
  The parsing is extremely lenient, accepting any input string whose first character is a decimal digit.
  <p>
  For example, the following version strings are valid:
  <pre>
  - "3.a.2" (3.0.0) considered only a major version since there's a char where minor number should be
  - "2" (2.0.0)
  - "3.11" (3.11.0)
  - "3.14.15" (3.14.15)
  - "1.2.3-SNAPSHOT-12.10.2014" (1.2.3)
  </pre>
  <p>
  Bad version strings cause an {@link IllegalArgumentException}, whereas a null one will cause
  a {@link NullPointerException}.
  
  @param versionString the string to parse into a Version.
  @return the major.minor.patch Version corresponding to the string.
  @throws IllegalArgumentException if the string cannot be correctly parsed into a Version.
  This happens if the input is empty,
  the first character is not a decimal digit,
  or if any version component is greater than Integer.MAX_VALUE.
  @throws NullPointerException     if the string is null.