private static async Task <IListBlobEntry> ParseBlobEntryAsync(XmlReader reader, Uri baseUri, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            BlobAttributes blob = new BlobAttributes();
            string         name = null;

            // copy blob attribute strings
            string copyId                      = null;
            string copyStatus                  = null;
            string copyCompletionTime          = null;
            string copyProgress                = null;
            string copySource                  = null;
            string copyStatusDescription       = null;
            string copyDestinationSnapshotTime = null;

            string         blobTierString           = null;
            bool?          blobTierInferred         = null;
            string         rehydrationStatusString  = null;
            DateTimeOffset?blobTierLastModifiedTime = null;

            await reader.ReadStartElementAsync().ConfigureAwait(false);

            while (await reader.IsStartElementAsync().ConfigureAwait(false))
            {
                token.ThrowIfCancellationRequested();

                if (reader.IsEmptyElement)
                {
                    await reader.SkipAsync().ConfigureAwait(false);
                }
                else
                {
                    switch (reader.Name)
                    {
                    case Constants.NameElement:
                        name = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                        break;

                    case Constants.SnapshotElement:
                        blob.SnapshotTime = (await reader.ReadElementContentAsStringAsync().ConfigureAwait(false)).ToUTCTime();
                        break;

                    case Constants.DeletedElement:
                        blob.IsDeleted = BlobHttpResponseParsers.GetDeletionStatus(await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                        break;

                    case Constants.PropertiesElement:
                        await reader.ReadStartElementAsync().ConfigureAwait(false);

                        while (await reader.IsStartElementAsync().ConfigureAwait(false))
                        {
                            token.ThrowIfCancellationRequested();

                            if (reader.IsEmptyElement)
                            {
                                await reader.SkipAsync().ConfigureAwait(false);
                            }
                            else
                            {
                                switch (reader.Name)
                                {
                                case Constants.CreationTimeElement:
                                    blob.Properties.Created = (await reader.ReadElementContentAsStringAsync().ConfigureAwait(false)).ToUTCTime();
                                    break;

                                case Constants.LastModifiedElement:
                                    blob.Properties.LastModified = (await reader.ReadElementContentAsStringAsync().ConfigureAwait(false)).ToUTCTime();
                                    break;

                                case Constants.EtagElement:
                                    blob.Properties.ETag = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                                    break;

                                case Constants.ContentLengthElement:
                                    blob.Properties.Length = await reader.ReadElementContentAsInt64Async().ConfigureAwait(false);

                                    break;

                                case Constants.CacheControlElement:
                                    blob.Properties.CacheControl = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.ContentTypeElement:
                                    blob.Properties.ContentType = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.HeaderConstants.ContentDispositionResponseHeader:
                                    blob.Properties.ContentDisposition = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.ContentEncodingElement:
                                    blob.Properties.ContentEncoding = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.ContentLanguageElement:
                                    blob.Properties.ContentLanguage = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.ContentMD5Element:
                                    blob.Properties.ContentMD5 = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.BlobTypeElement:
                                    string blobTypeString = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    switch (blobTypeString)
                                    {
                                    case Constants.BlockBlobValue:
                                        blob.Properties.BlobType = BlobType.BlockBlob;
                                        break;

                                    case Constants.PageBlobValue:
                                        blob.Properties.BlobType = BlobType.PageBlob;
                                        break;

                                    case Constants.AppendBlobValue:
                                        blob.Properties.BlobType = BlobType.AppendBlob;
                                        break;
                                    }

                                    break;

                                case Constants.LeaseStatusElement:
                                    blob.Properties.LeaseStatus = BlobHttpResponseParsers.GetLeaseStatus(await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                                    break;

                                case Constants.LeaseStateElement:
                                    blob.Properties.LeaseState = BlobHttpResponseParsers.GetLeaseState(await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                                    break;

                                case Constants.LeaseDurationElement:
                                    blob.Properties.LeaseDuration = BlobHttpResponseParsers.GetLeaseDuration(await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                                    break;

                                case Constants.CopyIdElement:
                                    copyId = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.CopyCompletionTimeElement:
                                    copyCompletionTime = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.CopyStatusElement:
                                    copyStatus = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.CopyProgressElement:
                                    copyProgress = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.CopySourceElement:
                                    copySource = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.CopyStatusDescriptionElement:
                                    copyStatusDescription = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.ServerEncryptionElement:
                                    blob.Properties.IsServerEncrypted = BlobHttpResponseParsers.GetServerEncrypted(await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                                    break;

                                case Constants.IncrementalCopy:
                                    blob.Properties.IsIncrementalCopy = BlobHttpResponseParsers.GetIncrementalCopyStatus(await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                                    break;

                                case Constants.CopyDestinationSnapshotElement:
                                    copyDestinationSnapshotTime = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.AccessTierElement:
                                    blobTierString = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.ArchiveStatusElement:
                                    rehydrationStatusString = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    break;

                                case Constants.AccessTierInferred:
                                    blobTierInferred = await reader.ReadElementContentAsBooleanAsync().ConfigureAwait(false);

                                    break;

                                case Constants.AccessTierChangeTimeElement:
                                    string t = await reader.ReadElementContentAsStringAsync().ConfigureAwait(false);

                                    blobTierLastModifiedTime = DateTimeOffset.Parse(t, CultureInfo.InvariantCulture);
                                    break;

                                case Constants.DeletedTimeElement:
                                    blob.Properties.DeletedTime = (await reader.ReadElementContentAsStringAsync().ConfigureAwait(false)).ToUTCTime();
                                    break;

                                case Constants.RemainingRetentionDaysElement:
                                    blob.Properties.RemainingDaysBeforePermanentDelete = int.Parse(await reader.ReadElementContentAsStringAsync().ConfigureAwait(false));
                                    break;

                                default:
                                    await reader.SkipAsync().ConfigureAwait(false);

                                    break;
                                }
                            }
                        }

                        await reader.ReadEndElementAsync().ConfigureAwait(false);

                        break;

                    case Constants.MetadataElement:
                        blob.Metadata = await Response.ParseMetadataAsync(reader).ConfigureAwait(false);

                        break;

                    default:
                        await reader.SkipAsync().ConfigureAwait(false);

                        break;
                    }
                }
            }

            await reader.ReadEndElementAsync().ConfigureAwait(false);

            Uri uri = NavigationHelper.AppendPathToSingleUri(baseUri, name);

            if (blob.SnapshotTime.HasValue)
            {
                UriQueryBuilder builder = new UriQueryBuilder();
                builder.Add("snapshot", Request.ConvertDateTimeToSnapshotString(blob.SnapshotTime.Value));
                uri = builder.AddToUri(uri);
            }

            blob.StorageUri = new StorageUri(uri);

            if (!string.IsNullOrEmpty(copyStatus))
            {
                blob.CopyState = BlobHttpResponseParsers.GetCopyAttributes(
                    copyStatus,
                    copyId,
                    copySource,
                    copyProgress,
                    copyCompletionTime,
                    copyStatusDescription,
                    copyDestinationSnapshotTime);
            }

            if (!string.IsNullOrEmpty(blobTierString))
            {
                StandardBlobTier?   standardBlobTier;
                PremiumPageBlobTier?premiumPageBlobTier;
                BlobHttpResponseParsers.GetBlobTier(blob.Properties.BlobType, blobTierString, out standardBlobTier, out premiumPageBlobTier);
                blob.Properties.StandardBlobTier    = standardBlobTier;
                blob.Properties.PremiumPageBlobTier = premiumPageBlobTier;
            }

            blob.Properties.RehydrationStatus        = BlobHttpResponseParsers.GetRehydrationStatus(rehydrationStatusString);
            blob.Properties.BlobTierLastModifiedTime = blobTierLastModifiedTime;
            blob.Properties.BlobTierInferred         = blobTierInferred;

            return(new ListBlobEntry(name, blob));
        }
        private IListBlobEntry ParseBlobEntry(Uri baseUri)
        {
            BlobAttributes blob = new BlobAttributes();
            string         name = null;

            // copy blob attribute strings
            string copyId                      = null;
            string copyStatus                  = null;
            string copyCompletionTime          = null;
            string copyProgress                = null;
            string copySource                  = null;
            string copyStatusDescription       = null;
            string copyDestinationSnapshotTime = null;

            string blobTierString          = null;
            string rehydrationStatusString = null;

            this.reader.ReadStartElement();
            while (this.reader.IsStartElement())
            {
                if (this.reader.IsEmptyElement)
                {
                    this.reader.Skip();
                }
                else
                {
                    switch (this.reader.Name)
                    {
                    case Constants.NameElement:
                        name = reader.ReadElementContentAsString();
                        break;

                    case Constants.SnapshotElement:
                        blob.SnapshotTime = reader.ReadElementContentAsString().ToUTCTime();
                        break;

                    case Constants.PropertiesElement:
                        this.reader.ReadStartElement();
                        while (this.reader.IsStartElement())
                        {
                            if (this.reader.IsEmptyElement)
                            {
                                this.reader.Skip();
                            }
                            else
                            {
                                switch (this.reader.Name)
                                {
                                case Constants.LastModifiedElement:
                                    blob.Properties.LastModified = reader.ReadElementContentAsString().ToUTCTime();
                                    break;

                                case Constants.EtagElement:
                                    blob.Properties.ETag = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", reader.ReadElementContentAsString());
                                    break;

                                case Constants.ContentLengthElement:
                                    blob.Properties.Length = reader.ReadElementContentAsLong();
                                    break;

                                case Constants.CacheControlElement:
                                    blob.Properties.CacheControl = reader.ReadElementContentAsString();
                                    break;

                                case Constants.ContentTypeElement:
                                    blob.Properties.ContentType = reader.ReadElementContentAsString();
                                    break;

                                case Constants.HeaderConstants.ContentDispositionResponseHeader:
                                    blob.Properties.ContentDisposition = reader.ReadElementContentAsString();
                                    break;

                                case Constants.ContentEncodingElement:
                                    blob.Properties.ContentEncoding = reader.ReadElementContentAsString();
                                    break;

                                case Constants.ContentLanguageElement:
                                    blob.Properties.ContentLanguage = reader.ReadElementContentAsString();
                                    break;

                                case Constants.ContentMD5Element:
                                    blob.Properties.ContentMD5 = reader.ReadElementContentAsString();
                                    break;

                                case Constants.BlobTypeElement:
                                    string blobTypeString = reader.ReadElementContentAsString();
                                    switch (blobTypeString)
                                    {
                                    case Constants.BlockBlobValue:
                                        blob.Properties.BlobType = BlobType.BlockBlob;
                                        break;

                                    case Constants.PageBlobValue:
                                        blob.Properties.BlobType = BlobType.PageBlob;
                                        break;

                                    case Constants.AppendBlobValue:
                                        blob.Properties.BlobType = BlobType.AppendBlob;
                                        break;
                                    }

                                    break;

                                case Constants.LeaseStatusElement:
                                    blob.Properties.LeaseStatus = BlobHttpResponseParsers.GetLeaseStatus(reader.ReadElementContentAsString());
                                    break;

                                case Constants.LeaseStateElement:
                                    blob.Properties.LeaseState = BlobHttpResponseParsers.GetLeaseState(reader.ReadElementContentAsString());
                                    break;

                                case Constants.LeaseDurationElement:
                                    blob.Properties.LeaseDuration = BlobHttpResponseParsers.GetLeaseDuration(reader.ReadElementContentAsString());
                                    break;

                                case Constants.CopyIdElement:
                                    copyId = reader.ReadElementContentAsString();
                                    break;

                                case Constants.CopyCompletionTimeElement:
                                    copyCompletionTime = reader.ReadElementContentAsString();
                                    break;

                                case Constants.CopyStatusElement:
                                    copyStatus = reader.ReadElementContentAsString();
                                    break;

                                case Constants.CopyProgressElement:
                                    copyProgress = reader.ReadElementContentAsString();
                                    break;

                                case Constants.CopySourceElement:
                                    copySource = reader.ReadElementContentAsString();
                                    break;

                                case Constants.CopyStatusDescriptionElement:
                                    copyStatusDescription = reader.ReadElementContentAsString();
                                    break;

                                case Constants.ServerEncryptionElement:
                                    blob.Properties.IsServerEncrypted = BlobHttpResponseParsers.GetServerEncrypted(reader.ReadElementContentAsString());
                                    break;

                                case Constants.IncrementalCopy:
                                    blob.Properties.IsIncrementalCopy = BlobHttpResponseParsers.GetIncrementalCopyStatus(reader.ReadElementContentAsString());
                                    break;

                                case Constants.CopyDestinationSnapshotElement:
                                    copyDestinationSnapshotTime = reader.ReadElementContentAsString();
                                    break;

                                case Constants.AccessTierElement:
                                    blobTierString = reader.ReadElementContentAsString();
                                    break;

                                case Constants.ArchiveStatusElement:
                                    rehydrationStatusString = reader.ReadElementContentAsString();
                                    break;

                                default:
                                    reader.Skip();
                                    break;
                                }
                            }
                        }

                        this.reader.ReadEndElement();
                        break;

                    case Constants.MetadataElement:
                        blob.Metadata = Response.ParseMetadata(this.reader);
                        break;

                    default:
                        this.reader.Skip();
                        break;
                    }
                }
            }

            this.reader.ReadEndElement();

            Uri uri = NavigationHelper.AppendPathToSingleUri(baseUri, name);

            if (blob.SnapshotTime.HasValue)
            {
                UriQueryBuilder builder = new UriQueryBuilder();
                builder.Add("snapshot", Request.ConvertDateTimeToSnapshotString(blob.SnapshotTime.Value));
                uri = builder.AddToUri(uri);
            }

            blob.StorageUri = new StorageUri(uri);

            if (!string.IsNullOrEmpty(copyStatus))
            {
                blob.CopyState = BlobHttpResponseParsers.GetCopyAttributes(
                    copyStatus,
                    copyId,
                    copySource,
                    copyProgress,
                    copyCompletionTime,
                    copyStatusDescription,
                    copyDestinationSnapshotTime);
            }

            if (!string.IsNullOrEmpty(blobTierString))
            {
                StandardBlobTier?   standardBlobTier;
                PremiumPageBlobTier?premiumPageBlobTier;
                BlobHttpResponseParsers.GetBlobTier(blob.Properties.BlobType, blobTierString, out standardBlobTier, out premiumPageBlobTier);
                blob.Properties.StandardBlobTier    = standardBlobTier;
                blob.Properties.PremiumPageBlobTier = premiumPageBlobTier;
                blob.Properties.BlobTierInferred    = false;
            }

            blob.Properties.RehydrationStatus = BlobHttpResponseParsers.GetRehydrationStatus(rehydrationStatusString);

            return(new ListBlobEntry(name, blob));
        }