<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def recipients(preferences, message, valid_paths, config):
 """ The main API function. Accepts a fedmsg message as an argument. Returns a dict mapping context names to lists of recipients. """


    rule_cache = dict()
    results = defaultdict(list)
    notified = set()

    for preference in preferences:
        user = preference['user']
        context = preference['context']
        if (user['openid'], context['name']) in notified:
            continue

        for filter in preference['filters']:
            if matches(filter, message, valid_paths, rule_cache, config):
                for detail_value in preference['detail_values']:
                    results[context['name']].append({
                        'user': user['openid'],
                        context['detail_name']: detail_value,
                        'filter_name': filter['name'],
                        'filter_id': filter['id'],
                        'filter_oneshot': filter['oneshot'],
                        'markup_messages': preference['markup_messages'],
                        'triggered_by_links': preference['triggered_by_links'],
                        'shorten_links': preference['shorten_links'],
                        'verbose': preference['verbose'],
                    })
                notified.add((user['openid'], context['name']))
                break

    return results