public static MediaType parse(String string) {
    if (string == null) {
      return null;
    }

    // Optimization for the common cases
    synchronized (SIMPLE_TYPES) {
      MediaType type = SIMPLE_TYPES.get(string);
      if (type == null) {
        int slash = string.indexOf('/');
        if (slash == -1) {
          return null;
        } else if (SIMPLE_TYPES.size() < 10000
            && isSimpleName(string.substring(0, slash))
            && isSimpleName(string.substring(slash + 1))) {
          type = new MediaType(string, slash);
          SIMPLE_TYPES.put(string, type);
        }
      }
      if (type != null) {
        return type;
      }
    }

    Matcher matcher;
    matcher = TYPE_PATTERN.matcher(string);
    if (matcher.matches()) {
      return new MediaType(
          matcher.group(1), matcher.group(2),
          parseParameters(matcher.group(3)));
    }
    matcher = CHARSET_FIRST_PATTERN.matcher(string);
    if (matcher.matches()) {
      return new MediaType(
          matcher.group(2), matcher.group(3),
          parseParameters(matcher.group(1)));
    }

    return null;
  }
Parses the given string to a media type. The string is expected
to be of the form "type/subtype(; parameter=...)*" as defined in
RFC 2045, though we also handle "charset=xxx; type/subtype" for
broken web servers.

@param string media type string to be parsed
@return parsed media type, or <code>null</code> if parsing fails
crawler-commons/src/main/java/achecrawler/crawler/crawlercommons/util/MediaType.java