public static int AddWebSite(int packageId, int domainId, int packageAddressId,
            bool addInstantAlias)
        {
            // check account
            int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
            if (accountCheck < 0) return accountCheck;

            // check package
            int packageCheck = SecurityContext.CheckPackage(packageId, DemandPackage.IsActive);
            if (packageCheck < 0) return packageCheck;

            // check quota
            QuotaValueInfo sitesQuota = PackageController.GetPackageQuota(packageId, Quotas.WEB_SITES);
            if (sitesQuota.QuotaExhausted)
                return BusinessErrorCodes.ERROR_WEB_SITES_QUOTA_LIMIT;

            // load domain name
            DomainInfo domain = ServerController.GetDomain(domainId);
            string domainName = domain.DomainName;

            // check if the web site already exists
            if (PackageController.GetPackageItemByName(packageId, domainName, typeof(WebSite)) != null)
                return BusinessErrorCodes.ERROR_WEB_SITE_ALREADY_EXISTS;

            // place log record
            TaskManager.StartTask("WEB_SITE", "ADD", domainName);

            try
            {

                // get service
                int serviceId = PackageController.GetPackageServiceId(packageId, ResourceGroups.Web);
                if (serviceId == 0)
                    return BusinessErrorCodes.ERROR_WEB_SITE_SERVICE_UNAVAILABLE;

				#region Fix for bug #587
				// Initialize IIS provider webservice proxy
				WebServer web = new WebServer();
				ServiceProviderProxy.Init(web, serviceId);

				// Ensure the web site is being created doesn't exist on the server
				if (web.SiteExists(domainName))
				{
					//
					PackageInfo packageInfo = PackageController.GetPackage(packageId);
					//
					ServerInfo serverInfo = ServerController.GetServerById(packageInfo.ServerId);
					// Give as much clues for the issue to an administrator as possible
					TaskManager.WriteError("Web site '{0}' could not be created because site with the name requested already " +
						"exists on '{1}' server.", domainName, serverInfo.ServerName);
					// Return generic operation failed error
					return BusinessErrorCodes.FAILED_EXECUTE_SERVICE_OPERATION;
				} 
				#endregion

                // load web settings
                StringDictionary webSettings = ServerController.GetServiceSettings(serviceId);
                int addressId = Utils.ParseInt(webSettings["SharedIP"], 0);

                bool dedicatedIp = false;
                if (packageAddressId != 0)
                {
                    // dedicated IP
                    PackageIPAddress packageIp = ServerController.GetPackageIPAddress(packageAddressId);
                    if (packageIp != null)
                    {
                        addressId = packageIp.AddressID;
                        dedicatedIp = true;
                    }
                }

                // load assigned IP address
                string ipAddr = "*";
                IPAddressInfo ip = ServerController.GetIPAddress(addressId);
                if (ip != null)
                    ipAddr = !String.IsNullOrEmpty(ip.InternalIP) ? ip.InternalIP : ip.ExternalIP;

                // load domain instant alias
                string instantAlias = ServerController.GetDomainAlias(packageId, domainName);
                DomainInfo instantDomain = ServerController.GetDomain(instantAlias);
                if (instantDomain == null || instantDomain.WebSiteId > 0)
                    instantAlias = "";

                // load web DNS records
                List<GlobalDnsRecord> dnsRecords = ServerController.GetDnsRecordsByService(serviceId);

                // prepare site bindings
                List<ServerBinding> bindings = new List<ServerBinding>();

                if (!dedicatedIp)
                {
                    // SHARED IP
                    // fill main domain bindings
                    FillWebServerBindings(bindings, dnsRecords, ipAddr, domain.DomainName);

                    // fill alias bindings if required
                    if (addInstantAlias && !String.IsNullOrEmpty(instantAlias))
                    {
                        // fill bindings from DNS "A" records
                        FillWebServerBindings(bindings, dnsRecords, ipAddr, instantAlias);
                    }
                }
                else
                {
                    // DEDICATED IP
                    bindings.Add(new ServerBinding(ipAddr, "80", ""));
                }

                UserInfo user = PackageController.GetPackageOwner(packageId);
                UserSettings webPolicy = UserController.GetUserSettings(user.UserId, UserSettings.WEB_POLICY);

                // craete web site
                string siteId = null;
                WebSite site = new WebSite();

                // web site name and bindings
                site.Name = domainName;
                site.Bindings = bindings.ToArray();

                site.AnonymousUsername = GetWebSiteUsername(webPolicy, domainName);
                site.AnonymousUserPassword = Guid.NewGuid().ToString("P");

                // folders
                string packageHome = FilesController.GetHomeFolder(packageId);

                // add random string to the domain if specified
                string randDomainName = domainName;
                if (!String.IsNullOrEmpty(webPolicy["AddRandomDomainString"])
                    && Utils.ParseBool(webPolicy["AddRandomDomainString"], false))
                    randDomainName += "_" + Utils.GetRandomString(DOMAIN_RANDOM_LENGTH);

                // ROOT folder
                site.ContentPath = GetWebFolder(packageId, WEBSITE_ROOT_FOLDER_PATTERN, randDomainName);
                if (!String.IsNullOrEmpty(webPolicy["WebRootFolder"]))
                    site.ContentPath = GetWebFolder(packageId, webPolicy["WebRootFolder"], randDomainName);

                // LOGS folder
                site.LogsPath = GetWebFolder(packageId, WEBSITE_LOGS_FOLDER_PATTERN, randDomainName);
                if (!String.IsNullOrEmpty(webPolicy["WebLogsFolder"]))
                    site.LogsPath = GetWebFolder(packageId, webPolicy["WebLogsFolder"], randDomainName);

                // DATA folder
                site.DataPath = GetWebFolder(packageId, WEBSITE_DATA_FOLDER_PATTERN, randDomainName);
                if (!String.IsNullOrEmpty(webPolicy["WebDataFolder"]))
                    site.DataPath = GetWebFolder(packageId, webPolicy["WebDataFolder"], randDomainName);

                // default documents
                site.DefaultDocs = null; // inherit from service
                if (!String.IsNullOrEmpty(webPolicy["DefaultDocuments"]))
                    site.DefaultDocs = webPolicy["DefaultDocuments"];

				if (!String.IsNullOrEmpty(webPolicy["EnableWritePermissions"]))
                {
                    // security settings
                    site.EnableWritePermissions = Utils.ParseBool(webPolicy["EnableWritePermissions"], false);
                    site.EnableDirectoryBrowsing = Utils.ParseBool(webPolicy["EnableDirectoryBrowsing"], false);
                    site.EnableParentPaths = Utils.ParseBool(webPolicy["EnableParentPaths"], false);
					site.DedicatedApplicationPool = Utils.ParseBool(webPolicy["EnableDedicatedPool"], false);
                    
					#region Fix for bug: #1556
					// Ensure the website meets hosting plan quotas
					QuotaValueInfo quotaInfo = PackageController.GetPackageQuota(packageId, Quotas.WEB_APPPOOLS);
					site.DedicatedApplicationPool = site.DedicatedApplicationPool && (quotaInfo.QuotaAllocatedValue > 0);
				
					#endregion

                    site.EnableAnonymousAccess = Utils.ParseBool(webPolicy["EnableAnonymousAccess"], false);
                    site.EnableWindowsAuthentication = Utils.ParseBool(webPolicy["EnableWindowsAuthentication"], false);
                    site.EnableBasicAuthentication = Utils.ParseBool(webPolicy["EnableBasicAuthentication"], false);

                    // extensions
                    site.AspInstalled = Utils.ParseBool(webPolicy["AspInstalled"], false);
                    site.AspNetInstalled = webPolicy["AspNetInstalled"];
                    site.PhpInstalled = webPolicy["PhpInstalled"];
                    site.PerlInstalled = Utils.ParseBool(webPolicy["PerlInstalled"], false);
                    site.PythonInstalled = Utils.ParseBool(webPolicy["PythonInstalled"], false);
                    site.CgiBinInstalled = Utils.ParseBool(webPolicy["CgiBinInstalled"], false);
                    site.ColdFusionInstalled = false;
                    
                }
                else
                {
                    // security settings
                    site.EnableWritePermissions = false;
                    site.EnableDirectoryBrowsing = false;
                    site.EnableParentPaths = false;
                    site.DedicatedApplicationPool = false;

                    site.EnableAnonymousAccess = true;
                    site.EnableWindowsAuthentication = true;
                    site.EnableBasicAuthentication = false;

                    // extensions
                    site.AspInstalled = true;
                    site.AspNetInstalled = "1";
                    site.PhpInstalled = "";
                    site.PerlInstalled = false;
                    site.PythonInstalled = false;
                    site.CgiBinInstalled = false;
                    site.ColdFusionInstalled = false;
                }

                site.HttpRedirect = "";
                site.HttpErrors = null;
                site.MimeMaps = null;

                // CREATE WEB SITE
                siteId = web.CreateSite(site);

                // register item
                site.ServiceId = serviceId;
                site.PackageId = packageId;
                site.Name = domainName;
                site.SiteIPAddressId = addressId;
                site.SiteId = siteId;

                int siteItemId = PackageController.AddPackageItem(site);

                // associate IP with web site
                if (packageAddressId != 0)
                    ServerController.AddItemIPAddress(siteItemId, packageAddressId);

                // update domain
                // add main pointer
                AddWebSitePointer(siteItemId, domain.DomainId, false);

                // add instant pointer
                if (addInstantAlias && !String.IsNullOrEmpty(instantAlias))
                    AddWebSitePointer(siteItemId, instantDomain.DomainId, false);

                // add parking page
                // load package
                if (webPolicy["AddParkingPage"] != null)
                {
                    bool addParkingPage = Utils.ParseBool(webPolicy["AddParkingPage"], false);
                    if (addParkingPage)
                    {
                        // add page
                        string pageName = webPolicy["ParkingPageName"];
                        string pageContent = webPolicy["ParkingPageContent"];

                        if (!String.IsNullOrEmpty(pageName)
                            && pageContent != null)
                        {
                            string path = Path.Combine(
                                 FilesController.GetVirtualPackagePath(packageId, site.ContentPath), pageName);

                            if (!FilesController.FileExists(packageId, path))
                            {
                                FilesController.CreateFile(packageId, path);

								byte[] content = Encoding.UTF8.GetBytes(pageContent);
								byte[] fileContent = new byte[content.Length + 3];
								fileContent[0] = 0xEF;
								fileContent[1] = 0xBB;
								fileContent[2] = 0xBF;
								content.CopyTo(fileContent, 3);
                                FilesController.UpdateFileBinaryContent(packageId, path, fileContent);
                            }
                        }
                    }
                }

                TaskManager.ItemId = siteItemId;

                return siteItemId;
            }
            catch (Exception ex)
            {
                throw TaskManager.WriteError(ex);
            }
            finally
            {
                TaskManager.CompleteTask();
            }
        }