code: @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;
      }
docs: {@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&lt;String, String&gt;}
  or {@code Collection&lt;String&gt;}.
  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>