':param attributes_a:    A dict of functions to their attributes
:param attributes_b:    A dict of functions to their attributes
The following parameters are optional.
:param filter_set_a:    A set to limit attributes_a to the functions in this set.
:param filter_set_b:    A set to limit attributes_b to the functions in this set.
:returns:               A list of tuples of matching objects.'

@staticmethod
def _get_function_matches(attributes_a, attributes_b, filter_set_a=None, filter_set_b=None):

    if (filter_set_a is None):
        filtered_attributes_a = {k: v for (k, v) in attributes_a.items()}
    else:
        filtered_attributes_a = {k: v for (k, v) in attributes_a.items() if (k in filter_set_a)}
    if (filter_set_b is None):
        filtered_attributes_b = {k: v for (k, v) in attributes_b.items()}
    else:
        filtered_attributes_b = {k: v for (k, v) in attributes_b.items() if (k in filter_set_b)}
    closest_a = _get_closest_matches(filtered_attributes_a, filtered_attributes_b)
    closest_b = _get_closest_matches(filtered_attributes_b, filtered_attributes_a)
    matches = []
    for a in closest_a:
        if (len(closest_a[a]) == 1):
            match = closest_a[a][0]
            if ((len(closest_b[match]) == 1) and (closest_b[match][0] == a)):
                matches.append((a, match))
    return matches
