@RequiresBackgroundThread
  private boolean prepareToInstall(@NotNull PluginNode pluginNode,
                                   @NotNull List<PluginId> pluginIds) throws IOException {
    if (!checkMissingDependencies(pluginNode, pluginIds)) return false;
    if (!PluginManagementPolicy.getInstance().canInstallPlugin(pluginNode)) {
      LOG.warn("The plugin " + pluginNode.getPluginId() + " is not allowed to install for the organization");
      return false;
    }
    IdeaPluginDescriptor toDisable = checkDependenciesAndReplacements(pluginNode);

    myShownErrors = false;

    PluginDownloader downloader = PluginDownloader.createDownloader(pluginNode, pluginNode.getRepositoryName(), null);

    IdeaPluginDescriptor previousDescriptor = PluginManagerCore.getPlugin(pluginNode.getPluginId());
    String previousVersion = (previousDescriptor == null) ? null : previousDescriptor.getVersion();
    PluginManagerUsageCollector.pluginInstallationStarted(
      pluginNode,
      downloader.isFromMarketplace() ? InstallationSourceEnum.MARKETPLACE : InstallationSourceEnum.CUSTOM_REPOSITORY,
      previousVersion
    );

    boolean prepared = downloader.prepareToInstall(myIndicator);
    if (prepared) {
      IdeaPluginDescriptorImpl descriptor = (IdeaPluginDescriptorImpl)downloader.getDescriptor();

      if (pluginNode.getDependencies().isEmpty() && !descriptor.getDependencies().isEmpty()) {  // installing from custom plugins repo
        if (!checkMissingDependencies(descriptor, pluginIds)) return false;
      }

      boolean allowNoRestart = myAllowInstallWithoutRestart &&
                               DynamicPlugins.allowLoadUnloadWithoutRestart(
                                 descriptor, null,
                                 ContainerUtil.map(myPendingDynamicPluginInstalls, pluginInstall -> pluginInstall.getPluginDescriptor())
                               );
      if (allowNoRestart) {
        myPendingDynamicPluginInstalls.add(new PendingDynamicPluginInstall(downloader.getFilePath(), descriptor));
        InstalledPluginsState state = InstalledPluginsState.getInstanceIfLoaded();
        if (state != null) {
          state.onPluginInstall(downloader.getDescriptor(), false, false);
        }
      }
      else {
        myRestartRequired = true;
        synchronized (PluginInstaller.ourLock) {
          downloader.install();
        }
      }
      myDependant.add(new PluginInstallCallbackData(downloader.getFilePath(), descriptor, !allowNoRestart));
      pluginNode.setStatus(PluginNode.Status.DOWNLOADED);
      if (toDisable != null) {
        myPluginEnabler.disable(Set.of(toDisable));
      }

      return true;
    }
    else {
      myShownErrors = downloader.isShownErrors();
      return false;
    }
  }
@RequiresBackgroundThread
  private boolean prepareToInstall(@NotNull PluginNode pluginNode,
                                   @NotNull List<PluginId> pluginIds)