public Key next()
      {
        count++;
        Key keyToReturn = null;
        while (currentNode != null && !currentNode.isKey1Visited)
        {
          nodeStack.push(currentNode);
          currentNode = currentNode.left; //We continue going left to reach the smallest key
        }
        
        //Now we cannot go any further on the left, we found the smallest key which was the last pushed element
        currentNode = nodeStack.pop();
        
        if (!currentNode.isKey1Visited)
        {
          keyToReturn = currentNode.key1;
          if (currentNode.key2 != null)
          {
            currentNode.isKey1Visited = true;
            //push this node back, so that next time, we take its key2
            nodeStack.push(currentNode);
          }
          
          if (currentNode.middle != null)
          {
            currentNode = currentNode.middle;
          }
          else if (currentNode.right != null)
          {
            currentNode = currentNode.right;
          }
          //else: we don't have middle and right nodes (and we don't have left also because of the while loop), basically this is a leaf.
          //we don't need to push it back!
          else
          {
            currentNode = null; //This will pop the parent next time
          }
        }
        else
        {
          currentNode.isKey1Visited = false;
          keyToReturn = currentNode.key2;
          currentNode = currentNode.right;
        }
        
        return keyToReturn;
      }
    }
    
    public class Iterator implements Iterable<Key>
    {
      private Key lo;
      private Key hi;
      
      public Iterator()
      {
        lo = hi = null;
      }
      
      public Iterator(Key lo, Key hi)
      {
        this.lo = lo;
        this.hi = hi;
      }
      
      public java.util.Iterator<Key> iterator()
      {
        return new TwoThreeTreeIterator(lo, hi);
      }
    }
    
    
    public Iterable<Key> keys()
    {
      return new Iterator();
    }