/// <summary>
        /// Combines independent resolutions in a disjointed dictionary, resulting in a
        /// resolution dictionary that has type parameter keys that are not referenced
        /// in its values. Null mappings are removed in the resulting dictionary.
        /// Returns the resulting dictionary.
        /// </summary>
        private TypeParameterResolutions CombineTypeResolutionDictionary(TypeParameterResolutions independentResolutions)
        {
            var combinedBuilder = ImmutableDictionary.CreateBuilder <TypeParameterName, ResolvedType>();

            foreach (var(typeParam, paramRes) in independentResolutions)
            {
                // Skip any null mappings
                if (paramRes is null)
                {
                    continue;
                }

                // Contains a lookup of all the keys in the combined resolutions whose value needs to be updated
                // if a certain type parameter is resolved by the currently processed dictionary.
                var mayBeReplaced = GetReplaceable(combinedBuilder);

                // Check that we are not constricting a type parameter to another type parameter of the same callable
                // both before and after updating the current value with the resolutions processed so far.
                this.UpdateConstrictionFlag(typeParam, paramRes);
                var resolvedParamRes = ResolvedType.ResolveTypeParameters(combinedBuilder.ToImmutable(), paramRes);
                this.UpdateConstrictionFlag(typeParam, resolvedParamRes);

                // Do any replacements for type parameters that may be replaced with the current resolution.
                this.UpdatedReplaceableResolutions(mayBeReplaced, combinedBuilder, typeParam, resolvedParamRes);

                // Add the resolution to the current dictionary.
                combinedBuilder[typeParam] = resolvedParamRes;
            }

            return(combinedBuilder.ToImmutable());
        }
        /// <summary>
        /// Uses the given lookup, mayBeReplaced, to determine what records in the combinedBuilder can be updated
        /// from the given type parameter, typeParam, and its resolution, paramRes. Then updates the combinedBuilder
        /// appropriately.
        /// </summary>
        private void UpdatedReplaceableResolutions(
            ILookup <TypeParameterName, TypeParameterName> mayBeReplaced,
            TypeParameterResolutions.Builder combinedBuilder,
            TypeParameterName typeParam,
            ResolvedType paramRes)
        {
            // Create a dictionary with just the current resolution in it.
            var singleResolution = new[] { 0 }.ToImmutableDictionary(_ => typeParam, _ => paramRes);

            // Get all the parameters whose value is dependent on the current resolution's type parameter,
            // and update their values with this resolution's value.
            foreach (var keyInCombined in mayBeReplaced[typeParam])
            {
                // Check that we are not constricting a type parameter to another type parameter of the same callable.
                this.UpdateConstrictionFlag(keyInCombined, paramRes);
                combinedBuilder[keyInCombined] = ResolvedType.ResolveTypeParameters(singleResolution, combinedBuilder[keyInCombined]);
            }
        }