Find a manager matching the given protocol and endpoint.  If
        no matching manager currently exists, creates a new one.
        (Manager classes are looked up using the ``tendril.manager``
        entrypoint, and the name of the entrypoint corresponds to the
        ``proto``.  This method makes no guarantees about whether the
        manager is running; make sure to check the ``running``
        attribute and call the ``start()`` method if necessary.

        :param proto: The underlying network protocol, such as "tcp"
                      or "udp".
        :param endpoint: Identifies the endpoint of the
                         TendrilManager.  This will be the IP address
                         and port number, as a tuple, on which to
                         accept connections and from which to initiate
                         connections.  If not given, defaults to
                         ``('', 0)``.

        Note: TendrilManager instances can only support one of IPv4 or
        IPv6, and outgoing connection addresses must match how the
        TendrilManager was initialized.  To get a TendrilManager
        supporting outgoing IPv6 connections, use the endpoint
        ``('::', 0)``.

def get_manager(cls, proto, endpoint=None):
        """
        Find a manager matching the given protocol and endpoint.  If
        no matching manager currently exists, creates a new one.
        (Manager classes are looked up using the ``tendril.manager``
        entrypoint, and the name of the entrypoint corresponds to the
        ``proto``.  This method makes no guarantees about whether the
        manager is running; make sure to check the ``running``
        attribute and call the ``start()`` method if necessary.

        :param proto: The underlying network protocol, such as "tcp"
                      or "udp".
        :param endpoint: Identifies the endpoint of the
                         TendrilManager.  This will be the IP address
                         and port number, as a tuple, on which to
                         accept connections and from which to initiate
                         connections.  If not given, defaults to
                         ``('', 0)``.

        Note: TendrilManager instances can only support one of IPv4 or
        IPv6, and outgoing connection addresses must match how the
        TendrilManager was initialized.  To get a TendrilManager
        supporting outgoing IPv6 connections, use the endpoint
        ``('::', 0)``.
        """

        # First, normalize the proto and endpoint
        proto = proto.lower()
        endpoint = endpoint or ('', 0)

        # See if the manager already exists
        if (proto, endpoint) in cls._managers:
            return cls._managers[(proto, endpoint)]

        # OK, need to create a new one; use pkg_resources
        for ep in pkg_resources.iter_entry_points('tendril.manager', proto):
            try:
                manager_cls = ep.load()
                break
            except (ImportError, pkg_resources.UnknownExtra):
                continue
        else:
            raise ValueError("unknown protocol %r" % proto)

        return manager_cls(endpoint)