class PrincipalToken extends Token {

    public boolean isValidAuthorizedServiceToken(StringBuilder errMsg) {
        
        /* we start our by checking if this is an authorized service token */
        errMsg = errMsg == null ? new StringBuilder(512) : errMsg;
        if (authorizedServices == null) {
            
            /* if both the service name list and signature are not present
             * then we have a standard principal token */
            
            if (authorizedServiceSignature == null) {
                return true;
            }
            
            /* otherwise we have an invalid token without the signature */
            errMsg.append("PrincipalToken:isValidAuthorizedServiceToken: Invalid Token=").
                   append(unsignedToken).
                   append(" : Authorized Service Signature available without service name"); 
            LOG.error(errMsg.toString());
            return false;
        }
        
        /* if we have an authorized service name then we must have a corresponding
         * signature available in the token */
        
        if (authorizedServiceSignature == null) {
            errMsg.append("PrincipalToken:isValidAuthorizedServiceToken: Invalid Token=").
                   append(unsignedToken).
                   append(" : Missing signature for specified authorized service"); 
            LOG.error(errMsg.toString());
            return false;
        }
        
        /* if we have a specific authorized service name specified then
         * it must be present in our service list otherwise we must
         * have a single entry in our list */
        
        if (authorizedServiceName != null) {
            if (!authorizedServices.contains(authorizedServiceName)) {
                errMsg.append("PrincipalToken:isValidAuthorizedServiceToken: Invalid Token=").
                       append(unsignedToken).
                       append(" : Authorized service name=").append(authorizedServiceName).
                       append(" is not listed in the service list"); 
                LOG.error(errMsg.toString());
                return false;
            }
        } else if (authorizedServices.size() != 1) {
            errMsg.append("PrincipalToken:isValidAuthorizedServiceToken: Invalid Token=").
                   append(unsignedToken).
                   append(" : No service name and Authorized service list contains multiple entries"); 
            LOG.error(errMsg.toString());
            return false;
        }
        
        return true;
    }

    private  PrincipalToken(Builder builder);
    public  PrincipalToken(String signedToken);

}