@Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
      final Component orig =
          super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
      if (myPluginDescriptor != null) {
        myNameLabel.setText(myPluginDescriptor.getName());
        final PluginId pluginId = myPluginDescriptor.getPluginId();
        final String idString = pluginId.getIdString();
        if (myPluginDescriptor.isBundled()) {
          myBundledLabel.setText("Bundled");
        } else {
          final String host = myPlugin2host.get(idString);
          if (host != null) {
            String presentableUrl = VfsUtil.urlToPath(host);
            final int idx = presentableUrl.indexOf('/');
            if (idx > -1) {
              presentableUrl = presentableUrl.substring(0, idx);
            }
            myBundledLabel.setText("From " + presentableUrl);
          } else {
            if (PluginManagerUISettings.getInstance().getInstalledPlugins().contains(idString)) {
              myBundledLabel.setText("From repository");
            } else {
              myBundledLabel.setText("Custom");
            }
          }
        }
        if (myPluginDescriptor instanceof IdeaPluginDescriptorImpl
            && ((IdeaPluginDescriptorImpl) myPluginDescriptor).isDeleted()) {
          myNameLabel.setIcon(AllIcons.Actions.Clean);
        } else if (hasNewerVersion(pluginId)) {
          myNameLabel.setIcon(AllIcons.Nodes.Pluginobsolete);
          myPanel.setToolTipText("Newer version of the plugin is available");
        } else {
          myNameLabel.setIcon(AllIcons.Nodes.Plugin);
        }

        final Color fg = orig.getForeground();
        final Color bg = orig.getBackground();
        final Color grayedFg = isSelected ? fg : Color.GRAY;

        myPanel.setBackground(bg);
        myNameLabel.setBackground(bg);
        myBundledLabel.setBackground(bg);

        myNameLabel.setForeground(fg);
        final boolean wasUpdated = wasUpdated(pluginId);
        if (wasUpdated || PluginManager.getPlugin(pluginId) == null) {
          if (!isSelected) {
            myNameLabel.setForeground(FileStatus.COLOR_ADDED);
          }
          if (wasUpdated) {
            myPanel.setToolTipText(
                "Plugin was updated to the newest version. Changes will be available after restart");
          } else {
            myPanel.setToolTipText("Plugin will be activated after restart.");
          }
        }
        myBundledLabel.setForeground(grayedFg);

        final Set<PluginId> required = myDependentToRequiredListMap.get(pluginId);
        if (required != null && required.size() > 0) {
          myNameLabel.setForeground(Color.RED);

          final StringBuilder s = new StringBuilder();
          if (myEnabled.get(pluginId) == null) {
            s.append("Plugin was not loaded.\n");
          }
          if (required.contains(PluginId.getId("com.intellij.modules.ultimate"))) {
            s.append("The plugin requires IntelliJ IDEA Ultimate");
          } else {
            s.append("Required plugin").append(required.size() == 1 ? " \"" : "s \"");
            s.append(
                StringUtil.join(
                    required,
                    new Function<PluginId, String>() {
                      @Override
                      public String fun(final PluginId id) {
                        final IdeaPluginDescriptor plugin = PluginManager.getPlugin(id);
                        return plugin == null ? id.getIdString() : plugin.getName();
                      }
                    },
                    ","));

            s.append(required.size() == 1 ? "\" is not enabled!" : "\" are not enabled!");
          }
          myPanel.setToolTipText(s.toString());
        }

        if (PluginManager.isIncompatible(myPluginDescriptor)) {
          myPanel.setToolTipText(
              IdeBundle.message(
                  "plugin.manager.incompatible.tooltip.warning",
                  ApplicationNamesInfo.getInstance().getFullProductName()));
          myNameLabel.setForeground(Color.red);
        }
      }

      return myPanel;
    }
  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"));
              }
            });
      }
    }
  }