public boolean testPredicate(Feature targetFeature) {
    String targetKey = targetFeature.getKey().getKeyString();
    if (sameKey && !targetKey.equals(key)) return false;

    Vector<String> chadoNames = null;
    if (isDatabaseEntry) {
      GFFStreamFeature gffFeature = ((GFFStreamFeature) targetFeature.getEmblFeature());
      if (gffFeature.getChadoGene() != null) {
        chadoNames = new Vector<String>();

        ChadoCanonicalGene chadoGene = gffFeature.getChadoGene();
        chadoNames.add(chadoGene.getGeneUniqueName());
        List<uk.ac.sanger.artemis.io.Feature> transcripts = chadoGene.getTranscripts();
        for (int i = 0; i < transcripts.size(); i++) {
          GFFStreamFeature feature = (GFFStreamFeature) transcripts.get(i);
          chadoNames.add(GeneUtils.getUniqueName(feature));
        }
      }
    }

    String thisFeatureSystematicName = targetFeature.getSystematicName();
    for (int i = 0; i < geneNames.length; i++) {
      if (geneNames[i].equals(thisFeatureSystematicName)
          || (chadoNames != null && chadoNames.contains(geneNames[i]))) {
        geneName = geneNames[i];
        return true;
      }
    }
    return false;
  }
  /**
   * Add a panel to display a given features qualifiers.
   *
   * @param f
   * @param qualifierPanels
   * @param c
   * @param nrows
   * @param pane
   */
  private void addQualifierPanel(
      Feature f,
      Vector<QualifierPanel> qualifierPanels,
      GridBagConstraints c,
      int nrows,
      JPanel pane) {
    QualifierPanel qPanel = new QualifierPanel(f, f.getKey().getKeyString());
    if (qPanel.nrows == 0) return;

    c.fill = GridBagConstraints.HORIZONTAL;
    c.anchor = GridBagConstraints.WEST;
    c.weightx = 100;
    qualifierPanels.add(qPanel);
    c.gridy = ++nrows;

    JLabel l = new JLabel(f.getIDString());
    l.setFont(l.getFont().deriveFont(Font.BOLD));
    l.setForeground(STEEL_BLUE);
    pane.add(l, c);

    c.gridy = ++nrows;
    pane.add(qPanel, c);
    c.weightx = 0.d;
  }
  /**
   * Transfer selected qualifiers to the list of features defined by the selected names.
   *
   * @param qualifierCheckBoxes - list of qualifier check boxes
   * @param geneNameTextArea - text with a list of feature names to transfer to
   * @param feature - feature to copy from
   * @param entryGroup
   * @param sameKey
   * @param overwrite
   */
  protected static int transferAnnotation(
      final Hashtable<JCheckBox, Vector<JCheckBox>> qualifierCheckBoxes,
      final Vector<JCheckBox> geneNameCheckBoxes,
      final Feature orginatingFeature,
      final EntryGroup entryGroup,
      final boolean sameKey,
      final boolean overwrite,
      final boolean setEvidenceAndWithFrom,
      final StringBuffer buff,
      final StringBuffer genesUpdated) {
    // transfer selected annotation to genes
    final QualifierVector qualifiers = orginatingFeature.getQualifiers();
    final QualifierVector qualifiersToTransfer = new QualifierVector();

    Enumeration<JCheckBox> enumQualifiers = qualifierCheckBoxes.keys();
    while (enumQualifiers.hasMoreElements()) {
      JCheckBox cb = enumQualifiers.nextElement();
      if (cb.isSelected()) {
        Vector<JCheckBox> qualifierValuesCheckBox = qualifierCheckBoxes.get(cb);
        final StringVector values = qualifiers.getQualifierByName(cb.getText()).getValues();
        StringVector valuesToTransfer = new StringVector(values);

        logger4j.debug("TRANSFER " + cb.getText());
        for (int i = 0; i < qualifierValuesCheckBox.size(); i++) {
          JCheckBox valuesCb = qualifierValuesCheckBox.get(i);
          if (!valuesCb.isSelected()) {
            valuesToTransfer.remove(valuesCb.getText());
            logger4j.debug("NOT TRANSFERING " + valuesCb.getText());
          }
        }

        if (valuesToTransfer.size() < 1) continue;

        valuesToTransfer =
            new StringVector(
                getTransferValues(
                    setEvidenceAndWithFrom, orginatingFeature, cb.getText(), valuesToTransfer));

        qualifiersToTransfer.addElement(new Qualifier(cb.getText(), valuesToTransfer));
      }
    }

    int count = 0;
    for (int i = 0; i < geneNameCheckBoxes.size(); i++) {
      if (geneNameCheckBoxes.get(i).isSelected()) count++;
    }

    if (count < 1) {
      JOptionPane.showMessageDialog(
          null, "No genes selected.", "Warning", JOptionPane.WARNING_MESSAGE);
      return -1;
    }

    String geneNames[] = new String[count];
    count = 0;
    for (int i = 0; i < geneNameCheckBoxes.size(); i++) {
      JCheckBox cb = geneNameCheckBoxes.get(i);
      if (cb.isSelected()) {
        geneNames[count] = cb.getText();
        logger4j.debug("TRANSFER ANNOTATION TO " + geneNames[count]);
        count++;
      }
    }

    final String key = orginatingFeature.getKey().getKeyString();
    final FeatureVector features = entryGroup.getAllFeatures();

    // transfer selected annotation
    entryGroup.getActionController().startAction();
    geneNames =
        transfer(
            features,
            qualifiersToTransfer,
            key,
            sameKey,
            overwrite,
            GeneUtils.isDatabaseEntry(entryGroup),
            geneNames,
            genesUpdated);
    entryGroup.getActionController().endAction();

    //
    // Commit changes to genes not in Artemis but in the database
    //
    Vector<String> genesNotFound = null;
    if (geneNames != null
        && orginatingFeature.getEntry().getEMBLEntry() instanceof DatabaseDocumentEntry) {
      DatabaseDocumentEntry db_entry =
          (DatabaseDocumentEntry) orginatingFeature.getEntry().getEMBLEntry();
      DatabaseDocument doc = (DatabaseDocument) db_entry.getDocument();

      for (int i = 0; i < geneNames.length; i++) {
        DatabaseDocumentEntry newDbEntry = GeneEdit.makeGeneEntry(null, geneNames[i], doc, null);

        if (newDbEntry == null) {
          if (genesNotFound == null) genesNotFound = new Vector<String>();
          genesNotFound.add(geneNames[i]);
          continue;
        }

        char[] c = new char[1];
        PartialSequence ps = new PartialSequence(c, 100, 0, null, null);
        newDbEntry.setPartialSequence(ps);
        Entry entry = null;
        try {
          entry = new Entry(newDbEntry);
        } catch (Exception e) {
          e.printStackTrace();
        }

        SimpleEntryGroup entry_group = new SimpleEntryGroup();
        entry_group.addElement(entry);

        ChadoTransactionManager ctm = new ChadoTransactionManager();
        entry_group.addFeatureChangeListener(ctm);
        entry_group.addEntryChangeListener(ctm);
        ctm.setEntryGroup(entry_group);

        transfer(
            entry.getAllFeatures(),
            qualifiersToTransfer,
            key,
            sameKey,
            overwrite,
            true,
            geneNames,
            genesUpdated);

        for (int j = 0; j < ctm.getTransactionCount(); j++)
          buff.append(ctm.getTransactionAt(j).getLogComment() + "\n");
        ChadoTransactionManager.commit((DatabaseDocument) newDbEntry.getDocument(), false, ctm);

        entry_group.removeFeatureChangeListener(ctm);
        entry_group.removeEntryChangeListener(ctm);
        // if(newDbEntry != null)
        // GeneEdit.showGeneEditor(null, geneNames[i], newDbEntry);
      }
    }

    if (genesNotFound != null)
      JOptionPane.showMessageDialog(
          null,
          "Gene(s) Not Found:\n" + genesNotFound.toString(),
          "Gene(s) Not Found",
          JOptionPane.WARNING_MESSAGE);
    return 0;
  }