/// <summary>
        /// Converts the permissions specified for the shared access policy to a string.
        /// </summary>
        /// <param name="permissions">A <see cref="SharedAccessFilePermissions"/> object.</param>
        /// <returns>The shared access permissions, in string format.</returns>
        public static string PermissionsToString(SharedAccessFilePermissions permissions) 
        {
            // The service supports a fixed order => rcwdl
            StringBuilder builder = new StringBuilder();

            if ((permissions & SharedAccessFilePermissions.Read) == SharedAccessFilePermissions.Read)
            {
                builder.Append("r");
            }

            if ((permissions & SharedAccessFilePermissions.Create) == SharedAccessFilePermissions.Create)
            {
                builder.Append("c");
            }

            if ((permissions & SharedAccessFilePermissions.Write) == SharedAccessFilePermissions.Write)
            {
                builder.Append("w");
            }

            if ((permissions & SharedAccessFilePermissions.Delete) == SharedAccessFilePermissions.Delete)
            {
                builder.Append("d");
            }

            if ((permissions & SharedAccessFilePermissions.List) == SharedAccessFilePermissions.List)
            {
                builder.Append("l");
            }

            return builder.ToString();
        }
        private static void TestAccess(string sasToken, SharedAccessFilePermissions permissions, SharedAccessFileHeaders headers, CloudFileShare share, CloudFile file)
        {
            StorageCredentials credentials = string.IsNullOrEmpty(sasToken) ?
                new StorageCredentials() :
                new StorageCredentials(sasToken);

            if (share != null)
            {
                share = new CloudFileShare(credentials.TransformUri(share.Uri));
                file = share.GetRootDirectoryReference().GetFileReference(file.Name);
            }
            else
            {
                file = new CloudFile(credentials.TransformUri(file.Uri));
            }

            if (share != null)
            {
                if ((permissions & SharedAccessFilePermissions.List) == SharedAccessFilePermissions.List)
                {
                    share.GetRootDirectoryReference().ListFilesAndDirectories().ToArray();
                }
                else
                {
                    TestHelper.ExpectedException(
                        () => share.GetRootDirectoryReference().ListFilesAndDirectories().ToArray(),
                        "List files while SAS does not allow for listing",
                        HttpStatusCode.NotFound);
                }
            }

            if ((permissions & SharedAccessFilePermissions.Read) == SharedAccessFilePermissions.Read)
            {
                file.FetchAttributes();
                
                // Test headers
                if (headers != null)
                {
                    if (headers.CacheControl != null)
                    {
                        Assert.AreEqual(headers.CacheControl, file.Properties.CacheControl);
                    }

                    if (headers.ContentDisposition != null)
                    {
                        Assert.AreEqual(headers.ContentDisposition, file.Properties.ContentDisposition);
                    }

                    if (headers.ContentEncoding != null)
                    {
                        Assert.AreEqual(headers.ContentEncoding, file.Properties.ContentEncoding);
                    }

                    if (headers.ContentLanguage != null)
                    {
                        Assert.AreEqual(headers.ContentLanguage, file.Properties.ContentLanguage);
                    }

                    if (headers.ContentType != null)
                    {
                        Assert.AreEqual(headers.ContentType, file.Properties.ContentType);
                    }
                }
            }
            else
            {
                TestHelper.ExpectedException(
                    () => file.FetchAttributes(),
                    "Fetch file attributes while SAS does not allow for reading",
                    HttpStatusCode.NotFound);
            }

            if ((permissions & SharedAccessFilePermissions.Write) == SharedAccessFilePermissions.Write)
            {
                file.SetMetadata();
            }
            else
            {
                TestHelper.ExpectedException(
                    () => file.SetMetadata(),
                    "Set file metadata while SAS does not allow for writing",
                    HttpStatusCode.NotFound);
            }

            if ((permissions & SharedAccessFilePermissions.Delete) == SharedAccessFilePermissions.Delete)
            {
                file.Delete();
            }
            else
            {
                TestHelper.ExpectedException(
                    () => file.Delete(),
                    "Delete file while SAS does not allow for deleting",
                    HttpStatusCode.NotFound);
            }
        }
        private static void TestFileSAS(CloudFile testFile, SharedAccessFilePermissions permissions, SharedAccessFileHeaders headers)
        {
            UploadText(testFile, "file", Encoding.UTF8);

            SharedAccessFilePolicy policy = new SharedAccessFilePolicy()
            {
                SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                Permissions = permissions,
            };

            string sasToken = testFile.GetSharedAccessSignature(policy, headers, null);
            TestAccess(sasToken, permissions, headers, null, testFile);
        }
        private static async Task TestAccess(string sasToken, SharedAccessFilePermissions permissions, SharedAccessFileHeaders headers, CloudFileShare share, CloudFile file)
        {
            CloudFileShare SASshare = null;
            CloudFile SASfile;
            OperationContext context = new OperationContext();
            StorageCredentials credentials = string.IsNullOrEmpty(sasToken) ?
                new StorageCredentials() :
                new StorageCredentials(sasToken);
            string fileText = "file";

            if (share != null)
            {
                SASshare = new CloudFileShare(credentials.TransformUri(share.Uri));
                SASfile = SASshare.GetRootDirectoryReference().GetFileReference(file.Name);
            }
            else
            {
                SASfile = new CloudFile(credentials.TransformUri(file.Uri));
            }

            if ((permissions & SharedAccessFilePermissions.Write) == SharedAccessFilePermissions.Write)
            {
                await UploadTextAsync(SASfile, fileText, Encoding.UTF8);
            }
            else if ((permissions & SharedAccessFilePermissions.Create) == SharedAccessFilePermissions.Create)
            {
                await SASfile.CreateAsync(Encoding.UTF8.GetBytes(fileText).Length);
                context = new OperationContext();
                await TestHelper.ExpectedExceptionAsync(
                    async () => await UploadTextAsync(SASfile, fileText, Encoding.UTF8, operationContext:context),
                    context,
                    "UploadText SAS does not allow for writing",
                    HttpStatusCode.Forbidden,
                    "");
                await UploadTextAsync(file, fileText, Encoding.UTF8);

            }
            else
            {
                context = new OperationContext();
                await TestHelper.ExpectedExceptionAsync(
                        async () => await SASfile.CreateAsync(Encoding.UTF8.GetBytes(fileText).Length, null /* accessCondition */, null /* options */, context),
                        context,
                        "Create file succeeded but SAS does not allow for writing/creating",
                        HttpStatusCode.Forbidden,
                        "");
                context = new OperationContext();
                await TestHelper.ExpectedExceptionAsync(
                    async () => await UploadTextAsync(SASfile, fileText, Encoding.UTF8, operationContext:context),
                        context,
                        "UploadText SAS does not allow for writing/creating",
                        HttpStatusCode.Forbidden,
                        "");
                await UploadTextAsync(file, fileText, Encoding.UTF8);
            }

            if (SASshare != null)
            {
                if ((permissions & SharedAccessFilePermissions.List) == SharedAccessFilePermissions.List)
                {
                    var results = await SASshare.GetRootDirectoryReference().ListFilesAndDirectoriesSegmentedAsync(null);
                }
                else
                {
                    context = new OperationContext();
                    await TestHelper.ExpectedExceptionAsync(
                        async () => { var results = await SASshare.GetRootDirectoryReference().ListFilesAndDirectoriesSegmentedAsync(null /* maxResults */, null /* currentToken */, null /* options */, context); },
                        context,
                        "List files while SAS does not allow for listing",
                        HttpStatusCode.Forbidden,
                        "");
                }
            }

            if ((permissions & SharedAccessFilePermissions.Read) == SharedAccessFilePermissions.Read)
            {
                await SASfile.FetchAttributesAsync();

                // Test headers
                if (headers != null)
                {
                    if (headers.CacheControl != null)
                    {
                        Assert.AreEqual(headers.CacheControl, SASfile.Properties.CacheControl);
                    }

                    if (headers.ContentDisposition != null)
                    {
                        Assert.AreEqual(headers.ContentDisposition, SASfile.Properties.ContentDisposition);
                    }

                    if (headers.ContentEncoding != null)
                    {
                        Assert.AreEqual(headers.ContentEncoding, SASfile.Properties.ContentEncoding);
                    }

                    if (headers.ContentLanguage != null)
                    {
                        Assert.AreEqual(headers.ContentLanguage, SASfile.Properties.ContentLanguage);
                    }

                    if (headers.ContentType != null)
                    {
                        Assert.AreEqual(headers.ContentType, SASfile.Properties.ContentType);
                    }
                }
            }
            else
            {
                context = new OperationContext();
                await TestHelper.ExpectedExceptionAsync(
                    async () => await SASfile.FetchAttributesAsync(null /* accessCondition */, null /* options */, context),
                    context,
                    "Fetch file attributes while SAS does not allow for reading",
                    HttpStatusCode.Forbidden,
                    "");
            }

            if ((permissions & SharedAccessFilePermissions.Write) == SharedAccessFilePermissions.Write)
            {
                await SASfile.SetMetadataAsync();
            }
            else
            {
                context = new OperationContext();
                await TestHelper.ExpectedExceptionAsync(
                    async () => await SASfile.SetMetadataAsync(null /* accessCondition */, null /* options */, context),
                    context,
                    "Set file metadata while SAS does not allow for writing",
                    HttpStatusCode.Forbidden,
                    "");
            }

            if ((permissions & SharedAccessFilePermissions.Delete) == SharedAccessFilePermissions.Delete)
            {
                await SASfile.DeleteAsync();
            }
            else
            {
                context = new OperationContext();
                await TestHelper.ExpectedExceptionAsync(
                    async () => await SASfile.DeleteAsync(null /* accessCondition */, null /* options */, context),
                    context,
                    "Delete file while SAS does not allow for deleting",
                    HttpStatusCode.Forbidden,
                    "");
            }
        }
        private static async Task TestFileSAS(CloudFile testFile, SharedAccessFilePermissions permissions, SharedAccessFileHeaders headers)
        {
            SharedAccessFilePolicy policy = new SharedAccessFilePolicy()
            {
                SharedAccessStartTime = DateTimeOffset.UtcNow.AddMinutes(-5),
                SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30),
                Permissions = permissions,
            };

            string sasToken = testFile.GetSharedAccessSignature(policy, headers, null);
            await TestAccess(sasToken, permissions, headers, null, testFile);
        }
        private static void TestAccess(string sasToken, SharedAccessFilePermissions permissions, SharedAccessFileHeaders headers, CloudFileShare share, CloudFile file)
        {
            CloudFileShare SASshare = null;
            CloudFile SASfile;
            StorageCredentials credentials = string.IsNullOrEmpty(sasToken) ?
                new StorageCredentials() :
                new StorageCredentials(sasToken);
            string fileText = "file";

            if (share != null)
            {
                SASshare = new CloudFileShare(credentials.TransformUri(share.Uri));
                SASfile = SASshare.GetRootDirectoryReference().GetFileReference(file.Name);
            }
            else
            {
                SASfile = new CloudFile(credentials.TransformUri(file.Uri));
            }

            if ((permissions & SharedAccessFilePermissions.Write) == SharedAccessFilePermissions.Write)
            {
                UploadText(SASfile, fileText, Encoding.UTF8);
            }
            else if ((permissions & SharedAccessFilePermissions.Create) == SharedAccessFilePermissions.Create)
            {
                SASfile.Create(Encoding.UTF8.GetBytes(fileText).Length);
                TestHelper.ExpectedException(
                    () => UploadText(SASfile, fileText, Encoding.UTF8),
                    "UploadText SAS does not allow for writing",
                    HttpStatusCode.Forbidden);
                UploadText(file, fileText, Encoding.UTF8);

            }
            else 
            {
                TestHelper.ExpectedException(
                        () => SASfile.Create(Encoding.UTF8.GetBytes(fileText).Length),
                        "Create file succeeded but SAS does not allow for writing/creating",
                        HttpStatusCode.Forbidden);
                TestHelper.ExpectedException(
                        () => UploadText(SASfile, fileText, Encoding.UTF8),
                        "UploadText SAS does not allow for writing/creating",
                        HttpStatusCode.Forbidden);
                UploadText(file, fileText, Encoding.UTF8);
            }

            if (SASshare != null)
            {
                if ((permissions & SharedAccessFilePermissions.List) == SharedAccessFilePermissions.List)
                {
                    SASshare.GetRootDirectoryReference().ListFilesAndDirectories().ToArray();
                }
                else
                {
                    TestHelper.ExpectedException(
                        () => SASshare.GetRootDirectoryReference().ListFilesAndDirectories().ToArray(),
                        "List files while SAS does not allow for listing",
                        HttpStatusCode.Forbidden);
                }
            }

            if ((permissions & SharedAccessFilePermissions.Read) == SharedAccessFilePermissions.Read)
            {
                SASfile.FetchAttributes();
                
                // Test headers
                if (headers != null)
                {
                    if (headers.CacheControl != null)
                    {
                        Assert.AreEqual(headers.CacheControl, SASfile.Properties.CacheControl);
                    }

                    if (headers.ContentDisposition != null)
                    {
                        Assert.AreEqual(headers.ContentDisposition, SASfile.Properties.ContentDisposition);
                    }

                    if (headers.ContentEncoding != null)
                    {
                        Assert.AreEqual(headers.ContentEncoding, SASfile.Properties.ContentEncoding);
                    }

                    if (headers.ContentLanguage != null)
                    {
                        Assert.AreEqual(headers.ContentLanguage, SASfile.Properties.ContentLanguage);
                    }

                    if (headers.ContentType != null)
                    {
                        Assert.AreEqual(headers.ContentType, SASfile.Properties.ContentType);
                    }
                }
            }
            else
            {
                TestHelper.ExpectedException(
                    () => SASfile.FetchAttributes(),
                    "Fetch file attributes while SAS does not allow for reading",
                    HttpStatusCode.Forbidden);
            }

            if ((permissions & SharedAccessFilePermissions.Write) == SharedAccessFilePermissions.Write)
            {
                SASfile.SetMetadata();
            }
            else
            {
                TestHelper.ExpectedException(
                    () => SASfile.SetMetadata(),
                    "Set file metadata while SAS does not allow for writing",
                    HttpStatusCode.Forbidden);
            }

            if ((permissions & SharedAccessFilePermissions.Delete) == SharedAccessFilePermissions.Delete)
            {
                SASfile.Delete();
            }
            else
            {
                TestHelper.ExpectedException(
                    () => SASfile.Delete(),
                    "Delete file while SAS does not allow for deleting",
                    HttpStatusCode.Forbidden);
            }
        }