
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//
// Code generated by Microsoft (R) AutoRest C++ Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
#include <azure/storage/queues/rest_client.hpp>

#include <string>
#include <unordered_map>
#include <vector>

#include <azure/core/context.hpp>
#include <azure/core/datetime.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/http/http_status_code.hpp>
#include <azure/core/internal/http/pipeline.hpp>
#include <azure/core/io/body_stream.hpp>
#include <azure/core/response.hpp>
#include <azure/core/url.hpp>
#include <azure/storage/common/crypt.hpp>
#include <azure/storage/common/internal/xml_wrapper.hpp>
#include <azure/storage/common/storage_exception.hpp>

namespace {
std::string ListQueuesIncludeFlagsToString(
    const Azure::Storage::Queues::Models::ListQueuesIncludeFlags& val)
{
  const Azure::Storage::Queues::Models::ListQueuesIncludeFlags valueList[] = {
      Azure::Storage::Queues::Models::ListQueuesIncludeFlags::Metadata,
  };
  const char* stringList[] = {
      "metadata",
  };
  std::string ret;
  for (size_t i = 0; i < 1; ++i)
  {
    if ((val & valueList[i]) == valueList[i])
    {
      if (!ret.empty())
      {
        ret += ",";
      }
      ret += stringList[i];
    }
  }
  return ret;
}
} // namespace
namespace Azure { namespace Storage { namespace Queues {
  namespace Models {
    const GeoReplicationStatus GeoReplicationStatus::Live("live");
    const GeoReplicationStatus GeoReplicationStatus::Bootstrap("bootstrap");
    const GeoReplicationStatus GeoReplicationStatus::Unavailable("unavailable");
  } // namespace Models
  namespace _detail {
    Response<Models::SetServicePropertiesResult> ServiceClient::SetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetServicePropertiesOptions& options,
        const Core::Context& context)
    {
      std::string xmlBody;
      {
        _internal::XmlWriter writer;
        writer.Write(
            _internal::XmlNode{_internal::XmlNodeType::StartTag, "StorageServiceProperties"});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Logging"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Version",
            options.QueueServiceProperties.Logging.Version});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Delete",
            options.QueueServiceProperties.Logging.Delete ? "true" : "false"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Read",
            options.QueueServiceProperties.Logging.Read ? "true" : "false"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Write",
            options.QueueServiceProperties.Logging.Write ? "true" : "false"});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.QueueServiceProperties.Logging.RetentionPolicy.IsEnabled ? "true" : "false"});
        if (options.QueueServiceProperties.Logging.RetentionPolicy.Days.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "Days",
              std::to_string(options.QueueServiceProperties.Logging.RetentionPolicy.Days.Value())});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "HourMetrics"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Version",
            options.QueueServiceProperties.HourMetrics.Version});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.QueueServiceProperties.HourMetrics.IsEnabled ? "true" : "false"});
        if (options.QueueServiceProperties.HourMetrics.IncludeApis.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "IncludeAPIs",
              options.QueueServiceProperties.HourMetrics.IncludeApis.Value() ? "true" : "false"});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.QueueServiceProperties.HourMetrics.RetentionPolicy.IsEnabled ? "true"
                                                                                 : "false"});
        if (options.QueueServiceProperties.HourMetrics.RetentionPolicy.Days.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "Days",
              std::to_string(
                  options.QueueServiceProperties.HourMetrics.RetentionPolicy.Days.Value())});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "MinuteMetrics"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Version",
            options.QueueServiceProperties.MinuteMetrics.Version});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.QueueServiceProperties.MinuteMetrics.IsEnabled ? "true" : "false"});
        if (options.QueueServiceProperties.MinuteMetrics.IncludeApis.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "IncludeAPIs",
              options.QueueServiceProperties.MinuteMetrics.IncludeApis.Value() ? "true" : "false"});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.QueueServiceProperties.MinuteMetrics.RetentionPolicy.IsEnabled ? "true"
                                                                                   : "false"});
        if (options.QueueServiceProperties.MinuteMetrics.RetentionPolicy.Days.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "Days",
              std::to_string(
                  options.QueueServiceProperties.MinuteMetrics.RetentionPolicy.Days.Value())});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Cors"});
        for (const auto& i1 : options.QueueServiceProperties.Cors)
        {
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "CorsRule"});
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag, "AllowedOrigins", i1.AllowedOrigins});
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag, "AllowedMethods", i1.AllowedMethods});
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag, "AllowedHeaders", i1.AllowedHeaders});
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag, "ExposedHeaders", i1.ExposedHeaders});
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "MaxAgeInSeconds",
              std::to_string(i1.MaxAgeInSeconds)});
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::End});
        xmlBody = writer.GetDocument();
      }
      Core::IO::MemoryBodyStream requestBody(
          reinterpret_cast<const uint8_t*>(xmlBody.data()), xmlBody.length());
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody);
      request.SetHeader("Content-Type", "application/xml; charset=UTF-8");
      request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
      request.GetUrl().AppendQueryParameter("restype", "service");
      request.GetUrl().AppendQueryParameter("comp", "properties");
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetServicePropertiesResult response;
      return Response<Models::SetServicePropertiesResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::QueueServiceProperties> ServiceClient::GetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetServicePropertiesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "service");
      request.GetUrl().AppendQueryParameter("comp", "properties");
      request.SetHeader("x-ms-version", "2018-03-28");
      (void)options;
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::QueueServiceProperties response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kStorageServiceProperties,
          kLogging,
          kVersion,
          kDelete,
          kRead,
          kWrite,
          kRetentionPolicy,
          kEnabled,
          kDays,
          kHourMetrics,
          kIncludeAPIs,
          kMinuteMetrics,
          kCors,
          kCorsRule,
          kAllowedOrigins,
          kAllowedMethods,
          kAllowedHeaders,
          kExposedHeaders,
          kMaxAgeInSeconds,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"StorageServiceProperties", XmlTagEnum::kStorageServiceProperties},
            {"Logging", XmlTagEnum::kLogging},
            {"Version", XmlTagEnum::kVersion},
            {"Delete", XmlTagEnum::kDelete},
            {"Read", XmlTagEnum::kRead},
            {"Write", XmlTagEnum::kWrite},
            {"RetentionPolicy", XmlTagEnum::kRetentionPolicy},
            {"Enabled", XmlTagEnum::kEnabled},
            {"Days", XmlTagEnum::kDays},
            {"HourMetrics", XmlTagEnum::kHourMetrics},
            {"IncludeAPIs", XmlTagEnum::kIncludeAPIs},
            {"MinuteMetrics", XmlTagEnum::kMinuteMetrics},
            {"Cors", XmlTagEnum::kCors},
            {"CorsRule", XmlTagEnum::kCorsRule},
            {"AllowedOrigins", XmlTagEnum::kAllowedOrigins},
            {"AllowedMethods", XmlTagEnum::kAllowedMethods},
            {"AllowedHeaders", XmlTagEnum::kAllowedHeaders},
            {"ExposedHeaders", XmlTagEnum::kExposedHeaders},
            {"MaxAgeInSeconds", XmlTagEnum::kMaxAgeInSeconds},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::CorsRule vectorElement1;
        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kVersion)
            {
              response.Logging.Version = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kDelete)
            {
              response.Logging.Delete = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kRead)
            {
              response.Logging.Read = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kWrite)
            {
              response.Logging.Write = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kRetentionPolicy
                && xmlPath[3] == XmlTagEnum::kEnabled)
            {
              response.Logging.RetentionPolicy.IsEnabled = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kLogging && xmlPath[2] == XmlTagEnum::kRetentionPolicy
                && xmlPath[3] == XmlTagEnum::kDays)
            {
              response.Logging.RetentionPolicy.Days = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kHourMetrics && xmlPath[2] == XmlTagEnum::kVersion)
            {
              response.HourMetrics.Version = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kHourMetrics && xmlPath[2] == XmlTagEnum::kEnabled)
            {
              response.HourMetrics.IsEnabled = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kHourMetrics && xmlPath[2] == XmlTagEnum::kIncludeAPIs)
            {
              response.HourMetrics.IncludeApis = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kHourMetrics
                && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kEnabled)
            {
              response.HourMetrics.RetentionPolicy.IsEnabled = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kHourMetrics
                && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kDays)
            {
              response.HourMetrics.RetentionPolicy.Days = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kMinuteMetrics && xmlPath[2] == XmlTagEnum::kVersion)
            {
              response.MinuteMetrics.Version = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kMinuteMetrics && xmlPath[2] == XmlTagEnum::kEnabled)
            {
              response.MinuteMetrics.IsEnabled = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kMinuteMetrics
                && xmlPath[2] == XmlTagEnum::kIncludeAPIs)
            {
              response.MinuteMetrics.IncludeApis = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kMinuteMetrics
                && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kEnabled)
            {
              response.MinuteMetrics.RetentionPolicy.IsEnabled = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kMinuteMetrics
                && xmlPath[2] == XmlTagEnum::kRetentionPolicy && xmlPath[3] == XmlTagEnum::kDays)
            {
              response.MinuteMetrics.RetentionPolicy.Days = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule
                && xmlPath[3] == XmlTagEnum::kAllowedOrigins)
            {
              vectorElement1.AllowedOrigins = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule
                && xmlPath[3] == XmlTagEnum::kAllowedMethods)
            {
              vectorElement1.AllowedMethods = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule
                && xmlPath[3] == XmlTagEnum::kAllowedHeaders)
            {
              vectorElement1.AllowedHeaders = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule
                && xmlPath[3] == XmlTagEnum::kExposedHeaders)
            {
              vectorElement1.ExposedHeaders = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule
                && xmlPath[3] == XmlTagEnum::kMaxAgeInSeconds)
            {
              vectorElement1.MaxAgeInSeconds = std::stoi(node.Value);
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kCors && xmlPath[2] == XmlTagEnum::kCorsRule)
            {
              response.Cors.push_back(std::move(vectorElement1));
              vectorElement1 = Models::CorsRule();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::QueueServiceProperties>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::ServiceStatistics> ServiceClient::GetStatistics(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetServiceStatisticsOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "service");
      request.GetUrl().AppendQueryParameter("comp", "stats");
      request.SetHeader("x-ms-version", "2018-03-28");
      (void)options;
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::ServiceStatistics response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kStorageServiceStats,
          kGeoReplication,
          kStatus,
          kLastSyncTime,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"StorageServiceStats", XmlTagEnum::kStorageServiceStats},
            {"GeoReplication", XmlTagEnum::kGeoReplication},
            {"Status", XmlTagEnum::kStatus},
            {"LastSyncTime", XmlTagEnum::kLastSyncTime},
        };
        std::vector<XmlTagEnum> xmlPath;

        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceStats
                && xmlPath[1] == XmlTagEnum::kGeoReplication && xmlPath[2] == XmlTagEnum::kStatus)
            {
              response.GeoReplication.Status = Models::GeoReplicationStatus(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kStorageServiceStats
                && xmlPath[1] == XmlTagEnum::kGeoReplication
                && xmlPath[2] == XmlTagEnum::kLastSyncTime)
            {
              response.GeoReplication.LastSyncedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {

            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::ServiceStatistics>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ListQueuesResult> ServiceClient::ListQueuesSegment(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ListServiceQueuesSegmentOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("comp", "list");
      if (options.Prefix.HasValue() && !options.Prefix.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value()));
      }
      if (options.Marker.HasValue() && !options.Marker.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value()));
      }
      if (options.MaxResults.HasValue())
      {
        request.GetUrl().AppendQueryParameter(
            "maxresults", std::to_string(options.MaxResults.Value()));
      }
      if (options.Include.HasValue()
          && !ListQueuesIncludeFlagsToString(options.Include.Value()).empty())
      {
        request.GetUrl().AppendQueryParameter(
            "include",
            _internal::UrlEncodeQueryParameter(
                ListQueuesIncludeFlagsToString(options.Include.Value())));
      }
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ListQueuesResult response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kEnumerationResults,
          kPrefix,
          kQueues,
          kQueue,
          kName,
          kMetadata,
          kNextMarker,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"EnumerationResults", XmlTagEnum::kEnumerationResults},
            {"Prefix", XmlTagEnum::kPrefix},
            {"Queues", XmlTagEnum::kQueues},
            {"Queue", XmlTagEnum::kQueue},
            {"Name", XmlTagEnum::kName},
            {"Metadata", XmlTagEnum::kMetadata},
            {"NextMarker", XmlTagEnum::kNextMarker},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::QueueItem vectorElement1;
        std::string mapKey2;
        std::string mapValue3;
        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
            if (xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue
                && xmlPath[3] == XmlTagEnum::kMetadata)
            {
              mapKey2 = node.Name;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kPrefix)
            {
              response.Prefix = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue
                && xmlPath[3] == XmlTagEnum::kName)
            {
              vectorElement1.Name = node.Value;
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue
                && xmlPath[3] == XmlTagEnum::kMetadata)
            {
              mapValue3 = node.Value;
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kNextMarker)
            {
              response.ContinuationToken = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
            if (xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && node.Name == "ServiceEndpoint")
            {
              response.ServiceEndpoint = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue
                && xmlPath[3] == XmlTagEnum::kMetadata)
            {
              vectorElement1.Metadata[std::move(mapKey2)] = std::move(mapValue3);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kQueues && xmlPath[2] == XmlTagEnum::kQueue)
            {
              response.Items.push_back(std::move(vectorElement1));
              vectorElement1 = Models::QueueItem();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::_detail::ListQueuesResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::CreateQueueResult> QueueClient::Create(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const CreateQueueOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      for (const auto& p : options.Metadata)
      {
        request.SetHeader("x-ms-meta-" + p.first, p.second);
      }
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (!(httpStatusCode == Core::Http::HttpStatusCode::Created
            || httpStatusCode == Core::Http::HttpStatusCode::NoContent))
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::CreateQueueResult response;
      return Response<Models::CreateQueueResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::DeleteQueueResult> QueueClient::Delete(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const DeleteQueueOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
      request.SetHeader("x-ms-version", "2018-03-28");
      (void)options;
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::DeleteQueueResult response;
      return Response<Models::DeleteQueueResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::QueueProperties> QueueClient::GetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetQueuePropertiesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("comp", "metadata");
      request.SetHeader("x-ms-version", "2018-03-28");
      (void)options;
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::QueueProperties response;
      for (auto i = pRawResponse->GetHeaders().lower_bound("x-ms-meta-");
           i != pRawResponse->GetHeaders().end() && i->first.substr(0, 10) == "x-ms-meta-";
           ++i)
      {
        response.Metadata.emplace(i->first.substr(10), i->second);
      }
      response.ApproximateMessageCount
          = std::stoi(pRawResponse->GetHeaders().at("x-ms-approximate-messages-count"));
      return Response<Models::QueueProperties>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetQueueMetadataResult> QueueClient::SetMetadata(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetQueueMetadataOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "metadata");
      for (const auto& p : options.Metadata)
      {
        request.SetHeader("x-ms-meta-" + p.first, p.second);
      }
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetQueueMetadataResult response;
      return Response<Models::SetQueueMetadataResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::QueueAccessPolicy> QueueClient::GetAccessPolicy(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetQueueAccessPolicyOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("comp", "acl");
      request.SetHeader("x-ms-version", "2018-03-28");
      (void)options;
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::QueueAccessPolicy response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kSignedIdentifiers,
          kSignedIdentifier,
          kId,
          kAccessPolicy,
          kStart,
          kExpiry,
          kPermission,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"SignedIdentifiers", XmlTagEnum::kSignedIdentifiers},
            {"SignedIdentifier", XmlTagEnum::kSignedIdentifier},
            {"Id", XmlTagEnum::kId},
            {"AccessPolicy", XmlTagEnum::kAccessPolicy},
            {"Start", XmlTagEnum::kStart},
            {"Expiry", XmlTagEnum::kExpiry},
            {"Permission", XmlTagEnum::kPermission},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::SignedIdentifier vectorElement1;
        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers
                && xmlPath[1] == XmlTagEnum::kSignedIdentifier && xmlPath[2] == XmlTagEnum::kId)
            {
              vectorElement1.Id = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers
                && xmlPath[1] == XmlTagEnum::kSignedIdentifier
                && xmlPath[2] == XmlTagEnum::kAccessPolicy && xmlPath[3] == XmlTagEnum::kStart)
            {
              vectorElement1.StartsOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339);
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers
                && xmlPath[1] == XmlTagEnum::kSignedIdentifier
                && xmlPath[2] == XmlTagEnum::kAccessPolicy && xmlPath[3] == XmlTagEnum::kExpiry)
            {
              vectorElement1.ExpiresOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc3339);
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers
                && xmlPath[1] == XmlTagEnum::kSignedIdentifier
                && xmlPath[2] == XmlTagEnum::kAccessPolicy && xmlPath[3] == XmlTagEnum::kPermission)
            {
              vectorElement1.Permissions = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kSignedIdentifiers
                && xmlPath[1] == XmlTagEnum::kSignedIdentifier)
            {
              response.SignedIdentifiers.push_back(std::move(vectorElement1));
              vectorElement1 = Models::SignedIdentifier();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::QueueAccessPolicy>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetQueueAccessPolicyResult> QueueClient::SetAccessPolicy(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetQueueAccessPolicyOptions& options,
        const Core::Context& context)
    {
      std::string xmlBody;
      {
        _internal::XmlWriter writer;
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "SignedIdentifiers"});
        for (const auto& i1 : options.QueueAcl)
        {
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "SignedIdentifier"});
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Id", i1.Id});
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "AccessPolicy"});
          if (i1.StartsOn.HasValue())
          {
            writer.Write(_internal::XmlNode{
                _internal::XmlNodeType::StartTag,
                "Start",
                i1.StartsOn.Value().ToString(
                    Azure::DateTime::DateFormat::Rfc3339,
                    Azure::DateTime::TimeFractionFormat::AllDigits)});
          }
          if (i1.ExpiresOn.HasValue())
          {
            writer.Write(_internal::XmlNode{
                _internal::XmlNodeType::StartTag,
                "Expiry",
                i1.ExpiresOn.Value().ToString(
                    Azure::DateTime::DateFormat::Rfc3339,
                    Azure::DateTime::TimeFractionFormat::AllDigits)});
          }
          writer.Write(
              _internal::XmlNode{_internal::XmlNodeType::StartTag, "Permission", i1.Permissions});
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::End});
        xmlBody = writer.GetDocument();
      }
      Core::IO::MemoryBodyStream requestBody(
          reinterpret_cast<const uint8_t*>(xmlBody.data()), xmlBody.length());
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody);
      request.SetHeader("Content-Type", "application/xml; charset=UTF-8");
      request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
      request.GetUrl().AppendQueryParameter("comp", "acl");
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetQueueAccessPolicyResult response;
      return Response<Models::SetQueueAccessPolicyResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::ReceivedMessages> QueueClient::ReceiveMessages(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ReceiveQueueMessagesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      if (options.NumberOfMessages.HasValue())
      {
        request.GetUrl().AppendQueryParameter(
            "numofmessages", std::to_string(options.NumberOfMessages.Value()));
      }
      if (options.Visibilitytimeout.HasValue())
      {
        request.GetUrl().AppendQueryParameter(
            "visibilitytimeout", std::to_string(options.Visibilitytimeout.Value()));
      }
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::ReceivedMessages response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kQueueMessagesList,
          kQueueMessage,
          kMessageId,
          kInsertionTime,
          kExpirationTime,
          kPopReceipt,
          kTimeNextVisible,
          kDequeueCount,
          kMessageText,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"QueueMessagesList", XmlTagEnum::kQueueMessagesList},
            {"QueueMessage", XmlTagEnum::kQueueMessage},
            {"MessageId", XmlTagEnum::kMessageId},
            {"InsertionTime", XmlTagEnum::kInsertionTime},
            {"ExpirationTime", XmlTagEnum::kExpirationTime},
            {"PopReceipt", XmlTagEnum::kPopReceipt},
            {"TimeNextVisible", XmlTagEnum::kTimeNextVisible},
            {"DequeueCount", XmlTagEnum::kDequeueCount},
            {"MessageText", XmlTagEnum::kMessageText},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::QueueMessage vectorElement1;
        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kMessageId)
            {
              vectorElement1.MessageId = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kInsertionTime)
            {
              vectorElement1.InsertedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kExpirationTime)
            {
              vectorElement1.ExpiresOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kPopReceipt)
            {
              vectorElement1.PopReceipt = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kTimeNextVisible)
            {
              vectorElement1.NextVisibleOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kDequeueCount)
            {
              vectorElement1.DequeueCount = std::stoll(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kMessageText)
            {
              vectorElement1.MessageText = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage)
            {
              response.Messages.push_back(std::move(vectorElement1));
              vectorElement1 = Models::QueueMessage();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::ReceivedMessages>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::ClearMessagesResult> QueueClient::ClearMessages(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ClearQueueMessagesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
      request.SetHeader("x-ms-version", "2018-03-28");
      (void)options;
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::ClearMessagesResult response;
      return Response<Models::ClearMessagesResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::EnqueueMessageResult> QueueClient::EnqueueMessage(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const EnqueueQueueMessageOptions& options,
        const Core::Context& context)
    {
      std::string xmlBody;
      {
        _internal::XmlWriter writer;
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag, "MessageText", options.QueueMessage.MessageText});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::End});
        xmlBody = writer.GetDocument();
      }
      Core::IO::MemoryBodyStream requestBody(
          reinterpret_cast<const uint8_t*>(xmlBody.data()), xmlBody.length());
      auto request = Core::Http::Request(Core::Http::HttpMethod::Post, url, &requestBody);
      request.SetHeader("Content-Type", "application/xml; charset=UTF-8");
      request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
      if (options.Visibilitytimeout.HasValue())
      {
        request.GetUrl().AppendQueryParameter(
            "visibilitytimeout", std::to_string(options.Visibilitytimeout.Value()));
      }
      if (options.MessageTimeToLive.HasValue())
      {
        request.GetUrl().AppendQueryParameter(
            "messagettl", std::to_string(options.MessageTimeToLive.Value()));
      }
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::EnqueueMessageResult response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kQueueMessagesList,
          kQueueMessage,
          kMessageId,
          kInsertionTime,
          kExpirationTime,
          kPopReceipt,
          kTimeNextVisible,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"QueueMessagesList", XmlTagEnum::kQueueMessagesList},
            {"QueueMessage", XmlTagEnum::kQueueMessage},
            {"MessageId", XmlTagEnum::kMessageId},
            {"InsertionTime", XmlTagEnum::kInsertionTime},
            {"ExpirationTime", XmlTagEnum::kExpirationTime},
            {"PopReceipt", XmlTagEnum::kPopReceipt},
            {"TimeNextVisible", XmlTagEnum::kTimeNextVisible},
        };
        std::vector<XmlTagEnum> xmlPath;

        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kMessageId)
            {
              response.MessageId = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kInsertionTime)
            {
              response.InsertedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kExpirationTime)
            {
              response.ExpiresOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kPopReceipt)
            {
              response.PopReceipt = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kTimeNextVisible)
            {
              response.NextVisibleOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {

            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::EnqueueMessageResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::PeekedMessages> QueueClient::PeekMessages(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const PeekQueueMessagesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("peekonly", "true");
      if (options.NumberOfMessages.HasValue())
      {
        request.GetUrl().AppendQueryParameter(
            "numofmessages", std::to_string(options.NumberOfMessages.Value()));
      }
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::PeekedMessages response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kQueueMessagesList,
          kQueueMessage,
          kMessageId,
          kInsertionTime,
          kExpirationTime,
          kDequeueCount,
          kMessageText,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"QueueMessagesList", XmlTagEnum::kQueueMessagesList},
            {"QueueMessage", XmlTagEnum::kQueueMessage},
            {"MessageId", XmlTagEnum::kMessageId},
            {"InsertionTime", XmlTagEnum::kInsertionTime},
            {"ExpirationTime", XmlTagEnum::kExpirationTime},
            {"DequeueCount", XmlTagEnum::kDequeueCount},
            {"MessageText", XmlTagEnum::kMessageText},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::PeekedQueueMessage vectorElement1;
        while (true)
        {
          auto node = reader.Read();
          if (node.Type == _internal::XmlNodeType::End)
          {
            break;
          }
          else if (node.Type == _internal::XmlNodeType::StartTag)
          {
            auto ite = XmlTagEnumMap.find(node.Name);
            xmlPath.push_back(ite == XmlTagEnumMap.end() ? XmlTagEnum::kUnknown : ite->second);
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage && xmlPath[2] == XmlTagEnum::kMessageId)
            {
              vectorElement1.MessageId = node.Value;
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kInsertionTime)
            {
              vectorElement1.InsertedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kExpirationTime)
            {
              vectorElement1.ExpiresOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kDequeueCount)
            {
              vectorElement1.DequeueCount = std::stoll(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage
                && xmlPath[2] == XmlTagEnum::kMessageText)
            {
              vectorElement1.MessageText = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kQueueMessagesList
                && xmlPath[1] == XmlTagEnum::kQueueMessage)
            {
              response.Messages.push_back(std::move(vectorElement1));
              vectorElement1 = Models::PeekedQueueMessage();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::PeekedMessages>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::UpdateMessageResult> QueueClient::UpdateMessage(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const UpdateQueueMessageOptions& options,
        const Core::Context& context)
    {
      std::string xmlBody;
      {
        _internal::XmlWriter writer;
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "QueueMessage"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag, "MessageText", options.QueueMessage.MessageText});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::EndTag});
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::End});
        xmlBody = writer.GetDocument();
      }
      Core::IO::MemoryBodyStream requestBody(
          reinterpret_cast<const uint8_t*>(xmlBody.data()), xmlBody.length());
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody);
      request.SetHeader("Content-Type", "application/xml; charset=UTF-8");
      request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
      if (!options.PopReceipt.empty())
      {
        request.GetUrl().AppendQueryParameter(
            "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt));
      }
      request.GetUrl().AppendQueryParameter(
          "visibilitytimeout", std::to_string(options.Visibilitytimeout));
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::UpdateMessageResult response;
      response.PopReceipt = pRawResponse->GetHeaders().at("x-ms-popreceipt");
      response.NextVisibleOn = DateTime::Parse(
          pRawResponse->GetHeaders().at("x-ms-time-next-visible"),
          Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::UpdateMessageResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::DeleteMessageResult> QueueClient::DeleteMessage(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const DeleteQueueMessageOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
      if (!options.PopReceipt.empty())
      {
        request.GetUrl().AppendQueryParameter(
            "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt));
      }
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::DeleteMessageResult response;
      return Response<Models::DeleteMessageResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::UpdateMessageResult> QueueClient::UpdateMessageVisibility(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const UpdateQueueMessageVisibilityOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      if (!options.PopReceipt.empty())
      {
        request.GetUrl().AppendQueryParameter(
            "popreceipt", _internal::UrlEncodeQueryParameter(options.PopReceipt));
      }
      request.GetUrl().AppendQueryParameter(
          "visibilitytimeout", std::to_string(options.Visibilitytimeout));
      request.SetHeader("x-ms-version", "2018-03-28");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::UpdateMessageResult response;
      response.PopReceipt = pRawResponse->GetHeaders().at("x-ms-popreceipt");
      response.NextVisibleOn = DateTime::Parse(
          pRawResponse->GetHeaders().at("x-ms-time-next-visible"),
          Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::UpdateMessageResult>(std::move(response), std::move(pRawResponse));
    }
  } // namespace _detail
}}} // namespace Azure::Storage::Queues