private RESTCommand <NullType> SetServicePropertiesImpl(ServiceProperties properties, BlobRequestOptions requestOptions)
        {
            MultiBufferMemoryStream memoryStream = new MultiBufferMemoryStream(null /* bufferManager */, (int)(1 * Constants.KB));

            try
            {
                properties.WriteServiceProperties(memoryStream);
            }
            catch (InvalidOperationException invalidOpException)
            {
                throw new ArgumentException(invalidOpException.Message, "properties");
            }

            RESTCommand <NullType> retCmd = new RESTCommand <NullType>(this.Credentials, this.StorageUri, this.HttpClient);

            requestOptions.ApplyToStorageCommand(retCmd);
            retCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.SetServiceProperties(uri, serverTimeout, cnt, ctx, this.GetCanonicalizer(), this.Credentials);
            retCmd.BuildContent           = (cmd, ctx) => HttpContentFactory.BuildContentFromStream(memoryStream, 0, memoryStream.Length, Checksum.None, cmd, ctx);
            retCmd.StreamToDispose        = memoryStream;
            retCmd.RetrieveResponseStream = true;
            retCmd.PreProcessResponse     =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex);
            requestOptions.ApplyToStorageCommand(retCmd);
            return(retCmd);
        }
        private static RESTCommand <IList <BlobBatchSubOperationResponse> > BatchImpl(BatchOperation batch, CloudBlobClient client, BlobRequestOptions requestOptions)
        {
            // ContentMD5??
            //string contentMD5 = null;

            /*if (requestOptions.UseTransactionalMD5.HasValue && requestOptions.UseTransactionalMD5.Value)
             * {
             *  contentMD5 = memoryStream.ComputeMD5Hash();
             * }*/

            RESTCommand <IList <BlobBatchSubOperationResponse> > batchCmd = new RESTCommand <IList <BlobBatchSubOperationResponse> >(client.Credentials, client.StorageUri, client.HttpClient);

            requestOptions.ApplyToStorageCommand(batchCmd);

            List <BlobBatchSubOperationResponse> results = new List <BlobBatchSubOperationResponse>();

            batchCmd.CommandLocationMode      = CommandLocationMode.PrimaryOnly;
            batchCmd.RetrieveResponseStream   = true;
            batchCmd.PreProcessResponse       = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, null /* retVal */, cmd, ex);
            batchCmd.BuildContent             = (cmd, ctx) => BlobHttpRequestMessageFactory.WriteBatchBody(client, cmd, batch, ctx);
            batchCmd.BuildRequest             = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.PrepareBatchRequest(uri, client.BufferManager, serverTimeout, batch, cnt, ctx, client.GetCanonicalizer(), client.Credentials);
            batchCmd.PostProcessResponseAsync = (cmd, resp, ctx, ct) => BlobHttpResponseParsers.BatchPostProcessAsync(results, cmd, new[] { HttpStatusCode.Accepted, HttpStatusCode.OK }, resp, ctx, ct);

            return(batchCmd);
        }
        private RESTCommand <ServiceProperties> GetServicePropertiesImpl(BlobRequestOptions requestOptions)
        {
            RESTCommand <ServiceProperties> retCmd = new RESTCommand <ServiceProperties>(this.Credentials, this.StorageUri, this.HttpClient);

            retCmd.CommandLocationMode    = CommandLocationMode.PrimaryOrSecondary;
            retCmd.BuildRequest           = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.GetServiceProperties(uri, serverTimeout, ctx, this.GetCanonicalizer(), this.Credentials);
            retCmd.RetrieveResponseStream = true;
            retCmd.PreProcessResponse     =
                (cmd, resp, ex, ctx) =>
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);

            retCmd.PostProcessResponseAsync = (cmd, resp, ctx, ct) => BlobHttpResponseParsers.ReadServicePropertiesAsync(cmd.ResponseStream, ct);

            requestOptions.ApplyToStorageCommand(retCmd);
            return(retCmd);
        }
        /// <summary>
        /// Implements the FetchAttributes method. The attributes are updated immediately.
        /// </summary>
        /// <param name="blobUri">The URI of the blob.</param>
        /// <param name="accessCondition">An <see cref="AccessCondition"/> object that represents the access conditions for the blob. If <c>null</c>, no condition is used.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies additional options for the request.</param>
        /// <returns>A <see cref="RESTCommand"/> that fetches the attributes.</returns>
        private RESTCommand <ICloudBlob> GetBlobReferenceImpl(StorageUri blobUri, AccessCondition accessCondition, BlobRequestOptions options)
        {
            // If the blob Uri contains SAS credentials, we need to use those
            // credentials instead of this service client's stored credentials.
            StorageCredentials parsedCredentials;
            DateTimeOffset?    parsedSnapshot;

            blobUri = NavigationHelper.ParseBlobQueryAndVerify(blobUri, out parsedCredentials, out parsedSnapshot);
            CloudBlobClient client = parsedCredentials != null ? new CloudBlobClient(this.StorageUri, parsedCredentials) : this;

            RESTCommand <ICloudBlob> getCmd = new RESTCommand <ICloudBlob>(client.Credentials, blobUri, this.HttpClient);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode = CommandLocationMode.PrimaryOrSecondary;
            getCmd.BuildRequest        = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.GetProperties(uri, serverTimeout,
                                                                                                                                     parsedSnapshot, accessCondition, cnt, ctx, client.GetCanonicalizer(), client.Credentials, options);
            getCmd.PreProcessResponse = (cmd, resp, ex, ctx) =>
            {
                HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
                BlobAttributes attributes = new BlobAttributes()
                {
                    StorageUri   = blobUri,
                    SnapshotTime = parsedSnapshot,
                };

                CloudBlob.UpdateAfterFetchAttributes(attributes, resp);

                switch (attributes.Properties.BlobType)
                {
                case BlobType.BlockBlob:
                    return(new CloudBlockBlob(attributes, client));

                case BlobType.PageBlob:
                    return(new CloudPageBlob(attributes, client));

                case BlobType.AppendBlob:
                    return(new CloudAppendBlob(attributes, client));

                default:
                    throw new InvalidOperationException();
                }
            };

            return(getCmd);
        }
        /// <summary>
        /// Core implementation for the ListContainers method.
        /// </summary>
        /// <param name="prefix">The container prefix.</param>
        /// <param name="detailsIncluded">The details included.</param>
        /// <param name="currentToken">The continuation token.</param>
        /// <param name="maxResults">A non-negative integer value that indicates the maximum number of results to be returned at a time, up to the
        /// per-operation limit of 5000. If this value is <c>null</c>, the maximum possible number of results will be returned, up to 5000.</param>
        /// <param name="options">A <see cref="BlobRequestOptions"/> object that specifies execution options, such as retry policy and timeout settings, for the operation.</param>
        /// <returns>A <see cref="TaskSequence"/> that lists the containers.</returns>
        private RESTCommand <ResultSegment <CloudBlobContainer> > ListContainersImpl(string prefix, ContainerListingDetails detailsIncluded, BlobContinuationToken currentToken, int?maxResults, BlobRequestOptions options)
        {
            ListingContext listingContext = new ListingContext(prefix, maxResults)
            {
                Marker = currentToken != null ? currentToken.NextMarker : null
            };

            RESTCommand <ResultSegment <CloudBlobContainer> > getCmd = new RESTCommand <ResultSegment <CloudBlobContainer> >(this.Credentials, this.StorageUri, this.HttpClient);

            options.ApplyToStorageCommand(getCmd);
            getCmd.CommandLocationMode      = CommonUtility.GetListingLocationMode(currentToken);
            getCmd.RetrieveResponseStream   = true;
            getCmd.BuildRequest             = (cmd, uri, builder, cnt, serverTimeout, ctx) => ContainerHttpRequestMessageFactory.List(uri, serverTimeout, listingContext, detailsIncluded, cnt, ctx, this.GetCanonicalizer(), this.Credentials);
            getCmd.PreProcessResponse       = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex);
            getCmd.PostProcessResponseAsync = async(cmd, resp, ctx, ct) =>
            {
                ListContainersResponse listContainersResponse = await ListContainersResponse.ParseAsync(cmd.ResponseStream, ct).ConfigureAwait(false);

                List <CloudBlobContainer> containersList    = listContainersResponse.Containers.Select(item => new CloudBlobContainer(item.Properties, item.Metadata, item.Name, this)).ToList();
                BlobContinuationToken     continuationToken = null;
                if (listContainersResponse.NextMarker != null)
                {
                    continuationToken = new BlobContinuationToken()
                    {
                        NextMarker     = listContainersResponse.NextMarker,
                        TargetLocation = cmd.CurrentResult.TargetLocation,
                    };
                }

                return(new ResultSegment <CloudBlobContainer>(containersList)
                {
                    ContinuationToken = continuationToken,
                });
            };

            return(getCmd);
        }