code: public static List<String> fixPath(final String path) throws ServletException {
      if (path == null) {
        return null;
      }
  
      String decoded;
      try {
        decoded = URLDecoder.decode(path, "UTF8");
      } catch (Throwable t) {
        throw new ServletException("bad path: " + path);
      }
  
      if (decoded == null) {
        return (null);
      }
  
      /** Make any backslashes into forward slashes.
       */
      if (decoded.indexOf('\\') >= 0) {
        decoded = decoded.replace('\\', '/');
      }
  
      /** Ensure a leading '/'
       */
      if (!decoded.startsWith("/")) {
        decoded = "/" + decoded;
      }
  
      /** Remove all instances of '//'.
       */
      while (decoded.contains("//")) {
        decoded = decoded.replaceAll("//", "/");
      }
  
      /** Somewhere we may have /./ or /../
       */
  
      final StringTokenizer st = new StringTokenizer(decoded, "/");
  
      ArrayList<String> al = new ArrayList<String>();
      while (st.hasMoreTokens()) {
        String s = st.nextToken();
  
        if (s.equals(".")) {
          // ignore
        } else if (s.equals("..")) {
          // Back up 1
          if (al.size() == 0) {
            // back too far
            return null;
          }
  
          al.remove(al.size() - 1);
        } else {
          al.add(s);
        }
      }
  
      return al;
    }
docs: Return a path, broken into its elements, after "." and ".." are removed.
  If the parameter path attempts to go above the root we return null.
  
  Other than the backslash thing why not use URI?
  
  @param path      String path to be fixed
  @return String[]   fixed path broken into elements
  @throws ServletException