static void runUpdateAll(@NotNull Collection<PluginDownloader> toDownload,
                           @Nullable JComponent ownerComponent,
                           @Nullable Runnable finishCallback,
                           @Nullable Consumer<Boolean> customRestarter) {
    String message = IdeBundle.message("updates.notification.title", ApplicationNamesInfo.getInstance().getFullProductName());
    new Task.Backgroundable(null, message, true, PerformInBackgroundOption.DEAF) {
      @Override
      public void run(@NotNull ProgressIndicator indicator) {
        List<PluginDownloader> downloaders = downloadPluginUpdates(toDownload, indicator);
        if (downloaders.isEmpty()) {
          return;
        }

        ApplicationManager.getApplication().invokeLater(() -> {
          List<IdeaPluginDescriptor> installedDescriptors = installPluginUpdates(downloaders);

          boolean restartRequired = downloaders.size() != installedDescriptors.size();
          if (customRestarter != null) {
            customRestarter.accept(restartRequired);
            return;
          }
          if (!restartRequired) {
            UpdateChecker.getNotificationGroupForPluginUpdateResults()
              .createNotification(getUpdateNotificationMessage(installedDescriptors),
                                  NotificationType.INFORMATION)
              .setDisplayId("plugins.updated.without.restart")
              .notify(myProject);
          }
          else if (WelcomeFrame.getInstance() == null) {
            PluginManagerMain.notifyPluginsUpdated(null);
          }
          else {
            PluginManagerConfigurable.shutdownOrRestartApp();
          }
        }, ownerComponent != null ? ModalityState.stateForComponent(ownerComponent) : ModalityState.defaultModalityState());
      }

      @Override
      public void onFinished() {
        if (finishCallback != null) {
          finishCallback.run();
        }
      }

      private @NotNull List<IdeaPluginDescriptor> installPluginUpdates(@NotNull List<PluginDownloader> downloaders) {
        List<IdeaPluginDescriptor> installedDescriptors = new ArrayList<>();
        for (PluginDownloader downloader : downloaders) {
          try {
            if (downloader.installDynamically(ownerComponent)) {
              installedDescriptors.add(downloader.getDescriptor());
            }
          }
          catch (Exception e) {
            Logger.getInstance(PluginUpdateDialog.class).info(e);
          }
        }
        return installedDescriptors;
      }

      private static @NotNull @Nls String getUpdateNotificationMessage(@NotNull List<? extends IdeaPluginDescriptor> descriptors) {
        if (descriptors.size() == 1) {
          IdeaPluginDescriptor descriptor = descriptors.get(0);
          return IdeBundle.message("notification.content.updated.plugin.to.version", descriptor.getName(), descriptor.getVersion());
        }
        else {
          String names = descriptors.stream()
            .map(IdeaPluginDescriptor::getName)
            .collect(Collectors.joining(", "));
          return IdeBundle.message("notification.content.updated.plugins", names);
        }
      }
    }.queue();
  }
static void runUpdateAll(@NotNull Collection<PluginDownloader> toDownload,
                           @Nullable JComponent ownerComponent,
                           @Nullable Runnable finishCallback,
                           @Nullable Consumer<Boolean> customRestarter)