@Override
  protected void closed() {
    super.closed();

    PluginRepositoryLoader.removeListener(this);
    PluginInstaller.removeListener(this);
    PluginLoader.removeListener(this);
  }
  @Override
  protected void updateButtonsStateInternal() {
    super.updateButtonsStateInternal();

    if (PluginLoader.isLoading()) {
      refreshButton.setText("Reloading...");
      refreshButton.setEnabled(false);
    } else {
      refreshButton.setText("Reload list");
      refreshButton.setEnabled(true);
    }

    final PluginDescriptor plugin = getSelectedPlugin();

    if (plugin == null) {
      action1Button.setEnabled(false);
      action2Button.setEnabled(false);
      return;
    }

    // special case where plugin is currently begin removed
    if (PluginInstaller.isDesinstallingPlugin(plugin)) {
      action1Button.setText("Deleting...");
      action1Button.setEnabled(false);
    } else {
      action1Button.setText("Delete");
      action1Button.setEnabled(true);
    }

    switch (getPluginLocalState(plugin)) {
      case CHECKING_UPDATE:
        action1Button.setEnabled(false);
        action2Button.setText("Checking...");
        action2Button.setEnabled(false);
        break;

      case UPDATING:
        action1Button.setEnabled(false);
        action2Button.setText("Updating...");
        action2Button.setEnabled(false);
        break;

      case HAS_UPDATE:
        action2Button.setText("Update");
        action2Button.setEnabled(true);
        break;

      case NO_UPDATE:
        action2Button.setText("No update");
        action2Button.setEnabled(false);
        break;

      case NULL:
        action1Button.setEnabled(false);
        action2Button.setEnabled(false);
        break;
    }

    // keep delete button enabled only if we can actually delete the plugin
    if (action1Button.isEnabled()) action1Button.setEnabled(plugin.isInstalled());
  }
  @Override
  protected void updateButtonsStateInternal() {
    super.updateButtonsStateInternal();

    final List<PluginDescriptor> selectedPlugins = getSelectedPlugins();
    final boolean selected = (selectedPlugins.size() > 0);

    if (PluginLoader.isLoading()) {
      refreshButton.setText("Reloading...");
      refreshButton.setEnabled(false);
    } else {
      refreshButton.setText("Reload list");
      refreshButton.setEnabled(true);
    }

    if (!selected) {
      action1Button.setEnabled(false);
      action2Button.setEnabled(false);
      return;
    }

    boolean removing = true;
    for (PluginDescriptor plugin : selectedPlugins) {
      if (!PluginInstaller.isDesinstallingPlugin(plugin)) {
        removing = false;
        break;
      }
    }

    // special case where plugins are currently begin removed
    if (removing) {
      action1Button.setText("Removing...");
      action1Button.setEnabled(false);
    } else {
      action1Button.setText("Remove");
      action1Button.setEnabled(true);
    }

    PluginLocalState state = PluginLocalState.NULL;

    for (PluginDescriptor plugin : selectedPlugins) {
      switch (getPluginLocalState(plugin)) {
        case CHECKING_UPDATE:
          if ((state == PluginLocalState.NULL) || (state == PluginLocalState.NO_UPDATE))
            state = PluginLocalState.CHECKING_UPDATE;
          break;

        case UPDATING:
          if ((state == PluginLocalState.NULL)
              || (state == PluginLocalState.NO_UPDATE)
              || (state == PluginLocalState.CHECKING_UPDATE)) state = PluginLocalState.UPDATING;
          break;

        case HAS_UPDATE:
          state = PluginLocalState.HAS_UPDATE;
          break;

        case NO_UPDATE:
          if (state == PluginLocalState.NULL) state = PluginLocalState.NO_UPDATE;
          break;
      }
    }

    switch (state) {
      case CHECKING_UPDATE:
        action1Button.setEnabled(false);
        action2Button.setText("Checking...");
        action2Button.setEnabled(false);
        break;

      case UPDATING:
        action1Button.setEnabled(false);
        action2Button.setText("Updating...");
        action2Button.setEnabled(false);
        break;

      case HAS_UPDATE:
        action2Button.setText("Update");
        action2Button.setEnabled(true);
        break;

      case NO_UPDATE:
        action2Button.setText("No update");
        action2Button.setEnabled(false);
        break;

      case NULL:
        action1Button.setEnabled(false);
        action2Button.setEnabled(false);
        break;
    }

    // keep delete button enabled only if we can actually delete the plugin
    if (action1Button.isEnabled()) {
      boolean canDelete = false;
      for (PluginDescriptor plugin : selectedPlugins) {
        if (plugin.isInstalled()) {
          canDelete = true;
          break;
        }
      }

      action1Button.setEnabled(canDelete);
    }
  }