def _compose_mro(cls, types):  # noqa
    """Calculates the method resolution order for a given class *cls*.

    Includes relevant abstract base classes (with their respective bases) from
    the *types* iterable. Uses a modified C3 linearization algorithm.

    """
    bases = set(cls.__mro__)

    # Remove entries which are already present in the __mro__ or unrelated.
    def is_related(_type):
        return (  # :off
            _type not in bases and
            hasattr(_type, '__mro__') and
            issubclass(cls, _type)
        )  # :on

    types = [n for n in types if is_related(n)]

    # Remove entries which are strict bases of other entries (they will end up
    # in the MRO anyway.
    def is_strict_base(_typ):
        for other in types:
            if _typ != other and _typ in other.__mro__:
                return True
        return False

    types = [n for n in types if not is_strict_base(n)]
    # Subclasses of the ABCs in *types* which are also implemented by
    # *cls* can be used to stabilize ABC ordering.
    type_set = set(types)
    mro = []
    for typ in types:
        found = []
        for sub in typ.__subclasses__():
            if sub not in bases and issubclass(cls, sub):
                found.append([s for s in sub.__mro__ if s in type_set])
        if not found:
            mro.append(typ)
            continue
        # Favor subclasses with the biggest number of useful bases
        found.sort(key=len, reverse=True)
        for sub in found:
            for subcls in sub:
                if subcls not in mro:
                    mro.append(subcls)
    return _c3_mro(cls, abcs=mro)
Calculates the method resolution order for a given class *cls*.

    Includes relevant abstract base classes (with their respective bases) from
    the *types* iterable. Uses a modified C3 linearization algorithm.