class ComplexTypeSAML2AttributeConverter implements AttributeConverter {

    /** {@inheritDoc} */
    @Override
    public Object convert(final Object a) {
        val attribute = (Attribute) a;

        List<SAML2AuthenticationCredentials.SAMLAttribute> extractedAttributes = new ArrayList<>();

        // collect all complex values
        attribute.getAttributeValues().stream()
            .filter(XMLObject::hasChildren)
            .forEach(attributeValue -> {
                val attrs = collectAttributesFromNodeList(attributeValue.getDOM().getChildNodes());
                extractedAttributes.addAll(attrs);
            });
        // collect all simple values
        SAML2AuthenticationCredentials.SAMLAttribute simpleValues = from(attribute);
        if (!simpleValues.getAttributeValues().isEmpty()) {
            extractedAttributes.add(simpleValues);
        }

        return extractedAttributes;
    }

    private SAML2AuthenticationCredentials.SAMLAttribute from(Attribute attribute) {<FILL_FUNCTION_BODY>}

    private List<SAML2AuthenticationCredentials.SAMLAttribute> collectAttributesFromNodeList(NodeList nodeList)  {

        List<SAML2AuthenticationCredentials.SAMLAttribute> results = new ArrayList<>();

        if (nodeList == null) {
            return results;
        }

        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);

            if (node.hasChildNodes()) {
                results.addAll(collectAttributesFromNodeList(node.getChildNodes()));
            } else if (!node.getTextContent().isBlank()) {
                SAML2AuthenticationCredentials.SAMLAttribute samlAttribute = new SAML2AuthenticationCredentials.SAMLAttribute();
                samlAttribute.setName(node.getParentNode().getLocalName());
                samlAttribute.getAttributeValues().add(node.getTextContent());
                results.add(samlAttribute);
            }
        }

        return results;
    }
}

        val samlAttribute = new SAML2AuthenticationCredentials.SAMLAttribute();
        samlAttribute.setFriendlyName(attribute.getFriendlyName());
        samlAttribute.setName(attribute.getName());
        samlAttribute.setNameFormat(attribute.getNameFormat());
        List<String> values = attribute.getAttributeValues()
            .stream()
            .filter(val -> !val.hasChildren())
            .map(XMLObject::getDOM)
            .filter(dom -> dom != null && dom.getTextContent() != null)
            .map(Element::getTextContent)
            .collect(Collectors.toList());
        samlAttribute.setAttributeValues(values);
        return samlAttribute;
    
<no_super_class>