static void showUpdatedPluginsNotification(Project project) {
    ApplicationManager.getApplication().getMessageBus().simpleConnect().subscribe(AppLifecycleListener.TOPIC, new AppLifecycleListener() {
      @Override
      public void appWillBeClosed(boolean isRestart) {
        Collection<PluginId> plugins = InstalledPluginsState.getInstance().getUpdatedPlugins();
        if (plugins.isEmpty()) return;

        Set<String> idStrings = getUpdatedPlugins();
        for (PluginId plugin : plugins) {
          idStrings.add(plugin.getIdString());
        }
        try {
          Files.write(getUpdatedPluginsFile(), idStrings);
        }
        catch (IOException e) {
          LOG.warn(e);
        }
      }
    });

    List<HtmlChunk.Element> links = new ArrayList<>();
    for (String id : getUpdatedPlugins()) {
      PluginId pluginId = PluginId.findId(id);
      if (pluginId != null) {
        IdeaPluginDescriptor descriptor = PluginManagerCore.getPlugin(pluginId);
        if (descriptor != null) {
          links.add(HtmlChunk.link(id, descriptor.getName()));
        }
      }
    }
    if (links.isEmpty()) return;

    String title = IdeBundle.message("update.installed.notification.title");
    String text = new HtmlBuilder().appendWithSeparators(HtmlChunk.text(", "), links).wrapWith("html").toString();
    //noinspection deprecation
    UpdateChecker.getNotificationGroupForPluginUpdateResults()
      .createNotification(title, text, NotificationType.INFORMATION)
      .setListener((__, e) -> showPluginConfigurable(e, project))  // benign leak - notifications are disposed of on project close
      .setDisplayId("plugins.updated.after.restart")
      .notify(project);
  }
static void showUpdatedPluginsNotification(Project project)