Convert a path to a cananonical form.
All instances of "." and ".." are factored out.  Null is returned
if the path tries to .. above its root.

@param path the path to convert
@return path or null.
432903
public static String canonical(String path) {
        if (path == null || path.length() == 0) {
            return path;
        }

        int end = path.length();
        int start = path.lastIndexOf('/', end);

        search:
        while (end > 0) {
            switch (end - start) {
                case 2: // possible single dot
                    if (path.charAt(start + 1) != '.') {
                        break;
                    }
                    break search;
                case 3: // possible double dot
                    if (path.charAt(start + 1) != '.' || path.charAt(start + 2) != '.') {
                        break;
                    }
                    break search;
            }

            end = start;
            start = path.lastIndexOf('/', end - 1);
        }

        // If we have checked the entire string
        if (start >= end) {
            return path;
        }

        StringBuilder buf = new StringBuilder(path);
        int delStart = -1;
        int delEnd = -1;
        int skip = 0;

        while (end > 0) {
            switch (end - start) {
                case 2: // possible single dot
                    if (buf.charAt(start + 1) != '.') {
                        if (skip > 0 && --skip == 0) {
                            delStart = start >= 0 ? start : 0;
                            if (delStart > 0 && delEnd == buf.length() && buf.charAt(delEnd - 1) == '.') {
                                delStart++;
                            }
                        }
                        break;
                    }

                    if (start < 0 && buf.length() > 2 && buf.charAt(1) == '/' && buf.charAt(2) == '/') {
                        break;
                    }

                    if (delEnd < 0) {
                        delEnd = end;
                    }
                    delStart = start;
                    if (delStart < 0 || delStart == 0 && buf.charAt(delStart) == '/') {
                        delStart++;
                        if (delEnd < buf.length() && buf.charAt(delEnd) == '/') {
                            delEnd++;
                        }
                        break;
                    }
                    if (end == buf.length()) {
                        delStart++;
                    }

                    end = start--;
                    while (start >= 0 && buf.charAt(start) != '/') {
                        start--;
                    }
                    continue;

                case 3: // possible double dot
                    if (buf.charAt(start + 1) != '.' || buf.charAt(start + 2) != '.') {
                        if (skip > 0 && --skip == 0) {
                            delStart = start >= 0 ? start : 0;
                            if (delStart > 0 && delEnd == buf.length() && buf.charAt(delEnd - 1) == '.') {
                                delStart++;
                            }
                        }
                        break;
                    }

                    delStart = start;
                    if (delEnd < 0) {
                        delEnd = end;
                    }

                    skip++;
                    end = start--;
                    while (start >= 0 && buf.charAt(start) != '/') {
                        start--;
                    }
                    continue;

                default:
                    if (skip > 0 && --skip == 0) {
                        delStart = start >= 0 ? start : 0;
                        if (delEnd == buf.length() && buf.charAt(delEnd - 1) == '.') {
                            delStart++;
                        }
                    }
            }

            // Do the delete
            if (skip <= 0 && delStart >= 0 && delEnd >= delStart) {
                buf.delete(delStart, delEnd);
                delStart = delEnd = -1;
            }

            end = start--;
            while (start >= 0 && buf.charAt(start) != '/') {
                start--;
            }
        }

        // Too many ..
        if (skip > 0) {
            return null;
        }

        // Do the delete
        if (delEnd >= 0) {
            buf.delete(delStart, delEnd);
        }

        return buf.toString();
    }
695099
public static String normalizePath(String path)
  {
    if(File.separatorChar == '/') {
      return path.replace('\\', '/');
    }
    return path.replace('/', '\\');
  }
769116
public static String revisePath(String path) {
        if (!path.trim().equals("")) {
//            path = path.replaceAll("/", File.separator);
            File f = new File(path);
            if (f != null && !f.exists()) {
                f.mkdirs();
            }
            if (!f.isDirectory()) {
                f = f.getParentFile();
                path = f.getPath();
            }
            if (!path.endsWith(File.separator)) {
                path += File.separator;
            }
        }
        return path;
    }
