cdm/src/main/java/ucar/nc2/dataset/DatasetUrl.java
static public List<String> getProtocols(String url) {
    List<String> allprotocols = new ArrayList<>(); // all leading protocols upto path or host

    // Note, we cannot use split because of the context sensitivity
    // This code is quite ugly because of all the confounding cases
    // (e.g. windows path, embedded colons, etc.).
    // Specifically, the 'file:' protocol is a problem because
    // it has no many non-standard forms such as file:x/y file://x/y file:///x/y.
    StringBuilder buf = new StringBuilder(url);
    // If there are any leading protocols, then they must stop at the first '/'.
    int slashpos = buf.indexOf("/");
    // Check special case of file:<path> with no slashes after file:
    if (url.startsWith("file:") && "/\\".indexOf(url.charAt(5)) < 0) {
      allprotocols.add("file");
    } else if (slashpos >= 0) {
      // Remove everything after the first slash
      buf.delete(slashpos + 1, buf.length());
      for (; ; ) {
        int index = buf.indexOf(":");
        if (index < 0) break; // no more protocols
        // Validate protocol
        if (!validateprotocol(url, 0, index))
          break;
        String protocol = buf.substring(0, index);  // not including trailing ':'
        allprotocols.add(protocol);
        buf.delete(0, index + 1); // remove the leading protocol
      }
    }
    return allprotocols;
  }
static public List<String> getProtocols(String url) {
    List<String> allprotocols = new ArrayList<>(); // all leading protocols upto path or host

    // Note, we cannot use split because of the context sensitivity
    // This code is quite ugly because of all the confounding cases
    // (e.g. windows path, embedded colons, etc.).
    // Specifically, the 'file:' protocol is a problem because
    // it has no many non-standard forms such as file:x/y file://x/y file:///x/y.
    StringBuilder buf = new StringBuilder(url);
    // If there are any leading protocols, then they must stop at the first '/'.
    int slashpos = buf.indexOf("/");
    // Check special case of file:<path> with no slashes after file:
    if (url.startsWith("file:") && "/\\".indexOf(url.charAt(5)) < 0) {
      allprotocols.add("file");
    } else if (slashpos >= 0) {
      // Remove everything after the first slash
      buf.delete(slashpos + 1, buf.length());
      for (; ; ) {
        int index = buf.indexOf(":");
        if (index < 0) break; // no more protocols
        // Validate protocol
        if (!validateprotocol(url, 0, index))
          break;
        String protocol = buf.substring(0, index);  // not including trailing ':'
        allprotocols.add(protocol);
        buf.delete(0, index + 1); // remove the leading protocol
      }
    }
    return allprotocols;
  }
Return the set of leading protocols for a url; may be more than one.
Watch out for Windows paths starting with a drive letter => protocol
names must all have a length > 1.
Watch out for '::'
Each captured protocol is saved without trailing ':'
Assume: the protocols MUST be terminated by the occurrence of '/'.

@param url the url whose protocols to return
@return list of leading protocols without the trailing :