def find_loaders(scheme, protocols=None):
    matching_groups = ['plaster.loader_factory']
    if protocols:
        matching_groups += [
            'plaster.{0}_loader_factory'.format(proto)
            for proto in protocols
        ]
    scheme = scheme.lower()
    parts = scheme.split('+', 1)
    if len(parts) == 2:
        try:
            distro = pkg_resources.get_distribution(parts[0])
        except pkg_resources.DistributionNotFound:
            pass
        else:
            ep = _find_ep_in_dist(distro, parts[1], matching_groups)
            if ep:
                return [EntryPointLoaderInfo(ep, protocols)]
    possible_entry_points = [
        ep
        for ep in pkg_resources.iter_entry_points('plaster.loader_factory')
        if scheme is None or scheme == ep.name.lower()
    ]
    distros = {ep.dist for ep in possible_entry_points}
    matched_entry_points = list(filter(None, [
        _find_ep_in_dist(distro, scheme, matching_groups)
        for distro in distros
    ]))
    return [
        EntryPointLoaderInfo(ep, protocols=protocols)
        for ep in matched_entry_points
    ]