911512
public static String getName(String path)
    {
        if (path == null) throw new IllegalArgumentException("'path' can't be null");
        if (path.length() == 0) return null;
        if (!path.startsWith("/")) throw new IllegalArgumentException("Not a valid path.  Doesn't start with a \"/\": \"" + path + "\"");
        if (path.endsWith("/")) throw new IllegalArgumentException("Not a valid path.  Ends with a \"/\": \"" + path + "\"");

        int start = path.length() - 1;
        while (path.charAt(start) != '/') {
            start--;
        }
        return path.substring(start+1);
    }
1337677
public static String separatorsToSystem(final String path) {
        if (path == null) {
            return null;
        }
        if (IOUtil.IS_OS_WINDOWS) {
            return separatorsToWindows(path);
        } else {
            return separatorsToUnix(path);
        }
    }
830032
function convertToNativePath(path) {
        path = unescape(path);
        if (path.indexOf(":") !== -1 && path[0] === "/") {
            return path.substr(1);
        }

        return path;
    }
1184084
public OptionsBuilder path(String path) {
		options.put(Options.CHAIN_PATH, path != null ? path : DEFAULT_PATH);
		return this;
    }
1021602
public static String path( String path ) {
		String pathToBase = getPathToBase();
		if( pathToBase == null )
			return path;
		return new File(pathToBase,path).getAbsolutePath();
	}
166225
public static String asPath(String path) {
        if (path == null) {
            return null;
        }

        // On windows we have to replace the backslash
        if (!File.separator.equals(FileUtil.URI_SEPARATOR_CHAR)) {
            return path.replace(File.separator, FileUtil.URI_SEPARATOR_CHAR);
        } else {
            return path;
        }
    }
865800
static List<String> path(String name, @Nullable Path path) {
    if (path != null && !path.toString().isEmpty()) {
      return Arrays.asList("--" + name, path.toAbsolutePath().toString());
    }
    return Collections.emptyList();
  }
633030
public static String optionallyRemovePrecedingSlash(final String path) {
        // Precondition check
        assertSpecified(path);

        // Is there's a first character of slash
        if (isFirstCharSlash(path)) {
            // Return everything but first char
            return path.substring(1);
        }

        // Return as-is
        return path;
    }
602236
public static String cleanPath(String path) throws InvalidPathException {
    validatePath(path);
    return FilenameUtils.separatorsToUnix(FilenameUtils.normalizeNoEndSeparator(path));
  }
212843
public static String getClassName(String path) {
        for (Pattern pattern : patterns) {
            Matcher m = pattern.matcher(path);
            if (m.find()) {
                return m.group(1).replaceAll("[/\\\\]", ".");
            }
        }
        return null;
    }
684801
public static String normalizePath(String path) {
    String normalizedPath = path.replaceAll("//+", "/").replaceFirst("(.+)/$", "$1");
    PathUtils.validatePath(normalizedPath);
    return normalizedPath;
  }
1320339
public static String separatorsToSystem(final String path)
    {
        if (path == null)
        {
            return null;
        }
        if (isSystemWindows())
        {
            return separatorsToWindows(path);
        }
        else
        {
            return separatorsToUnix(path);
        }
    }
798133
public static String getNodeFromPath(String path)
    {
        PathUtils.validatePath(path);
        int i = path.lastIndexOf(PATH_SEPARATOR);
        if ( i < 0 )
        {
            return path;
        }
        if ( (i + 1) >= path.length() )
        {
            return "";
        }
        return path.substring(i + 1);
    }
1011007
@Nullable
  protected String getParentPath(String path) {
    // Root does not have a parent.
    if (isRoot(path)) {
      return null;
    }
    int separatorIndex = path.lastIndexOf(PATH_SEPARATOR);
    if (separatorIndex < 0) {
      return null;
    }
    return path.substring(0, separatorIndex);
  }