/// <summary>
        /// Checks for the existence of a specific storage container, if it doesn't exist it will create it.
        /// It also checks for a specific storage account that suits the system, if it doesn't exist in the subscription
        /// it will create it before attempting to create the container.
        /// </summary>
        /// <param name="client">The <see cref="StorageManagementClient"/> that is performing the operation.</param>
        /// <param name="model">The DevOpsFlex rich model object that contains everything there is to know about this database spec.</param>
        /// <returns>The async <see cref="Task"/> wrapper.</returns>
        public static async Task CreateContainerIfNotExistsAsync(this StorageManagementClient client, AzureStorageContainer model)
        {
            Contract.Requires(client != null);
            Contract.Requires(model != null);
            Contract.Requires(model.System != null);

            string accountName;

            lock (StorageAccountGate)
            {
                FlexStreams.BuildEventsObserver.OnNext(new CheckForParentResourceEvent(AzureResource.StorageAccount, AzureResource.StorageContainer, model.Name));
                accountName = FlexConfiguration.StorageAccountChooser.Choose(client, model.System.StorageType.GetEnumDescription()).Result;
                StorageAccountGetResponse account = null;

                try
                {
                    account = client.StorageAccounts.Get(accountName);
                }
                catch
                {
                    // ignored
                }

                if (account == null)
                {
                    accountName = (model.System.LogicalName + FlexDataConfiguration.StorageAccountString + FlexDataConfiguration.Branch).ToLower();

                    client.StorageAccounts.Create(
                        new StorageAccountCreateParameters
                    {
                        Name        = accountName,
                        Location    = model.System.Location.GetEnumDescription(),
                        AccountType = model.System.StorageType.GetEnumDescription()
                    });

                    FlexStreams.BuildEventsObserver.OnNext(new ProvisionEvent(AzureResource.StorageAccount, accountName));
                }
                else
                {
                    accountName = account.StorageAccount.Name;
                    FlexStreams.BuildEventsObserver.OnNext(new FoundExistingEvent(AzureResource.StorageAccount, accountName));
                }
            }

            await client.CreateContainerIfNotExistsAsync(
                accountName,
                FlexConfiguration.GetNaming <AzureStorageContainer>()
                .GetSlotName(model, FlexDataConfiguration.Branch, FlexDataConfiguration.Configuration),
                model.PublicAccess,
                model.Acl);
        }
        /// <summary>
        /// Checks for the existence of a specific Azure Sql Database, if it doesn't exist it will create it.
        /// </summary>
        /// <param name="client">The <see cref="SqlManagementClient"/> that is performing the operation.</param>
        /// <param name="model">The DevOpsFlex rich model object that contains everything there is to know about this database spec.</param>
        /// <returns>The async <see cref="Task"/> wrapper.</returns>
        public static async Task CreateDatabaseIfNotExistsAsync(this SqlManagementClient client, SqlAzureDb model)
        {
            Contract.Requires(client != null);
            Contract.Requires(model != null);

            string serverName;

            lock (SqlServerGate)
            {
                FlexStreams.BuildEventsObserver.OnNext(new CheckForParentResourceEvent(AzureResource.SqlServer, AzureResource.SqlDatabase, model.Name));
                serverName = FlexConfiguration.SqlServerChooser.Choose(client, model.System.Location.GetEnumDescription()).Result;

                if (serverName == null)
                {
                    string serverMaxVersion = null;

                    try
                    {
                        client.Servers.Create(
                            new ServerCreateParameters
                        {
                            AdministratorUserName = FlexConfiguration.FlexSaUser,
                            AdministratorPassword = FlexConfiguration.FlexSaPwd,
                            Location = model.System.Location.GetEnumDescription(),
                            Version  = "100.0"    // This needs to be an invalid version number
                        });
                    }
                    catch (CloudException ex)
                    {
                        if (ex.Error.Code == "40856") // SQL Version doesn't exist in the target location
                        {
                            var serverVersions = Regex.Match(ex.Error.Message, "server versions: '([^']*)'.").Groups[1].Value.Split(',');
                            var maxVersion     = serverVersions.Max((s => decimal.Parse(s)));
                            serverMaxVersion = serverVersions.First(s => s.Contains(maxVersion.ToString("F1", CultureInfo.InvariantCulture)));
                        }
                        else
                        {
                            throw;
                        }
                    }

                    serverName = client.Servers.Create(
                        new ServerCreateParameters
                    {
                        AdministratorUserName = FlexConfiguration.FlexSaUser,
                        AdministratorPassword = FlexConfiguration.FlexSaPwd,
                        Location = model.System.Location.GetEnumDescription(),
                        Version  = serverMaxVersion
                    }).ServerName;

                    FlexStreams.BuildEventsObserver.OnNext(new ProvisionEvent(AzureResource.SqlServer, serverName));
                }
                else
                {
                    FlexStreams.BuildEventsObserver.OnNext(new FoundExistingEvent(AzureResource.SqlServer, serverName));
                }
            }

            var dbName = FlexConfiguration.GetNaming <SqlAzureDb>()
                         .GetSlotName(
                model,
                FlexDataConfiguration.Branch,
                FlexDataConfiguration.Configuration);

            await client.CreateDatabaseIfNotExistsAsync(serverName, dbName, model.Edition.GetEnumDescription(), model.CollationName, model.MaximumDatabaseSizeInGB, model.CreateAppUser);
        }