'Finds compilers in the paths supplied.
Looks for all combinations of ``compiler_names`` with the
``prefixes`` and ``suffixes`` defined for this compiler
class.  If any compilers match the compiler_names,
prefixes, or suffixes, uses ``detect_version`` to figure
out what version the compiler is.
This returns a dict with compilers grouped by (prefix,
suffix, version) tuples.  This can be further organized by
find().'

@classmethod
def _find_matches_in_path(cls, compiler_names, detect_version, *path):

    if (not path):
        path = get_path('PATH')
    prefixes = ([''] + cls.prefixes)
    suffixes = ([''] + cls.suffixes)
    checks = []
    for directory in path:
        if (not (os.path.isdir(directory) and os.access(directory, (os.R_OK | os.X_OK)))):
            continue
        files = os.listdir(directory)
        for exe in files:
            full_path = join_path(directory, exe)
            prod = itertools.product(prefixes, compiler_names, suffixes)
            for (pre, name, suf) in prod:
                regex = ('^(%s)%s(%s)$' % (pre, re.escape(name), suf))
                match = re.match(regex, exe)
                if match:
                    key = ((full_path,) + match.groups())
                    checks.append(key)
    def check(key):
        try:
            (full_path, prefix, suffix) = key
            version = detect_version(full_path)
            return (version, prefix, suffix, full_path)
        except ProcessError as e:
            tty.debug(("Couldn't    get    version    for    compiler    %s" % full_path), e)
            return None
        except Exception as e:
            tty.debug(('Error    while    executing    candidate    compiler    %s' % full_path), ('%s:    %s' % (e.__class__.__name__, e)))
            return None
    successful = [k for k in parmap(check, checks) if (k is not None)]
    successful.reverse()
    return dict((((v, p, s), path) for (v, p, s, path) in successful))
