private VirtualFilePointerContainer registerContainer(
      @NotNull Disposable parent,
      @NotNull final VirtualFilePointerContainerImpl virtualFilePointerContainer) {
    synchronized (myContainers) {
      myContainers.add(virtualFilePointerContainer);
    }
    Disposer.register(
        parent,
        new Disposable() {
          @Override
          public void dispose() {
            Disposer.dispose(virtualFilePointerContainer);
            boolean removed;
            synchronized (myContainers) {
              removed = myContainers.remove(virtualFilePointerContainer);
            }
            if (!ApplicationManager.getApplication().isUnitTestMode()) {
              assert removed;
            }
          }

          public String toString() {
            return "Disposing container " + virtualFilePointerContainer;
          }
        });
    return virtualFilePointerContainer;
  }
  public synchronized void assertPointersDisposed() {
    for (Map.Entry<VirtualFilePointerListener, TreeMap<String, VirtualFilePointerImpl>> entry :
        myUrlToPointerMaps.entrySet()) {
      VirtualFilePointerListener listener = entry.getKey();
      TreeMap<String, VirtualFilePointerImpl> map = entry.getValue();
      for (VirtualFilePointerImpl pointer : map.values()) {
        myUrlToPointerMaps.clear();
        pointer.throwNotDisposedError("Not disposed pointer: listener=" + listener);
      }
    }

    synchronized (myContainers) {
      if (!myContainers.isEmpty()) {
        VirtualFilePointerContainerImpl container = myContainers.iterator().next();
        myContainers.clear();
        throw new RuntimeException("Not disposed container " + container);
      }
    }
  }
 @TestOnly
 public synchronized void cleanupForNextTest() {
   myUrlToPointerMaps.clear();
   myContainers.clear();
 }