String (@NotNull String path) { if (path.isEmpty()) { return path; } if (path.charAt(0) == '.') { if (path.length() == 1) { return ""; } char c = path.charAt(1); if (c == '/') { path = path.substring(2); } } // trying to speed up the common case when there are no "//" or "/." int index = -1; do { index = path.indexOf('/', index + 1); char next = index == path.length() - 1 ? 0 : path.charAt(index + 1); if (next == '.' || next == '/') { break; } } while (index != -1); if (index == -1) { return path; } StringBuilder result = new StringBuilder(path.length()); int start = processRoot(path, result); int dots = 0; boolean separator = true; for (int i = start; i < path.length(); ++i) { char c = path.charAt(i); if (c == '/') { if (!separator) { processDots(result, dots, start); dots = 0; } separator = true; } else if (c == '.') { if (separator || dots > 0) { ++dots; } else { result.append('.'); } separator = false; } else { while (dots > 0) { result.append('.'); dots--; } result.append(c); separator = false; } } if (dots > 0) { processDots(result, dots, start); } return result.toString(); }