'What attribute and attribute values returns depends on what
the SP has said it wants in the request or in the metadata file and
what the IdP/AA wants to release. An assumption is that what the SP
asks for overrides whatever is in the metadata. But of course the
IdP never releases anything it doesn\'t want to.
:param ava: The information about the subject as a dictionary
:param sp_entity_id: The entity ID of the SP
:param mdstore: A Metadata store
:param required: Attributes that the SP requires in the assertion
:param optional: Attributes that the SP regards as optional
:return: A possibly modified AVA'

def filter(self, ava, sp_entity_id, mdstore, required=None, optional=None):

    _ava = None
    if (required or optional):
        logger.debug(('required:    %s,    optional:    %s' % (required, optional)))
        _ava = filter_on_attributes(ava.copy(), required, optional, self.acs, self.get_fail_on_missing_requested(sp_entity_id))
    _rest = self.get_entity_categories(sp_entity_id, mdstore)
    if _rest:
        ava_ec = filter_attribute_value_assertions(ava.copy(), _rest)
        if (_ava is None):
            _ava = ava_ec
        else:
            _ava.update(ava_ec)
    _rest = self.get_attribute_restrictions(sp_entity_id)
    if _rest:
        if (_ava is None):
            _ava = ava.copy()
        _ava = filter_attribute_value_assertions(_ava, _rest)
    elif (_ava is None):
        _ava = ava.copy()
    if (_ava is None):
        return {}
    else:
        return _ava
