Collect the nearest type variables and effective parameters from the type,
        its bases, and their origins as necessary.

def derive_configuration(cls):
        """
        Collect the nearest type variables and effective parameters from the type,
        its bases, and their origins as necessary.
        """
        base_params = cls.base.__parameters__
        if hasattr(cls.type, '__args__'):
            # typing as of commit abefbe4
            tvars = {p: p for p in base_params}
            types = {}
            for t in iter_generic_bases(cls.type):
                if t is cls.base:
                    type_vars = tuple(tvars[p] for p in base_params)
                    parameters = (types.get(tvar, tvar) for tvar in type_vars)
                    break
                if t.__args__:
                    for arg, tvar in zip(t.__args__, t.__origin__.__parameters__):
                        if isinstance(arg, typing.TypeVar):
                            tvars[tvar] = tvars.get(arg, arg)
                        else:
                            types[tvar] = arg
        else:
            # typing 3.5.0
            tvars = [None] * len(base_params)
            for t in iter_generic_bases(cls.type):
                for i, p in enumerate(t.__parameters__):
                    if tvars[i] is None and isinstance(p, typing.TypeVar):
                        tvars[i] = p
                if all(tvars):
                    type_vars = tvars
                    parameters = cls.type.__parameters__
                    break
        cls.type_vars = type_vars
        cls.parameters = tuple(normalize_type(p, 1) for p in parameters)