List<String> (@NotNull String path) { int end = path.length(); if (end == 0) return Collections.emptyList(); List<String> names = new ArrayList<>(Math.max(20, end/4)); // path length -> path height approximation while (true) { boolean isJarSeparator = StringUtil.endsWith(path, 0, end, JarFileSystem.JAR_SEPARATOR) && (end == 2 && SystemInfo.isWindows || end > 2 && path.charAt(end - 3) != '/'); if (isJarSeparator) { names.add(JarFileSystem.JAR_SEPARATOR); end -= 2; } if (end != 0 && path.charAt(end-1) == '/') { end--; } if (end == 0) { break; // here's separator between non-empty root (e.g. on Windows) and path's tail } int startIndex = extractName(path, end); assert startIndex != end : "startIndex: "+startIndex+"; end: "+end+"; path:'"+path+"'; toExtract: '"+path.substring(0, end)+"'"; names.add(path.substring(startIndex, end)); if (startIndex == 0) { break; } end = startIndex; } return names; }