public ServiceHost Create(Type serviceImplementationType, Type serviceInterfaceType, Uri serviceUri, bool isAuthorizationEnabled, bool isMetadataEnabled, Uri metadataUri, string certificateFriendlyName)
        {
            ServiceHost serviceHost = new ServiceHost(serviceImplementationType, serviceUri);

            WSHttpBinding wsHttpBinding = new WSHttpBinding();

            wsHttpBinding.MaxBufferPoolSize           = 1024 * 1024 * 10;
            wsHttpBinding.MaxReceivedMessageSize      = 1024 * 1024 * 10;
            wsHttpBinding.ReaderQuotas.MaxArrayLength = 1024 * 1024 * 10;

            wsHttpBinding.OpenTimeout    = new TimeSpan(0, 10, 0);
            wsHttpBinding.CloseTimeout   = new TimeSpan(0, 10, 0);
            wsHttpBinding.SendTimeout    = new TimeSpan(0, 10, 0);
            wsHttpBinding.ReceiveTimeout = new TimeSpan(3, 0, 0);

            wsHttpBinding.Security.Mode = isAuthorizationEnabled ? SecurityMode.TransportWithMessageCredential : SecurityMode.None;
            wsHttpBinding.Security.Message.ClientCredentialType   = MessageCredentialType.UserName;
            wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

            serviceHost.AddServiceEndpoint(serviceInterfaceType, wsHttpBinding, "");

            if (isMetadataEnabled)
            {
                ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
                serviceMetadataBehavior.HttpGetEnabled = true;
                serviceMetadataBehavior.HttpGetUrl     = metadataUri;
                serviceHost.Description.Behaviors.Add(serviceMetadataBehavior);
            }

            ServiceCredentials credentials = new ServiceCredentials();

            credentials.UserNameAuthentication.UserNamePasswordValidationMode  = UserNamePasswordValidationMode.Custom;
            credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new ConfigSourceValidator();
            serviceHost.Description.Behaviors.Add(credentials);

            serviceHost.Description.Behaviors.OfType <ServiceDebugBehavior>().First().IncludeExceptionDetailInFaults = true;

            if (isAuthorizationEnabled)
            {
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                store.Open(OpenFlags.OpenExistingOnly);

                X509Certificate2 certificate = store.FindByFriendlyName(certificateFriendlyName);

                if (certificate == null)
                {
                    throw new SatelliteServiceException("Certificate not found: " + certificateFriendlyName);
                }

                serviceHost.Credentials.ServiceCertificate.Certificate = certificate;

                store.Close();
            }

            return(serviceHost);
        }
        public override void Run()
        {
            using (ServerManager serverManager = new ServerManager())
            {
                this.StopSite(serverManager, (string)this.configuration.siteName);

                if (Directory.Exists((string)this.configuration.destination))
                {
                    this.backupDirectoryGuid = this.BackupRepository.StoreDirectory((string)this.configuration.destination);
                    DirectoryHelper.DeleteContents((string)this.configuration.destination);
                }

                packageRepository.ExtractProject(
                    (int)this.configuration.projectId,
                    (string)this.configuration.destination);

                Site site = this.Site(serverManager, (string)this.configuration.siteName);
                //this.backupSiteConfigurationGuid = this.BackupRepository.StoreObject(site);

                ApplicationPool applicationPool = this.ApplicationPool(serverManager, (string)this.configuration.applicationPoolName);
                Application     application     = this.Application(serverManager, site, (string)this.configuration.destination);

                site.Applications["/"].VirtualDirectories["/"].PhysicalPath = (string)this.configuration.destination;
                site.ApplicationDefaults.ApplicationPoolName = (string)configuration.applicationPoolName;
                site.ServerAutoStart                  = true;
                applicationPool.AutoStart             = true;
                applicationPool.ManagedRuntimeVersion = "v4.0";

                string webConfigPath = Path.Combine((string)this.configuration.destination, "web.config");

                if (File.Exists(webConfigPath))
                {
                    XDocument webConfig = XDocument.Load(webConfigPath);

                    if (webConfig.Descendants("aspNetCore").Any(d => d.Attribute("processPath")?.Value == "dotnet"))
                    {
                        applicationPool.ManagedRuntimeVersion = ""; // dotnetcore
                    }
                }

                site.Bindings.Clear();

                foreach (dynamic bindingConfig in configuration.bindings)
                {
                    Binding binding = site.Bindings.CreateElement();

                    string ip = (string)bindingConfig.IP;

                    binding.Protocol           = (string)bindingConfig.protocol;
                    binding.BindingInformation = (string.IsNullOrWhiteSpace(ip) ? "" : ip) + ":" + (int)bindingConfig.port + ":" + (string)bindingConfig.host;

                    switch (binding.Protocol.ToLower())
                    {
                    case "http":
                        site.Bindings.Add(binding);
                        break;

                    default:
                    {
                        X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                        store.Open(OpenFlags.OpenExistingOnly);
                        X509Certificate2 certificate = store.FindByFriendlyName((string)bindingConfig.certificateName);

                        if (certificate != null)
                        {
                            binding.CertificateHash      = certificate.GetCertHash();
                            binding.CertificateStoreName = store.Name;

                            site.Bindings.Add(binding);
                        }

                        store.Close();
                    }
                    break;
                    }
                }

                serverManager.CommitChanges();
            }

            try
            {
                using (ServerManager serverManager = new ServerManager())
                {
                    this.StartSite(serverManager, (string)this.configuration.siteName);
                    serverManager.CommitChanges();
                }
            }
            catch (Exception e)
            {
                // ignore, will pop for just created sites
            }
        }