common/src/main/java/org/beiter/michael/authn/jaas/common/propsbuilder/JaasBasedCommonPropsBuilder.java
@SuppressWarnings({"PMD.ExcessiveMethodLength", "PMD.NPathComplexity", "PMD.CyclomaticComplexity", "PMD.StdCyclomaticComplexity", "PMD.ModifiedCyclomaticComplexity"})
    // CHECKSTYLE:ON
    public static CommonProperties build(final Map<String, ?> properties) {

        Validate.notNull(properties, "The validated object 'properties' is null");

        final CommonProperties commonProps = new CommonProperties();
        String tmp = getOption(KEY_AUDIT_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setAuditClassName(tmp);
            logValue(KEY_AUDIT_CLASS_NAME, tmp);
        } else {
            commonProps.setAuditClassName(DEFAULT_AUDIT_CLASS_NAME);
            logDefault(KEY_AUDIT_CLASS_NAME, DEFAULT_AUDIT_CLASS_NAME);
        }

        tmp = getOption(KEY_AUDIT_IS_ENABLED, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setAuditEnabled(Boolean.parseBoolean(tmp));
            logValue(KEY_AUDIT_IS_ENABLED, tmp);
        } else {
            commonProps.setAuditEnabled(DEFAULT_AUDIT_IS_ENABLED);
            logDefault(KEY_AUDIT_IS_ENABLED, String.valueOf(DEFAULT_AUDIT_IS_ENABLED));
        }

        tmp = getOption(KEY_AUDIT_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setAuditSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_AUDIT_IS_SINGLETON, tmp);
        } else {
            commonProps.setAuditSingleton(DEFAULT_AUDIT_IS_SINGLETON);
            logDefault(KEY_AUDIT_IS_SINGLETON, String.valueOf(DEFAULT_AUDIT_IS_SINGLETON));
        }

        tmp = getOption(KEY_MESSAGEQ_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setMessageQueueClassName(tmp);
            logValue(KEY_MESSAGEQ_CLASS_NAME, tmp);
        } else {
            commonProps.setMessageQueueClassName(DEFAULT_MESSAGEQ_CLASS_NAME);
            logDefault(KEY_MESSAGEQ_CLASS_NAME, DEFAULT_MESSAGEQ_CLASS_NAME);
        }

        tmp = getOption(KEY_MESSAGEQ_IS_ENABLED, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setMessageQueueEnabled(Boolean.parseBoolean(tmp));
            logValue(KEY_MESSAGEQ_IS_ENABLED, tmp);
        } else {
            commonProps.setMessageQueueEnabled(DEFAULT_MESSAGEQ_IS_ENABLED);
            logDefault(KEY_MESSAGEQ_IS_ENABLED, String.valueOf(DEFAULT_MESSAGEQ_IS_ENABLED));
        }

        tmp = getOption(KEY_MESSAGEQ_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setMessageQueueSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_MESSAGEQ_IS_SINGLETON, tmp);
        } else {
            commonProps.setMessageQueueSingleton(DEFAULT_MESSAGEQ_IS_SINGLETON);
            logDefault(KEY_MESSAGEQ_IS_SINGLETON, String.valueOf(DEFAULT_MESSAGEQ_IS_SINGLETON));
        }

        tmp = getOption(KEY_PASSWORD_AUTHENTICATOR_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordAuthenticatorClassName(tmp);
            logValue(KEY_PASSWORD_AUTHENTICATOR_CLASS_NAME, tmp);
        } else {
            commonProps.setPasswordAuthenticatorClassName(DEFAULT_PASSWORD_AUTHENTICATOR_CLASS_NAME);
            logDefault(KEY_PASSWORD_AUTHENTICATOR_CLASS_NAME, DEFAULT_PASSWORD_AUTHENTICATOR_CLASS_NAME);
        }

        tmp = getOption(KEY_PASSWORD_AUTHENTICATOR_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordAuthenticatorSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_PASSWORD_AUTHENTICATOR_IS_SINGLETON, tmp);
        } else {
            commonProps.setPasswordAuthenticatorSingleton(DEFAULT_PASSWORD_AUTHENTICATOR_IS_SINGLETON);
            logDefault(KEY_PASSWORD_AUTHENTICATOR_IS_SINGLETON,
                    String.valueOf(DEFAULT_PASSWORD_AUTHENTICATOR_IS_SINGLETON));
        }

        tmp = getOption(KEY_PASSWORD_VALIDATOR_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordValidatorClassName(tmp);
            logValue(KEY_PASSWORD_VALIDATOR_CLASS_NAME, tmp);
        } else {
            commonProps.setPasswordValidatorClassName(DEFAULT_PASSWORD_VALIDATOR_CLASS_NAME);
            logDefault(KEY_PASSWORD_VALIDATOR_CLASS_NAME, DEFAULT_PASSWORD_VALIDATOR_CLASS_NAME);
        }

        tmp = getOption(KEY_PASSWORD_VALIDATOR_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordValidatorSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_PASSWORD_VALIDATOR_IS_SINGLETON, tmp);
        } else {
            commonProps.setPasswordValidatorSingleton(DEFAULT_PASSWORD_VALIDATOR_IS_SINGLETON);
            logDefault(KEY_PASSWORD_VALIDATOR_IS_SINGLETON, String.valueOf(DEFAULT_PASSWORD_VALIDATOR_IS_SINGLETON));
        }

        // set the additional properties, preserving the originally provided properties
        // create a defensive copy of the map and all its properties
        // the code looks a little more complicated than a simple "putAll()", but it catches situations
        // where a Map is provided that supports null values (e.g. a HashMap) vs Map implementations
        // that do not (e.g. ConcurrentHashMap).
        final Map<String, String> tempMap = new ConcurrentHashMap<>();
        try {
            for (final Map.Entry<String, ?> entry : properties.entrySet()) {
                final String key = entry.getKey();
                final String value = (String) entry.getValue();

                if (value != null) {
                    tempMap.put(key, value);
                }
            }
        } catch (ClassCastException e) {
            final String error = "The values of the configured JAAS properties must be Strings. "
                    + "Sorry, but we do not support anything else here!";
            throw new IllegalArgumentException(error, e);
        }
        commonProps.setAdditionalProperties(tempMap);

        return commonProps;
    }
