code: private static String resolveSibling(String fromPath, String toPath) {
      // If the destination is an absolute path, nothing to do.
      if (toPath.startsWith("/")) {
        return toPath;
      }
  
      List<String> fromPathParts = new ArrayList<>(Arrays.asList(fromPath.split("/")));
      List<String> toPathParts = new ArrayList<>(Arrays.asList(toPath.split("/")));
      if (!fromPathParts.isEmpty()) {
        fromPathParts.remove(fromPathParts.size() - 1);
      }
  
      while (!fromPathParts.isEmpty() && !toPathParts.isEmpty()) {
        if (toPathParts.get(0).equals(".")) {
          toPathParts.remove(0);
        } else if (toPathParts.get(0).equals("..")) {
          toPathParts.remove(0);
          fromPathParts.remove(fromPathParts.size() - 1);
        } else {
          break;
        }
      }
  
      fromPathParts.addAll(toPathParts);
      return String.join("/", fromPathParts);
    }
docs: Simplistic implementation of the java.nio.file.Path resolveSibling method that works with GWT.
  
  @param fromPath - must be a file (not directory)
  @param toPath - must be a file (not directory)