docs: private static Url parseUrl(final String spec) {
          final Url url = new Url();
          int startIndex = 0;
          int endIndex = spec.length();
  
          // Section 2.4.1: Parsing the Fragment Identifier
          //
          //   If the parse string contains a crosshatch "#" character, then the
          //   substring after the first (left-most) crosshatch "#" and up to the
          //   end of the parse string is the <fragment> identifier. If the
          //   crosshatch is the last character, or no crosshatch is present, then
          //   the fragment identifier is empty. The matched substring, including
          //   the crosshatch character, is removed from the parse string before
          //   continuing.
          //
          //   Note that the fragment identifier is not considered part of the URL.
          //   However, since it is often attached to the URL, parsers must be able
          //   to recognize and set aside fragment identifiers as part of the
          //   process.
          final int crosshatchIndex = indexOf(spec, '#', startIndex, endIndex);
  
          if (crosshatchIndex >= 0) {
              url.fragment = spec.substring(crosshatchIndex + 1, endIndex);
              endIndex = crosshatchIndex;
          }
          // Section 2.4.2: Parsing the Scheme
          //
          //   If the parse string contains a colon ":" after the first character
          //   and before any characters not allowed as part of a scheme name (i.e.,
          //   any not an alphanumeric, plus "+", period ".", or hyphen "-"), the
          //   <scheme> of the URL is the substring of characters up to but not
          //   including the first colon. These characters and the colon are then
          //   removed from the parse string before continuing.
          final int colonIndex = indexOf(spec, ':', startIndex, endIndex);
  
          if (colonIndex > 0) {
              final String scheme = spec.substring(startIndex, colonIndex);
              if (isValidScheme(scheme)) {
                  url.scheme = scheme;
                  startIndex = colonIndex + 1;
              }
          }
          // Section 2.4.3: Parsing the Network Location/Login
          //
          //   If the parse string begins with a double-slash "//", then the
          //   substring of characters after the double-slash and up to, but not
          //   including, the next slash "/" character is the network location/login
          //   (<net_loc>) of the URL. If no trailing slash "/" is present, the
          //   entire remaining parse string is assigned to <net_loc>. The double-
          //   slash and <net_loc> are removed from the parse string before
          //   continuing.
          //
          // Note: We also accept a question mark "?" or a semicolon ";" character as
          //       delimiters for the network location/login (<net_loc>) of the URL.
          final int locationStartIndex;
          int locationEndIndex;
  
          if (spec.startsWith("//", startIndex)) {
              locationStartIndex = startIndex + 2;
              locationEndIndex = indexOf(spec, '/', locationStartIndex, endIndex);
              if (locationEndIndex >= 0) {
                  startIndex = locationEndIndex;
              }
          } else {
              locationStartIndex = -1;
              locationEndIndex = -1;
          }
          // Section 2.4.4: Parsing the Query Information
          //
          //   If the parse string contains a question mark "?" character, then the
          //   substring after the first (left-most) question mark "?" and up to the
          //   end of the parse string is the <query> information. If the question
          //   mark is the last character, or no question mark is present, then the
          //   query information is empty. The matched substring, including the
          //   question mark character, is removed from the parse string before
          //   continuing.
          final int questionMarkIndex = indexOf(spec, '?', startIndex, endIndex);
  
          if (questionMarkIndex >= 0) {
              if ((locationStartIndex >= 0) && (locationEndIndex < 0)) {
                  // The substring of characters after the double-slash and up to, but not
                  // including, the question mark "?" character is the network location/login
                  // (<net_loc>) of the URL.
                  locationEndIndex = questionMarkIndex;
                  startIndex = questionMarkIndex;
              }
              url.query = spec.substring(questionMarkIndex + 1, endIndex);
              endIndex = questionMarkIndex;
          }
          // Section 2.4.5: Parsing the Parameters
          //
          //   If the parse string contains a semicolon ";" character, then the
          //   substring after the first (left-most) semicolon ";" and up to the end
          //   of the parse string is the parameters (<params>). If the semicolon
          //   is the last character, or no semicolon is present, then <params> is
          //   empty. The matched substring, including the semicolon character, is
          //   removed from the parse string before continuing.
          final int semicolonIndex = indexOf(spec, ';', startIndex, endIndex);
  
          if (semicolonIndex >= 0) {
              if ((locationStartIndex >= 0) && (locationEndIndex < 0)) {
                  // The substring of characters after the double-slash and up to, but not
                  // including, the semicolon ";" character is the network location/login
                  // (<net_loc>) of the URL.
                  locationEndIndex = semicolonIndex;
                  startIndex = semicolonIndex;
              }
              url.parameters = spec.substring(semicolonIndex + 1, endIndex);
              endIndex = semicolonIndex;
          }
          // Section 2.4.6: Parsing the Path
          //
          //   After the above steps, all that is left of the parse string is the
          //   URL <path> and the slash "/" that may precede it. Even though the
          //   initial slash is not part of the URL path, the parser must remember
          //   whether or not it was present so that later processes can
          //   differentiate between relative and absolute paths. Often this is
          //   done by simply storing the preceding slash along with the path.
          if ((locationStartIndex >= 0) && (locationEndIndex < 0)) {
              // The entire remaining parse string is assigned to the network
              // location/login (<net_loc>) of the URL.
              locationEndIndex = endIndex;
          } else if (startIndex < endIndex) {
              url.path = spec.substring(startIndex, endIndex);
          }
          // Set the network location/login (<net_loc>) of the URL.
          if ((locationStartIndex >= 0) && (locationEndIndex >= 0)) {
              url.location = spec.substring(locationStartIndex, locationEndIndex);
          }
          return url;
      }