/**
   * Searches for an item that matches the given pattern. The AbstractAutoCompleteAdaptor is used to
   * access the candidate items. The match is case-sensitive and will only match at the beginning of
   * each item's string representation.
   *
   * @param pattern the pattern that should be matched
   * @return the first item that matches the pattern or <code>null</code> if no item matches
   */
  private LookupResult lookupItem(String pattern) {
    Object selectedItem = adaptor.getSelectedItem();

    String[] possibleStrings;

    // iterate over all items to find an exact match
    for (int i = 0, n = adaptor.getItemCount(); i < n; i++) {
      Object currentItem = adaptor.getItem(i);
      possibleStrings = stringConverter.getPossibleStringsForItem(currentItem);
      if (possibleStrings != null) {
        // current item exactly matches the pattern?
        for (int j = 0; j < possibleStrings.length; j++) {
          if (possibleStrings[j].equals(pattern)) {
            return new LookupResult(currentItem, possibleStrings[j]);
          }
        }
      }
    }
    // check if the currently selected item matches
    possibleStrings = stringConverter.getPossibleStringsForItem(selectedItem);
    if (possibleStrings != null) {
      for (int i = 0; i < possibleStrings.length; i++) {
        if (startsWith(possibleStrings[i], pattern)) {
          return new LookupResult(selectedItem, possibleStrings[i]);
        }
      }
    }
    // search for any matching item, if the currently selected does not match
    for (int i = 0, n = adaptor.getItemCount(); i < n; i++) {
      Object currentItem = adaptor.getItem(i);
      possibleStrings = stringConverter.getPossibleStringsForItem(currentItem);
      if (possibleStrings != null) {
        for (int j = 0; j < possibleStrings.length; j++) {
          if (startsWith(possibleStrings[j], pattern)) {
            return new LookupResult(currentItem, possibleStrings[j]);
          }
        }
      }
    }
    // no item starts with the pattern => return null
    return new LookupResult(null, "");
  }
 /**
  * Creates a new AutoCompleteDocument for the given AbstractAutoCompleteAdaptor.
  *
  * @param adaptor The adaptor that will be used to find and select matching items.
  * @param strictMatching true, if only items from the adaptor's list should be allowed to be
  *     entered
  * @param stringConverter the converter used to transform items to strings
  */
 public AutoCompleteDocument(
     AbstractAutoCompleteAdaptor adaptor,
     boolean strictMatching,
     ObjectToStringConverter stringConverter) {
   this.adaptor = adaptor;
   this.strictMatching = strictMatching;
   this.stringConverter = stringConverter;
   // Handle initially selected object
   Object selected = adaptor.getSelectedItem();
   if (selected != null) setText(stringConverter.getPreferredStringForItem(selected));
   adaptor.markEntireText();
 }