// This method adds automatic endpoints at the base addresses, 1 per site binding (http or https). It only configures
        // the security on the binding. It does not add any behaviors.
        // If there are no base addresses, or if endpoints have been configured explicitly, it does not add any
        // automatic endpoints.
        // If it adds automatic endpoints, it validates that the service implements a single contract
        internal static void AddAutomaticWebHttpBindingEndpoints(ServiceHost host, IDictionary<string, ContractDescription> implementedContracts,  string multipleContractsErrorMessage, string noContractErrorMessage, string standardEndpointKind)
        {
            bool enableAutoEndpointCompat = AppSettings.EnableAutomaticEndpointsCompatibility;
            // We do not add an automatic endpoint if an explicit endpoint has been configured unless
            // the user has specifically opted into compat mode.  See CSDMain bugs 176157 & 262728 for history
            if (host.Description.Endpoints != null 
                && host.Description.Endpoints.Count > 0
                && !enableAutoEndpointCompat)
            {
                return;
            }

            AuthenticationSchemes supportedSchemes = AuthenticationSchemes.None;
            if (host.BaseAddresses.Count > 0)
            {
                supportedSchemes = AspNetEnvironment.Current.GetAuthenticationSchemes(host.BaseAddresses[0]);

                if (AspNetEnvironment.Current.IsSimpleApplicationHost)
                {
                    // Cassini always reports the auth scheme as anonymous or Ntlm. Map this to Ntlm, except when forms auth
                    // is requested
                    if (supportedSchemes == (AuthenticationSchemes.Anonymous | AuthenticationSchemes.Ntlm))
                    {
                        if (AspNetEnvironment.Current.IsWindowsAuthenticationConfigured())
                        {
                            supportedSchemes = AuthenticationSchemes.Ntlm;
                        }
                        else
                        {
                            supportedSchemes = AuthenticationSchemes.Anonymous;
                        }
                    }
                }
            }
            Type contractType = null;
            // add an endpoint with the contract at each base address
            foreach (Uri baseAddress in host.BaseAddresses)
            {
                string uriScheme = baseAddress.Scheme;
                
                // HTTP and HTTPs are only supported schemes
                if (Object.ReferenceEquals(uriScheme, Uri.UriSchemeHttp) || Object.ReferenceEquals(uriScheme, Uri.UriSchemeHttps))
                {
                    // bypass adding the automatic endpoint if there's already one at the base address
                    bool isExplicitEndpointConfigured = false;
                    foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
                    {
                        if (endpoint.Address != null && EndpointAddress.UriEquals(endpoint.Address.Uri, baseAddress, true, false))
                        {
                            isExplicitEndpointConfigured = true;
                            break;
                        }
                    }
                    if (isExplicitEndpointConfigured)
                    {
                        continue;
                    }

                    if (contractType == null)
                    {
                        if (implementedContracts.Count > 1)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(multipleContractsErrorMessage));
                        }
                        else if (implementedContracts.Count == 0)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(noContractErrorMessage));
                        }
                        foreach (ContractDescription contract in implementedContracts.Values)
                        {
                            contractType = contract.ContractType;
                            break;
                        }
                    }
                    
                    // Get the default web endpoint
                    ConfigLoader configLoader = new ConfigLoader(host.GetContractResolver(implementedContracts));
                    ServiceEndpointElement serviceEndpointElement = new ServiceEndpointElement();
                    serviceEndpointElement.Contract = contractType.FullName;
                    // Check for a protocol mapping
                    ProtocolMappingItem protocolMappingItem = ConfigLoader.LookupProtocolMapping(baseAddress.Scheme);
                    if (protocolMappingItem != null &&
                        string.Equals(protocolMappingItem.Binding, WebHttpBinding.WebHttpBindingConfigurationStrings.WebHttpBindingCollectionElementName, StringComparison.Ordinal))
                    {
                        serviceEndpointElement.BindingConfiguration = protocolMappingItem.BindingConfiguration;
                    }
                    serviceEndpointElement.Kind = standardEndpointKind;

                    // LookupEndpoint will not set the Endpoint address and listenUri
                    // because omitSettingEndpointAddress is set to true.
                    // We will set them after setting the binding security
                    ServiceEndpoint automaticEndpoint = configLoader.LookupEndpoint(serviceEndpointElement, null, host, host.Description, true /*omitSettingEndpointAddress*/);
                    WebHttpBinding binding = automaticEndpoint.Binding as WebHttpBinding;
                                    
                    bool automaticallyConfigureSecurity = !binding.Security.IsModeSet;
                    if (automaticallyConfigureSecurity)
                    {
                        if (Object.ReferenceEquals(uriScheme, Uri.UriSchemeHttps))
                        {
                            binding.Security.Mode = WebHttpSecurityMode.Transport;
                        }
                        else if (supportedSchemes != AuthenticationSchemes.None && supportedSchemes != AuthenticationSchemes.Anonymous)
                        {
                            binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly;
                        }
                        else
                        {
                            binding.Security.Mode = WebHttpSecurityMode.None;
                        }
                    }
                    
                    if (automaticallyConfigureSecurity && AspNetEnvironment.Enabled)
                    {
                        SetBindingCredentialBasedOnHostedEnvironment(automaticEndpoint, supportedSchemes);
                    }

                    // Setting the Endpoint address and listenUri now that we've set the binding security
                    ConfigLoader.ConfigureEndpointAddress(serviceEndpointElement, host, automaticEndpoint);
                    ConfigLoader.ConfigureEndpointListenUri(serviceEndpointElement, host, automaticEndpoint);

                    host.AddServiceEndpoint(automaticEndpoint);
                }
            }
        }