public static StringResultObject Install(int packageId, string webAppId, string siteName, string virtualDir, List <DeploymentParameter> parameters)
        {
            StringResultObject result = new StringResultObject();

            try
            {
                // database operation results
                int databaseResult     = -1;
                int databaseUserResult = -1;

                // initialize task manager
                TaskManager.StartTask(TASK_MANAGER_SOURCE, "INSTALL_WEB_APP");
                TaskManager.WriteParameter("Package ID", packageId);
                TaskManager.WriteParameter("Site Name", siteName);

                #region Check Space and Account
                // Check account
                int accountCheck = SecurityContext.CheckAccount(DemandAccount.NotDemo | DemandAccount.IsActive);
                if (accountCheck < 0)
                {
                    return(Warning <StringResultObject>((-accountCheck).ToString()));
                }

                // Check space
                int packageCheck = SecurityContext.CheckPackage(packageId, DemandPackage.IsActive);
                if (packageCheck < 0)
                {
                    return(Warning <StringResultObject>((-packageCheck).ToString()));
                }
                #endregion

                #region Check MS Deploy, web site and application pack
                // get target web server
                WebServer webServer = GetAssociatedWebServer(packageId);

                // Check if Web App Gallery is installed
                if (!webServer.IsMsDeployInstalled())
                {
                    return(Error <StringResultObject>(GalleryErrors.MsDeployIsNotInstalled));
                }

                // Check web site for existence
                WebSite webSite = WebServerController.GetWebSite(packageId, siteName);
                if (webSite == null)
                {
                    return(Error <StringResultObject>(GalleryErrors.WebSiteNotFound, siteName));
                }

                // get application pack details
                GalleryApplicationResult app = webServer.GetGalleryApplication(webAppId);
                if (!app.IsSuccess)
                {
                    return(Error <StringResultObject>(app, GalleryErrors.GeneralError));
                }
                if (app.Value == null)
                {
                    return(Error <StringResultObject>(GalleryErrors.WebApplicationNotFound, webAppId));
                }
                #endregion

                #region Trace app details

                // Assign web app pack title to the currently running task
                TaskManager.ItemName = app.Value.Title;

                // Trace additional details from the feed
                TaskManager.WriteParameter("Title", app.Value.Title);
                TaskManager.WriteParameter("Version", app.Value.Version);
                TaskManager.WriteParameter("Download URL", app.Value.DownloadUrl);
                TaskManager.WriteParameter("Author", app.Value.AuthorName);
                TaskManager.WriteParameter("Last Updated", app.Value.LastUpdated);

                // Trace out all deployment parameters
                Array.ForEach <DeploymentParameter>(parameters.ToArray(), p => TaskManager.WriteParameter(p.Name, p.Value));
                #endregion

                // elevate security context
                SecurityContext.SetThreadSupervisorPrincipal();

                #region Set AppPath
                // set correct application path
                DeploymentParameter appPath = FindParameterByTag(parameters, DeploymentParameterWellKnownTag.IisApp);
                if (appPath == null)
                {
                    return(Error <StringResultObject>(GalleryErrors.AppPathParameterNotFound));
                }

                appPath.Value = String.IsNullOrEmpty(virtualDir) ? siteName : String.Format("{0}/{1}", siteName, virtualDir);
                #endregion

                // database context
                // find database resource parameter
                DeploymentParameter databaseResoure = parameters.Find(p =>
                {
                    return(p.Name == DeploymentParameter.ResourceGroupParameterName);
                });

                // database is required for this application
                if (databaseResoure != null)
                {
                    // try to get database service
                    int dbServiceId = PackageController.GetPackageServiceId(packageId, databaseResoure.Value);
                    if (dbServiceId == 0)
                    {
                        return(Error <StringResultObject>(GalleryErrors.DatabaseServiceIsNotAvailable));
                    }

                    #region Setup Database server and DB Admin credentials
                    // get database service settings
                    StringDictionary dbSettings = ServerController.GetServiceSettingsAdmin(dbServiceId);

                    // database server
                    DeploymentParameter databaseServer = FindParameterByTag(parameters, DeploymentParameterWellKnownTag.DBServer);
                    if (databaseServer != null)
                    {
                        databaseServer.Value = dbSettings["ExternalAddress"];
                        if (String.IsNullOrEmpty(databaseServer.Value))
                        {
                            return(Error <StringResultObject>(GalleryErrors.DatabaseServerExternalAddressIsEmpty));
                        }
                    }

                    // database admin
                    DeploymentParameter databaseAdminUsername = FindParameterByTag(parameters, DeploymentParameterWellKnownTag.DBAdminUserName);
                    if (databaseAdminUsername != null)
                    {
                        databaseAdminUsername.Value = dbSettings["RootLogin"];
                        if (String.IsNullOrEmpty(databaseAdminUsername.Value))
                        {
                            databaseAdminUsername.Value = dbSettings["SaLogin"];
                        }

                        // raise error if database service is in Integrated Security mode (for SQL Server)
                        // or DB Admin username is not provided
                        if (String.IsNullOrEmpty(databaseAdminUsername.Value))
                        {
                            return(Error <StringResultObject>(GalleryErrors.DatabaseAdminUsernameNotSpecified));
                        }
                    }

                    // database admin password
                    DeploymentParameter databaseAdminPassword = FindParameterByTag(parameters, DeploymentParameterWellKnownTag.DBAdminPassword);
                    if (databaseAdminPassword != null)
                    {
                        databaseAdminPassword.Value = dbSettings["RootPassword"];
                        if (String.IsNullOrEmpty(databaseAdminPassword.Value))
                        {
                            databaseAdminPassword.Value = dbSettings["SaPassword"];
                        }

                        // raise error if database service is in Integrated Security mode (for SQL Server)
                        // or DB Admin password is not provided
                        if (String.IsNullOrEmpty(databaseAdminPassword.Value))
                        {
                            return(Error <StringResultObject>(GalleryErrors.DatabaseAdminPasswordNotSpecified));
                        }
                    }
                    #endregion

                    #region Create database and db user account if new selected

                    // create database
                    DeploymentParameter databaseName = FindParameterByTag(parameters, DeploymentParameterWellKnownTag.DBName);
                    if (databaseName != null)
                    {
                        SqlDatabase db = PackageController.GetPackageItemByName(packageId, databaseResoure.Value, databaseName.Value, typeof(SqlDatabase)) as SqlDatabase;

                        if (db == null)
                        {
                            try
                            {
                                db           = new SqlDatabase();
                                db.PackageId = packageId;
                                db.Name      = databaseName.Value;

                                // create
                                databaseResult = DatabaseServerController.AddSqlDatabase(db, databaseResoure.Value);
                                if (databaseResult < 0)
                                {
                                    result.ErrorCodes.Add((-databaseResult).ToString());
                                    return(Error <StringResultObject>(result, GalleryErrors.DatabaseCreationError));
                                }
                            }
                            catch (Exception ex)
                            {
                                // log exception
                                TaskManager.WriteError(ex);

                                // return error
                                return(Error <StringResultObject>(GalleryErrors.DatabaseCreationException));
                            }
                        }
                    }

                    // create database user
                    DeploymentParameter databaseUsername     = FindParameterByTag(parameters, DeploymentParameterWellKnownTag.DBUserName);
                    DeploymentParameter databaseUserPassword = FindParameterByTag(parameters, DeploymentParameterWellKnownTag.DBUserPassword);

                    if (databaseUsername != null && databaseUserPassword != null)
                    {
                        SqlUser user = PackageController.GetPackageItemByName(packageId, databaseResoure.Value, databaseUsername.Value, typeof(SqlUser)) as SqlUser;
                        //
                        if (user == null)
                        {
                            // create new user account
                            try
                            {
                                user           = new SqlUser();
                                user.PackageId = packageId;
                                user.Name      = databaseUsername.Value;
                                user.Databases = (databaseName != null) ? new string[] { databaseName.Value } : new string[0];
                                user.Password  = databaseUserPassword.Value;

                                // create
                                databaseUserResult = DatabaseServerController.AddSqlUser(user, databaseResoure.Value);

                                // check results
                                if (databaseUserResult < 0)
                                {
                                    // Rollback and remove db if created
                                    if (databaseResult > 0)
                                    {
                                        DatabaseServerController.DeleteSqlDatabase(databaseResult);
                                    }

                                    // raise error
                                    result.ErrorCodes.Add((-databaseUserResult).ToString());
                                    return(Error <StringResultObject>(result, GalleryErrors.DatabaseUserCreationError));
                                }
                            }
                            catch (Exception ex)
                            {
                                // log exception
                                TaskManager.WriteError(ex);

                                // return error
                                return(Error <StringResultObject>(GalleryErrors.DatabaseUserCreationException, ex.Message));
                            }
                        }
                        else
                        {
                            // check existing user account
                            DatabaseServer databaseService = DatabaseServerController.GetDatabaseServer(dbServiceId);
                            if (!databaseService.CheckConnectivity(databaseName.Value, databaseUsername.Value, databaseUserPassword.Value))
                            {
                                return(Error <StringResultObject>(GalleryErrors.DatabaseUserCannotAccessDatabase, databaseUsername.Value));
                            }
                        }
                    }
                    #endregion

                    // remove database resource parameter from the list
                    // before calling "install" method
                    parameters.Remove(databaseResoure);
                }

                // install application
                result = webServer.InstallGalleryApplication(webAppId, parameters.ToArray());

                #region Rollback in case of failure
                // Rollback - remove resources have been created previously
                if (!result.IsSuccess)
                {
                    // delete database
                    if (databaseUserResult > 0)
                    {
                        DatabaseServerController.DeleteSqlUser(databaseUserResult);
                    }

                    // delete database user
                    if (databaseResult > 0)
                    {
                        DatabaseServerController.DeleteSqlDatabase(databaseResult);
                    }

                    // exit with errors
                    return(Error <StringResultObject>(result, GalleryErrors.ApplicationInstallationError));
                }
                #endregion

                #region Update Web Application settings

                WebVirtualDirectory iisApp = null;
                if (String.IsNullOrEmpty(virtualDir))
                {
                    // load web site
                    iisApp = WebServerController.GetWebSite(packageId, siteName);
                }
                else
                {
                    // load virtual directory
                    iisApp = WebServerController.GetVirtualDirectory(webSite.Id, virtualDir);
                }

                // put correct extensions
                if ((app.Value.WellKnownDependencies & GalleryApplicationWellKnownDependency.AspNet20) == GalleryApplicationWellKnownDependency.AspNet20)
                {
                    // ASP.NET 2.0
                    iisApp.AspNetInstalled = (iisApp.IIs7) ? "2I" : "2";
                    AddDefaultDocument(iisApp, "default.aspx");
                }
                else if ((app.Value.WellKnownDependencies & GalleryApplicationWellKnownDependency.AspNet40) == GalleryApplicationWellKnownDependency.AspNet40)
                {
                    // ASP.NET 4.0
                    iisApp.AspNetInstalled = (iisApp.IIs7) ? "4I" : "4";
                    AddDefaultDocument(iisApp, "default.aspx");
                }
                else if ((app.Value.WellKnownDependencies & GalleryApplicationWellKnownDependency.PHP) == GalleryApplicationWellKnownDependency.PHP)
                {
                    // PHP 5
                    iisApp.PhpInstalled = "5";
                    AddDefaultDocument(iisApp, "index.php");
                }

                // update web site or virtual directory
                int updateResult = 0;
                if (String.IsNullOrEmpty(virtualDir))
                {
                    // update web site
                    updateResult = WebServerController.UpdateWebSite(iisApp as WebSite);
                }
                else
                {
                    // update virtual directory
                    updateResult = WebServerController.UpdateVirtualDirectory(webSite.Id, iisApp);
                }

                if (updateResult < 0)
                {
                    TaskManager.WriteWarning("Cannot update website or virtual directory programming extensions and default documents. Result code: {0}", updateResult.ToString());
                }

                #endregion

                return(result);
            }
            catch (Exception ex)
            {
                // log error
                TaskManager.WriteError(ex);

                // exit with error code
                return(Error <StringResultObject>(GalleryErrors.GeneralError));
            }
            finally
            {
                TaskManager.CompleteTask();
            }
        }