internal static Type SubstituteIfNecessary(this Type type, IServiceProvider serviceProvider, IEnumerable <Assembly> assemblies, ModelTypeBuilder modelTypeBuilder)
        {
            Contract.Requires(serviceProvider != null);
            Contract.Requires(assemblies != null);
            Contract.Requires(modelTypeBuilder != null);
            Contract.Ensures(Contract.Result <Type>() != null);

            var result = type.CanBeSubstituted();

            if (!result.IsSupported)
            {
                return(type);
            }

            var innerType      = result.InnerType;
            var model          = serviceProvider.GetRequiredService <IEdmModel>();
            var structuredType = innerType.GetStructuredType(model, assemblies);

            if (structuredType == null)
            {
                return(type);
            }

            if (structuredType.IsEquivalentTo(innerType))
            {
                return(type.IsDelta() ? innerType : type);
            }

            var apiVersion = model.GetAnnotationValue <ApiVersionAnnotation>(model).ApiVersion;

            innerType = modelTypeBuilder.NewStructuredType(structuredType, innerType, apiVersion);

            if (!type.IsDelta())
            {
                foreach (var openType in result.OpenTypes)
                {
                    innerType = openType.MakeGenericType(innerType);
                }
            }

            return(innerType);
        }
 internal static Type SubstituteIfNecessary(this Type type, IServiceProvider serviceProvider, IAssembliesResolver assembliesResolver, ModelTypeBuilder modelTypeBuilder) =>
 type.SubstituteIfNecessary(serviceProvider, assembliesResolver.GetAssemblies(), modelTypeBuilder);