/// <summary>
        /// List all the keys stored in the KeyVault
        /// </summary>
        /// <returns>The list of Keys</returns>
        public async Task <List <String> > ListKeysAsync()
        {
            var             result   = new List <String>();
            IPage <KeyItem> keysPage = null;

            var retry = new RetryWithExponentialBackoff();
            await retry.RunAsync(async() =>
            {
                keysPage = await keyVaultClient.GetKeysAsync(vaultAddress);
            });

            String nextPageLink = null;

            do
            {
                if (!String.IsNullOrEmpty(nextPageLink))
                {
                    await retry.RunAsync(async() =>
                    {
                        keysPage = await keyVaultClient.GetKeysNextAsync(nextPageLink);
                    });
                }

                nextPageLink = keysPage.NextPageLink;

                foreach (var key in keysPage)
                {
                    result.Add(key.Identifier.Name);
                }
            } while (!String.IsNullOrEmpty(nextPageLink));


            return(result);
        }
        /// <summary>
        /// Gets a specific key
        /// </summary>
        /// <param name="key">The key to search for</param>
        /// <param name="version">The version of the key</param>
        /// <returns>The requested key</returns>
        public async Task <KeyBundle> GetFullKeyAsync(string key, string version = null)
        {
            KeyBundle retrievedKey = null;

            try
            {
                var retry = new RetryWithExponentialBackoff();
                await retry.RunAsync(async() =>
                {
                    if (!String.IsNullOrEmpty(version) || !String.IsNullOrEmpty(key))
                    {
                        // If version is specified get the tags for the specific version
                        if (!String.IsNullOrEmpty(version))
                        {
                            retrievedKey = await keyVaultClient.GetKeyAsync(vaultAddress, key, version);
                        }
                        else
                        {
                            // Get the tags for the latest version
                            retrievedKey = await keyVaultClient.GetKeyAsync(vaultAddress, key);
                        }
                    }
                });
            }
            catch (KeyVaultErrorException ex)
            {
                if (ex.Body.Error.Code != "KeyNotFound")
                {
                    throw ex;
                }
            }

            return(retrievedKey);
        }
        /// <summary>
        /// Adds or update the dictionary values with a specific key to the KeyVault
        /// </summary>
        /// <param name="key">The unique key</param>
        /// <param name="values">The dictionary values to be added</param>
        /// <returns></returns>
        /// <remarks>If an exception is generated the method returns it without any wrap</remarks>
        public async Task AddOrUpdateAsync(string key, IDictionary <String, String> values)
        {
            var tags = new Dictionary <String, String>();

            foreach (var item in values)
            {
                if (!String.IsNullOrEmpty(item.Value) && item.Value.Length > 256)
                {
                    // If the item is longer than 256 split in chunks of 256
                    for (var chunk = 0; chunk <= item.Value.Length / 256; chunk++)
                    {
                        tags.Add($"{item.Key}_{chunk}", item.Value.Substring(chunk * 256,
                                                                             (item.Value.Length - chunk * 256) > 256 ? 256 : item.Value.Length - chunk * 256));
                    }
                }
                else if (!String.IsNullOrEmpty(item.Value))
                {
                    // If the item is shorter than 256 add it directly
                    tags.Add(item.Key, item.Value);
                }
            }

            var attributes = new KeyAttributes(recoveryLevel: "Purgeable");

            attributes.Expires = DateTime.UtcNow.AddHours(12);

            var retry = new RetryWithExponentialBackoff();
            await retry.RunAsync(async() =>
            {
                var createdKey = await keyVaultClient.CreateKeyAsync(vaultAddress, key, JsonWebKeyType.Rsa, keyAttributes: attributes, tags: tags);
            });
        }
 /// <summary>
 /// Removes a specific key
 /// </summary>
 /// <param name="key">The key to search for</param>
 public async Task RemoveKeyAsync(string key)
 {
     try
     {
         var retry = new RetryWithExponentialBackoff();
         await retry.RunAsync(async() =>
         {
             // Deletes a key
             var deletedKey = await keyVaultClient.DeleteKeyAsync(vaultAddress, key);
             // And purges it immediately
             if (deletedKey.RecoveryId != null)
             {
                 await keyVaultClient.PurgeDeletedKeyAsync(deletedKey.RecoveryId);
             }
         });
     }
     catch (KeyVaultErrorException ex)
     {
         if (ex.Body.Error.Code != "KeyNotFound")
         {
             throw ex;
         }
     }
 }