@NotNull
  private VirtualFilePointer create(
      @Nullable VirtualFile file,
      @NotNull String url,
      @NotNull final Disposable parentDisposable,
      @Nullable VirtualFilePointerListener listener) {
    String protocol;
    VirtualFileSystem fileSystem;
    if (file == null) {
      protocol = VirtualFileManager.extractProtocol(url);
      fileSystem = myVirtualFileManager.getFileSystem(protocol);
    } else {
      protocol = null;
      fileSystem = file.getFileSystem();
    }
    if (fileSystem == TempFileSystem.getInstance()) {
      // for tests, recreate always since
      VirtualFile found =
          fileSystem == null
              ? null
              : file != null ? file : VirtualFileManager.getInstance().findFileByUrl(url);
      return new IdentityVirtualFilePointer(found, url);
    }
    if (fileSystem != LocalFileSystem.getInstance() && fileSystem != JarFileSystem.getInstance()) {
      // we are unable to track alien file systems for now
      VirtualFile found =
          fileSystem == null
              ? null
              : file != null ? file : VirtualFileManager.getInstance().findFileByUrl(url);
      // if file is null, this pointer will never be alive
      return getOrCreateIdentity(url, found);
    }

    String path;
    if (file == null) {
      path = VirtualFileManager.extractPath(url);
      path = cleanupPath(path, protocol);
      url = VirtualFileManager.constructUrl(protocol, path);
    } else {
      path = file.getPath();
      // url has come from VirtualFile.getUrl() and is good enough
    }

    VirtualFilePointerImpl pointer = getOrCreate(file, url, parentDisposable, listener, path);

    int newCount = pointer.incrementUsageCount();

    if (newCount == 1) {
      Disposer.register(parentDisposable, pointer);
    } else {
      // already registered
      register(parentDisposable, pointer);
    }

    return pointer;
  }
  protected void fireEventsInWriteAction() {
    final VirtualFileManagerEx manager = (VirtualFileManagerEx) VirtualFileManager.getInstance();

    manager.fireBeforeRefreshStart(myIsAsync);
    try {
      while (!myWorkQueue.isEmpty() || !myEvents.isEmpty()) {
        ManagingFS.getInstance().processEvents(mergeEventsAndReset());
        scan();
      }
    } finally {
      try {
        manager.fireAfterRefreshFinish(myIsAsync);
      } finally {
        if (myFinishRunnable != null) {
          myFinishRunnable.run();
        }
      }
    }
  }