Generates and memoizes a :class:`~bang.providers.provider.Provider` object
    for the given name.

    :param str name:  The provider name, as given in the config stanza.  This
        token is used to find the
        appropriate :class:`~bang.providers.provider.Provider`.

    :param dict creds:  The credentials dictionary that is appropriate for the
        desired provider.  Typically, a sub-dict from the main stack config.

    :rtype:  :class:`~bang.providers.provider.Provider`

def get_provider(name, creds):
    """
    Generates and memoizes a :class:`~bang.providers.provider.Provider` object
    for the given name.

    :param str name:  The provider name, as given in the config stanza.  This
        token is used to find the
        appropriate :class:`~bang.providers.provider.Provider`.

    :param dict creds:  The credentials dictionary that is appropriate for the
        desired provider.  Typically, a sub-dict from the main stack config.

    :rtype:  :class:`~bang.providers.provider.Provider`

    """
    p = _PROVIDERS.get(name)
    if not p:
        provider = PROVIDER_MAP.get(name)
        if not provider:
            if name == 'hpcloud':
                print "## Warning - 'hpcloud' is not currently supported as" \
                    "a provider; use hpcloud_v12 or hpcloud_v13. See " \
                    "release notes."
            raise Exception("No provider matches %s; check imports" % name)
        p = provider(creds)
        _PROVIDERS[name] = p
    return p