@SuppressWarnings({"PMD.ExcessiveMethodLength", "PMD.NPathComplexity", "PMD.CyclomaticComplexity", "PMD.StdCyclomaticComplexity", "PMD.ModifiedCyclomaticComplexity"})
    // CHECKSTYLE:ON
    public static CommonProperties build(final Map<String, ?> properties) {

        Validate.notNull(properties, "The validated object 'properties' is null");

        final CommonProperties commonProps = new CommonProperties();
        String tmp = getOption(KEY_AUDIT_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setAuditClassName(tmp);
            logValue(KEY_AUDIT_CLASS_NAME, tmp);
        } else {
            commonProps.setAuditClassName(DEFAULT_AUDIT_CLASS_NAME);
            logDefault(KEY_AUDIT_CLASS_NAME, DEFAULT_AUDIT_CLASS_NAME);
        }

        tmp = getOption(KEY_AUDIT_IS_ENABLED, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setAuditEnabled(Boolean.parseBoolean(tmp));
            logValue(KEY_AUDIT_IS_ENABLED, tmp);
        } else {
            commonProps.setAuditEnabled(DEFAULT_AUDIT_IS_ENABLED);
            logDefault(KEY_AUDIT_IS_ENABLED, String.valueOf(DEFAULT_AUDIT_IS_ENABLED));
        }

        tmp = getOption(KEY_AUDIT_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setAuditSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_AUDIT_IS_SINGLETON, tmp);
        } else {
            commonProps.setAuditSingleton(DEFAULT_AUDIT_IS_SINGLETON);
            logDefault(KEY_AUDIT_IS_SINGLETON, String.valueOf(DEFAULT_AUDIT_IS_SINGLETON));
        }

        tmp = getOption(KEY_MESSAGEQ_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setMessageQueueClassName(tmp);
            logValue(KEY_MESSAGEQ_CLASS_NAME, tmp);
        } else {
            commonProps.setMessageQueueClassName(DEFAULT_MESSAGEQ_CLASS_NAME);
            logDefault(KEY_MESSAGEQ_CLASS_NAME, DEFAULT_MESSAGEQ_CLASS_NAME);
        }

        tmp = getOption(KEY_MESSAGEQ_IS_ENABLED, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setMessageQueueEnabled(Boolean.parseBoolean(tmp));
            logValue(KEY_MESSAGEQ_IS_ENABLED, tmp);
        } else {
            commonProps.setMessageQueueEnabled(DEFAULT_MESSAGEQ_IS_ENABLED);
            logDefault(KEY_MESSAGEQ_IS_ENABLED, String.valueOf(DEFAULT_MESSAGEQ_IS_ENABLED));
        }

        tmp = getOption(KEY_MESSAGEQ_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setMessageQueueSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_MESSAGEQ_IS_SINGLETON, tmp);
        } else {
            commonProps.setMessageQueueSingleton(DEFAULT_MESSAGEQ_IS_SINGLETON);
            logDefault(KEY_MESSAGEQ_IS_SINGLETON, String.valueOf(DEFAULT_MESSAGEQ_IS_SINGLETON));
        }

        tmp = getOption(KEY_PASSWORD_AUTHENTICATOR_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordAuthenticatorClassName(tmp);
            logValue(KEY_PASSWORD_AUTHENTICATOR_CLASS_NAME, tmp);
        } else {
            commonProps.setPasswordAuthenticatorClassName(DEFAULT_PASSWORD_AUTHENTICATOR_CLASS_NAME);
            logDefault(KEY_PASSWORD_AUTHENTICATOR_CLASS_NAME, DEFAULT_PASSWORD_AUTHENTICATOR_CLASS_NAME);
        }

        tmp = getOption(KEY_PASSWORD_AUTHENTICATOR_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordAuthenticatorSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_PASSWORD_AUTHENTICATOR_IS_SINGLETON, tmp);
        } else {
            commonProps.setPasswordAuthenticatorSingleton(DEFAULT_PASSWORD_AUTHENTICATOR_IS_SINGLETON);
            logDefault(KEY_PASSWORD_AUTHENTICATOR_IS_SINGLETON,
                    String.valueOf(DEFAULT_PASSWORD_AUTHENTICATOR_IS_SINGLETON));
        }

        tmp = getOption(KEY_PASSWORD_VALIDATOR_CLASS_NAME, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordValidatorClassName(tmp);
            logValue(KEY_PASSWORD_VALIDATOR_CLASS_NAME, tmp);
        } else {
            commonProps.setPasswordValidatorClassName(DEFAULT_PASSWORD_VALIDATOR_CLASS_NAME);
            logDefault(KEY_PASSWORD_VALIDATOR_CLASS_NAME, DEFAULT_PASSWORD_VALIDATOR_CLASS_NAME);
        }

        tmp = getOption(KEY_PASSWORD_VALIDATOR_IS_SINGLETON, properties);
        if (StringUtils.isNotEmpty(tmp)) {
            commonProps.setPasswordValidatorSingleton(Boolean.parseBoolean(tmp));
            logValue(KEY_PASSWORD_VALIDATOR_IS_SINGLETON, tmp);
        } else {
            commonProps.setPasswordValidatorSingleton(DEFAULT_PASSWORD_VALIDATOR_IS_SINGLETON);
            logDefault(KEY_PASSWORD_VALIDATOR_IS_SINGLETON, String.valueOf(DEFAULT_PASSWORD_VALIDATOR_IS_SINGLETON));
        }

        // set the additional properties, preserving the originally provided properties
        // create a defensive copy of the map and all its properties
        // the code looks a little more complicated than a simple "putAll()", but it catches situations
        // where a Map is provided that supports null values (e.g. a HashMap) vs Map implementations
        // that do not (e.g. ConcurrentHashMap).
        final Map<String, String> tempMap = new ConcurrentHashMap<>();
        try {
            for (final Map.Entry<String, ?> entry : properties.entrySet()) {
                final String key = entry.getKey();
                final String value = (String) entry.getValue();

                if (value != null) {
                    tempMap.put(key, value);
                }
            }
        } catch (ClassCastException e) {
            final String error = "The values of the configured JAAS properties must be Strings. "
                    + "Sorry, but we do not support anything else here!";
            throw new IllegalArgumentException(error, e);
        }
        commonProps.setAdditionalProperties(tempMap);

        return commonProps;
    }
suppress warnings about this method being too complex (can't extract a generic subroutine to reduce exec paths)