void (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); }