private SGFLeaf readLeaf( StreamTokenizer st )
    throws IOException, SGFException
  {
    SGFLeaf leaf = null;
    SGFToken sgfToken;

    int token;

    // Keep reading in tokens until the end of the file, the start of a new
    // leaf, start of a new tree, or end of the current tree/game.  These
    // are a semi-colon, open parenthesis, and close parenthesis respectively.
    //
    while( ((token = st.nextToken()) != StreamTokenizer.TT_EOF) &&
            (token != (int)';') &&
            (token != (int)'(') &&
            (token != (int)')') )
    {
      if( token == StreamTokenizer.TT_WORD )
        if( (sgfToken = readToken( st )) != null )
        {
          // Since we found a token that belongs to the "information"
          // class, it gets a special place in habitat.
          //
          if( sgfToken instanceof InfoToken )
              myGameInfoTokens.add( sgfToken );
          else
          {
            if( leaf == null )
                leaf = new SGFLeaf( sgfToken );
            else
                leaf.addToken( sgfToken );
          }
        }
    }

    // We found something that couldn't be an SGFToken, so let the calling
    // method handle whatever we read.  (End of game/variation/leaf, etc.)
    //
    st.pushBack();
    return leaf;
  }