@Override
  public @Nullable VirtualFileSystemEntry findRoot(@NotNull String path, @NotNull NewVirtualFileSystem fs) {
    if (!myConnected.get()) {
      LOG.info("VFS disconnected. Can't provide root for " + path + " in " + fs);
      return null;
    }
    if (path.isEmpty()) {
      LOG.error("Invalid root, fs=" + fs);
      return null;
    }

    //RC: Why do we strip the trailing '/'? This makes rootUrl not a correct URL anymore, e.g.:
    //   'file:///' -> 'file:'
    //   'jar:///rt.jar!/' -> 'jar:///rt.jar!'
    String rootUrl = UriUtil.trimTrailingSlashes(VirtualFileManager.constructUrl(fs.getProtocol(), path));
    VirtualFileSystemEntry root = myRoots.get(rootUrl);
    if (root != null) return root;

    String rootName;
    String rootPath;
    FileAttributes attributes;
    if (fs instanceof ArchiveFileSystem afs) {
      //RC: I suspect that in most cases this will be an identity transformation:
      //   path(/x/y/z.jar!/) -> localFile(/x/y/z.jar) -> rootPath(/x/y/z.jar!/)
      //   So this branch is basically assigns rootName to jar-file name (instead of root path)
      //   and attributes to _archive_ attributes, instead of file attributes
      VirtualFile localFile = afs.findLocalByRootPath(path);
      if (localFile == null) return null;
      rootName = localFile.getName();
      rootPath = afs.getRootPathByLocal(localFile);// '/x/y/z.jar' -> '/x/y/z.jar!/'
      rootUrl = UriUtil.trimTrailingSlashes(VirtualFileManager.constructUrl(fs.getProtocol(), rootPath));
      attributes = afs.getArchiveRootAttributes(new StubVirtualFile(fs) {
        @Override
        public @NotNull String getPath() { return rootPath; }

        @Override
        public @Nullable VirtualFile getParent() { return null; }
      });
    }
    else {
      rootName = rootPath = path;
      attributes = loadAttributes(fs, rootPath);
    }

    if (attributes == null || !attributes.isDirectory()) {
      //FIXME RC: put special sentinel value into myRoots & myIdToDirCache so next attempt to resolve the root
      //          doesn't need to repeat the whole lookup process (which is slow)
      return null;
    }
    // assume roots have the FS default case sensitivity
    attributes = attributes.withCaseSensitivity(
      fs.isCaseSensitive() ? FileAttributes.CaseSensitivity.SENSITIVE : FileAttributes.CaseSensitivity.INSENSITIVE);
    // avoid creating gazillions of roots which are not actual roots
    String parentPath;
    if (fs instanceof LocalFileSystem && !(parentPath = PathUtil.getParentPath(rootPath)).isEmpty()) {
      FileAttributes parentAttributes = loadAttributes(fs, parentPath);
      if (parentAttributes != null) {
        throw new IllegalArgumentException(
          "Must pass FS root path, but got: '" + path + "' (url: " + rootUrl + "), " +
          "which has a parent '" + parentPath + "'. " +
          "Use NewVirtualFileSystem.extractRootPath() for obtaining root path");
      }
    }

    int rootId = vfsPeer.findOrCreateRootRecord(rootUrl);
    vfsPeer.loadRootData(rootId, path, fs);


    int rootNameId = vfsPeer.getNameId(rootName);
    boolean markModified;
    VirtualFileSystemEntry newRoot;
    synchronized (myRoots) {
      root = myRoots.get(rootUrl);
      if (root != null) return root;

      try {
        String pathBeforeSlash = UriUtil.trimTrailingSlashes(rootPath);
        newRoot = new FsRoot(rootId, myVfsData, fs, pathBeforeSlash, attributes, path, this);
      }
      catch (VfsData.FileAlreadyCreatedException e) {
        for (Map.Entry<String, VirtualFileSystemEntry> entry : myRoots.entrySet()) {
          VirtualFileSystemEntry existingRoot = entry.getValue();
          if (existingRoot.getId() == rootId) {
            String message =
              "Duplicate FS roots: " + rootUrl + " / " + entry.getKey() + " id=" + rootId + " valid=" + existingRoot.isValid();
            throw new RuntimeException(message, e);
          }
        }
        throw new RuntimeException(
          "No root duplication, rootName='" + rootName + "'; rootNameId=" + rootNameId + "; rootId=" + rootId + ";" +
          " path='" + path + "'; fs=" + fs + "; rootUrl='" + rootUrl + "'", e);
      }
      incStructuralModificationCount();
      markModified = writeRootFields(rootId, rootName, fs.isCaseSensitive(), attributes) != -1;

      myRoots.put(rootUrl, newRoot);
      myIdToDirCache.cacheDir(newRoot);
      //To be on a safe side: remove rootId from missed, to prevent any possibility of covering an actually existing root
      missedRootIds.remove(rootId);
    }

    if (!markModified && attributes.lastModified != vfsPeer.getTimestamp(rootId)) {
      newRoot.markDirtyRecursively();
    }

    LOG.assertTrue(rootId == newRoot.getId(), "root=" + newRoot + " expected=" + rootId + " actual=" + newRoot.getId());

    return newRoot;
  }
@Override
  public @Nullable VirtualFileSystemEntry findRoot(@NotNull String path, @NotNull NewVirtualFileSystem fs)