final protected function _validatePolicy() {
        //validate that required indices exist
        if (!isset($this->_userProfile['username'])
            || !isset($this->_userProfile['password'])
            || !isset($this->_userProfile['fullname'])
            || !isset($this->_userProfile['passhist'])
         ) {
            throw new UserCredentialException('The username and password are not set', 1016);
        }

        //determine which entropy to use (base or udf)
        $policyObj = $this->_udfPasswordPolicy;
        
        //check attempt limits
        if ($this->_userProfile['account_state'] == \USERCREDENTIAL_ACCOUNTSTATE_AUTHFAILED) {
            if ($this->_userProfile['policyinfo']['failed_attempt_count'] > $policyObj['illegal_attempts_limit']) {
                throw new UserCredentialException('The account has exceeded login attempts and is locked. Contact admin', \USERCREDENTIAL_ACCOUNTPOLICY_ATTEMPTLIMIT2);
            } elseif ($this->_userProfile['policyinfo']['failed_attempt_count'] == $policyObj['illegal_attempts_limit'])  {
                throw new UserCredentialException('The account has failed login '.(++$policyObj['illegal_attempts_limit']).' times in a row and is temporarily locked. Any further wrong passwords will lead to your account being locked fully. You will be automatically unlocked in '.(($policyObj['illegal_attempts_penalty_seconds']) / 60).' minutes or contact admin to unlock immediately', \USERCREDENTIAL_ACCOUNTPOLICY_ATTEMPTLIMIT1);
            } else {
                throw new UserCredentialException('Login failed. Wrong username or password', \USERCREDENTIAL_ACCOUNTPOLICY_VALID);
            }
        }
        
        //check needs reset
        $currDateTimeObj = new \DateTime();
        $passChangeDaysElapsedObj = $currDateTimeObj->diff($this->_userProfile['policyinfo']['password_last_changed_datetime']);
        $passChangeDaysElapsed = $passChangeDaysElapsedObj->format('%a');
        
        if ($passChangeDaysElapsed > $policyObj['password_reset_frequency']) {
            throw new UserCredentialException('The password has expired and must be changed', \USERCREDENTIAL_ACCOUNTPOLICY_EXPIRED);
        }
        
        return true;        
    }