public void setIndexer(LibrariesIndexer indexer) {
    this.indexer = indexer;

    DropdownItem<DownloadableContribution> previouslySelectedCategory = (DropdownItem<DownloadableContribution>) categoryChooser.getSelectedItem();
    DropdownItem<DownloadableContribution> previouslySelectedType = (DropdownItem<DownloadableContribution>) typeChooser.getSelectedItem();

    categoryChooser.removeActionListener(categoryChooserActionListener);
    typeChooser.removeActionListener(typeChooserActionListener);

    // TODO: Remove setIndexer and make getContribModel 
    // return a FilteredAbstractTableModel
    getContribModel().setIndexer(indexer);

    categoryFilter = null;
    categoryChooser.removeAllItems();

    // Load categories
    categoryChooser.addItem(new DropdownAllItem());
    Collection<String> categories = indexer.getIndex().getCategories();
    for (String category : categories) {
      categoryChooser.addItem(new DropdownLibraryOfCategoryItem(category));
    }

    categoryChooser.setEnabled(categoryChooser.getItemCount() > 1);

    categoryChooser.addActionListener(categoryChooserActionListener);
    if (previouslySelectedCategory != null) {
      categoryChooser.setSelectedItem(previouslySelectedCategory);
    } else {
      categoryChooser.setSelectedIndex(0);
    }

    typeFilter = null;
    typeChooser.removeAllItems();
    typeChooser.addItem(new DropdownAllItem());
    typeChooser.addItem(new DropdownInstalledLibraryItem(indexer.getIndex()));
    java.util.List<String> types = new LinkedList<String>(indexer.getIndex().getTypes());
    Collections.sort(types, new LibraryTypeComparator());
    for (String type : types) {
      typeChooser.addItem(new DropdownLibraryOfTypeItem(type));
    }
    typeChooser.setEnabled(typeChooser.getItemCount() > 1);
    typeChooser.addActionListener(typeChooserActionListener);
    if (previouslySelectedType != null) {
      typeChooser.setSelectedItem(previouslySelectedType);
    } else {
      typeChooser.setSelectedIndex(0);
    }

    filterField.setEnabled(contribModel.getRowCount() > 0);

    // Create LibrariesInstaller tied with the provided index
    installer = new LibraryInstaller(indexer, platform) {
      @Override
      public void onProgress(Progress progress) {
        setProgress(progress);
      }
    };
  }
  // WTF: this does not update packs!!
  // only updating info for selected pack. pulldown menus and info area!
  void updatePacks() {
    for (int i = 0; i < packPanels.size(); i++) {
      if (selectedPack == i && getIndex() >= 0) {
        ModPack pack = ModPack.getPackArray().get(getIndex());
        if (pack != null) {
          String mods = "";
          if (pack.getMods() != null) {
            mods += "<p>This pack contains the following mods by default:</p><ul>";
            for (String name : pack.getMods()) {
              mods += "<li>" + name + "</li>";
            }
            mods += "</ul>";
          }
          packPanels.get(i).setBackground(UIManager.getColor("control").darker().darker());
          packPanels.get(i).setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
          File tempDir =
              new File(
                  OSUtils.getCacheStorageLocation(), "ModPacks" + File.separator + pack.getDir());
          packInfo.setText(
              "<html><img src='file:///"
                  + tempDir.getPath()
                  + File.separator
                  + pack.getImageName()
                  + "' width=400 height=200></img> <br>"
                  + pack.getInfo()
                  + mods);
          packInfo.setCaretPosition(0);

          if (ModPack.getSelectedPack(isFTB()).getServerUrl().equals("")
              || ModPack.getSelectedPack(isFTB()).getServerUrl() == null) {
            server.setEnabled(false);
          } else {
            server.setEnabled(true);
          }
          String tempVer = Settings.getSettings().getPackVer(pack.getDir());
          version.removeActionListener(al);
          version.removeAllItems();
          version.addItem("Recommended");
          if (pack.getOldVersions() != null) {
            for (String s : pack.getOldVersions()) {
              version.addItem(s);
            }
            version.setSelectedItem(tempVer);
          }
          version.addActionListener(al);
        }
      } else {
        packPanels.get(i).setBackground(UIManager.getColor("control"));
        packPanels.get(i).setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
      }
    }
  }
  /** Parse clicks to cancel the recording if we get a click that's not in the JList (or ESC). */
  protected boolean parseClick(AWTEvent event) {

    if (isFinished()) {
      return false;
    }

    // FIXME add key-based activation/termination?
    boolean consumed = true;
    if (combo == null) {
      combo = getComboBox(event);
      listener =
          new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
              index = combo.getSelectedIndex();
              if (!combo.isPopupVisible()) {
                combo.removeActionListener(listener);
                setFinished(true);
              }
            }
          };
      combo.addActionListener(listener);
      setStatus("Waiting for selection");
    } else if (event.getID() == KeyEvent.KEY_RELEASED
        && (((KeyEvent) event).getKeyCode() == KeyEvent.VK_SPACE
            || ((KeyEvent) event).getKeyCode() == KeyEvent.VK_ENTER)) {
      index = combo.getSelectedIndex();
      setFinished(true);
    }
    // Cancel via click somewhere else
    else if (event.getID() == MouseEvent.MOUSE_PRESSED
        && !AWT.isOnPopup((Component) event.getSource())
        && combo != getComboBox(event)) {
      setFinished(true);
      consumed = false;
    }
    // Cancel via ESC key
    else if (event.getID() == KeyEvent.KEY_RELEASED
        && ((KeyEvent) event).getKeyCode() == KeyEvent.VK_ESCAPE) {
      setStatus("Selection canceled");
      setFinished(true);
    } else {
      Log.debug("Event ignored");
    }
    if (list == null && combo.isPopupVisible()) list = tester.findComboList(combo);

    if (isFinished()) {
      combo.removeActionListener(listener);
      listener = null;
    }

    return consumed;
  }
  /**
   * Constructor with a string argument that becomes part of the label of the button.
   *
   * @param settingsPanel : parent window
   */
  public ChooseOntologyPanel(
      SettingsPanel settingsPanel, String bingoDir, String[] choiceArray, String choice_def) {
    super();
    this.bingoDir = bingoDir;
    this.settingsPanel = settingsPanel;
    this.choiceArray = choiceArray;

    // annotationFilePath = new File(bingoDir, "bingo");
    setOpaque(false);
    makeJComponents();
    // Layout with GridLayout.
    setLayout(new GridLayout(1, 0));
    add(choiceBox);

    // defaults

    HashSet<String> choiceSet = new HashSet<String>();
    for (String s : choiceArray) {
      choiceSet.add(s);
    }
    if (choiceSet.contains(choice_def)) {
      choiceBox.setSelectedItem(choice_def);
      this.settingsPanel.getNamespacePanel().choiceBox.setEnabled(false);
      specifiedOntology = (String) choiceBox.getSelectedItem();
      def = true;
    } else {
      choiceBox.removeActionListener(this);
      choiceBox.setEditable(true);
      choiceBox.setSelectedItem(choice_def);
      choiceBox.setEditable(false);
      specifiedOntology = BingoAlgorithm.CUSTOM;
      def = false;
      if (choice_def.endsWith(".obo")) {
        this.settingsPanel.getNamespacePanel().choiceBox.setEnabled(true);
      } else {
        this.settingsPanel.getNamespacePanel().choiceBox.setEnabled(false);
      }
      choiceBox.addActionListener(this);
    }
  }