synchronized void clearPointerCaches(String url, VirtualFilePointerListener listener) {
   TreeMap<String, VirtualFilePointerImpl> urlToPointer = myUrlToPointerMaps.get(listener);
   if (urlToPointer == null && ApplicationManager.getApplication().isUnitTestMode()) return;
   assert urlToPointer != null;
   urlToPointer.remove(VfsUtil.urlToPath(url));
   if (urlToPointer.isEmpty()) {
     myUrlToPointerMaps.remove(listener);
   }
 }
    @Override
    public void after(@NotNull final List<? extends VFileEvent> events) {
      cleanContainerCaches();

      if (myUrlsToUpdate == null) {
        return;
      }
      for (String url : myUrlsToUpdate) {
        synchronized (VirtualFilePointerManagerImpl.this) {
          for (TreeMap<String, VirtualFilePointerImpl> urlToPointer : myUrlToPointerMaps.values()) {
            VirtualFilePointerImpl pointer = urlToPointer.remove(url);
            if (pointer != null) {
              String path = VfsUtil.urlToPath(pointer.getUrl());
              urlToPointer.put(path, pointer);
            }
          }
        }
      }

      for (VirtualFilePointer pointer : myPointersToUpdate) {
        ((VirtualFilePointerImpl) pointer).update();
      }

      for (EventDescriptor event : myEvents) {
        event.fireAfter();
      }

      if (!myPointersToUpdate.isEmpty()) {
        VirtualFilePointer[] arr =
            myPointersToUpdate.toArray(new VirtualFilePointer[myPointersToUpdate.size()]);
        myBus.syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(arr);
      }

      myUrlsToUpdate = null;
      myEvents = null;
      myPointersToUpdate = null;
    }