GrantEntry readGrantEntry( StreamTokenizer st )
        throws IOException,
               InvalidFormatException
    {
        String signer = null, codebase = null;
        Collection<PrincipalEntry> principals = new ArrayList<PrincipalEntry>();
        Collection<PermissionEntry> permissions = null;

        parsing:
        while( true )
        {
            switch( st.nextToken() )
            {

            case StreamTokenizer.TT_WORD:
                if(  "signedby".equalsIgnoreCase( st.sval ) )
                {
                    if( st.nextToken() == '"' )
                    {
                        signer = st.sval;
                    }
                    else
                    {
                        handleUnexpectedToken( st, "Expected syntax is : signedby \"name1,...,nameN\"" );
                    }
                }
                else if( "codebase".equalsIgnoreCase(  st.sval ) )
                {
                    if( st.nextToken() == '"' )
                    {
                        codebase = st.sval;
                    }
                    else
                    {
                        handleUnexpectedToken( st, "Expected syntax is : codebase \"url\"" );
                    }
                }
                else if( "principal".equalsIgnoreCase(  st.sval ) )
                {
                    principals.add( readPrincipalEntry( st ) );
                }
                else
                {
                    handleUnexpectedToken( st );
                }
                break;

            case ',': //just delimiter of entries
                break;

            case '{':
                permissions = readPermissionEntries( st );
                break parsing;

            default: // handle token in the main loop
                st.pushBack();
                break parsing;
            }
        }

        return new GrantEntry( signer, codebase, principals, permissions );
    }