private @NotNull VirtualFilePointer create(@Nullable("null means the pointer will be created from the (not null) url") VirtualFile file,
                                             @Nullable("null means url has to be computed from the (not-null) file path") String url,
                                             @NotNull Disposable parentDisposable,
                                             @Nullable VirtualFilePointerListener listener, boolean recursive) {
    VirtualFileSystem fileSystem;
    String protocol;
    String path;
    if (file == null) {
      //noinspection ConstantConditions (guaranteed by callers)
      int protocolEnd = url.indexOf(URLUtil.SCHEME_SEPARATOR);
      if (protocolEnd == -1) {
        protocol = null;
        fileSystem = null;
        path = url;
      }
      else {
        protocol = url.substring(0, protocolEnd);
        fileSystem = VirtualFileManager.getInstance().getFileSystem(protocol);
        path = url.substring(protocolEnd + URLUtil.SCHEME_SEPARATOR.length());
      }
      if (fileSystem == null) {
        if (IS_UNDER_UNIT_TEST || IS_INTERNAL) {
          throw new IllegalArgumentException("Unknown filesystem: '" + protocol + "' in url: '" + url+"'");
        }
        // will always be null
        return new LightFilePointer(url);
      }
    }
    else {
      fileSystem = file.getFileSystem();
      protocol = fileSystem.getProtocol();
      path = null;
      url = null;
    }

    if (fileSystem instanceof TempFileSystem && listener == null) {
      // Since VFS events work correctly in temp FS as well, ideally, this branch shouldn't exist and normal VFPointer should be used in all tests.
      // But we have so many tests that create pointers, not dispose and leak them,
      // so for now we create normal pointers only when there are listeners.
      // maybe, later we'll fix all those tests
      VirtualFile found = file == null ? VirtualFileManager.getInstance().findFileByUrl(url) : file;
      return found == null ? new LightFilePointer(url) : new LightFilePointer(found);
    }

    if (!(fileSystem instanceof VirtualFilePointerCapableFileSystem) || file != null && !(file instanceof VirtualFileSystemEntry)) {
      // we are unable to track alien file systems for now
      VirtualFile found = file == null ? VirtualFileManager.getInstance().findFileByUrl(url) : file;
      // if file is null, this pointer will never be alive
      if (url == null) {
        url = file.getUrl();
      }
      return getOrCreateIdentity(url, found, recursive, parentDisposable, listener);
    }

    if (file == null) {
      String cleanPath = cleanupPath(path);
      // if newly created path is the same as the one extracted from url then the url did not change, we can reuse it
      if (!Strings.areSameInstance(cleanPath, path)) {
        url = VirtualFileManager.constructUrl(protocol, cleanPath);
        path = cleanPath;
      }
      if (url.contains("..")) {
        // the url of the form "/x/../y" should resolve to "/y" (or something else in the case of symlinks)
        file = VirtualFileManager.getInstance().findFileByUrl(url);
        if (file != null) {
          url = file.getUrl();
          path = file.getPath();
        }
        else {
          // when someone is crazy enough to create VFP for not-yet existing file from the path with "..", ignore all symlinks
          path = FileUtil.toCanonicalPath(path);
          url = VirtualFileManager.constructUrl(protocol, path);
        }
      }
      if (file == null && StringUtil.isEmptyOrSpaces(path)) {
        // somebody tries to create pointer to root which is pointless but damages our fake root node.
        return getOrCreateIdentity(url, VirtualFileManager.getInstance().findFileByUrl(url), recursive, parentDisposable, listener);
      }
    }
    // else url has come from VirtualFile.getPath() and is good enough
    return getOrCreate((VirtualFileSystemEntry)file, path, url, recursive, parentDisposable, listener, (NewVirtualFileSystem)fileSystem);
  }
private @NotNull VirtualFilePointer create(@Nullable("null means the pointer will be created from the (not null) url") VirtualFile file,
                                             @Nullable("null means url has to be computed from the (not-null) file path") String url,
                                             @NotNull Disposable parentDisposable,
                                             @Nullable VirtualFilePointerListener listener, boolean recursive)