
// 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/files/shares/rest_client.hpp>

#include <algorithm>
#include <iterator>
#include <string>
#include <unordered_map>
#include <vector>

#include <azure/core/base64.hpp>
#include <azure/core/context.hpp>
#include <azure/core/datetime.hpp>
#include <azure/core/etag.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/internal/json/json.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 ListSharesIncludeFlagsToString(
    const Azure::Storage::Files::Shares::Models::ListSharesIncludeFlags& val)
{
  const Azure::Storage::Files::Shares::Models::ListSharesIncludeFlags valueList[] = {
      Azure::Storage::Files::Shares::Models::ListSharesIncludeFlags::Snapshots,
      Azure::Storage::Files::Shares::Models::ListSharesIncludeFlags::Metadata,
      Azure::Storage::Files::Shares::Models::ListSharesIncludeFlags::Deleted,
  };
  const char* stringList[] = {
      "snapshots",
      "metadata",
      "deleted",
  };
  std::string ret;
  for (size_t i = 0; i < 3; ++i)
  {
    if ((val & valueList[i]) == valueList[i])
    {
      if (!ret.empty())
      {
        ret += ",";
      }
      ret += stringList[i];
    }
  }
  return ret;
}
} // namespace
namespace Azure { namespace Storage { namespace Files { namespace Shares {
  namespace Models {
    const AccessTier AccessTier::TransactionOptimized("TransactionOptimized");
    const AccessTier AccessTier::Hot("Hot");
    const AccessTier AccessTier::Cool("Cool");
    const AccessTier AccessTier::Premium("Premium");
    const LeaseStatus LeaseStatus::Locked("locked");
    const LeaseStatus LeaseStatus::Unlocked("unlocked");
    const LeaseState LeaseState::Available("available");
    const LeaseState LeaseState::Leased("leased");
    const LeaseState LeaseState::Expired("expired");
    const LeaseState LeaseState::Breaking("breaking");
    const LeaseState LeaseState::Broken("broken");
    const LeaseDurationType LeaseDurationType::Infinite("infinite");
    const LeaseDurationType LeaseDurationType::Fixed("fixed");
    const DeleteSnapshotsOption DeleteSnapshotsOption::Include("include");
    FileAttributes::FileAttributes(const std::string& value)
    {
      const std::string delimiter = " | ";
      size_t cur = 0;
      while (cur != std::string::npos)
      {
        auto delimiter_pos = value.find(delimiter, cur);
        std::string v;
        if (delimiter_pos == std::string::npos)
        {
          v = value.substr(cur);
          cur = delimiter_pos;
        }
        else
        {
          v = value.substr(cur, delimiter_pos - cur);
          cur = delimiter_pos + delimiter.size();
        }
        if (!v.empty())
        {
          m_value.push_back(std::move(v));
        }
      }
      std::sort(m_value.begin(), m_value.end());
    }
    FileAttributes FileAttributes::operator|(const FileAttributes& other) const
    {
      FileAttributes ret;
      std::set_union(
          m_value.begin(),
          m_value.end(),
          other.m_value.begin(),
          other.m_value.end(),
          std::back_inserter(ret.m_value));
      return ret;
    }
    FileAttributes FileAttributes::operator&(const FileAttributes& other) const
    {
      FileAttributes ret;
      std::set_intersection(
          m_value.begin(),
          m_value.end(),
          other.m_value.begin(),
          other.m_value.end(),
          std::back_inserter(ret.m_value));
      return ret;
    }
    FileAttributes FileAttributes::operator^(const FileAttributes& other) const
    {
      FileAttributes ret;
      std::set_symmetric_difference(
          m_value.begin(),
          m_value.end(),
          other.m_value.begin(),
          other.m_value.end(),
          std::back_inserter(ret.m_value));
      return ret;
    }
    std::string FileAttributes::ToString() const
    {
      std::string ret;
      for (const auto& v : m_value)
      {
        ret += (ret.empty() ? "" : " | ") + v;
      }
      return ret;
    }
    const FileAttributes FileAttributes::ReadOnly("ReadOnly");
    const FileAttributes FileAttributes::Hidden("Hidden");
    const FileAttributes FileAttributes::System("System");
    const FileAttributes FileAttributes::None("None");
    const FileAttributes FileAttributes::Directory("Directory");
    const FileAttributes FileAttributes::Archive("Archive");
    const FileAttributes FileAttributes::Temporary("Temporary");
    const FileAttributes FileAttributes::Offline("Offline");
    const FileAttributes FileAttributes::NotContentIndexed("NotContentIndexed");
    const FileAttributes FileAttributes::NoScrubData("NoScrubData");
    const CopyStatus CopyStatus::Pending("pending");
    const CopyStatus CopyStatus::Success("success");
    const CopyStatus CopyStatus::Aborted("aborted");
    const CopyStatus CopyStatus::Failed("failed");
    const PermissionCopyMode PermissionCopyMode::Source("source");
    const PermissionCopyMode PermissionCopyMode::Override("override");
  } // 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, "HourMetrics"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Version",
            options.ShareServiceProperties.HourMetrics.Version});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.ShareServiceProperties.HourMetrics.Enabled ? "true" : "false"});
        if (options.ShareServiceProperties.HourMetrics.IncludeApis.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "IncludeAPIs",
              options.ShareServiceProperties.HourMetrics.IncludeApis.Value() ? "true" : "false"});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.ShareServiceProperties.HourMetrics.RetentionPolicy.Enabled ? "true" : "false"});
        if (options.ShareServiceProperties.HourMetrics.RetentionPolicy.Days.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "Days",
              std::to_string(
                  options.ShareServiceProperties.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.ShareServiceProperties.MinuteMetrics.Version});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.ShareServiceProperties.MinuteMetrics.Enabled ? "true" : "false"});
        if (options.ShareServiceProperties.MinuteMetrics.IncludeApis.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "IncludeAPIs",
              options.ShareServiceProperties.MinuteMetrics.IncludeApis.Value() ? "true" : "false"});
        }
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "RetentionPolicy"});
        writer.Write(_internal::XmlNode{
            _internal::XmlNodeType::StartTag,
            "Enabled",
            options.ShareServiceProperties.MinuteMetrics.RetentionPolicy.Enabled ? "true"
                                                                                 : "false"});
        if (options.ShareServiceProperties.MinuteMetrics.RetentionPolicy.Days.HasValue())
        {
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "Days",
              std::to_string(
                  options.ShareServiceProperties.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.ShareServiceProperties.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});
        if (options.ShareServiceProperties.Protocol.HasValue())
        {
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Protocol"});
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Settings"});
          writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "Multichannel"});
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag,
              "Enabled",
              options.ShareServiceProperties.Protocol.Value().Settings.Multichannel.Enabled
                  ? "true"
                  : "false"});
          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::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", "2020-02-10");
      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::ShareServiceProperties> 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", "2020-02-10");
      (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::ShareServiceProperties response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kStorageServiceProperties,
          kHourMetrics,
          kVersion,
          kEnabled,
          kIncludeAPIs,
          kRetentionPolicy,
          kDays,
          kMinuteMetrics,
          kCors,
          kCorsRule,
          kAllowedOrigins,
          kAllowedMethods,
          kAllowedHeaders,
          kExposedHeaders,
          kMaxAgeInSeconds,
          kProtocol,
          kSettings,
          kMultichannel,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"StorageServiceProperties", XmlTagEnum::kStorageServiceProperties},
            {"HourMetrics", XmlTagEnum::kHourMetrics},
            {"Version", XmlTagEnum::kVersion},
            {"Enabled", XmlTagEnum::kEnabled},
            {"IncludeAPIs", XmlTagEnum::kIncludeAPIs},
            {"RetentionPolicy", XmlTagEnum::kRetentionPolicy},
            {"Days", XmlTagEnum::kDays},
            {"MinuteMetrics", XmlTagEnum::kMinuteMetrics},
            {"Cors", XmlTagEnum::kCors},
            {"CorsRule", XmlTagEnum::kCorsRule},
            {"AllowedOrigins", XmlTagEnum::kAllowedOrigins},
            {"AllowedMethods", XmlTagEnum::kAllowedMethods},
            {"AllowedHeaders", XmlTagEnum::kAllowedHeaders},
            {"ExposedHeaders", XmlTagEnum::kExposedHeaders},
            {"MaxAgeInSeconds", XmlTagEnum::kMaxAgeInSeconds},
            {"Protocol", XmlTagEnum::kProtocol},
            {"Settings", XmlTagEnum::kSettings},
            {"Multichannel", XmlTagEnum::kMultichannel},
        };
        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);
            if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kProtocol)
            {
              response.Protocol = Models::ProtocolSettings();
            }
          }
          else if (node.Type == _internal::XmlNodeType::Text)
          {
            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.Enabled = 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.Enabled = 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.Enabled = 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.Enabled = 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 (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kStorageServiceProperties
                && xmlPath[1] == XmlTagEnum::kProtocol && xmlPath[2] == XmlTagEnum::kSettings
                && xmlPath[3] == XmlTagEnum::kMultichannel && xmlPath[4] == XmlTagEnum::kEnabled)
            {
              response.Protocol.Value().Settings.Multichannel.Enabled
                  = node.Value == std::string("true");
            }
          }
          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::ShareServiceProperties>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ListSharesResponse> ServiceClient::ListSharesSegment(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ListServiceSharesSegmentOptions& 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()
          && !ListSharesIncludeFlagsToString(options.Include.Value()).empty())
      {
        request.GetUrl().AppendQueryParameter(
            "include",
            _internal::UrlEncodeQueryParameter(
                ListSharesIncludeFlagsToString(options.Include.Value())));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ListSharesResponse response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kEnumerationResults,
          kPrefix,
          kMarker,
          kMaxResults,
          kShares,
          kShare,
          kName,
          kSnapshot,
          kDeleted,
          kVersion,
          kMetadata,
          kProperties,
          kLastModified,
          kEtag,
          kQuota,
          kProvisionedIops,
          kProvisionedIngressMBps,
          kProvisionedEgressMBps,
          kNextAllowedQuotaDowngradeTime,
          kDeletedTime,
          kRemainingRetentionDays,
          kAccessTier,
          kAccessTierChangeTime,
          kAccessTierTransitionState,
          kLeaseStatus,
          kLeaseState,
          kLeaseDuration,
          kNextMarker,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"EnumerationResults", XmlTagEnum::kEnumerationResults},
            {"Prefix", XmlTagEnum::kPrefix},
            {"Marker", XmlTagEnum::kMarker},
            {"MaxResults", XmlTagEnum::kMaxResults},
            {"Shares", XmlTagEnum::kShares},
            {"Share", XmlTagEnum::kShare},
            {"Name", XmlTagEnum::kName},
            {"Snapshot", XmlTagEnum::kSnapshot},
            {"Deleted", XmlTagEnum::kDeleted},
            {"Version", XmlTagEnum::kVersion},
            {"Metadata", XmlTagEnum::kMetadata},
            {"Properties", XmlTagEnum::kProperties},
            {"Last-Modified", XmlTagEnum::kLastModified},
            {"Etag", XmlTagEnum::kEtag},
            {"Quota", XmlTagEnum::kQuota},
            {"ProvisionedIops", XmlTagEnum::kProvisionedIops},
            {"ProvisionedIngressMBps", XmlTagEnum::kProvisionedIngressMBps},
            {"ProvisionedEgressMBps", XmlTagEnum::kProvisionedEgressMBps},
            {"NextAllowedQuotaDowngradeTime", XmlTagEnum::kNextAllowedQuotaDowngradeTime},
            {"DeletedTime", XmlTagEnum::kDeletedTime},
            {"RemainingRetentionDays", XmlTagEnum::kRemainingRetentionDays},
            {"AccessTier", XmlTagEnum::kAccessTier},
            {"AccessTierChangeTime", XmlTagEnum::kAccessTierChangeTime},
            {"AccessTierTransitionState", XmlTagEnum::kAccessTierTransitionState},
            {"LeaseStatus", XmlTagEnum::kLeaseStatus},
            {"LeaseState", XmlTagEnum::kLeaseState},
            {"LeaseDuration", XmlTagEnum::kLeaseDuration},
            {"NextMarker", XmlTagEnum::kNextMarker},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::ShareItem 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::kShares && xmlPath[2] == XmlTagEnum::kShare
                && 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() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kMarker)
            {
              response.Marker = node.Value;
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kMaxResults)
            {
              response.MaxResults = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kName)
            {
              vectorElement1.Name = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kSnapshot)
            {
              vectorElement1.Snapshot = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kDeleted)
            {
              vectorElement1.Deleted = node.Value == std::string("true");
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kVersion)
            {
              vectorElement1.Version = node.Value;
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kMetadata)
            {
              mapValue3 = node.Value;
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties && xmlPath[4] == XmlTagEnum::kLastModified)
            {
              vectorElement1.Details.LastModified
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties && xmlPath[4] == XmlTagEnum::kEtag)
            {
              vectorElement1.Details.Etag = ETag(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties && xmlPath[4] == XmlTagEnum::kQuota)
            {
              vectorElement1.Details.Quota = std::stoll(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kProvisionedIops)
            {
              vectorElement1.Details.ProvisionedIops = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kProvisionedIngressMBps)
            {
              vectorElement1.Details.ProvisionedIngressMBps = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kProvisionedEgressMBps)
            {
              vectorElement1.Details.ProvisionedEgressMBps = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kNextAllowedQuotaDowngradeTime)
            {
              vectorElement1.Details.NextAllowedQuotaDowngradeTime
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties && xmlPath[4] == XmlTagEnum::kDeletedTime)
            {
              vectorElement1.Details.DeletedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kRemainingRetentionDays)
            {
              vectorElement1.Details.RemainingRetentionDays = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties && xmlPath[4] == XmlTagEnum::kAccessTier)
            {
              vectorElement1.Details.AccessTier = Models::AccessTier(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kAccessTierChangeTime)
            {
              vectorElement1.Details.AccessTierChangedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kAccessTierTransitionState)
            {
              vectorElement1.Details.AccessTierTransitionState = node.Value;
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties && xmlPath[4] == XmlTagEnum::kLeaseStatus)
            {
              vectorElement1.Details.LeaseStatus = Models::LeaseStatus(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties && xmlPath[4] == XmlTagEnum::kLeaseState)
            {
              vectorElement1.Details.LeaseState = Models::LeaseState(node.Value);
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kLeaseDuration)
            {
              vectorElement1.Details.LeaseDuration = Models::LeaseDurationType(node.Value);
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kNextMarker)
            {
              response.NextMarker = 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::kShares && xmlPath[2] == XmlTagEnum::kShare
                && xmlPath[3] == XmlTagEnum::kMetadata)
            {
              vectorElement1.Metadata[std::move(mapKey2)] = std::move(mapValue3);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare)
            {
              response.ShareItems.push_back(std::move(vectorElement1));
              vectorElement1 = Models::ShareItem();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::_detail::ListSharesResponse>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::CreateShareResult> ShareClient::Create(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const CreateShareOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      for (const auto& p : options.Metadata)
      {
        request.SetHeader("x-ms-meta-" + p.first, p.second);
      }
      if (options.Quota.HasValue())
      {
        request.SetHeader("x-ms-share-quota", std::to_string(options.Quota.Value()));
      }
      if (options.AccessTier.HasValue() && !options.AccessTier.Value().ToString().empty())
      {
        request.SetHeader("x-ms-access-tier", options.AccessTier.Value().ToString());
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::CreateShareResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::CreateShareResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::ShareProperties> ShareClient::GetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetSharePropertiesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::ShareProperties 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.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.Quota = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-quota"));
      if (pRawResponse->GetHeaders().count("x-ms-share-provisioned-iops") != 0)
      {
        response.ProvisionedIops
            = std::stoi(pRawResponse->GetHeaders().at("x-ms-share-provisioned-iops"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-share-provisioned-ingress-mbps") != 0)
      {
        response.ProvisionedIngressMBps
            = std::stoi(pRawResponse->GetHeaders().at("x-ms-share-provisioned-ingress-mbps"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-share-provisioned-egress-mbps") != 0)
      {
        response.ProvisionedEgressMBps
            = std::stoi(pRawResponse->GetHeaders().at("x-ms-share-provisioned-egress-mbps"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-share-next-allowed-quota-downgrade-time") != 0)
      {
        response.NextAllowedQuotaDowngradeTime = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-share-next-allowed-quota-downgrade-time"),
            Azure::DateTime::DateFormat::Rfc1123);
      }
      if (pRawResponse->GetHeaders().count("x-ms-lease-duration") != 0)
      {
        response.LeaseDuration
            = Models::LeaseDurationType(pRawResponse->GetHeaders().at("x-ms-lease-duration"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-lease-state") != 0)
      {
        response.LeaseState = Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-lease-status") != 0)
      {
        response.LeaseStatus
            = Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-access-tier") != 0)
      {
        response.AccessTier = Models::AccessTier(pRawResponse->GetHeaders().at("x-ms-access-tier"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-access-tier-change-time") != 0)
      {
        response.AccessTierChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-access-tier-change-time"),
            Azure::DateTime::DateFormat::Rfc1123);
      }
      if (pRawResponse->GetHeaders().count("x-ms-access-tier-transition-state") != 0)
      {
        response.AccessTierTransitionState
            = pRawResponse->GetHeaders().at("x-ms-access-tier-transition-state");
      }
      return Response<Models::ShareProperties>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::DeleteShareResult> ShareClient::Delete(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const DeleteShareOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.DeleteSnapshots.HasValue() && !options.DeleteSnapshots.Value().ToString().empty())
      {
        request.SetHeader("x-ms-delete-snapshots", options.DeleteSnapshots.Value().ToString());
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::DeleteShareResult response;
      return Response<Models::DeleteShareResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::AcquireShareLeaseResult> ShareClient::AcquireLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const AcquireShareLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "acquire");
      request.GetUrl().AppendQueryParameter("restype", "share");
      if (options.Duration.HasValue())
      {
        request.SetHeader("x-ms-lease-duration", std::to_string(options.Duration.Value()));
      }
      if (options.ProposedLeaseId.HasValue() && !options.ProposedLeaseId.Value().empty())
      {
        request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value());
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::AcquireShareLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id");
      return Response<Models::_detail::AcquireShareLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ReleaseShareLeaseResult> ShareClient::ReleaseLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ReleaseShareLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "release");
      request.GetUrl().AppendQueryParameter("restype", "share");
      if (!options.LeaseId.empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId);
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ReleaseShareLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::_detail::ReleaseShareLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ChangeShareLeaseResult> ShareClient::ChangeLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ChangeShareLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "change");
      request.GetUrl().AppendQueryParameter("restype", "share");
      if (!options.LeaseId.empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId);
      }
      if (options.ProposedLeaseId.HasValue() && !options.ProposedLeaseId.Value().empty())
      {
        request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value());
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ChangeShareLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id");
      return Response<Models::_detail::ChangeShareLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::RenewShareLeaseResult> ShareClient::RenewLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const RenewShareLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "renew");
      request.GetUrl().AppendQueryParameter("restype", "share");
      if (!options.LeaseId.empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId);
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::RenewShareLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id");
      return Response<Models::_detail::RenewShareLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::BreakShareLeaseResult> ShareClient::BreakLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const BreakShareLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "break");
      request.GetUrl().AppendQueryParameter("restype", "share");
      if (options.BreakPeriod.HasValue())
      {
        request.SetHeader("x-ms-lease-break-period", std::to_string(options.BreakPeriod.Value()));
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::BreakShareLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.LeaseTime = std::stoi(pRawResponse->GetHeaders().at("x-ms-lease-time"));
      response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id");
      return Response<Models::_detail::BreakShareLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::CreateShareSnapshotResult> ShareClient::CreateSnapshot(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const CreateShareSnapshotOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      request.GetUrl().AppendQueryParameter("comp", "snapshot");
      for (const auto& p : options.Metadata)
      {
        request.SetHeader("x-ms-meta-" + p.first, p.second);
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::CreateShareSnapshotResult response;
      response.Snapshot = pRawResponse->GetHeaders().at("x-ms-snapshot");
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::CreateShareSnapshotResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::CreateSharePermissionResult> ShareClient::CreatePermission(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const CreateSharePermissionOptions& options,
        const Core::Context& context)
    {
      std::string jsonBody;
      {
        auto jsonRoot = Core::Json::_internal::json::object();
        jsonRoot["permission"] = options.SharePermission.Permission;
        jsonBody = jsonRoot.dump();
      }
      Core::IO::MemoryBodyStream requestBody(
          reinterpret_cast<const uint8_t*>(jsonBody.data()), jsonBody.length());
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody);
      request.SetHeader("Content-Type", "application/json");
      request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
      request.GetUrl().AppendQueryParameter("restype", "share");
      request.GetUrl().AppendQueryParameter("comp", "filepermission");
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::CreateSharePermissionResult response;
      response.FilePermissionKey = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      return Response<Models::CreateSharePermissionResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::SharePermission> ShareClient::GetPermission(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetSharePermissionOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      request.GetUrl().AppendQueryParameter("comp", "filepermission");
      if (!options.FilePermissionKey.empty())
      {
        request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey);
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::SharePermission response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        auto jsonRoot
            = Core::Json::_internal::json::parse(responseBody.begin(), responseBody.end());
        response.Permission = jsonRoot["permission"].get<std::string>();
      }
      return Response<Models::_detail::SharePermission>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetSharePropertiesResult> ShareClient::SetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetSharePropertiesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      request.GetUrl().AppendQueryParameter("comp", "properties");
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Quota.HasValue())
      {
        request.SetHeader("x-ms-share-quota", std::to_string(options.Quota.Value()));
      }
      if (options.AccessTier.HasValue() && !options.AccessTier.Value().ToString().empty())
      {
        request.SetHeader("x-ms-access-tier", options.AccessTier.Value().ToString());
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetSharePropertiesResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::SetSharePropertiesResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetShareMetadataResult> ShareClient::SetMetadata(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetShareMetadataOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      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", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetShareMetadataResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::SetShareMetadataResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::ShareAccessPolicy> ShareClient::GetAccessPolicy(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetShareAccessPolicyOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      request.GetUrl().AppendQueryParameter("comp", "acl");
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::ShareAccessPolicy 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.Policy.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.Policy.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.Policy.Permission = 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::ShareAccessPolicy>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetShareAccessPolicyResult> ShareClient::SetAccessPolicy(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetShareAccessPolicyOptions& options,
        const Core::Context& context)
    {
      std::string xmlBody;
      {
        _internal::XmlWriter writer;
        writer.Write(_internal::XmlNode{_internal::XmlNodeType::StartTag, "SignedIdentifiers"});
        for (const auto& i1 : options.ShareAcl)
        {
          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.Policy.StartsOn.HasValue())
          {
            writer.Write(_internal::XmlNode{
                _internal::XmlNodeType::StartTag,
                "Start",
                i1.Policy.StartsOn.Value().ToString(
                    Azure::DateTime::DateFormat::Rfc3339,
                    Azure::DateTime::TimeFractionFormat::AllDigits)});
          }
          if (i1.Policy.ExpiresOn.HasValue())
          {
            writer.Write(_internal::XmlNode{
                _internal::XmlNodeType::StartTag,
                "Expiry",
                i1.Policy.ExpiresOn.Value().ToString(
                    Azure::DateTime::DateFormat::Rfc3339,
                    Azure::DateTime::TimeFractionFormat::AllDigits)});
          }
          writer.Write(_internal::XmlNode{
              _internal::XmlNodeType::StartTag, "Permission", i1.Policy.Permission});
          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", "share");
      request.GetUrl().AppendQueryParameter("comp", "acl");
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetShareAccessPolicyResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::SetShareAccessPolicyResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::ShareStatistics> ShareClient::GetStatistics(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetShareStatisticsOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "share");
      request.GetUrl().AppendQueryParameter("comp", "stats");
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::ShareStatistics response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kShareStats,
          kShareUsageBytes,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"ShareStats", XmlTagEnum::kShareStats},
            {"ShareUsageBytes", XmlTagEnum::kShareUsageBytes},
        };
        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() == 2 && xmlPath[0] == XmlTagEnum::kShareStats
                && xmlPath[1] == XmlTagEnum::kShareUsageBytes)
            {
              response.ShareUsageInBytes = std::stoll(node.Value);
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {

            xmlPath.pop_back();
          }
        }
      }
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::ShareStatistics>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::CreateDirectoryResult> DirectoryClient::Create(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const CreateDirectoryOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("restype", "directory");
      for (const auto& p : options.Metadata)
      {
        request.SetHeader("x-ms-meta-" + p.first, p.second);
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty())
      {
        request.SetHeader("x-ms-file-permission", options.FilePermission.Value());
      }
      if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty())
      {
        request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value());
      }
      if (!options.FileAttributes.empty())
      {
        request.SetHeader("x-ms-file-attributes", options.FileAttributes);
      }
      if (!options.FileCreationTime.empty())
      {
        request.SetHeader("x-ms-file-creation-time", options.FileCreationTime);
      }
      if (!options.FileLastWriteTime.empty())
      {
        request.SetHeader("x-ms-file-last-write-time", options.FileLastWriteTime);
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::CreateDirectoryResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      if (pRawResponse->GetHeaders().count("x-ms-file-permission-key") != 0)
      {
        response.SmbProperties.PermissionKey
            = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      }
      response.SmbProperties.Attributes
          = Models::FileAttributes(pRawResponse->GetHeaders().at("x-ms-file-attributes"));
      if (pRawResponse->GetHeaders().count("x-ms-file-creation-time") != 0)
      {
        response.SmbProperties.CreatedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-creation-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-last-write-time") != 0)
      {
        response.SmbProperties.LastWrittenOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-last-write-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-change-time") != 0)
      {
        response.SmbProperties.ChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-change-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      response.SmbProperties.FileId = pRawResponse->GetHeaders().at("x-ms-file-id");
      response.SmbProperties.ParentFileId = pRawResponse->GetHeaders().at("x-ms-file-parent-id");
      return Response<Models::CreateDirectoryResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::DirectoryProperties> DirectoryClient::GetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetDirectoryPropertiesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "directory");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::DirectoryProperties 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.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-server-encrypted") == std::string("true");
      response.SmbProperties.Attributes
          = Models::FileAttributes(pRawResponse->GetHeaders().at("x-ms-file-attributes"));
      if (pRawResponse->GetHeaders().count("x-ms-file-creation-time") != 0)
      {
        response.SmbProperties.CreatedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-creation-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-last-write-time") != 0)
      {
        response.SmbProperties.LastWrittenOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-last-write-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-change-time") != 0)
      {
        response.SmbProperties.ChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-change-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-permission-key") != 0)
      {
        response.SmbProperties.PermissionKey
            = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      }
      response.SmbProperties.FileId = pRawResponse->GetHeaders().at("x-ms-file-id");
      response.SmbProperties.ParentFileId = pRawResponse->GetHeaders().at("x-ms-file-parent-id");
      return Response<Models::DirectoryProperties>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::DeleteDirectoryResult> DirectoryClient::Delete(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const DeleteDirectoryOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
      request.GetUrl().AppendQueryParameter("restype", "directory");
      request.SetHeader("x-ms-version", "2020-02-10");
      (void)options;
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::DeleteDirectoryResult response;
      return Response<Models::DeleteDirectoryResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetDirectoryPropertiesResult> DirectoryClient::SetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetDirectoryPropertiesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("restype", "directory");
      request.GetUrl().AppendQueryParameter("comp", "properties");
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty())
      {
        request.SetHeader("x-ms-file-permission", options.FilePermission.Value());
      }
      if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty())
      {
        request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value());
      }
      if (!options.FileAttributes.empty())
      {
        request.SetHeader("x-ms-file-attributes", options.FileAttributes);
      }
      if (!options.FileCreationTime.empty())
      {
        request.SetHeader("x-ms-file-creation-time", options.FileCreationTime);
      }
      if (!options.FileLastWriteTime.empty())
      {
        request.SetHeader("x-ms-file-last-write-time", options.FileLastWriteTime);
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetDirectoryPropertiesResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      if (pRawResponse->GetHeaders().count("x-ms-file-permission-key") != 0)
      {
        response.SmbProperties.PermissionKey
            = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      }
      response.SmbProperties.Attributes
          = Models::FileAttributes(pRawResponse->GetHeaders().at("x-ms-file-attributes"));
      if (pRawResponse->GetHeaders().count("x-ms-file-creation-time") != 0)
      {
        response.SmbProperties.CreatedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-creation-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-last-write-time") != 0)
      {
        response.SmbProperties.LastWrittenOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-last-write-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-change-time") != 0)
      {
        response.SmbProperties.ChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-change-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      response.SmbProperties.FileId = pRawResponse->GetHeaders().at("x-ms-file-id");
      response.SmbProperties.ParentFileId = pRawResponse->GetHeaders().at("x-ms-file-parent-id");
      return Response<Models::SetDirectoryPropertiesResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetDirectoryMetadataResult> DirectoryClient::SetMetadata(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetDirectoryMetadataOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("restype", "directory");
      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", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetDirectoryMetadataResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      return Response<Models::SetDirectoryMetadataResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ListFilesAndDirectoriesSegmentResponse>
    DirectoryClient::ListFilesAndDirectoriesSegment(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ListDirectoryFilesAndDirectoriesSegmentOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("restype", "directory");
      request.GetUrl().AppendQueryParameter("comp", "list");
      if (options.Prefix.HasValue() && !options.Prefix.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "prefix", _internal::UrlEncodeQueryParameter(options.Prefix.Value()));
      }
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.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()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ListFilesAndDirectoriesSegmentResponse response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kEnumerationResults,
          kPrefix,
          kMarker,
          kMaxResults,
          kEntries,
          kDirectory,
          kName,
          kFile,
          kProperties,
          kContentLength,
          kNextMarker,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"EnumerationResults", XmlTagEnum::kEnumerationResults},
            {"Prefix", XmlTagEnum::kPrefix},
            {"Marker", XmlTagEnum::kMarker},
            {"MaxResults", XmlTagEnum::kMaxResults},
            {"Entries", XmlTagEnum::kEntries},
            {"Directory", XmlTagEnum::kDirectory},
            {"Name", XmlTagEnum::kName},
            {"File", XmlTagEnum::kFile},
            {"Properties", XmlTagEnum::kProperties},
            {"Content-Length", XmlTagEnum::kContentLength},
            {"NextMarker", XmlTagEnum::kNextMarker},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::DirectoryItem vectorElement1;
        Models::FileItem vectorElement2;
        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() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kPrefix)
            {
              response.Prefix = node.Value;
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kMarker)
            {
              response.Marker = node.Value;
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kMaxResults)
            {
              response.MaxResults = std::stoi(node.Value);
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kEntries && xmlPath[2] == XmlTagEnum::kDirectory
                && xmlPath[3] == XmlTagEnum::kName)
            {
              vectorElement1.Name = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kEntries && xmlPath[2] == XmlTagEnum::kFile
                && xmlPath[3] == XmlTagEnum::kName)
            {
              vectorElement2.Name = node.Value;
            }
            else if (
                xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kEntries && xmlPath[2] == XmlTagEnum::kFile
                && xmlPath[3] == XmlTagEnum::kProperties
                && xmlPath[4] == XmlTagEnum::kContentLength)
            {
              vectorElement2.Details.FileSize = std::stoll(node.Value);
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kNextMarker)
            {
              response.NextMarker = 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 (
                xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && node.Name == "ShareName")
            {
              response.ShareName = node.Value;
            }
            else if (
                xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && node.Name == "ShareSnapshot")
            {
              response.ShareSnapshot = node.Value;
            }
            else if (
                xmlPath.size() == 1 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && node.Name == "DirectoryPath")
            {
              response.DirectoryPath = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kEntries && xmlPath[2] == XmlTagEnum::kDirectory)
            {
              response.Segment.DirectoryItems.push_back(std::move(vectorElement1));
              vectorElement1 = Models::DirectoryItem();
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kEntries && xmlPath[2] == XmlTagEnum::kFile)
            {
              response.Segment.FileItems.push_back(std::move(vectorElement2));
              vectorElement2 = Models::FileItem();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::_detail::ListFilesAndDirectoriesSegmentResponse>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ListHandlesResponse> DirectoryClient::ListHandles(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ListDirectoryHandlesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("comp", "listhandles");
      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.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      if (options.Recursive.HasValue())
      {
        request.SetHeader("x-ms-recursive", options.Recursive.Value() ? "true" : "false");
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ListHandlesResponse response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kEnumerationResults,
          kHandleList,
          kHandle,
          kHandleId,
          kPath,
          kFileId,
          kParentId,
          kSessionId,
          kClientIp,
          kOpenTime,
          kLastReconnectTime,
          kNextMarker,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"EnumerationResults", XmlTagEnum::kEnumerationResults},
            {"HandleList", XmlTagEnum::kHandleList},
            {"Handle", XmlTagEnum::kHandle},
            {"HandleId", XmlTagEnum::kHandleId},
            {"Path", XmlTagEnum::kPath},
            {"FileId", XmlTagEnum::kFileId},
            {"ParentId", XmlTagEnum::kParentId},
            {"SessionId", XmlTagEnum::kSessionId},
            {"ClientIp", XmlTagEnum::kClientIp},
            {"OpenTime", XmlTagEnum::kOpenTime},
            {"LastReconnectTime", XmlTagEnum::kLastReconnectTime},
            {"NextMarker", XmlTagEnum::kNextMarker},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::HandleItem 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() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kHandleId)
            {
              vectorElement1.HandleId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kPath)
            {
              vectorElement1.Path = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kFileId)
            {
              vectorElement1.FileId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kParentId)
            {
              vectorElement1.ParentId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kSessionId)
            {
              vectorElement1.SessionId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kClientIp)
            {
              vectorElement1.ClientIp = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kOpenTime)
            {
              vectorElement1.OpenedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kLastReconnectTime)
            {
              vectorElement1.LastReconnectedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kNextMarker)
            {
              response.NextMarker = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle)
            {
              response.HandleList.push_back(std::move(vectorElement1));
              vectorElement1 = Models::HandleItem();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::_detail::ListHandlesResponse>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ForceCloseDirectoryHandlesResult> DirectoryClient::ForceCloseHandles(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ForceDirectoryCloseHandlesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "forceclosehandles");
      if (options.Marker.HasValue() && !options.Marker.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value()));
      }
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      if (!options.HandleId.empty())
      {
        request.SetHeader("x-ms-handle-id", options.HandleId);
      }
      if (options.Recursive.HasValue())
      {
        request.SetHeader("x-ms-recursive", options.Recursive.Value() ? "true" : "false");
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ForceCloseDirectoryHandlesResult response;
      if (pRawResponse->GetHeaders().count("x-ms-marker") != 0)
      {
        response.ContinuationToken = pRawResponse->GetHeaders().at("x-ms-marker");
      }
      response.NumberOfHandlesClosed
          = std::stoi(pRawResponse->GetHeaders().at("x-ms-number-of-handles-closed"));
      response.NumberOfHandlesFailedToClose
          = std::stoi(pRawResponse->GetHeaders().at("x-ms-number-of-handles-failed"));
      return Response<Models::_detail::ForceCloseDirectoryHandlesResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::CreateFileResult> FileClient::Create(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const CreateFileOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.SetHeader("x-ms-version", "2020-02-10");
      request.SetHeader("x-ms-content-length", std::to_string(options.FileContentLength));
      request.SetHeader("x-ms-type", "file");
      if (options.FileContentType.HasValue() && !options.FileContentType.Value().empty())
      {
        request.SetHeader("x-ms-content-type", options.FileContentType.Value());
      }
      if (options.FileContentEncoding.HasValue() && !options.FileContentEncoding.Value().empty())
      {
        request.SetHeader("x-ms-content-encoding", options.FileContentEncoding.Value());
      }
      if (options.FileContentLanguage.HasValue() && !options.FileContentLanguage.Value().empty())
      {
        request.SetHeader("x-ms-content-language", options.FileContentLanguage.Value());
      }
      if (options.FileCacheControl.HasValue() && !options.FileCacheControl.Value().empty())
      {
        request.SetHeader("x-ms-cache-control", options.FileCacheControl.Value());
      }
      if (options.FileContentMD5.HasValue()
          && !Core::Convert::Base64Encode(options.FileContentMD5.Value()).empty())
      {
        request.SetHeader(
            "x-ms-content-md5", Core::Convert::Base64Encode(options.FileContentMD5.Value()));
      }
      if (options.FileContentDisposition.HasValue()
          && !options.FileContentDisposition.Value().empty())
      {
        request.SetHeader("x-ms-content-disposition", options.FileContentDisposition.Value());
      }
      for (const auto& p : options.Metadata)
      {
        request.SetHeader("x-ms-meta-" + p.first, p.second);
      }
      if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty())
      {
        request.SetHeader("x-ms-file-permission", options.FilePermission.Value());
      }
      if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty())
      {
        request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value());
      }
      if (!options.FileAttributes.empty())
      {
        request.SetHeader("x-ms-file-attributes", options.FileAttributes);
      }
      if (!options.FileCreationTime.empty())
      {
        request.SetHeader("x-ms-file-creation-time", options.FileCreationTime);
      }
      if (!options.FileLastWriteTime.empty())
      {
        request.SetHeader("x-ms-file-last-write-time", options.FileLastWriteTime);
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::CreateFileResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      if (pRawResponse->GetHeaders().count("x-ms-file-permission-key") != 0)
      {
        response.SmbProperties.PermissionKey
            = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      }
      response.SmbProperties.Attributes
          = Models::FileAttributes(pRawResponse->GetHeaders().at("x-ms-file-attributes"));
      if (pRawResponse->GetHeaders().count("x-ms-file-creation-time") != 0)
      {
        response.SmbProperties.CreatedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-creation-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-last-write-time") != 0)
      {
        response.SmbProperties.LastWrittenOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-last-write-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-change-time") != 0)
      {
        response.SmbProperties.ChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-change-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      response.SmbProperties.FileId = pRawResponse->GetHeaders().at("x-ms-file-id");
      response.SmbProperties.ParentFileId = pRawResponse->GetHeaders().at("x-ms-file-parent-id");
      return Response<Models::CreateFileResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::DownloadFileResult> FileClient::Download(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const DownloadFileOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url, false);
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Range.HasValue() && !options.Range.Value().empty())
      {
        request.SetHeader("x-ms-range", options.Range.Value());
      }
      if (options.RangeGetContentMD5.HasValue())
      {
        request.SetHeader(
            "x-ms-range-get-content-md5", options.RangeGetContentMD5.Value() ? "true" : "false");
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (!(httpStatusCode == Core::Http::HttpStatusCode::Ok
            || httpStatusCode == Core::Http::HttpStatusCode::PartialContent))
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::DownloadFileResult response;
      response.BodyStream = pRawResponse->ExtractBodyStream();
      response.Details.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      for (auto i = pRawResponse->GetHeaders().lower_bound("x-ms-meta-");
           i != pRawResponse->GetHeaders().end() && i->first.substr(0, 10) == "x-ms-meta-";
           ++i)
      {
        response.Details.Metadata.emplace(i->first.substr(10), i->second);
      }
      if (pRawResponse->GetHeaders().count("Content-Type") != 0)
      {
        response.HttpHeaders.ContentType = pRawResponse->GetHeaders().at("Content-Type");
      }
      response.Details.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      if (httpStatusCode == Core::Http::HttpStatusCode::Ok)
      {
        if (pRawResponse->GetHeaders().count("Content-MD5") != 0)
        {
          response.HttpHeaders.ContentHash.Value
              = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("Content-MD5"));
          response.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5;
        }
      }
      if (httpStatusCode == Core::Http::HttpStatusCode::Ok)
      {
        if (pRawResponse->GetHeaders().count("Content-MD5") != 0)
        {
          response.TransactionalContentHash = ContentHash();
          response.TransactionalContentHash.Value().Value
              = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("Content-MD5"));
          response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5;
        }
      }
      if (pRawResponse->GetHeaders().count("Content-Encoding") != 0)
      {
        response.HttpHeaders.ContentEncoding = pRawResponse->GetHeaders().at("Content-Encoding");
      }
      if (pRawResponse->GetHeaders().count("Cache-Control") != 0)
      {
        response.HttpHeaders.CacheControl = pRawResponse->GetHeaders().at("Cache-Control");
      }
      if (pRawResponse->GetHeaders().count("Content-Disposition") != 0)
      {
        response.HttpHeaders.ContentDisposition
            = pRawResponse->GetHeaders().at("Content-Disposition");
      }
      if (pRawResponse->GetHeaders().count("Content-Language") != 0)
      {
        response.HttpHeaders.ContentLanguage = pRawResponse->GetHeaders().at("Content-Language");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-completion-time") != 0)
      {
        response.Details.CopyCompletedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-copy-completion-time"),
            Azure::DateTime::DateFormat::Rfc1123);
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-status-description") != 0)
      {
        response.Details.CopyStatusDescription
            = pRawResponse->GetHeaders().at("x-ms-copy-status-description");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-id") != 0)
      {
        response.Details.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-progress") != 0)
      {
        response.Details.CopyProgress = pRawResponse->GetHeaders().at("x-ms-copy-progress");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-source") != 0)
      {
        response.Details.CopySource = pRawResponse->GetHeaders().at("x-ms-copy-source");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-status") != 0)
      {
        response.Details.CopyStatus
            = Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-content-md5") != 0)
      {
        response.HttpHeaders.ContentHash.Value
            = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("x-ms-content-md5"));
        response.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5;
      }
      response.Details.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-server-encrypted") == std::string("true");
      response.Details.SmbProperties.Attributes
          = Models::FileAttributes(pRawResponse->GetHeaders().at("x-ms-file-attributes"));
      if (pRawResponse->GetHeaders().count("x-ms-file-creation-time") != 0)
      {
        response.Details.SmbProperties.CreatedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-creation-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-last-write-time") != 0)
      {
        response.Details.SmbProperties.LastWrittenOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-last-write-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-change-time") != 0)
      {
        response.Details.SmbProperties.ChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-change-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-permission-key") != 0)
      {
        response.Details.SmbProperties.PermissionKey
            = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      }
      response.Details.SmbProperties.FileId = pRawResponse->GetHeaders().at("x-ms-file-id");
      response.Details.SmbProperties.ParentFileId
          = pRawResponse->GetHeaders().at("x-ms-file-parent-id");
      if (pRawResponse->GetHeaders().count("x-ms-lease-duration") != 0)
      {
        response.Details.LeaseDuration
            = Models::LeaseDurationType(pRawResponse->GetHeaders().at("x-ms-lease-duration"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-lease-state") != 0)
      {
        response.Details.LeaseState
            = Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-lease-status") != 0)
      {
        response.Details.LeaseStatus
            = Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status"));
      }
      if (httpStatusCode == Core::Http::HttpStatusCode::PartialContent)
      {
        if (pRawResponse->GetHeaders().count("Content-MD5") != 0)
        {
          response.TransactionalContentHash = ContentHash();
          response.TransactionalContentHash.Value().Value
              = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("Content-MD5"));
          response.TransactionalContentHash.Value().Algorithm = HashAlgorithm::Md5;
        }
      }
      return Response<Models::DownloadFileResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::FileProperties> FileClient::GetProperties(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetFilePropertiesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Head, url);
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::FileProperties response;
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      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.FileSize = std::stoll(pRawResponse->GetHeaders().at("Content-Length"));
      if (pRawResponse->GetHeaders().count("Content-Type") != 0)
      {
        response.HttpHeaders.ContentType = pRawResponse->GetHeaders().at("Content-Type");
      }
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      if (pRawResponse->GetHeaders().count("Content-MD5") != 0)
      {
        response.HttpHeaders.ContentHash.Value
            = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("Content-MD5"));
        response.HttpHeaders.ContentHash.Algorithm = HashAlgorithm::Md5;
      }
      if (pRawResponse->GetHeaders().count("Content-Encoding") != 0)
      {
        response.HttpHeaders.ContentEncoding = pRawResponse->GetHeaders().at("Content-Encoding");
      }
      if (pRawResponse->GetHeaders().count("Cache-Control") != 0)
      {
        response.HttpHeaders.CacheControl = pRawResponse->GetHeaders().at("Cache-Control");
      }
      if (pRawResponse->GetHeaders().count("Content-Disposition") != 0)
      {
        response.HttpHeaders.ContentDisposition
            = pRawResponse->GetHeaders().at("Content-Disposition");
      }
      if (pRawResponse->GetHeaders().count("Content-Language") != 0)
      {
        response.HttpHeaders.ContentLanguage = pRawResponse->GetHeaders().at("Content-Language");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-completion-time") != 0)
      {
        response.CopyCompletedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-copy-completion-time"),
            Azure::DateTime::DateFormat::Rfc1123);
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-status-description") != 0)
      {
        response.CopyStatusDescription
            = pRawResponse->GetHeaders().at("x-ms-copy-status-description");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-id") != 0)
      {
        response.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-progress") != 0)
      {
        response.CopyProgress = pRawResponse->GetHeaders().at("x-ms-copy-progress");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-source") != 0)
      {
        response.CopySource = pRawResponse->GetHeaders().at("x-ms-copy-source");
      }
      if (pRawResponse->GetHeaders().count("x-ms-copy-status") != 0)
      {
        response.CopyStatus = Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status"));
      }
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-server-encrypted") == std::string("true");
      response.SmbProperties.Attributes
          = Models::FileAttributes(pRawResponse->GetHeaders().at("x-ms-file-attributes"));
      if (pRawResponse->GetHeaders().count("x-ms-file-creation-time") != 0)
      {
        response.SmbProperties.CreatedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-creation-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-last-write-time") != 0)
      {
        response.SmbProperties.LastWrittenOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-last-write-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-change-time") != 0)
      {
        response.SmbProperties.ChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-change-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-permission-key") != 0)
      {
        response.SmbProperties.PermissionKey
            = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      }
      response.SmbProperties.FileId = pRawResponse->GetHeaders().at("x-ms-file-id");
      response.SmbProperties.ParentFileId = pRawResponse->GetHeaders().at("x-ms-file-parent-id");
      if (pRawResponse->GetHeaders().count("x-ms-lease-duration") != 0)
      {
        response.LeaseDuration
            = Models::LeaseDurationType(pRawResponse->GetHeaders().at("x-ms-lease-duration"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-lease-state") != 0)
      {
        response.LeaseState = Models::LeaseState(pRawResponse->GetHeaders().at("x-ms-lease-state"));
      }
      if (pRawResponse->GetHeaders().count("x-ms-lease-status") != 0)
      {
        response.LeaseStatus
            = Models::LeaseStatus(pRawResponse->GetHeaders().at("x-ms-lease-status"));
      }
      return Response<Models::FileProperties>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::DeleteFileResult> FileClient::Delete(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const DeleteFileOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Delete, url);
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::DeleteFileResult response;
      return Response<Models::DeleteFileResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetFilePropertiesResult> FileClient::SetHttpHeaders(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetFileHttpHeadersOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "properties");
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.FileContentLength.HasValue())
      {
        request.SetHeader("x-ms-content-length", std::to_string(options.FileContentLength.Value()));
      }
      if (options.FileContentType.HasValue() && !options.FileContentType.Value().empty())
      {
        request.SetHeader("x-ms-content-type", options.FileContentType.Value());
      }
      if (options.FileContentEncoding.HasValue() && !options.FileContentEncoding.Value().empty())
      {
        request.SetHeader("x-ms-content-encoding", options.FileContentEncoding.Value());
      }
      if (options.FileContentLanguage.HasValue() && !options.FileContentLanguage.Value().empty())
      {
        request.SetHeader("x-ms-content-language", options.FileContentLanguage.Value());
      }
      if (options.FileCacheControl.HasValue() && !options.FileCacheControl.Value().empty())
      {
        request.SetHeader("x-ms-cache-control", options.FileCacheControl.Value());
      }
      if (options.FileContentMD5.HasValue()
          && !Core::Convert::Base64Encode(options.FileContentMD5.Value()).empty())
      {
        request.SetHeader(
            "x-ms-content-md5", Core::Convert::Base64Encode(options.FileContentMD5.Value()));
      }
      if (options.FileContentDisposition.HasValue()
          && !options.FileContentDisposition.Value().empty())
      {
        request.SetHeader("x-ms-content-disposition", options.FileContentDisposition.Value());
      }
      if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty())
      {
        request.SetHeader("x-ms-file-permission", options.FilePermission.Value());
      }
      if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty())
      {
        request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value());
      }
      if (!options.FileAttributes.empty())
      {
        request.SetHeader("x-ms-file-attributes", options.FileAttributes);
      }
      if (!options.FileCreationTime.empty())
      {
        request.SetHeader("x-ms-file-creation-time", options.FileCreationTime);
      }
      if (!options.FileLastWriteTime.empty())
      {
        request.SetHeader("x-ms-file-last-write-time", options.FileLastWriteTime);
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetFilePropertiesResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      if (pRawResponse->GetHeaders().count("x-ms-file-permission-key") != 0)
      {
        response.SmbProperties.PermissionKey
            = pRawResponse->GetHeaders().at("x-ms-file-permission-key");
      }
      response.SmbProperties.Attributes
          = Models::FileAttributes(pRawResponse->GetHeaders().at("x-ms-file-attributes"));
      if (pRawResponse->GetHeaders().count("x-ms-file-creation-time") != 0)
      {
        response.SmbProperties.CreatedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-creation-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-last-write-time") != 0)
      {
        response.SmbProperties.LastWrittenOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-last-write-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      if (pRawResponse->GetHeaders().count("x-ms-file-change-time") != 0)
      {
        response.SmbProperties.ChangedOn = DateTime::Parse(
            pRawResponse->GetHeaders().at("x-ms-file-change-time"),
            Azure::DateTime::DateFormat::Rfc3339);
      }
      response.SmbProperties.FileId = pRawResponse->GetHeaders().at("x-ms-file-id");
      response.SmbProperties.ParentFileId = pRawResponse->GetHeaders().at("x-ms-file-parent-id");
      return Response<Models::SetFilePropertiesResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::SetFileMetadataResult> FileClient::SetMetadata(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const SetFileMetadataOptions& 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", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::SetFileMetadataResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.IsServerEncrypted
          = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      return Response<Models::SetFileMetadataResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::AcquireFileLeaseResult> FileClient::AcquireLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const AcquireFileLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "acquire");
      if (options.Duration.HasValue())
      {
        request.SetHeader("x-ms-lease-duration", std::to_string(options.Duration.Value()));
      }
      if (options.ProposedLeaseId.HasValue() && !options.ProposedLeaseId.Value().empty())
      {
        request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value());
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::AcquireFileLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id");
      return Response<Models::_detail::AcquireFileLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ReleaseFileLeaseResult> FileClient::ReleaseLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ReleaseFileLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "release");
      if (!options.LeaseId.empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId);
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ReleaseFileLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::_detail::ReleaseFileLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ChangeFileLeaseResult> FileClient::ChangeLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ChangeFileLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "change");
      if (!options.LeaseId.empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId);
      }
      if (options.ProposedLeaseId.HasValue() && !options.ProposedLeaseId.Value().empty())
      {
        request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value());
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ChangeFileLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.LeaseId = pRawResponse->GetHeaders().at("x-ms-lease-id");
      return Response<Models::_detail::ChangeFileLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::BreakFileLeaseResult> FileClient::BreakLease(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const BreakFileLeaseOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "lease");
      request.SetHeader("x-ms-lease-action", "break");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::BreakFileLeaseResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      return Response<Models::_detail::BreakFileLeaseResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::UploadFileRangeResult> FileClient::UploadRange(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        Core::IO::BodyStream& requestBody,
        const UploadFileRangeOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url, &requestBody);
      request.GetUrl().AppendQueryParameter("comp", "range");
      if (!options.Range.empty())
      {
        request.SetHeader("x-ms-range", options.Range);
      }
      if (!options.FileRangeWrite.empty())
      {
        request.SetHeader("x-ms-write", options.FileRangeWrite);
      }
      request.SetHeader("Content-Length", std::to_string(requestBody.Length()));
      if (options.ContentMD5.HasValue()
          && !Core::Convert::Base64Encode(options.ContentMD5.Value()).empty())
      {
        request.SetHeader("Content-MD5", Core::Convert::Base64Encode(options.ContentMD5.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::UploadFileRangeResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      if (pRawResponse->GetHeaders().count("Content-MD5") != 0)
      {
        response.TransactionalContentHash.Value
            = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("Content-MD5"));
        response.TransactionalContentHash.Algorithm = HashAlgorithm::Md5;
      }
      if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0)
      {
        response.IsServerEncrypted
            = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      }
      return Response<Models::UploadFileRangeResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::UploadFileRangeFromUriResult> FileClient::UploadRangeFromUri(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const UploadFileRangeFromUriOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "range");
      if (!options.Range.empty())
      {
        request.SetHeader("x-ms-range", options.Range);
      }
      if (!options.CopySource.empty())
      {
        request.SetHeader("x-ms-copy-source", options.CopySource);
      }
      if (options.SourceRange.HasValue() && !options.SourceRange.Value().empty())
      {
        request.SetHeader("x-ms-source-range", options.SourceRange.Value());
      }
      request.SetHeader("x-ms-write", "update");
      request.SetHeader("Content-Length", "0");
      if (options.SourceContentCrc64.HasValue()
          && !Core::Convert::Base64Encode(options.SourceContentCrc64.Value()).empty())
      {
        request.SetHeader(
            "x-ms-source-content-crc64",
            Core::Convert::Base64Encode(options.SourceContentCrc64.Value()));
      }
      if (options.SourceIfMatchCrc64.HasValue()
          && !Core::Convert::Base64Encode(options.SourceIfMatchCrc64.Value()).empty())
      {
        request.SetHeader(
            "x-ms-source-if-match-crc64",
            Core::Convert::Base64Encode(options.SourceIfMatchCrc64.Value()));
      }
      if (options.SourceIfNoneMatchCrc64.HasValue()
          && !Core::Convert::Base64Encode(options.SourceIfNoneMatchCrc64.Value()).empty())
      {
        request.SetHeader(
            "x-ms-source-if-none-match-crc64",
            Core::Convert::Base64Encode(options.SourceIfNoneMatchCrc64.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Created)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::UploadFileRangeFromUriResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      if (pRawResponse->GetHeaders().count("x-ms-content-crc64") != 0)
      {
        response.TransactionalContentHash.Value
            = Core::Convert::Base64Decode(pRawResponse->GetHeaders().at("x-ms-content-crc64"));
        response.TransactionalContentHash.Algorithm = HashAlgorithm::Crc64;
      }
      if (pRawResponse->GetHeaders().count("x-ms-request-server-encrypted") != 0)
      {
        response.IsServerEncrypted
            = pRawResponse->GetHeaders().at("x-ms-request-server-encrypted") == std::string("true");
      }
      return Response<Models::UploadFileRangeFromUriResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::GetFileRangeListResult> FileClient::GetRangeList(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const GetFileRangeListOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("comp", "rangelist");
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      if (options.Prevsharesnapshot.HasValue() && !options.Prevsharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "prevsharesnapshot",
            _internal::UrlEncodeQueryParameter(options.Prevsharesnapshot.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.Range.HasValue() && !options.Range.Value().empty())
      {
        request.SetHeader("x-ms-range", options.Range.Value());
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::GetFileRangeListResult response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kRanges,
          kRange,
          kStart,
          kEnd,
          kClearRange,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"Ranges", XmlTagEnum::kRanges},
            {"Range", XmlTagEnum::kRange},
            {"Start", XmlTagEnum::kStart},
            {"End", XmlTagEnum::kEnd},
            {"ClearRange", XmlTagEnum::kClearRange},
        };
        std::vector<XmlTagEnum> xmlPath;
        Core::Http::HttpRange vectorElement1;
        Core::Http::HttpRange vectorElement2;
        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::kRanges
                && xmlPath[1] == XmlTagEnum::kRange && xmlPath[2] == XmlTagEnum::kStart)
            {
              vectorElement1.Offset = std::stoll(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kRanges
                && xmlPath[1] == XmlTagEnum::kRange && xmlPath[2] == XmlTagEnum::kEnd)
            {
              vectorElement1.Length = std::stoll(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kRanges
                && xmlPath[1] == XmlTagEnum::kClearRange && xmlPath[2] == XmlTagEnum::kStart)
            {
              vectorElement2.Offset = std::stoll(node.Value);
            }
            else if (
                xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kRanges
                && xmlPath[1] == XmlTagEnum::kClearRange && xmlPath[2] == XmlTagEnum::kEnd)
            {
              vectorElement2.Length = std::stoll(node.Value);
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kRanges
                && xmlPath[1] == XmlTagEnum::kRange)
            {
              vectorElement1.Length = vectorElement1.Length.Value() - vectorElement1.Offset + 1;
              response.Ranges.push_back(std::move(vectorElement1));
              vectorElement1 = Core::Http::HttpRange();
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kRanges
                && xmlPath[1] == XmlTagEnum::kClearRange)
            {
              vectorElement2.Length = vectorElement2.Length.Value() - vectorElement2.Offset + 1;
              response.ClearRanges.push_back(std::move(vectorElement2));
              vectorElement2 = Core::Http::HttpRange();
            }
            xmlPath.pop_back();
          }
        }
      }
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.FileSize = std::stoll(pRawResponse->GetHeaders().at("x-ms-content-length"));
      return Response<Models::GetFileRangeListResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::StartFileCopyResult> FileClient::StartCopy(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const StartFileCopyOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.SetHeader("x-ms-version", "2020-02-10");
      for (const auto& p : options.Metadata)
      {
        request.SetHeader("x-ms-meta-" + p.first, p.second);
      }
      if (!options.CopySource.empty())
      {
        request.SetHeader("x-ms-copy-source", options.CopySource);
      }
      if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty())
      {
        request.SetHeader("x-ms-file-permission", options.FilePermission.Value());
      }
      if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty())
      {
        request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value());
      }
      if (options.FilePermissionCopyMode.HasValue()
          && !options.FilePermissionCopyMode.Value().ToString().empty())
      {
        request.SetHeader(
            "x-ms-file-permission-copy-mode", options.FilePermissionCopyMode.Value().ToString());
      }
      if (options.IgnoreReadOnly.HasValue())
      {
        request.SetHeader(
            "x-ms-file-copy-ignore-read-only", options.IgnoreReadOnly.Value() ? "true" : "false");
      }
      if (options.FileAttributes.HasValue() && !options.FileAttributes.Value().empty())
      {
        request.SetHeader("x-ms-file-attributes", options.FileAttributes.Value());
      }
      if (options.FileCreationTime.HasValue() && !options.FileCreationTime.Value().empty())
      {
        request.SetHeader("x-ms-file-creation-time", options.FileCreationTime.Value());
      }
      if (options.FileLastWriteTime.HasValue() && !options.FileLastWriteTime.Value().empty())
      {
        request.SetHeader("x-ms-file-last-write-time", options.FileLastWriteTime.Value());
      }
      if (options.SetArchiveAttribute.HasValue())
      {
        request.SetHeader(
            "x-ms-file-copy-set-archive", options.SetArchiveAttribute.Value() ? "true" : "false");
      }
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Accepted)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::StartFileCopyResult response;
      response.ETag = ETag(pRawResponse->GetHeaders().at("ETag"));
      response.LastModified = DateTime::Parse(
          pRawResponse->GetHeaders().at("Last-Modified"), Azure::DateTime::DateFormat::Rfc1123);
      response.CopyId = pRawResponse->GetHeaders().at("x-ms-copy-id");
      response.CopyStatus = Models::CopyStatus(pRawResponse->GetHeaders().at("x-ms-copy-status"));
      return Response<Models::_detail::StartFileCopyResult>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::AbortFileCopyResult> FileClient::AbortCopy(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const AbortFileCopyOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "copy");
      if (!options.CopyId.empty())
      {
        request.GetUrl().AppendQueryParameter(
            "copyid", _internal::UrlEncodeQueryParameter(options.CopyId));
      }
      request.SetHeader("x-ms-copy-action", "abort");
      request.SetHeader("x-ms-version", "2020-02-10");
      if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty())
      {
        request.SetHeader("x-ms-lease-id", options.LeaseId.Value());
      }
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::NoContent)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::AbortFileCopyResult response;
      return Response<Models::AbortFileCopyResult>(std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ListHandlesResponse> FileClient::ListHandles(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ListFileHandlesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url);
      request.GetUrl().AppendQueryParameter("comp", "listhandles");
      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.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ListHandlesResponse response;
      {
        const auto& responseBody = pRawResponse->GetBody();
        _internal::XmlReader reader(
            reinterpret_cast<const char*>(responseBody.data()), responseBody.size());
        enum class XmlTagEnum
        {
          kUnknown,
          kEnumerationResults,
          kHandleList,
          kHandle,
          kHandleId,
          kPath,
          kFileId,
          kParentId,
          kSessionId,
          kClientIp,
          kOpenTime,
          kLastReconnectTime,
          kNextMarker,
        };
        const std::unordered_map<std::string, XmlTagEnum> XmlTagEnumMap{
            {"EnumerationResults", XmlTagEnum::kEnumerationResults},
            {"HandleList", XmlTagEnum::kHandleList},
            {"Handle", XmlTagEnum::kHandle},
            {"HandleId", XmlTagEnum::kHandleId},
            {"Path", XmlTagEnum::kPath},
            {"FileId", XmlTagEnum::kFileId},
            {"ParentId", XmlTagEnum::kParentId},
            {"SessionId", XmlTagEnum::kSessionId},
            {"ClientIp", XmlTagEnum::kClientIp},
            {"OpenTime", XmlTagEnum::kOpenTime},
            {"LastReconnectTime", XmlTagEnum::kLastReconnectTime},
            {"NextMarker", XmlTagEnum::kNextMarker},
        };
        std::vector<XmlTagEnum> xmlPath;
        Models::HandleItem 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() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kHandleId)
            {
              vectorElement1.HandleId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kPath)
            {
              vectorElement1.Path = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kFileId)
            {
              vectorElement1.FileId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kParentId)
            {
              vectorElement1.ParentId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kSessionId)
            {
              vectorElement1.SessionId = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kClientIp)
            {
              vectorElement1.ClientIp = node.Value;
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kOpenTime)
            {
              vectorElement1.OpenedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 4 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle
                && xmlPath[3] == XmlTagEnum::kLastReconnectTime)
            {
              vectorElement1.LastReconnectedOn
                  = DateTime::Parse(node.Value, Azure::DateTime::DateFormat::Rfc1123);
            }
            else if (
                xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kNextMarker)
            {
              response.NextMarker = node.Value;
            }
          }
          else if (node.Type == _internal::XmlNodeType::Attribute)
          {
          }
          else if (node.Type == _internal::XmlNodeType::EndTag)
          {
            if (xmlPath.size() == 3 && xmlPath[0] == XmlTagEnum::kEnumerationResults
                && xmlPath[1] == XmlTagEnum::kHandleList && xmlPath[2] == XmlTagEnum::kHandle)
            {
              response.HandleList.push_back(std::move(vectorElement1));
              vectorElement1 = Models::HandleItem();
            }
            xmlPath.pop_back();
          }
        }
      }
      return Response<Models::_detail::ListHandlesResponse>(
          std::move(response), std::move(pRawResponse));
    }
    Response<Models::_detail::ForceFileCloseHandlesResult> FileClient::ForceCloseHandles(
        Core::Http::_internal::HttpPipeline& pipeline,
        const Core::Url& url,
        const ForceFileCloseHandlesOptions& options,
        const Core::Context& context)
    {
      auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url);
      request.GetUrl().AppendQueryParameter("comp", "forceclosehandles");
      if (options.Marker.HasValue() && !options.Marker.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "marker", _internal::UrlEncodeQueryParameter(options.Marker.Value()));
      }
      if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty())
      {
        request.GetUrl().AppendQueryParameter(
            "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value()));
      }
      if (!options.HandleId.empty())
      {
        request.SetHeader("x-ms-handle-id", options.HandleId);
      }
      request.SetHeader("x-ms-version", "2020-02-10");
      auto pRawResponse = pipeline.Send(request, context);
      auto httpStatusCode = pRawResponse->GetStatusCode();
      if (httpStatusCode != Core::Http::HttpStatusCode::Ok)
      {
        throw StorageException::CreateFromResponse(std::move(pRawResponse));
      }
      Models::_detail::ForceFileCloseHandlesResult response;
      if (pRawResponse->GetHeaders().count("x-ms-marker") != 0)
      {
        response.ContinuationToken = pRawResponse->GetHeaders().at("x-ms-marker");
      }
      response.NumberOfHandlesClosed
          = std::stoi(pRawResponse->GetHeaders().at("x-ms-number-of-handles-closed"));
      response.NumberOfHandlesFailedToClose
          = std::stoi(pRawResponse->GetHeaders().at("x-ms-number-of-handles-failed"));
      return Response<Models::_detail::ForceFileCloseHandlesResult>(
          std::move(response), std::move(pRawResponse));
    }
  } // namespace _detail
}}}} // namespace Azure::Storage::Files::Shares