private static IEnumerable <Pair <IList <ITypeParameter>, ISubstitution> > EnumeratePossibleTStateCandidates(
            [NotNull] IList <ITypeParameter> typeParameters, [NotNull] IList <ITypeParameter> candidateTypeParameters)
        {
            var typeParametersCount = typeParameters.Count;

            var delta = candidateTypeParameters.Count - typeParametersCount;

            if (delta <= 0)
            {
                yield break;
            }

            ISubstitution headSubstitution = EmptySubstitution.INSTANCE;

            var candidateTypes = candidateTypeParameters.ToIList(TypeFactory.CreateType);

            var stateTypeParameters = new List <ITypeParameter>();
            var tailTypeParameters  = new List <ITypeParameter>();
            var tailTypeArguments   = new List <IType>();

            for (var headIndex = 0; headIndex <= typeParametersCount; headIndex++)
            {
                tailTypeParameters.Clear();
                tailTypeArguments.Clear();

                for (var tailIndex = headIndex; tailIndex < typeParametersCount; tailIndex++)
                {
                    tailTypeParameters.Add(typeParameters[tailIndex]);
                    tailTypeArguments.Add(candidateTypes[tailIndex + delta]);
                }

                stateTypeParameters.Clear();
                for (var stateIndex = 0; stateIndex < delta; stateIndex++)
                {
                    stateTypeParameters.Add(candidateTypeParameters[headIndex + stateIndex]);
                }

                yield return(Pair.Of <IList <ITypeParameter>, ISubstitution>(
                                 stateTypeParameters, headSubstitution.Extend(tailTypeParameters, tailTypeArguments)));

                if (headIndex == typeParametersCount)
                {
                    yield break;
                }

                headSubstitution = headSubstitution.Extend(typeParameters[headIndex], candidateTypes[headIndex]);
            }
        }