private boolean installSelected(PluginTable pluginTable) {
   IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects();
   if (selection != null) {
     boolean enabled = true;
     for (IdeaPluginDescriptor descr : selection) {
       if (descr instanceof PluginNode) {
         enabled &= !PluginManagerColumnInfo.isDownloaded((PluginNode) descr);
         if (((PluginNode) descr).getStatus() == PluginNode.STATUS_INSTALLED) {
           enabled &= InstalledPluginsTableModel.hasNewerVersion(descr.getPluginId());
         }
       } else if (descr instanceof IdeaPluginDescriptorImpl) {
         PluginId id = descr.getPluginId();
         enabled &= InstalledPluginsTableModel.hasNewerVersion(id);
       }
     }
     if (enabled) {
       new ActionInstallPlugin(this, installed).install();
     }
     return true;
   }
   return false;
 }
  public void install(@Nullable final Runnable onSuccess, boolean confirmed) {
    IdeaPluginDescriptor[] selection = getPluginTable().getSelectedObjects();

    if (confirmed || userConfirm(selection)) {
      final List<PluginNode> list = new ArrayList<PluginNode>();
      for (IdeaPluginDescriptor descr : selection) {
        PluginNode pluginNode = null;
        if (descr instanceof PluginNode) {
          pluginNode = (PluginNode) descr;
        } else if (descr instanceof IdeaPluginDescriptorImpl) {
          PluginId pluginId = descr.getPluginId();
          pluginNode = new PluginNode(pluginId);
          pluginNode.setName(descr.getName());
          pluginNode.setDepends(
              Arrays.asList(descr.getDependentPluginIds()), descr.getOptionalDependentPluginIds());
          pluginNode.setSize("-1");
          pluginNode.setRepositoryName(PluginInstaller.UNKNOWN_HOST_MARKER);
        }

        if (pluginNode != null) {
          list.add(pluginNode);
          ourInstallingNodes.add(pluginNode);
        }
      }

      final InstalledPluginsTableModel installedModel =
          (InstalledPluginsTableModel) myInstalled.getPluginsModel();
      final Set<IdeaPluginDescriptor> disabled = new HashSet<IdeaPluginDescriptor>();
      final Set<IdeaPluginDescriptor> disabledDependants = new HashSet<IdeaPluginDescriptor>();
      for (PluginNode node : list) {
        final PluginId pluginId = node.getPluginId();
        if (installedModel.isDisabled(pluginId)) {
          disabled.add(node);
        }
        final List<PluginId> depends = node.getDepends();
        if (depends != null) {
          final Set<PluginId> optionalDeps =
              new HashSet<PluginId>(Arrays.asList(node.getOptionalDependentPluginIds()));
          for (PluginId dependantId : depends) {
            if (optionalDeps.contains(dependantId)) continue;
            final IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(dependantId);
            if (pluginDescriptor != null && installedModel.isDisabled(dependantId)) {
              disabledDependants.add(pluginDescriptor);
            }
          }
        }
      }

      if (suggestToEnableInstalledPlugins(installedModel, disabled, disabledDependants, list)) {
        myInstalled.setRequireShutdown(true);
      }

      try {
        Runnable onInstallRunnable =
            new Runnable() {
              @Override
              public void run() {
                for (PluginNode node : list) {
                  installedModel.appendOrUpdateDescriptor(node);
                }
                if (!myInstalled.isDisposed()) {
                  getPluginTable().updateUI();
                  myInstalled.setRequireShutdown(true);
                } else {
                  boolean needToRestart = false;
                  for (PluginNode node : list) {
                    final IdeaPluginDescriptor pluginDescriptor =
                        PluginManager.getPlugin(node.getPluginId());
                    if (pluginDescriptor == null || pluginDescriptor.isEnabled()) {
                      needToRestart = true;
                      break;
                    }
                  }

                  if (needToRestart) {
                    PluginManagerMain.notifyPluginsUpdated(null);
                  }
                }
                if (onSuccess != null) {
                  onSuccess.run();
                }
              }
            };
        Runnable cleanupRunnable =
            new Runnable() {
              @Override
              public void run() {
                ourInstallingNodes.removeAll(list);
              }
            };
        PluginManagerMain.downloadPlugins(
            list, myHost.getPluginsModel().getAllPlugins(), onInstallRunnable, cleanupRunnable);
      } catch (final IOException e1) {
        ourInstallingNodes.removeAll(list);
        PluginManagerMain.LOG.error(e1);
        //noinspection SSBasedInspection
        SwingUtilities.invokeLater(
            new Runnable() {
              @Override
              public void run() {
                IOExceptionDialog.showErrorDialog(
                    IdeBundle.message("action.download.and.install.plugin"),
                    IdeBundle.message("error.plugin.download.failed"));
              }
            });
      }
    }
  }
  private static boolean suggestToEnableInstalledPlugins(
      InstalledPluginsTableModel pluginsModel,
      Set<IdeaPluginDescriptor> disabled,
      Set<IdeaPluginDescriptor> disabledDependants,
      List<PluginNode> list) {
    if (!disabled.isEmpty() || !disabledDependants.isEmpty()) {
      String message = "";
      if (disabled.size() == 1) {
        message += "Updated plugin '" + disabled.iterator().next().getName() + "' is disabled.";
      } else if (!disabled.isEmpty()) {
        message +=
            "Updated plugins "
                + StringUtil.join(
                    disabled,
                    new Function<IdeaPluginDescriptor, String>() {
                      @Override
                      public String fun(IdeaPluginDescriptor pluginDescriptor) {
                        return pluginDescriptor.getName();
                      }
                    },
                    ", ")
                + " are disabled.";
      }

      if (!disabledDependants.isEmpty()) {
        message += "<br>";
        message += "Updated plugin" + (list.size() > 1 ? "s depend " : " depends ") + "on disabled";
        if (disabledDependants.size() == 1) {
          message += " plugin '" + disabledDependants.iterator().next().getName() + "'.";
        } else {
          message +=
              " plugins "
                  + StringUtil.join(
                      disabledDependants,
                      new Function<IdeaPluginDescriptor, String>() {
                        @Override
                        public String fun(IdeaPluginDescriptor pluginDescriptor) {
                          return pluginDescriptor.getName();
                        }
                      },
                      ", ")
                  + ".";
        }
      }
      message +=
          " Disabled plugins "
              + (disabled.isEmpty() ? "and plugins which depend on disabled " : "")
              + "won't be activated after restart.";

      int result;
      if (!disabled.isEmpty() && !disabledDependants.isEmpty()) {
        result =
            Messages.showYesNoCancelDialog(
                XmlStringUtil.wrapInHtml(message),
                CommonBundle.getWarningTitle(),
                "Enable all",
                "Enable updated plugin" + (disabled.size() > 1 ? "s" : ""),
                CommonBundle.getCancelButtonText(),
                Messages.getQuestionIcon());
        if (result == Messages.CANCEL) return false;
      } else {
        message += "<br>Would you like to enable ";
        if (!disabled.isEmpty()) {
          message += "updated plugin" + (disabled.size() > 1 ? "s" : "");
        } else {
          //noinspection SpellCheckingInspection
          message += "plugin dependenc" + (disabledDependants.size() > 1 ? "ies" : "y");
        }
        message += "?";
        result =
            Messages.showYesNoDialog(
                XmlStringUtil.wrapInHtml(message),
                CommonBundle.getWarningTitle(),
                Messages.getQuestionIcon());
        if (result == Messages.NO) return false;
      }

      if (result == Messages.YES) {
        disabled.addAll(disabledDependants);
        pluginsModel.enableRows(disabled.toArray(new IdeaPluginDescriptor[disabled.size()]), true);
      } else if (result == Messages.NO && !disabled.isEmpty()) {
        pluginsModel.enableRows(disabled.toArray(new IdeaPluginDescriptor[disabled.size()]), true);
      }
      return true;
    }
    return false;
  }