public boolean next() {
    if (!m_started) {
      // At the start of the iteration process it is necessary
      // to push all nodes up to the first node to process
      // onto the stack.

      pushLongestPathFrom(m_root);

      m_started = true;
    } else {
      if (m_traversalStack.empty()) {
        // If the user hits next when the stack is already empty (as indicated
        // by the return value of the previous call to next) he gets a runtime
        // exception that tells him that he used the iterator improperly.

        throw new RuntimeException("Internal Error: Traversal already finished");
      }

      // The top of the stack always contains the last processed node.
      // To find out what to do next, we pop the last processed node off the
      // stack and examine it.

      final Pair<IOperandTreeNode, Integer> lastProcessed = m_traversalStack.pop();

      // The node that was last processed.
      final IOperandTreeNode lastProcessedNode = lastProcessed.first();

      // The number of children of the last processed node that were
      // already processed.
      final int lastProcessedChildrenProcessed = lastProcessed.second();

      if (lastProcessedChildrenProcessed < lastProcessedNode.getChildren().size()) {
        // If we're here, there are more children to process. Now we have
        // to distinguish between nodes with two or more children and nodes
        // with just one child. Those nodes with two or more children are
        // infix operators, meaning that we have to process them after
        // each but the last of their children. Nodes with just one child
        // are prefix operators and were already handled when moving down
        // through the tree.

        if (lastProcessed.first().getChildren().size() > 1) {
          // We're dealing with an infix operator. The infix operator
          // must be revisited after each of its children is processed.
          // That's why it needs to go back onto the stack.

          m_traversalStack.add(lastProcessed);
        }

        pushLongestPathFrom(lastProcessedNode.getChildren().get(lastProcessedChildrenProcessed));

        return true;
      } else {
        if (m_traversalStack.empty()) {
          // That's it. The stack is empty and all children of the last
          // processed node were processed previously. We're done.

          return false;
        } else {
          // If the stack is not empty we need to pop all completely
          // processed nodes off the stack. Those are the nodes whose
          // children were all completely processed before.

          do {
            final Pair<IOperandTreeNode, Integer> parent = m_traversalStack.pop();

            if (parent.second() < (parent.first().getChildren().size() - 1)) {
              // We found a node that still needs processing. Increase
              // its number of processed children and push it back onto
              // the stack.
              m_traversalStack.push(
                  new Pair<IOperandTreeNode, Integer>(parent.first(), parent.second() + 1));

              return true;
            }
          } while (!m_traversalStack.empty());
        }
      }
    }

    return !m_traversalStack.empty();
  }
Moves the iterator to the next node in the proper iteration order.

@return False, if the iteration process is finished. True, otherwise.
java/zylib/src/main/java/com/google/security/zynamics/zylib/disassembly/OperandOrderIterator.java