private @Nullable Icon doGetIcon(@NotNull VirtualFile virtualFile, int flags) {
    if (!isNativeFileType(virtualFile)) {
      return null;
    }

    if (virtualFile instanceof VirtualFileWithoutContent) {
      return null;
    }

    Ext ext = getExtension(virtualFile, flags);
    Path ioFile = virtualFile.getFileSystem().getNioPath(virtualFile);
    if (ioFile == null) return null;

    synchronized (myIconCache) {
      Icon icon;
      if (myCustomIconExtensions.contains(ext)) {
        icon = myCustomIconCache.get(ioFile.toString());
      }
      else {
        icon = ext == null ? null : myIconCache.get(ext);
      }
      if (icon != null) {
        return icon;
      }
    }

    return DeferredIconImpl.Companion.withoutReadAction(AllIcons.Nodes.NodePlaceholder, ioFile, file -> {
      if (!Files.exists(file)) {
        return null;
      }

      // we should have no read access here, to avoid deadlock with EDT needed to init component
      if (ApplicationManager.getApplication().isReadAccessAllowed()) {
        return null;
      }

      Icon icon;
      try {
        icon = fileChooser.getValue().getIcon(file.toFile());
      }
      catch (Exception e) {
        // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4854174
        return null;
      }

      if (ext != null) {
        synchronized (myIconCache) {
          if (myCustomIconExtensions.contains(ext)) {
            myCustomIconCache.put(file.toString(), icon);
          }
          else {
            myIconCache.put(ext, icon);
          }
        }
      }
      return icon;
    });
  }
private @Nullable Icon doGetIcon(@NotNull VirtualFile virtualFile, int flags)