private String getDisplayName(SeqFeatureI sf) {
    String display_name = "";

    // Annot
    if (sf instanceof AnnotatedFeatureI) {
      display_name = sf.getName();
    }

    // Not Annot
    else {
      // FeatPair
      FeatureSetI fset =
          (sf.canHaveChildren() ? (FeatureSetI) sf : (FeatureSetI) sf.getRefFeature());
      // cant do as seqfeature as getHitSequence() is in FeatureSet and not
      // SeqFeature and furthermore cant do a getHitFeature().getRefSequence()
      // as FeatureSet has no hit feature yet it has hit sequence
      // SeqFeatureI fset = sf.canHaveChildren() ? sf : sf.getRefFeature();
      SequenceI seq = (fset != null ? fset.getHitSequence() : null);
      SeqFeatureI featPair = null; // FeaturePairI fp;

      if (fset != null && fset.size() > 0 && (fset.getFeatureAt(0).hasHitFeature())) {
        featPair = fset.getFeatureAt(0);
      } else if (sf.hasHitFeature()) {
        featPair = sf; // fp = (FeaturePairI) sf;
      } // else {//fp = null; } // not necasary - already null

      if (seq == null && featPair != null) seq = featPair.getHitFeature().getRefSequence();
      if (seq == null) seq = sf.getFeatureSequence();

      if (seq != null) {
        display_name = seq.getName() != null ? seq.getName() : "";
      } else if (featPair != null) {
        SeqFeatureI hit = featPair.getHitFeature();
        display_name = hit.getName() != null ? hit.getName() : "";
      }
      /* NOT FeaturePair
         this will only be reached if not an annot, not a FS w fps
         and not a FeaturePair (or if fp hit name is "")
         in otherwords a seqfeature result
         added getName in for chado gene predics which are leaf seq feats
      */
      // shouldnt we check getName != null before using biotype??
      else display_name = getBioTypeForDisplay(sf);
    }
    return display_name;
  }
  protected String getIdForURL(SeqFeatureI f) {
    /* 02/06/2004: If user selected a whole result (a FeatureSet),
     * neither the id nor the name is what we want.
     * So just look at the first child of the FeatureSet
     * (which is probably a FeaturePair).  Is this bad?  --NH */
    if (f instanceof FeatureSet) {
      f = ((FeatureSet) f).getFeatureAt(0);
    }
    String id;
    if (f instanceof FeaturePair) {
      FeaturePair fp = (FeaturePair) f;
      SeqFeatureI sbjct = (SeqFeatureI) fp.getHitFeature();
      id = sbjct.getName();
      if (id.equals("") || id.equals("no_name")) id = f.getName();
      //      System.out.println("getIdForURL: for feature pair " + f.getName() + ", subject name =
      // " + id); // DEL
    } else {
      id = getDisplayName(f);
      //      System.out.println("getIdForURL: for feature " + f.getName() + ", display name = " +
      // id); // DEL
    }
    // Special case:  BDGP EST IDs look like "LD18592.5prime" rather than "LD18592",
    // which isn't what we want.  Need to leave out the .[53]prime part.
    // (Sima says there aren't any cases where we'd want to preserve that part.)
    if (id.endsWith(".3prime") || id.endsWith(".5prime")) {
      //      System.out.println("Truncating EST/cDNA ID " + id + " to remove .[35]prime");
      id = id.substring(0, id.lastIndexOf("."));
    }
    // Some ESTs IDs have :contig1 at the end
    if (id.indexOf(":contig") > 0) {
      id = id.substring(0, id.indexOf(":contig"));
      // In r4.1, I see EST IDs like UNKNOWN_RE01983:contig1 and INVERTED_GH07123:contig1
      if (id.indexOf("_") > 0) id = id.substring(id.indexOf("_") + 1);
    }
    // Some ESTs have _revcomp at the end, e.g. BE975849_revcomp
    if (id.indexOf("_revcomp") > 0) id = id.substring(0, id.indexOf("_revcomp"));

    return id;
  }