public static boolean prepareToInstall(
      List<PluginNode> pluginsToInstall, List<IdeaPluginDescriptor> allPlugins) {
    ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator();

    final List<PluginId> pluginIds = new ArrayList<PluginId>();
    for (PluginNode pluginNode : pluginsToInstall) {
      pluginIds.add(pluginNode.getPluginId());
    }

    boolean result = false;

    for (final PluginNode pluginNode : pluginsToInstall) {
      if (pi != null) pi.setText(pluginNode.getName());

      try {
        result |= prepareToInstall(pluginNode, pluginIds, allPlugins);
      } catch (final IOException e) {
        SwingUtilities.invokeLater(
            new Runnable() {
              public void run() {
                Messages.showErrorDialog(
                    pluginNode.getName() + ": " + e.getMessage(),
                    CommonBundle.message("title.error"));
              }
            });
      }
    }
    return result;
  }
  private static boolean prepareToInstall(
      final PluginNode pluginNode,
      final List<PluginId> pluginIds,
      List<IdeaPluginDescriptor> allPlugins)
      throws IOException {
    // check for dependent plugins at first.
    if (pluginNode.getDepends() != null && pluginNode.getDepends().size() > 0) {
      // prepare plugins list for install

      final PluginId[] optionalDependentPluginIds = pluginNode.getOptionalDependentPluginIds();
      final List<PluginNode> depends = new ArrayList<PluginNode>();
      final List<PluginNode> optionalDeps = new ArrayList<PluginNode>();
      for (int i = 0; i < pluginNode.getDepends().size(); i++) {
        PluginId depPluginId = pluginNode.getDepends().get(i);

        if (PluginManager.isPluginInstalled(depPluginId)
            || PluginManager.isModuleDependency(depPluginId)
            || (pluginIds != null && pluginIds.contains(depPluginId))) {
          //  ignore installed or installing plugins
          continue;
        }

        PluginNode depPlugin = new PluginNode(depPluginId);
        depPlugin.setSize("-1");
        depPlugin.setName(depPluginId.getIdString()); // prevent from exceptions

        if (optionalDependentPluginIds != null
            && ArrayUtil.indexOf(optionalDependentPluginIds, depPluginId) != -1) {
          if (isPluginInRepo(depPluginId, allPlugins)) {
            optionalDeps.add(depPlugin);
          }
        } else {
          depends.add(depPlugin);
        }
      }

      if (depends.size() > 0) { // has something to install prior installing the plugin
        final boolean[] proceed = new boolean[1];
        final StringBuffer buf = new StringBuffer();
        for (PluginNode depend : depends) {
          buf.append(depend.getName()).append(",");
        }
        try {
          GuiUtils.runOrInvokeAndWait(
              new Runnable() {
                public void run() {
                  proceed[0] =
                      Messages.showYesNoDialog(
                              IdeBundle.message(
                                  "plugin.manager.dependencies.detected.message",
                                  depends.size(),
                                  buf.substring(0, buf.length() - 1)),
                              IdeBundle.message("plugin.manager.dependencies.detected.title"),
                              Messages.getWarningIcon())
                          == DialogWrapper.OK_EXIT_CODE;
                }
              });
        } catch (Exception e) {
          return false;
        }
        if (proceed[0]) {
          if (!prepareToInstall(depends, allPlugins)) {
            return false;
          }
        } else {
          return false;
        }
      }

      if (optionalDeps.size() > 0) {
        final StringBuffer buf = new StringBuffer();
        for (PluginNode depend : optionalDeps) {
          buf.append(depend.getName()).append(",");
        }
        final boolean[] proceed = new boolean[1];
        try {
          GuiUtils.runOrInvokeAndWait(
              new Runnable() {
                public void run() {
                  proceed[0] =
                      Messages.showYesNoDialog(
                              IdeBundle.message(
                                  "plugin.manager.optional.dependencies.detected.message",
                                  optionalDeps.size(),
                                  buf.substring(0, buf.length() - 1)),
                              IdeBundle.message("plugin.manager.dependencies.detected.title"),
                              Messages.getWarningIcon())
                          == DialogWrapper.OK_EXIT_CODE;
                }
              });
        } catch (Exception e) {
          return false;
        }
        if (proceed[0]) {
          if (!prepareToInstall(optionalDeps, allPlugins)) {
            return false;
          }
        }
      }
    }

    synchronized (PluginManager.lock) {
      final PluginDownloader downloader = PluginDownloader.createDownloader(pluginNode);
      if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) {
        downloader.install();
        pluginNode.setStatus(PluginNode.STATUS_DOWNLOADED);
      } else {
        return false;
      }
    }

    return true;
  }