final public Iterator <K> iterator() {
    final int height = heightFor(root) ;
    final Node nodeStack[] = new Node[height + 1] ;
    final Side sideStack[] = new Side[height + 1] ;
    if (root != null) {
      nodeStack[0] = root ;
      sideStack[0] = Side.L ;
    }
    return new Iterator <K> () {
      int level = root == null ? -1 : 0 ;
      Node current = getNext() ;
      
      Node getNext() {
        while (level >= 0) {
          final Node next = nodeStack[level] ;
          final Side nextSide = sideStack[level] ;
          if (nextSide == Side.L) {
            sideStack[level] = Side.R ;
            if (next.kidL != null) {
              level++ ;
              nodeStack[level] = next.kidL ;
              sideStack[level] = Side.L ;
            }
          }
          else if (nextSide == Side.R) {
            sideStack[level] = Side.NEITHER ;
            if (next.kidR != null) {
              level++ ;
              nodeStack[level] = next.kidR ;
              sideStack[level] = Side.L ;
            }
            return next ;
          }
          else if (nextSide == Side.NEITHER) {
            level-- ;
          }
        }
        return null ;
      }
      
      public boolean hasNext() {
        return current != null ;
      }
      
      public K next() {
        final K returned = (K) current.value ;
        current = getNext() ;
        return returned ;
      }
      
      public void remove() {}
    } ;
  }