protected Expression computeNext() {
        start();
        while (!stack.isEmpty()) {
            this.current = (ExpressionIterator)stack.peek();
            try {
                if (!current.hasNext()) {
                    if (!backtrackingEnabled()) break;
                    stack.pop();
                    back();
                    continue;
                }
                
                Expression result = current.next();
                if (goalTest(result)) {
                    return gotFinal(result);
                }
                else {
                    ExpressionIterator next = successor(result);
                    this.stack.push(next);
                }
            }
            catch (FailException f) {
                // fail() has been called: ignore current "result"
            }
        }
        expired();
        return null;
    }