@Override
    public Map<String, List<Object>> filter(final Map<String, List<Object>> givenAttributes) {
        val attributesToRelease = new HashMap<String, List<Object>>();
        givenAttributes.entrySet()
            .stream()
            .filter(entry -> {
                val attributeName = entry.getKey();
                val attributeValue = entry.getValue();
                LOGGER.debug("Received attribute [{}] with value [{}]", attributeName, attributeValue);
                return attributeValue != null;
            })
            .forEach(entry -> {
                val attributeName = entry.getKey();
                val attributeValue = entry.getValue();
                LOGGER.trace("Attribute value [{}] is a collection", attributeValue);
                val filteredAttributes = filterAttributes(attributeValue, attributeName);
                if (!filteredAttributes.isEmpty()) {
                    attributesToRelease.put(attributeName, filteredAttributes);
                }
            });
        LOGGER.debug("Received [{}] attributes. Filtered and released [{}]", givenAttributes.size(), attributesToRelease.size());
        return attributesToRelease;
    }
{@inheritDoc}
<p>
Given attribute values may be an extension of {@link Collection}, {@link Map} or an array.
<ul>
<li>The filtering operation is non-recursive. </li>
<li>Multi-valued attributes such as those of type {@link Collection} and
{@link Map} are expected to allow casting to {@code Map<String, String>}
or {@code Collection<String>}.
Values that are of type array are expected to allow casting to {@code String[]}.
</li>
<li>Multi-valued attributes are always put back into the final released collection of
attributes as {@code String[]}.</li>
<li>If the final filtered collection is empty, it will not be put into the collection of attributes.</li>
</ul>
core/cas-server-core-services-api/src/main/java/org/apereo/cas/services/support/RegisteredServiceRegexAttributeFilter.java