class NameGrabber implements GrabberIF<TopicIF, NameIF> {

  @Override
  public NameIF grab(TopicIF topic) {
    if (topic == null)
      return null;
    
    List<TopicNameIF> basenames = new ArrayList<TopicNameIF>(topic.getTopicNames());
    if (basenames.isEmpty())
      return null;

    // If subject indicator of theme is set use this to setup scope
    if (themeIndicator != null) {
      // Get theme
      TopicMapIF tm = topic.getTopicMap();
      
      // Test if tm is null before getting theme. tm may be null if topic was
      // created (for internal purposes) in situations where no topic map was
      // available.
      if (tm != null) {
        TopicIF theme = tm.getTopicBySubjectIdentifier(themeIndicator);
        if (theme != null) {
          if (indicatorVariant)
            variantScope = Collections.singleton(theme);
          else
            scope = Collections.singleton(theme);
        }
      }
    }
    
    // sort the base names
    Collections.sort(basenames, new TopicNameComparator(scope));

    // TODO: Do we really have to create this grabber over and over again?
    VariantNameGrabber vngrabber = new VariantNameGrabber(variantScope);
    NameIF name = null;
    VariantNameIF vn = null;

    for (TopicNameIF current : basenames) {
      if (name == null)
        name = current;

      if (!variantScope.isEmpty()) {
        vn = vngrabber.grab(current);
        if (vn != null) {
          // TODO: Should not use intersection to find appropriate
          // variant, but rather exact matching, or perhaps ranking.
          
          // if there exists some overlap between variant name themes
          // and specified scope then we are delivering this variant
          Collection<TopicIF> interSection = new HashSet<TopicIF>(vn.getScope());
          interSection.retainAll(variantScope);
          if (!interSection.isEmpty())
            break;
          else
            vn = null;
        }
      }
    } // while

    // if valid variant name get base name which belongs to this
    if (vn != null) {
      if (grabOnlyTopicName)
        name = vn.getTopicName();
      else
        name = vn;
    }

    return name;
  }

  public  NameGrabber(LocatorIF themeIndicator);
  public  NameGrabber(LocatorIF themeIndicator, boolean variant);
  public  NameGrabber(Collection<TopicIF> scope);
  public  NameGrabber(Collection<TopicIF> basenameScope, Collection<TopicIF> variantScope);
  public  NameGrabber(Collection<TopicIF> basenameScope, Collection<TopicIF> variantScope,
                     boolean grabOnlyTopicName);

}