protected static Map<String, List<Object>> convertPrincipalAttributesToPersonAttributes(final Map<String, ?> attributes) {
        val convertedAttributes = new TreeMap<String, List<Object>>(String.CASE_INSENSITIVE_ORDER);
        val principalAttributes = new LinkedHashMap<>(attributes);
        LOGGER.trace("Principal attributes to convert to person attributes are [{}]", principalAttributes);
        principalAttributes.forEach((key, values) -> {
            if (values instanceof final Collection collection) {
                val uniqueValues = new LinkedHashSet<Object>(collection);
                val listedValues = new ArrayList<Object>(uniqueValues);
                convertedAttributes.put(key, listedValues);
            } else {
                convertedAttributes.put(key, CollectionUtils.wrap(values));
            }
        });
        LOGGER.trace("Converted principal attributes, now as person attributes are [{}]", convertedAttributes);
        return convertedAttributes;
    }
The merging strategy that deals with existing principal attributes
and those that are retrieved from the source. By default, existing attributes
are ignored and the source is always consulted.
core/cas-server-core-authentication-attributes/src/main/java/org/apereo/cas/authentication/principal/cache/AbstractPrincipalAttributesRepository.java