class PrincipalToken extends Token {

    public boolean validateForAuthorizedService(String pubKey, StringBuilder errMsg) {
        errMsg = errMsg == null ? new StringBuilder(512) : errMsg;
        if (authorizedServiceSignature == null) {
            errMsg.append("PrincipalToken:validateForAuthorizedService: token=").
                   append(unsignedToken).
                   append(" : missing data/signature component: public key=").
                   append(pubKey);
            LOG.error(errMsg.toString());
            return false;
        }
        
        int idx = signedToken.indexOf(";bs=");
        if (idx == -1) {
            errMsg.append("PrincipalToken:validateForAuthorizedService: token=").
                   append(unsignedToken).append(" : not signed by any authorized service");
            LOG.error(errMsg.toString());
            return false;
        }
        
        String unsignedAuthorizedServiceToken = signedToken.substring(0, idx);
        
        if (pubKey == null) {
            errMsg.append("PrincipalToken:validateForAuthorizedService: token=").
                   append(unsignedToken).append(" : No public key provided");
            LOG.error(errMsg.toString());
            return false;
        }
        
        PublicKey pub;
        boolean verified = false; // fail safe
        try {
            pub = Crypto.loadPublicKey(pubKey);
            verified = Crypto.verify(unsignedAuthorizedServiceToken, pub, authorizedServiceSignature);
            ///CLOVER:OFF
            if (!verified) {
                errMsg.append("PrincipalToken:validateForAuthorizedService: token=").
                       append(unsignedToken).append(" : authentication failed: public key=").
                       append(pubKey);
                LOG.error(errMsg.toString());
            } else if (LOG.isDebugEnabled()) {
                LOG.debug("validateForAuthorizedService: Token: " + unsignedToken +
                        " -  successfully authenticated");
            }
            ///CLOVER:ON
        } catch (Exception e) {
            errMsg.append("PrincipalToken:validateForAuthorizedService: token=").
                   append(unsignedToken).
                   append(" : authentication failed verifying signature: exc=").
                   append(e.getMessage()).append(" : public key=").append(pubKey);
            LOG.error(errMsg.toString());
        }

        return verified;
    }

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

}