docs: public static String normalize(String path) {
          // We don't want to normalize if this is not a file name. This could be improved, but
          // might involve some work.
          if ((path.startsWith("http:") || (path.startsWith("https:")) || (path.startsWith("ftp:")))) {
              return path;
          }
          boolean slash_change = false;
          final String origFullPath = path;
          boolean pathChanged = false;
  
          String prefix = "";
  
          // remove the file:// prefix for UNC path before normalize
          // must preserve file:////UNC/Path w/ //UNC/path all in the "getPath"
          // portion of
          // URI.
          if (path.length() >= 9 && path.startsWith("file:////")) {
              prefix = "file://";
              path = path.substring(7); // skip "file://", new path will start with //
              slash_change = true;
              pathChanged = true;
          }
          if (path.length() >= 9 && path.startsWith("file:///")) {
              prefix = "file:///";
              path = path.substring(8);
          } else if (path.length() >= 6 && path.startsWith("file:/") && path.charAt(7) != '/') {
              prefix = "file:/";
              path = path.substring(6);
          }
  
          int origLength = path.length();
  
          int i = 0;
          int j = 0;
          int num_segments = 0;
          int lastSlash = 0;
          boolean dotSegment = false;
          boolean backslash = false;
  
          if (origLength != 0) {
              if (path.charAt(0) == '.') // potential dot segment
                  dotSegment = true;
  
              for (; i < origLength; i++) {
                  char c = path.charAt(i);
  
                  if (c == '/' || c == '\\') {
                      if (c == '\\') // need to slashify
                          backslash = true;
  
                      if (i == 0) // catch leading slash(es) (whee! UNC paths: \\remote\location)
                      {
                          num_segments++;
                          while (i + 1 < origLength && (path.charAt(i + 1) == '/' || path.charAt(i + 1) == '\\'))
                              i++;
  
                          if (i > 0) // if there are extra leading slashes, note it
                              slash_change = true;
                      } else if (i == lastSlash) // catch repeated//slash in the middle of path
                          slash_change = true;
                      else if (i != lastSlash) // at least one character since the last slash:
                          // another path segment
                          num_segments++;
  
                      // leading dot in next segment could be a '.' or '..' segment
                      if (!dotSegment && i + 1 < origLength && path.charAt(i + 1) == '.')
                          dotSegment = true;
  
                      lastSlash = i + 1; // increment beyond the slash character
                  }
              }
  
              if (i > lastSlash)
                  num_segments++;
  
              if (backslash) {
                  path = slashify(path);
                  pathChanged = true;
              }
  
              // Remove leading slash: /c:/windows/path... have to adjust "original" length
              if (path.length() > 3 && path.charAt(0) == '/' && path.charAt(2) == ':') {
                  path = path.substring(1);
                  pathChanged = true;
              }
          }
  
          // if there are no segment-sensitive/collapsing elements, just return
          if (!slash_change && !dotSegment)
              return pathChanged ? prefix + path : origFullPath;
  
          pathChanged = false;
          origLength = path.length();
  
          ArrayList<String> segments = new ArrayList<String>(num_segments);
          for (lastSlash = 0, i = 0; i < origLength; i++) {
              if (path.charAt(i) == '/') {
                  if (i == 0) // catch leading slash(es) (whee! UNC paths: //remote/location/)
                  {
                      // Guard against a case where we have multiple slashes for a unix root
                      while ((i + 1) < origLength && path.charAt(i + 1) == '/')
                          i++;
  
                      segments.add(path.substring(0, i + 1));
                  } else if (i == lastSlash) // ignore extra slashes
                      pathChanged = true;
                  else if (i != lastSlash)
                      segments.add(path.substring(lastSlash, i + 1));
  
                  lastSlash = i + 1; // increment beyond the slash character
              }
          }
  
          if (i > lastSlash)
              segments.add(path.substring(lastSlash));
  
          int ns = segments.size() - 1;
  
          for (i = ns; i >= 0; i--) {
              String s = segments.get(i);
              String t = trimSlash(s);
  
              if (i >= 1 && t.equals("..")) {
                  j = i - 1;
                  String p = segments.get(j);
                  String q = trimSlash(p);
                  if (q.equals(".")) {
                      pathChanged = true;
                      // ./.. is really ..
                      segments.remove(j);
                  } else if (!q.equals("..") && !isSymbol(q)) {
                      pathChanged = true;
                      segments.remove(i);
                      segments.remove(j);
                  }
                  // with i-- we should see the .. again on the next round which we need for ../..
                  if (segments.size() == j)
                      i = j;
              } else if (t.equals(".")) {
                  pathChanged = true;
                  segments.remove(i);
              }
          }
  
          if (pathChanged) {
              StringBuilder sb = new StringBuilder(origFullPath.length());
              sb.append(prefix);
  
              for (String s : segments)
                  sb.append(s);
  
              return sb.toString();
          }
  
          return prefix + path;
      }