protected int handleNext() {
    // if we're already at the end of the text, return DONE.
    CharacterIterator text = getText();
    if (text.getIndex() == text.getEndIndex()) {
      return BreakIterator.DONE;
    }

    // no matter what, we always advance at least one character forward
    int result = getNextIndex();
    int lookaheadResult = 0;

    // begin in state 1
    int state = START_STATE;
    int category;
    int c = getCurrent();

    // loop until we reach the end of the text or transition to state 0
    while (c != CharacterIterator.DONE && state != STOP_STATE) {

      // look up the current character's character category (which tells us
      // which column in the state table to look at)
      category = lookupCategory(c);

      // if the character isn't an ignore character, look up a state
      // transition in the state table
      if (category != IGNORE) {
        state = lookupState(state, category);
      }

      // if the state we've just transitioned to is a lookahead state,
      // (but not also an end state), save its position. If it's
      // both a lookahead state and an end state, update the break position
      // to the last saved lookup-state position
      if (lookaheadStates[state]) {
        if (endStates[state]) {
          result = lookaheadResult;
        }
        else {
          lookaheadResult = getNextIndex();
        }
      }

      // otherwise, if the state we've just transitioned to is an accepting
      // state, update the break position to be the current iteration position
      else {
        if (endStates[state]) {
          result = getNextIndex();
        }
      }

      c = getNext();
    }

    // if we've run off the end of the text, and the very last character took us into
    // a lookahead state, advance the break position to the lookahead position
    // (the theory here is that if there are no characters at all after the lookahead
    // position, that always matches the lookahead criteria)
    if (c == CharacterIterator.DONE && lookaheadResult == text.getEndIndex()) {
      result = lookaheadResult;
    }

    text.setIndex(result);
    return result;
  }