'Find a distribution and all distributions it depends on.
:param requirement: The requirement specifying the distribution to
find, or a Distribution instance.
:param meta_extras: A list of meta extras such as :test:, :build: and
so on.
:param prereleases: If ``True``, allow pre-release versions to be
returned - otherwise, don\'t return prereleases
unless they\'re all that\'s available.
Return a set of :class:`Distribution` instances and a set of
problems.
The distributions returned should be such that they have the
:attr:`required` attribute set to ``True`` if they were
from the ``requirement`` passed to ``find()``, and they have the
:attr:`build_time_dependency` attribute set to ``True`` unless they
are post-installation dependencies of the ``requirement``.
The problems should be a tuple consisting of the string
``\'unsatisfied\'`` and the requirement which couldn\'t be satisfied
by any distribution known to the locator.'

def find(self, requirement, meta_extras=None, prereleases=False):

    self.provided = {}
    self.dists = {}
    self.dists_by_name = {}
    self.reqts = {}
    meta_extras = set((meta_extras or []))
    if (':*:' in meta_extras):
        meta_extras.remove(':*:')
        meta_extras |= set([':test:', ':build:', ':dev:'])
    if isinstance(requirement, Distribution):
        dist = odist = requirement
        logger.debug('passed    %s    as    requirement', odist)
    else:
        dist = odist = self.locator.locate(requirement, prereleases=prereleases)
        if (dist is None):
            raise DistlibException(('Unable    to    locate    %r' % requirement))
        logger.debug('located    %s', odist)
    dist.requested = True
    problems = set()
    todo = set([dist])
    install_dists = set([odist])
    while todo:
        dist = todo.pop()
        name = dist.key
        if (name not in self.dists_by_name):
            self.add_distribution(dist)
        else:
            other = self.dists_by_name[name]
            if (other != dist):
                self.try_to_replace(dist, other, problems)
        ireqts = (dist.run_requires | dist.meta_requires)
        sreqts = dist.build_requires
        ereqts = set()
        if (dist in install_dists):
            for key in ('test', 'build', 'dev'):
                e = (':%s:' % key)
                if (e in meta_extras):
                    ereqts |= getattr(dist, ('%s_requires' % key))
        all_reqts = ((ireqts | sreqts) | ereqts)
        for r in all_reqts:
            providers = self.find_providers(r)
            if (not providers):
                logger.debug('No    providers    found    for    %r', r)
                provider = self.locator.locate(r, prereleases=prereleases)
                if ((provider is None) and (not prereleases)):
                    provider = self.locator.locate(r, prereleases=True)
                if (provider is None):
                    logger.debug('Cannot    satisfy    %r', r)
                    problems.add(('unsatisfied', r))
                else:
                    (n, v) = (provider.key, provider.version)
                    if ((n, v) not in self.dists):
                        todo.add(provider)
                    providers.add(provider)
                    if ((r in ireqts) and (dist in install_dists)):
                        install_dists.add(provider)
                        logger.debug('Adding    %s    to    install_dists', provider.name_and_version)
            for p in providers:
                name = p.key
                if (name not in self.dists_by_name):
                    self.reqts.setdefault(p, set()).add(r)
                else:
                    other = self.dists_by_name[name]
                    if (other != p):
                        self.try_to_replace(p, other, problems)
    dists = set(self.dists.values())
    for dist in dists:
        dist.build_time_dependency = (dist not in install_dists)
        if dist.build_time_dependency:
            logger.debug('%s    is    a    build-time    dependency    only.', dist.name_and_version)
    logger.debug('find    done    for    %s', odist)
    return (dists, problems)
