/// <summary>
        /// Creates an <see cref="IWebHostBuilder"/> as if the environment variables are set as per <paramref name="environment"/>.
        /// The actual system environment variables are ignored. Command line arguments are not supported, as (by design) everything
        /// that can be specified on the command line can also be specified via environment variables.
        /// This method is primarily used for writing integration tests where a high degree of control is required,
        /// for example to simulate the difference between running in a container or not.
        /// </summary>
        /// <param name="environment">The fake environment variables to use when constructing the host builder.</param>
        /// <param name="functionAssembly">The assembly containing the target function. May be null, in which case the calling assembly
        /// is used.</param>
        /// <returns>A host builder that can be used for integration testing.</returns>
        public static IHostBuilder CreateHostBuilder(IReadOnlyDictionary <string, string> environment, Assembly?functionAssembly = null)
        {
            var variables           = ConfigurationVariableProvider.FromDictionary(environment);
            var functionEnvironment = FunctionEnvironment.Create(functionAssembly ?? Assembly.GetCallingAssembly(), new string[0], variables);

            return(functionEnvironment.CreateHostBuilder());
        }
        /// <summary>
        /// Starts a web server to serve the function in the specified assembly. This method is called
        /// automatically be the generated entry point.
        /// </summary>
        /// <param name="functionAssembly">The assembly containing the function to execute.</param>
        /// <param name="args">Arguments to parse </param>
        /// <returns>A task representing the asynchronous operation.
        /// The result of the task is an exit code for the process, which is 0 for success or non-zero
        /// for any failures.
        /// </returns>
        public static async Task <int> StartAsync(Assembly functionAssembly, string[] args)
        {
            // Clear out the ASPNETCORE_URLS environment variable in order to avoid a warning when we start the server.
            // An alternative would be to *use* the environment variable, but as it's populated (with a non-ideal value) by
            // default, I suspect that would be tricky.
            Environment.SetEnvironmentVariable("ASPNETCORE_URLS", null);

            // TODO: Catch exceptions and return 1, or just let the exception propagate? It probably
            // doesn't matter much. Potentially catch exceptions during configuration, but let any
            // during web server execution propagate.
            var environment = FunctionEnvironment.Create(functionAssembly, args, ConfigurationVariableProvider.System);
            await environment.CreateHostBuilder().Build().RunAsync();

            return(0);
        }