text: /*
   * Copyright (c) Microsoft Corporation. All rights reserved.
   * Licensed under the MIT License. See License.txt in the project root for
   * license information.
   *
   * Code generated by Microsoft (R) AutoRest Code Generator.
   * Changes may cause incorrect behavior and will be lost if the code is
   * regenerated.
   */
  
  'use strict';
  
  const msRest = require('ms-rest');
  const msRestAzure = require('ms-rest-azure');
  const WebResource = msRest.WebResource;
  
  /**
   * Checks that the storage account name is valid and is not already in use.
   *
   * @param {string} name The storage account name.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link CheckNameAvailabilityResult} for more
   *                      information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _checkNameAvailability(name, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (name === null || name === undefined || typeof name.valueOf() !== 'string') {
        throw new Error('name cannot be null or undefined and it must be of type string.');
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
    let accountName = new client.models['StorageAccountCheckNameAvailabilityParameters']();
    try {
      if (name !== null && name !== undefined)
      {
        accountName.name = name;
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/providers/Microsoft.Storage/checkNameAvailability';
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'POST';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    // Serialize Request
    let requestContent = null;
    let requestModel = null;
    try {
      if (accountName !== null && accountName !== undefined) {
        let requestModelMapper = new client.models['StorageAccountCheckNameAvailabilityParameters']().mapper();
        requestModel = client.serialize(requestModelMapper, accountName, 'accountName');
        requestContent = JSON.stringify(requestModel);
      }
    } catch (error) {
      let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
          `payload - ${JSON.stringify(accountName, null, 2)}.`);
      return callback(serializationError);
    }
    httpRequest.body = requestContent;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['CheckNameAvailabilityResult']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  
  /**
   * Asynchronously creates a new storage account with the specified parameters.
   * If an account is already created and a subsequent create request is issued
   * with different properties, the account properties will be updated. If an
   * account is already created and a subsequent create or update request is
   * issued with the exact same set of properties, the request will succeed.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} parameters The parameters to provide for the created
   * account.
   *
   * @param {object} parameters.sku Required. Gets or sets the sku name.
   *
   * @param {string} parameters.sku.name Gets or sets the sku name. Required for
   * account creation; optional for update. Note that in older versions, sku name
   * was called accountType. Possible values include: 'Standard_LRS',
   * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
   * 'Premium_ZRS'
   *
   * @param {array} [parameters.sku.restrictions] The restrictions because of
   * which SKU cannot be used. This is empty if there are no restrictions.
   *
   * @param {string} parameters.kind Required. Indicates the type of storage
   * account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage',
   * 'FileStorage', 'BlockBlobStorage'
   *
   * @param {string} parameters.location Required. Gets or sets the location of
   * the resource. This will be one of the supported and registered Azure Geo
   * Regions (e.g. West US, East US, Southeast Asia, etc.). The geo region of a
   * resource cannot be changed once it is created, but if an identical geo
   * region is specified on update, the request will succeed.
   *
   * @param {object} [parameters.tags] Gets or sets a list of key value pairs
   * that describe the resource. These tags can be used for viewing and grouping
   * this resource (across resource groups). A maximum of 15 tags can be provided
   * for a resource. Each tag must have a key with a length no greater than 128
   * characters and a value with a length no greater than 256 characters.
   *
   * @param {object} [parameters.identity] The identity of the resource.
   *
   * @param {object} [parameters.customDomain] User domain assigned to the
   * storage account. Name is the CNAME source. Only one custom domain is
   * supported per storage account at this time. To clear the existing custom
   * domain, use an empty string for the custom domain name property.
   *
   * @param {string} parameters.customDomain.name Gets or sets the custom domain
   * name assigned to the storage account. Name is the CNAME source.
   *
   * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
   * indirect CName validation is enabled. Default value is false. This should
   * only be set on updates.
   *
   * @param {object} [parameters.encryption] Provides the encryption settings on
   * the account. If left unspecified the account encryption settings will remain
   * the same. The default setting is unencrypted.
   *
   * @param {object} [parameters.encryption.services] List of services which
   * support encryption.
   *
   * @param {object} [parameters.encryption.services.blob] The encryption
   * function of the blob storage service.
   *
   * @param {object} [parameters.encryption.services.file] The encryption
   * function of the file storage service.
   *
   * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
   * indicating whether or not the service encrypts the data as it is stored.
   *
   * @param {string} parameters.encryption.keySource The encryption keySource
   * (provider). Possible values (case-insensitive):  Microsoft.Storage,
   * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
   * 'Microsoft.Keyvault'
   *
   * @param {object} [parameters.encryption.keyVaultProperties] Properties
   * provided by key vault.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
   * of KeyVault key.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
   * version of KeyVault key.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
   * Uri of KeyVault.
   *
   * @param {object} [parameters.networkRuleSet] Network rule set
   *
   * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
   * is bypassed for Logging/Metrics/AzureServices. Possible values are any
   * combination of Logging|Metrics|AzureServices (For example, "Logging,
   * Metrics"), or None to bypass none of those traffics. Possible values
   * include: 'None', 'Logging', 'Metrics', 'AzureServices'
   *
   * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
   * virtual network rules
   *
   * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
   *
   * @param {string} parameters.networkRuleSet.defaultAction Specifies the
   * default action of allow or deny when no other rules match. Possible values
   * include: 'Allow', 'Deny'
   *
   * @param {string} [parameters.accessTier] Required for storage accounts where
   * kind = BlobStorage. The access tier used for billing. Possible values
   * include: 'Hot', 'Cool'
   *
   * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
   * Files AAD Integration for SMB if sets to true.
   *
   * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
   * only to storage service if sets to true.
   *
   * @param {boolean} [parameters.isHnsEnabled] Account HierarchicalNamespace
   * enabled if sets to true.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccount} for more information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _create(resourceGroupName, accountName, parameters, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
  
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
  
    // Send request
    this.beginCreate(resourceGroupName, accountName, parameters, options, (err, parsedResult, httpRequest, response) => {
      if (err) return callback(err);
  
      let initialResult = new msRest.HttpOperationResponse();
      initialResult.request = httpRequest;
      initialResult.response = response;
      initialResult.body = response.body;
      client.getLongRunningOperationResult(initialResult, options, (err, pollingResult) => {
        if (err) return callback(err);
  
        // Create Result
        let result = null;
  
        httpRequest = pollingResult.request;
        response = pollingResult.response;
        let responseBody = pollingResult.body;
        if (responseBody === '') responseBody = null;
  
        // Deserialize Response
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccount']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
  
        return callback(null, result, httpRequest, response);
      });
    });
  }
  
  /**
   * Deletes a storage account in Microsoft Azure.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _deleteMethod(resourceGroupName, accountName, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'DELETE';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    httpRequest.body = null;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200 && statusCode !== 204) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * Returns the properties for the specified storage account including but not
   * limited to name, SKU name, location, and account status. The ListKeys
   * operation should be used to retrieve storage keys.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccount} for more information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _getProperties(resourceGroupName, accountName, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'GET';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    httpRequest.body = null;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccount']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * The update operation can be used to update the SKU, encryption, access tier,
   * or tags for a storage account. It can also be used to map the account to a
   * custom domain. Only one custom domain is supported per storage account; the
   * replacement/change of custom domain is not supported. In order to replace an
   * old custom domain, the old value must be cleared/unregistered before a new
   * value can be set. The update of multiple properties is supported. This call
   * does not change the storage keys for the account. If you want to change the
   * storage account keys, use the regenerate keys operation. The location and
   * name of the storage account cannot be changed after creation.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} parameters The parameters to provide for the updated
   * account.
   *
   * @param {object} [parameters.sku] Gets or sets the SKU name. Note that the
   * SKU name cannot be updated to Standard_ZRS, Premium_LRS or Premium_ZRS, nor
   * can accounts of those sku names be updated to any other value.
   *
   * @param {string} parameters.sku.name Gets or sets the sku name. Required for
   * account creation; optional for update. Note that in older versions, sku name
   * was called accountType. Possible values include: 'Standard_LRS',
   * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
   * 'Premium_ZRS'
   *
   * @param {array} [parameters.sku.restrictions] The restrictions because of
   * which SKU cannot be used. This is empty if there are no restrictions.
   *
   * @param {object} [parameters.tags] Gets or sets a list of key value pairs
   * that describe the resource. These tags can be used in viewing and grouping
   * this resource (across resource groups). A maximum of 15 tags can be provided
   * for a resource. Each tag must have a key no greater in length than 128
   * characters and a value no greater in length than 256 characters.
   *
   * @param {object} [parameters.identity] The identity of the resource.
   *
   * @param {object} [parameters.customDomain] Custom domain assigned to the
   * storage account by the user. Name is the CNAME source. Only one custom
   * domain is supported per storage account at this time. To clear the existing
   * custom domain, use an empty string for the custom domain name property.
   *
   * @param {string} parameters.customDomain.name Gets or sets the custom domain
   * name assigned to the storage account. Name is the CNAME source.
   *
   * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
   * indirect CName validation is enabled. Default value is false. This should
   * only be set on updates.
   *
   * @param {object} [parameters.encryption] Provides the encryption settings on
   * the account. The default setting is unencrypted.
   *
   * @param {object} [parameters.encryption.services] List of services which
   * support encryption.
   *
   * @param {object} [parameters.encryption.services.blob] The encryption
   * function of the blob storage service.
   *
   * @param {object} [parameters.encryption.services.file] The encryption
   * function of the file storage service.
   *
   * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
   * indicating whether or not the service encrypts the data as it is stored.
   *
   * @param {string} parameters.encryption.keySource The encryption keySource
   * (provider). Possible values (case-insensitive):  Microsoft.Storage,
   * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
   * 'Microsoft.Keyvault'
   *
   * @param {object} [parameters.encryption.keyVaultProperties] Properties
   * provided by key vault.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
   * of KeyVault key.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
   * version of KeyVault key.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
   * Uri of KeyVault.
   *
   * @param {string} [parameters.accessTier] Required for storage accounts where
   * kind = BlobStorage. The access tier used for billing. Possible values
   * include: 'Hot', 'Cool'
   *
   * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
   * Files AAD Integration for SMB if sets to true.
   *
   * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
   * only to storage service if sets to true.
   *
   * @param {object} [parameters.networkRuleSet] Network rule set
   *
   * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
   * is bypassed for Logging/Metrics/AzureServices. Possible values are any
   * combination of Logging|Metrics|AzureServices (For example, "Logging,
   * Metrics"), or None to bypass none of those traffics. Possible values
   * include: 'None', 'Logging', 'Metrics', 'AzureServices'
   *
   * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
   * virtual network rules
   *
   * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
   *
   * @param {string} parameters.networkRuleSet.defaultAction Specifies the
   * default action of allow or deny when no other rules match. Possible values
   * include: 'Allow', 'Deny'
   *
   * @param {string} [parameters.kind] Optional. Indicates the type of storage
   * account. Currently only StorageV2 value supported by server. Possible values
   * include: 'Storage', 'StorageV2', 'BlobStorage', 'FileStorage',
   * 'BlockBlobStorage'
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccount} for more information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _update(resourceGroupName, accountName, parameters, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    if (parameters === null || parameters === undefined)
    {
      parameters = {};
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (parameters === null || parameters === undefined) {
        throw new Error('parameters cannot be null or undefined.');
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'PATCH';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    // Serialize Request
    let requestContent = null;
    let requestModel = null;
    try {
      if (parameters !== null && parameters !== undefined) {
        let requestModelMapper = new client.models['StorageAccountUpdateParameters']().mapper();
        requestModel = client.serialize(requestModelMapper, parameters, 'parameters');
        requestContent = JSON.stringify(requestModel);
      }
    } catch (error) {
      let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
          `payload - ${JSON.stringify(parameters, null, 2)}.`);
      return callback(serializationError);
    }
    httpRequest.body = requestContent;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccount']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * Lists all the storage accounts available under the subscription. Note that
   * storage keys are not returned; use the ListKeys operation for this.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccountListResult} for more
   *                      information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _list(options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/providers/Microsoft.Storage/storageAccounts';
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'GET';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    httpRequest.body = null;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccountListResult']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * Lists all the storage accounts available under the given resource group.
   * Note that storage keys are not returned; use the ListKeys operation for
   * this.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccountListResult} for more
   *                      information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _listByResourceGroup(resourceGroupName, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'GET';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    httpRequest.body = null;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccountListResult']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * Lists the access keys for the specified storage account.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccountListKeysResult} for more
   *                      information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _listKeys(resourceGroupName, accountName, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/listKeys';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'POST';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    httpRequest.body = null;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccountListKeysResult']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * Regenerates one of the access keys for the specified storage account.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {string} keyName The name of storage keys that want to be
   * regenerated, possible vaules are key1, key2.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccountListKeysResult} for more
   *                      information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _regenerateKey(resourceGroupName, accountName, keyName, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (keyName === null || keyName === undefined || typeof keyName.valueOf() !== 'string') {
        throw new Error('keyName cannot be null or undefined and it must be of type string.');
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
    let regenerateKeyParameter;
    if (keyName !== null && keyName !== undefined) {
      regenerateKeyParameter = new client.models['StorageAccountRegenerateKeyParameters']();
      regenerateKeyParameter.keyName = keyName;
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/regenerateKey';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'POST';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    // Serialize Request
    let requestContent = null;
    let requestModel = null;
    try {
      if (regenerateKeyParameter !== null && regenerateKeyParameter !== undefined) {
        let requestModelMapper = new client.models['StorageAccountRegenerateKeyParameters']().mapper();
        requestModel = client.serialize(requestModelMapper, regenerateKeyParameter, 'regenerateKeyParameter');
        requestContent = JSON.stringify(requestModel);
      }
    } catch (error) {
      let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
          `payload - ${JSON.stringify(regenerateKeyParameter, null, 2)}.`);
      return callback(serializationError);
    }
    httpRequest.body = requestContent;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccountListKeysResult']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * List SAS credentials of a storage account.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} parameters The parameters to provide to list SAS credentials
   * for the storage account.
   *
   * @param {string} parameters.services The signed services accessible with the
   * account SAS. Possible values include: Blob (b), Queue (q), Table (t), File
   * (f). Possible values include: 'b', 'q', 't', 'f'
   *
   * @param {string} parameters.resourceTypes The signed resource types that are
   * accessible with the account SAS. Service (s): Access to service-level APIs;
   * Container (c): Access to container-level APIs; Object (o): Access to
   * object-level APIs for blobs, queue messages, table entities, and files.
   * Possible values include: 's', 'c', 'o'
   *
   * @param {string} parameters.permissions The signed permissions for the
   * account SAS. Possible values include: Read (r), Write (w), Delete (d), List
   * (l), Add (a), Create (c), Update (u) and Process (p). Possible values
   * include: 'r', 'd', 'w', 'l', 'a', 'c', 'u', 'p'
   *
   * @param {string} [parameters.iPAddressOrRange] An IP address or a range of IP
   * addresses from which to accept requests.
   *
   * @param {string} [parameters.protocols] The protocol permitted for a request
   * made with the account SAS. Possible values include: 'https,http', 'https'
   *
   * @param {date} [parameters.sharedAccessStartTime] The time at which the SAS
   * becomes valid.
   *
   * @param {date} parameters.sharedAccessExpiryTime The time at which the shared
   * access signature becomes invalid.
   *
   * @param {string} [parameters.keyToSign] The key to sign the account SAS token
   * with.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ListAccountSasResponse} for more
   *                      information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _listAccountSAS(resourceGroupName, accountName, parameters, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (parameters === null || parameters === undefined) {
        throw new Error('parameters cannot be null or undefined.');
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/ListAccountSas';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'POST';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    // Serialize Request
    let requestContent = null;
    let requestModel = null;
    try {
      if (parameters !== null && parameters !== undefined) {
        let requestModelMapper = new client.models['AccountSasParameters']().mapper();
        requestModel = client.serialize(requestModelMapper, parameters, 'parameters');
        requestContent = JSON.stringify(requestModel);
      }
    } catch (error) {
      let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
          `payload - ${JSON.stringify(parameters, null, 2)}.`);
      return callback(serializationError);
    }
    httpRequest.body = requestContent;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['ListAccountSasResponse']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * List service SAS credentials of a specific resource.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} parameters The parameters to provide to list service SAS
   * credentials.
   *
   * @param {string} parameters.canonicalizedResource The canonical path to the
   * signed resource.
   *
   * @param {string} [parameters.resource] The signed services accessible with
   * the service SAS. Possible values include: Blob (b), Container (c), File (f),
   * Share (s). Possible values include: 'b', 'c', 'f', 's'
   *
   * @param {string} [parameters.permissions] The signed permissions for the
   * service SAS. Possible values include: Read (r), Write (w), Delete (d), List
   * (l), Add (a), Create (c), Update (u) and Process (p). Possible values
   * include: 'r', 'd', 'w', 'l', 'a', 'c', 'u', 'p'
   *
   * @param {string} [parameters.iPAddressOrRange] An IP address or a range of IP
   * addresses from which to accept requests.
   *
   * @param {string} [parameters.protocols] The protocol permitted for a request
   * made with the account SAS. Possible values include: 'https,http', 'https'
   *
   * @param {date} [parameters.sharedAccessStartTime] The time at which the SAS
   * becomes valid.
   *
   * @param {date} [parameters.sharedAccessExpiryTime] The time at which the
   * shared access signature becomes invalid.
   *
   * @param {string} [parameters.identifier] A unique value up to 64 characters
   * in length that correlates to an access policy specified for the container,
   * queue, or table.
   *
   * @param {string} [parameters.partitionKeyStart] The start of partition key.
   *
   * @param {string} [parameters.partitionKeyEnd] The end of partition key.
   *
   * @param {string} [parameters.rowKeyStart] The start of row key.
   *
   * @param {string} [parameters.rowKeyEnd] The end of row key.
   *
   * @param {string} [parameters.keyToSign] The key to sign the account SAS token
   * with.
   *
   * @param {string} [parameters.cacheControl] The response header override for
   * cache control.
   *
   * @param {string} [parameters.contentDisposition] The response header override
   * for content disposition.
   *
   * @param {string} [parameters.contentEncoding] The response header override
   * for content encoding.
   *
   * @param {string} [parameters.contentLanguage] The response header override
   * for content language.
   *
   * @param {string} [parameters.contentType] The response header override for
   * content type.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ListServiceSasResponse} for more
   *                      information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _listServiceSAS(resourceGroupName, accountName, parameters, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (parameters === null || parameters === undefined) {
        throw new Error('parameters cannot be null or undefined.');
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/ListServiceSas';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'POST';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    // Serialize Request
    let requestContent = null;
    let requestModel = null;
    try {
      if (parameters !== null && parameters !== undefined) {
        let requestModelMapper = new client.models['ServiceSasParameters']().mapper();
        requestModel = client.serialize(requestModelMapper, parameters, 'parameters');
        requestContent = JSON.stringify(requestModel);
      }
    } catch (error) {
      let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
          `payload - ${JSON.stringify(parameters, null, 2)}.`);
      return callback(serializationError);
    }
    httpRequest.body = requestContent;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['ListServiceSasResponse']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  
  /**
   * Failover request can be triggered for a storage account in case of
   * availability issues. The failover occurs from the storage account's primary
   * cluster to secondary cluster for RA-GRS accounts. The secondary cluster will
   * become primary after failover.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _failover(resourceGroupName, accountName, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
  
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
  
    // Send request
    this.beginFailover(resourceGroupName, accountName, options, (err, parsedResult, httpRequest, response) => {
      if (err) return callback(err);
  
      let initialResult = new msRest.HttpOperationResponse();
      initialResult.request = httpRequest;
      initialResult.response = response;
      initialResult.body = response.body;
      client.getLongRunningOperationResult(initialResult, options, (err, pollingResult) => {
        if (err) return callback(err);
  
        // Create Result
        let result = null;
  
        httpRequest = pollingResult.request;
        response = pollingResult.response;
        let responseBody = pollingResult.body;
        if (responseBody === '') responseBody = null;
  
        // Deserialize Response
  
        return callback(null, result, httpRequest, response);
      });
    });
  }
  
  /**
   * Asynchronously creates a new storage account with the specified parameters.
   * If an account is already created and a subsequent create request is issued
   * with different properties, the account properties will be updated. If an
   * account is already created and a subsequent create or update request is
   * issued with the exact same set of properties, the request will succeed.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} parameters The parameters to provide for the created
   * account.
   *
   * @param {object} parameters.sku Required. Gets or sets the sku name.
   *
   * @param {string} parameters.sku.name Gets or sets the sku name. Required for
   * account creation; optional for update. Note that in older versions, sku name
   * was called accountType. Possible values include: 'Standard_LRS',
   * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
   * 'Premium_ZRS'
   *
   * @param {array} [parameters.sku.restrictions] The restrictions because of
   * which SKU cannot be used. This is empty if there are no restrictions.
   *
   * @param {string} parameters.kind Required. Indicates the type of storage
   * account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage',
   * 'FileStorage', 'BlockBlobStorage'
   *
   * @param {string} parameters.location Required. Gets or sets the location of
   * the resource. This will be one of the supported and registered Azure Geo
   * Regions (e.g. West US, East US, Southeast Asia, etc.). The geo region of a
   * resource cannot be changed once it is created, but if an identical geo
   * region is specified on update, the request will succeed.
   *
   * @param {object} [parameters.tags] Gets or sets a list of key value pairs
   * that describe the resource. These tags can be used for viewing and grouping
   * this resource (across resource groups). A maximum of 15 tags can be provided
   * for a resource. Each tag must have a key with a length no greater than 128
   * characters and a value with a length no greater than 256 characters.
   *
   * @param {object} [parameters.identity] The identity of the resource.
   *
   * @param {object} [parameters.customDomain] User domain assigned to the
   * storage account. Name is the CNAME source. Only one custom domain is
   * supported per storage account at this time. To clear the existing custom
   * domain, use an empty string for the custom domain name property.
   *
   * @param {string} parameters.customDomain.name Gets or sets the custom domain
   * name assigned to the storage account. Name is the CNAME source.
   *
   * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
   * indirect CName validation is enabled. Default value is false. This should
   * only be set on updates.
   *
   * @param {object} [parameters.encryption] Provides the encryption settings on
   * the account. If left unspecified the account encryption settings will remain
   * the same. The default setting is unencrypted.
   *
   * @param {object} [parameters.encryption.services] List of services which
   * support encryption.
   *
   * @param {object} [parameters.encryption.services.blob] The encryption
   * function of the blob storage service.
   *
   * @param {object} [parameters.encryption.services.file] The encryption
   * function of the file storage service.
   *
   * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
   * indicating whether or not the service encrypts the data as it is stored.
   *
   * @param {string} parameters.encryption.keySource The encryption keySource
   * (provider). Possible values (case-insensitive):  Microsoft.Storage,
   * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
   * 'Microsoft.Keyvault'
   *
   * @param {object} [parameters.encryption.keyVaultProperties] Properties
   * provided by key vault.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
   * of KeyVault key.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
   * version of KeyVault key.
   *
   * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
   * Uri of KeyVault.
   *
   * @param {object} [parameters.networkRuleSet] Network rule set
   *
   * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
   * is bypassed for Logging/Metrics/AzureServices. Possible values are any
   * combination of Logging|Metrics|AzureServices (For example, "Logging,
   * Metrics"), or None to bypass none of those traffics. Possible values
   * include: 'None', 'Logging', 'Metrics', 'AzureServices'
   *
   * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
   * virtual network rules
   *
   * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
   *
   * @param {string} parameters.networkRuleSet.defaultAction Specifies the
   * default action of allow or deny when no other rules match. Possible values
   * include: 'Allow', 'Deny'
   *
   * @param {string} [parameters.accessTier] Required for storage accounts where
   * kind = BlobStorage. The access tier used for billing. Possible values
   * include: 'Hot', 'Cool'
   *
   * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
   * Files AAD Integration for SMB if sets to true.
   *
   * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
   * only to storage service if sets to true.
   *
   * @param {boolean} [parameters.isHnsEnabled] Account HierarchicalNamespace
   * enabled if sets to true.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link StorageAccount} for more information.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _beginCreate(resourceGroupName, accountName, parameters, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    if (parameters === null || parameters === undefined)
    {
      parameters = {};
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (parameters === null || parameters === undefined) {
        throw new Error('parameters cannot be null or undefined.');
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'PUT';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    // Serialize Request
    let requestContent = null;
    let requestModel = null;
    try {
      if (parameters !== null && parameters !== undefined) {
        let requestModelMapper = new client.models['StorageAccountCreateParameters']().mapper();
        requestModel = client.serialize(requestModelMapper, parameters, 'parameters');
        requestContent = JSON.stringify(requestModel);
      }
    } catch (error) {
      let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
          `payload - ${JSON.stringify(parameters, null, 2)}.`);
      return callback(serializationError);
    }
    httpRequest.body = requestContent;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200 && statusCode !== 202) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
      // Deserialize Response
      if (statusCode === 200) {
        let parsedResponse = null;
        try {
          parsedResponse = JSON.parse(responseBody);
          result = JSON.parse(responseBody);
          if (parsedResponse !== null && parsedResponse !== undefined) {
            let resultMapper = new client.models['StorageAccount']().mapper();
            result = client.deserialize(resultMapper, parsedResponse, 'result');
          }
        } catch (error) {
          let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
          deserializationError.request = msRest.stripRequest(httpRequest);
          deserializationError.response = msRest.stripResponse(response);
          return callback(deserializationError);
        }
      }
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /**
   * Failover request can be triggered for a storage account in case of
   * availability issues. The failover occurs from the storage account's primary
   * cluster to secondary cluster for RA-GRS accounts. The secondary cluster will
   * become primary after failover.
   *
   * @param {string} resourceGroupName The name of the resource group within the
   * user's subscription. The name is case insensitive.
   *
   * @param {string} accountName The name of the storage account within the
   * specified resource group. Storage account names must be between 3 and 24
   * characters in length and use numbers and lower-case letters only.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} callback - The callback.
   *
   * @returns {function} callback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  function _beginFailover(resourceGroupName, accountName, options, callback) {
     /* jshint validthis: true */
    let client = this.client;
    if(!callback && typeof options === 'function') {
      callback = options;
      options = null;
    }
    if (!callback) {
      throw new Error('callback cannot be null.');
    }
    let apiVersion = '2018-07-01';
    // Validate
    try {
      if (resourceGroupName === null || resourceGroupName === undefined || typeof resourceGroupName.valueOf() !== 'string') {
        throw new Error('resourceGroupName cannot be null or undefined and it must be of type string.');
      }
      if (resourceGroupName !== null && resourceGroupName !== undefined) {
        if (resourceGroupName.length > 90)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MaxLength": 90');
        }
        if (resourceGroupName.length < 1)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "MinLength": 1');
        }
        if (resourceGroupName.match(/^[-\w\._\(\)]+$/) === null)
        {
          throw new Error('"resourceGroupName" should satisfy the constraint - "Pattern": /^[-\w\._\(\)]+$/');
        }
      }
      if (accountName === null || accountName === undefined || typeof accountName.valueOf() !== 'string') {
        throw new Error('accountName cannot be null or undefined and it must be of type string.');
      }
      if (accountName !== null && accountName !== undefined) {
        if (accountName.length > 24)
        {
          throw new Error('"accountName" should satisfy the constraint - "MaxLength": 24');
        }
        if (accountName.length < 3)
        {
          throw new Error('"accountName" should satisfy the constraint - "MinLength": 3');
        }
      }
      if (this.client.subscriptionId === null || this.client.subscriptionId === undefined || typeof this.client.subscriptionId.valueOf() !== 'string') {
        throw new Error('this.client.subscriptionId cannot be null or undefined and it must be of type string.');
      }
      if (this.client.subscriptionId !== null && this.client.subscriptionId !== undefined) {
        if (this.client.subscriptionId.length < 1)
        {
          throw new Error('"this.client.subscriptionId" should satisfy the constraint - "MinLength": 1');
        }
      }
      if (this.client.acceptLanguage !== null && this.client.acceptLanguage !== undefined && typeof this.client.acceptLanguage.valueOf() !== 'string') {
        throw new Error('this.client.acceptLanguage must be of type string.');
      }
    } catch (error) {
      return callback(error);
    }
  
    // Construct URL
    let baseUrl = this.client.baseUri;
    let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/failover';
    requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
    requestUrl = requestUrl.replace('{accountName}', encodeURIComponent(accountName));
    requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
    let queryParameters = [];
    queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
    if (queryParameters.length > 0) {
      requestUrl += '?' + queryParameters.join('&');
    }
  
    // Create HTTP transport objects
    let httpRequest = new WebResource();
    httpRequest.method = 'POST';
    httpRequest.url = requestUrl;
    httpRequest.headers = {};
    // Set Headers
    httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
    if (this.client.generateClientRequestId) {
        httpRequest.headers['x-ms-client-request-id'] = msRestAzure.generateUuid();
    }
    if (this.client.acceptLanguage !== undefined && this.client.acceptLanguage !== null) {
      httpRequest.headers['accept-language'] = this.client.acceptLanguage;
    }
    if(options) {
      for(let headerName in options['customHeaders']) {
        if (options['customHeaders'].hasOwnProperty(headerName)) {
          httpRequest.headers[headerName] = options['customHeaders'][headerName];
        }
      }
    }
    httpRequest.body = null;
    // Send Request
    return client.pipeline(httpRequest, (err, response, responseBody) => {
      if (err) {
        return callback(err);
      }
      let statusCode = response.statusCode;
      if (statusCode !== 200 && statusCode !== 202) {
        let error = new Error(responseBody);
        error.statusCode = response.statusCode;
        error.request = msRest.stripRequest(httpRequest);
        error.response = msRest.stripResponse(response);
        if (responseBody === '') responseBody = null;
        let parsedErrorResponse;
        try {
          parsedErrorResponse = JSON.parse(responseBody);
          if (parsedErrorResponse) {
            if (parsedErrorResponse.error) parsedErrorResponse = parsedErrorResponse.error;
            if (parsedErrorResponse.code) error.code = parsedErrorResponse.code;
            if (parsedErrorResponse.message) error.message = parsedErrorResponse.message;
          }
          if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
            let resultMapper = new client.models['CloudError']().mapper();
            error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
          }
        } catch (defaultError) {
          error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                           `- "${responseBody}" for the default response.`;
          return callback(error);
        }
        return callback(error);
      }
      // Create Result
      let result = null;
      if (responseBody === '') responseBody = null;
  
      return callback(null, result, httpRequest, response);
    });
  }
  
  /** Class representing a StorageAccounts. */
  class StorageAccounts {
    /**
     * Create a StorageAccounts.
     * @param {StorageManagementClient} client Reference to the service client.
     */
    constructor(client) {
      this.client = client;
      this._checkNameAvailability = _checkNameAvailability;
      this._create = _create;
      this._deleteMethod = _deleteMethod;
      this._getProperties = _getProperties;
      this._update = _update;
      this._list = _list;
      this._listByResourceGroup = _listByResourceGroup;
      this._listKeys = _listKeys;
      this._regenerateKey = _regenerateKey;
      this._listAccountSAS = _listAccountSAS;
      this._listServiceSAS = _listServiceSAS;
      this._failover = _failover;
      this._beginCreate = _beginCreate;
      this._beginFailover = _beginFailover;
    }
  
    /**
     * Checks that the storage account name is valid and is not already in use.
     *
     * @param {string} name The storage account name.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<CheckNameAvailabilityResult>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    checkNameAvailabilityWithHttpOperationResponse(name, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._checkNameAvailability(name, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Checks that the storage account name is valid and is not already in use.
     *
     * @param {string} name The storage account name.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {CheckNameAvailabilityResult} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link CheckNameAvailabilityResult} for more
     *                      information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    checkNameAvailability(name, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._checkNameAvailability(name, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._checkNameAvailability(name, options, optionalCallback);
      }
    }
  
    /**
     * Asynchronously creates a new storage account with the specified parameters.
     * If an account is already created and a subsequent create request is issued
     * with different properties, the account properties will be updated. If an
     * account is already created and a subsequent create or update request is
     * issued with the exact same set of properties, the request will succeed.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide for the created
     * account.
     *
     * @param {object} parameters.sku Required. Gets or sets the sku name.
     *
     * @param {string} parameters.sku.name Gets or sets the sku name. Required for
     * account creation; optional for update. Note that in older versions, sku name
     * was called accountType. Possible values include: 'Standard_LRS',
     * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
     * 'Premium_ZRS'
     *
     * @param {array} [parameters.sku.restrictions] The restrictions because of
     * which SKU cannot be used. This is empty if there are no restrictions.
     *
     * @param {string} parameters.kind Required. Indicates the type of storage
     * account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage',
     * 'FileStorage', 'BlockBlobStorage'
     *
     * @param {string} parameters.location Required. Gets or sets the location of
     * the resource. This will be one of the supported and registered Azure Geo
     * Regions (e.g. West US, East US, Southeast Asia, etc.). The geo region of a
     * resource cannot be changed once it is created, but if an identical geo
     * region is specified on update, the request will succeed.
     *
     * @param {object} [parameters.tags] Gets or sets a list of key value pairs
     * that describe the resource. These tags can be used for viewing and grouping
     * this resource (across resource groups). A maximum of 15 tags can be provided
     * for a resource. Each tag must have a key with a length no greater than 128
     * characters and a value with a length no greater than 256 characters.
     *
     * @param {object} [parameters.identity] The identity of the resource.
     *
     * @param {object} [parameters.customDomain] User domain assigned to the
     * storage account. Name is the CNAME source. Only one custom domain is
     * supported per storage account at this time. To clear the existing custom
     * domain, use an empty string for the custom domain name property.
     *
     * @param {string} parameters.customDomain.name Gets or sets the custom domain
     * name assigned to the storage account. Name is the CNAME source.
     *
     * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
     * indirect CName validation is enabled. Default value is false. This should
     * only be set on updates.
     *
     * @param {object} [parameters.encryption] Provides the encryption settings on
     * the account. If left unspecified the account encryption settings will remain
     * the same. The default setting is unencrypted.
     *
     * @param {object} [parameters.encryption.services] List of services which
     * support encryption.
     *
     * @param {object} [parameters.encryption.services.blob] The encryption
     * function of the blob storage service.
     *
     * @param {object} [parameters.encryption.services.file] The encryption
     * function of the file storage service.
     *
     * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
     * indicating whether or not the service encrypts the data as it is stored.
     *
     * @param {string} parameters.encryption.keySource The encryption keySource
     * (provider). Possible values (case-insensitive):  Microsoft.Storage,
     * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
     * 'Microsoft.Keyvault'
     *
     * @param {object} [parameters.encryption.keyVaultProperties] Properties
     * provided by key vault.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
     * of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
     * version of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
     * Uri of KeyVault.
     *
     * @param {object} [parameters.networkRuleSet] Network rule set
     *
     * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
     * is bypassed for Logging/Metrics/AzureServices. Possible values are any
     * combination of Logging|Metrics|AzureServices (For example, "Logging,
     * Metrics"), or None to bypass none of those traffics. Possible values
     * include: 'None', 'Logging', 'Metrics', 'AzureServices'
     *
     * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
     * virtual network rules
     *
     * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
     *
     * @param {string} parameters.networkRuleSet.defaultAction Specifies the
     * default action of allow or deny when no other rules match. Possible values
     * include: 'Allow', 'Deny'
     *
     * @param {string} [parameters.accessTier] Required for storage accounts where
     * kind = BlobStorage. The access tier used for billing. Possible values
     * include: 'Hot', 'Cool'
     *
     * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
     * Files AAD Integration for SMB if sets to true.
     *
     * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
     * only to storage service if sets to true.
     *
     * @param {boolean} [parameters.isHnsEnabled] Account HierarchicalNamespace
     * enabled if sets to true.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccount>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    createWithHttpOperationResponse(resourceGroupName, accountName, parameters, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._create(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Asynchronously creates a new storage account with the specified parameters.
     * If an account is already created and a subsequent create request is issued
     * with different properties, the account properties will be updated. If an
     * account is already created and a subsequent create or update request is
     * issued with the exact same set of properties, the request will succeed.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide for the created
     * account.
     *
     * @param {object} parameters.sku Required. Gets or sets the sku name.
     *
     * @param {string} parameters.sku.name Gets or sets the sku name. Required for
     * account creation; optional for update. Note that in older versions, sku name
     * was called accountType. Possible values include: 'Standard_LRS',
     * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
     * 'Premium_ZRS'
     *
     * @param {array} [parameters.sku.restrictions] The restrictions because of
     * which SKU cannot be used. This is empty if there are no restrictions.
     *
     * @param {string} parameters.kind Required. Indicates the type of storage
     * account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage',
     * 'FileStorage', 'BlockBlobStorage'
     *
     * @param {string} parameters.location Required. Gets or sets the location of
     * the resource. This will be one of the supported and registered Azure Geo
     * Regions (e.g. West US, East US, Southeast Asia, etc.). The geo region of a
     * resource cannot be changed once it is created, but if an identical geo
     * region is specified on update, the request will succeed.
     *
     * @param {object} [parameters.tags] Gets or sets a list of key value pairs
     * that describe the resource. These tags can be used for viewing and grouping
     * this resource (across resource groups). A maximum of 15 tags can be provided
     * for a resource. Each tag must have a key with a length no greater than 128
     * characters and a value with a length no greater than 256 characters.
     *
     * @param {object} [parameters.identity] The identity of the resource.
     *
     * @param {object} [parameters.customDomain] User domain assigned to the
     * storage account. Name is the CNAME source. Only one custom domain is
     * supported per storage account at this time. To clear the existing custom
     * domain, use an empty string for the custom domain name property.
     *
     * @param {string} parameters.customDomain.name Gets or sets the custom domain
     * name assigned to the storage account. Name is the CNAME source.
     *
     * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
     * indirect CName validation is enabled. Default value is false. This should
     * only be set on updates.
     *
     * @param {object} [parameters.encryption] Provides the encryption settings on
     * the account. If left unspecified the account encryption settings will remain
     * the same. The default setting is unencrypted.
     *
     * @param {object} [parameters.encryption.services] List of services which
     * support encryption.
     *
     * @param {object} [parameters.encryption.services.blob] The encryption
     * function of the blob storage service.
     *
     * @param {object} [parameters.encryption.services.file] The encryption
     * function of the file storage service.
     *
     * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
     * indicating whether or not the service encrypts the data as it is stored.
     *
     * @param {string} parameters.encryption.keySource The encryption keySource
     * (provider). Possible values (case-insensitive):  Microsoft.Storage,
     * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
     * 'Microsoft.Keyvault'
     *
     * @param {object} [parameters.encryption.keyVaultProperties] Properties
     * provided by key vault.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
     * of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
     * version of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
     * Uri of KeyVault.
     *
     * @param {object} [parameters.networkRuleSet] Network rule set
     *
     * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
     * is bypassed for Logging/Metrics/AzureServices. Possible values are any
     * combination of Logging|Metrics|AzureServices (For example, "Logging,
     * Metrics"), or None to bypass none of those traffics. Possible values
     * include: 'None', 'Logging', 'Metrics', 'AzureServices'
     *
     * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
     * virtual network rules
     *
     * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
     *
     * @param {string} parameters.networkRuleSet.defaultAction Specifies the
     * default action of allow or deny when no other rules match. Possible values
     * include: 'Allow', 'Deny'
     *
     * @param {string} [parameters.accessTier] Required for storage accounts where
     * kind = BlobStorage. The access tier used for billing. Possible values
     * include: 'Hot', 'Cool'
     *
     * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
     * Files AAD Integration for SMB if sets to true.
     *
     * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
     * only to storage service if sets to true.
     *
     * @param {boolean} [parameters.isHnsEnabled] Account HierarchicalNamespace
     * enabled if sets to true.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccount} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccount} for more information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    create(resourceGroupName, accountName, parameters, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._create(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._create(resourceGroupName, accountName, parameters, options, optionalCallback);
      }
    }
  
    /**
     * Deletes a storage account in Microsoft Azure.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<null>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    deleteMethodWithHttpOperationResponse(resourceGroupName, accountName, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._deleteMethod(resourceGroupName, accountName, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Deletes a storage account in Microsoft Azure.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {null} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {null} [result]   - The deserialized result object if an error did not occur.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    deleteMethod(resourceGroupName, accountName, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._deleteMethod(resourceGroupName, accountName, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._deleteMethod(resourceGroupName, accountName, options, optionalCallback);
      }
    }
  
    /**
     * Returns the properties for the specified storage account including but not
     * limited to name, SKU name, location, and account status. The ListKeys
     * operation should be used to retrieve storage keys.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccount>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    getPropertiesWithHttpOperationResponse(resourceGroupName, accountName, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._getProperties(resourceGroupName, accountName, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Returns the properties for the specified storage account including but not
     * limited to name, SKU name, location, and account status. The ListKeys
     * operation should be used to retrieve storage keys.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccount} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccount} for more information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    getProperties(resourceGroupName, accountName, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._getProperties(resourceGroupName, accountName, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._getProperties(resourceGroupName, accountName, options, optionalCallback);
      }
    }
  
    /**
     * The update operation can be used to update the SKU, encryption, access tier,
     * or tags for a storage account. It can also be used to map the account to a
     * custom domain. Only one custom domain is supported per storage account; the
     * replacement/change of custom domain is not supported. In order to replace an
     * old custom domain, the old value must be cleared/unregistered before a new
     * value can be set. The update of multiple properties is supported. This call
     * does not change the storage keys for the account. If you want to change the
     * storage account keys, use the regenerate keys operation. The location and
     * name of the storage account cannot be changed after creation.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide for the updated
     * account.
     *
     * @param {object} [parameters.sku] Gets or sets the SKU name. Note that the
     * SKU name cannot be updated to Standard_ZRS, Premium_LRS or Premium_ZRS, nor
     * can accounts of those sku names be updated to any other value.
     *
     * @param {string} parameters.sku.name Gets or sets the sku name. Required for
     * account creation; optional for update. Note that in older versions, sku name
     * was called accountType. Possible values include: 'Standard_LRS',
     * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
     * 'Premium_ZRS'
     *
     * @param {array} [parameters.sku.restrictions] The restrictions because of
     * which SKU cannot be used. This is empty if there are no restrictions.
     *
     * @param {object} [parameters.tags] Gets or sets a list of key value pairs
     * that describe the resource. These tags can be used in viewing and grouping
     * this resource (across resource groups). A maximum of 15 tags can be provided
     * for a resource. Each tag must have a key no greater in length than 128
     * characters and a value no greater in length than 256 characters.
     *
     * @param {object} [parameters.identity] The identity of the resource.
     *
     * @param {object} [parameters.customDomain] Custom domain assigned to the
     * storage account by the user. Name is the CNAME source. Only one custom
     * domain is supported per storage account at this time. To clear the existing
     * custom domain, use an empty string for the custom domain name property.
     *
     * @param {string} parameters.customDomain.name Gets or sets the custom domain
     * name assigned to the storage account. Name is the CNAME source.
     *
     * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
     * indirect CName validation is enabled. Default value is false. This should
     * only be set on updates.
     *
     * @param {object} [parameters.encryption] Provides the encryption settings on
     * the account. The default setting is unencrypted.
     *
     * @param {object} [parameters.encryption.services] List of services which
     * support encryption.
     *
     * @param {object} [parameters.encryption.services.blob] The encryption
     * function of the blob storage service.
     *
     * @param {object} [parameters.encryption.services.file] The encryption
     * function of the file storage service.
     *
     * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
     * indicating whether or not the service encrypts the data as it is stored.
     *
     * @param {string} parameters.encryption.keySource The encryption keySource
     * (provider). Possible values (case-insensitive):  Microsoft.Storage,
     * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
     * 'Microsoft.Keyvault'
     *
     * @param {object} [parameters.encryption.keyVaultProperties] Properties
     * provided by key vault.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
     * of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
     * version of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
     * Uri of KeyVault.
     *
     * @param {string} [parameters.accessTier] Required for storage accounts where
     * kind = BlobStorage. The access tier used for billing. Possible values
     * include: 'Hot', 'Cool'
     *
     * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
     * Files AAD Integration for SMB if sets to true.
     *
     * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
     * only to storage service if sets to true.
     *
     * @param {object} [parameters.networkRuleSet] Network rule set
     *
     * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
     * is bypassed for Logging/Metrics/AzureServices. Possible values are any
     * combination of Logging|Metrics|AzureServices (For example, "Logging,
     * Metrics"), or None to bypass none of those traffics. Possible values
     * include: 'None', 'Logging', 'Metrics', 'AzureServices'
     *
     * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
     * virtual network rules
     *
     * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
     *
     * @param {string} parameters.networkRuleSet.defaultAction Specifies the
     * default action of allow or deny when no other rules match. Possible values
     * include: 'Allow', 'Deny'
     *
     * @param {string} [parameters.kind] Optional. Indicates the type of storage
     * account. Currently only StorageV2 value supported by server. Possible values
     * include: 'Storage', 'StorageV2', 'BlobStorage', 'FileStorage',
     * 'BlockBlobStorage'
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccount>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    updateWithHttpOperationResponse(resourceGroupName, accountName, parameters, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._update(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * The update operation can be used to update the SKU, encryption, access tier,
     * or tags for a storage account. It can also be used to map the account to a
     * custom domain. Only one custom domain is supported per storage account; the
     * replacement/change of custom domain is not supported. In order to replace an
     * old custom domain, the old value must be cleared/unregistered before a new
     * value can be set. The update of multiple properties is supported. This call
     * does not change the storage keys for the account. If you want to change the
     * storage account keys, use the regenerate keys operation. The location and
     * name of the storage account cannot be changed after creation.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide for the updated
     * account.
     *
     * @param {object} [parameters.sku] Gets or sets the SKU name. Note that the
     * SKU name cannot be updated to Standard_ZRS, Premium_LRS or Premium_ZRS, nor
     * can accounts of those sku names be updated to any other value.
     *
     * @param {string} parameters.sku.name Gets or sets the sku name. Required for
     * account creation; optional for update. Note that in older versions, sku name
     * was called accountType. Possible values include: 'Standard_LRS',
     * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
     * 'Premium_ZRS'
     *
     * @param {array} [parameters.sku.restrictions] The restrictions because of
     * which SKU cannot be used. This is empty if there are no restrictions.
     *
     * @param {object} [parameters.tags] Gets or sets a list of key value pairs
     * that describe the resource. These tags can be used in viewing and grouping
     * this resource (across resource groups). A maximum of 15 tags can be provided
     * for a resource. Each tag must have a key no greater in length than 128
     * characters and a value no greater in length than 256 characters.
     *
     * @param {object} [parameters.identity] The identity of the resource.
     *
     * @param {object} [parameters.customDomain] Custom domain assigned to the
     * storage account by the user. Name is the CNAME source. Only one custom
     * domain is supported per storage account at this time. To clear the existing
     * custom domain, use an empty string for the custom domain name property.
     *
     * @param {string} parameters.customDomain.name Gets or sets the custom domain
     * name assigned to the storage account. Name is the CNAME source.
     *
     * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
     * indirect CName validation is enabled. Default value is false. This should
     * only be set on updates.
     *
     * @param {object} [parameters.encryption] Provides the encryption settings on
     * the account. The default setting is unencrypted.
     *
     * @param {object} [parameters.encryption.services] List of services which
     * support encryption.
     *
     * @param {object} [parameters.encryption.services.blob] The encryption
     * function of the blob storage service.
     *
     * @param {object} [parameters.encryption.services.file] The encryption
     * function of the file storage service.
     *
     * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
     * indicating whether or not the service encrypts the data as it is stored.
     *
     * @param {string} parameters.encryption.keySource The encryption keySource
     * (provider). Possible values (case-insensitive):  Microsoft.Storage,
     * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
     * 'Microsoft.Keyvault'
     *
     * @param {object} [parameters.encryption.keyVaultProperties] Properties
     * provided by key vault.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
     * of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
     * version of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
     * Uri of KeyVault.
     *
     * @param {string} [parameters.accessTier] Required for storage accounts where
     * kind = BlobStorage. The access tier used for billing. Possible values
     * include: 'Hot', 'Cool'
     *
     * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
     * Files AAD Integration for SMB if sets to true.
     *
     * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
     * only to storage service if sets to true.
     *
     * @param {object} [parameters.networkRuleSet] Network rule set
     *
     * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
     * is bypassed for Logging/Metrics/AzureServices. Possible values are any
     * combination of Logging|Metrics|AzureServices (For example, "Logging,
     * Metrics"), or None to bypass none of those traffics. Possible values
     * include: 'None', 'Logging', 'Metrics', 'AzureServices'
     *
     * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
     * virtual network rules
     *
     * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
     *
     * @param {string} parameters.networkRuleSet.defaultAction Specifies the
     * default action of allow or deny when no other rules match. Possible values
     * include: 'Allow', 'Deny'
     *
     * @param {string} [parameters.kind] Optional. Indicates the type of storage
     * account. Currently only StorageV2 value supported by server. Possible values
     * include: 'Storage', 'StorageV2', 'BlobStorage', 'FileStorage',
     * 'BlockBlobStorage'
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccount} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccount} for more information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    update(resourceGroupName, accountName, parameters, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._update(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._update(resourceGroupName, accountName, parameters, options, optionalCallback);
      }
    }
  
    /**
     * Lists all the storage accounts available under the subscription. Note that
     * storage keys are not returned; use the ListKeys operation for this.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccountListResult>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    listWithHttpOperationResponse(options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._list(options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Lists all the storage accounts available under the subscription. Note that
     * storage keys are not returned; use the ListKeys operation for this.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccountListResult} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccountListResult} for more
     *                      information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    list(options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._list(options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._list(options, optionalCallback);
      }
    }
  
    /**
     * Lists all the storage accounts available under the given resource group.
     * Note that storage keys are not returned; use the ListKeys operation for
     * this.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccountListResult>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    listByResourceGroupWithHttpOperationResponse(resourceGroupName, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._listByResourceGroup(resourceGroupName, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Lists all the storage accounts available under the given resource group.
     * Note that storage keys are not returned; use the ListKeys operation for
     * this.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccountListResult} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccountListResult} for more
     *                      information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    listByResourceGroup(resourceGroupName, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._listByResourceGroup(resourceGroupName, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._listByResourceGroup(resourceGroupName, options, optionalCallback);
      }
    }
  
    /**
     * Lists the access keys for the specified storage account.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccountListKeysResult>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    listKeysWithHttpOperationResponse(resourceGroupName, accountName, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._listKeys(resourceGroupName, accountName, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Lists the access keys for the specified storage account.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccountListKeysResult} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccountListKeysResult} for more
     *                      information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    listKeys(resourceGroupName, accountName, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._listKeys(resourceGroupName, accountName, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._listKeys(resourceGroupName, accountName, options, optionalCallback);
      }
    }
  
    /**
     * Regenerates one of the access keys for the specified storage account.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {string} keyName The name of storage keys that want to be
     * regenerated, possible vaules are key1, key2.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccountListKeysResult>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    regenerateKeyWithHttpOperationResponse(resourceGroupName, accountName, keyName, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._regenerateKey(resourceGroupName, accountName, keyName, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Regenerates one of the access keys for the specified storage account.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {string} keyName The name of storage keys that want to be
     * regenerated, possible vaules are key1, key2.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccountListKeysResult} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccountListKeysResult} for more
     *                      information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    regenerateKey(resourceGroupName, accountName, keyName, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._regenerateKey(resourceGroupName, accountName, keyName, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._regenerateKey(resourceGroupName, accountName, keyName, options, optionalCallback);
      }
    }
  
    /**
     * List SAS credentials of a storage account.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide to list SAS credentials
     * for the storage account.
     *
     * @param {string} parameters.services The signed services accessible with the
     * account SAS. Possible values include: Blob (b), Queue (q), Table (t), File
     * (f). Possible values include: 'b', 'q', 't', 'f'
     *
     * @param {string} parameters.resourceTypes The signed resource types that are
     * accessible with the account SAS. Service (s): Access to service-level APIs;
     * Container (c): Access to container-level APIs; Object (o): Access to
     * object-level APIs for blobs, queue messages, table entities, and files.
     * Possible values include: 's', 'c', 'o'
     *
     * @param {string} parameters.permissions The signed permissions for the
     * account SAS. Possible values include: Read (r), Write (w), Delete (d), List
     * (l), Add (a), Create (c), Update (u) and Process (p). Possible values
     * include: 'r', 'd', 'w', 'l', 'a', 'c', 'u', 'p'
     *
     * @param {string} [parameters.iPAddressOrRange] An IP address or a range of IP
     * addresses from which to accept requests.
     *
     * @param {string} [parameters.protocols] The protocol permitted for a request
     * made with the account SAS. Possible values include: 'https,http', 'https'
     *
     * @param {date} [parameters.sharedAccessStartTime] The time at which the SAS
     * becomes valid.
     *
     * @param {date} parameters.sharedAccessExpiryTime The time at which the shared
     * access signature becomes invalid.
     *
     * @param {string} [parameters.keyToSign] The key to sign the account SAS token
     * with.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<ListAccountSasResponse>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    listAccountSASWithHttpOperationResponse(resourceGroupName, accountName, parameters, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._listAccountSAS(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * List SAS credentials of a storage account.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide to list SAS credentials
     * for the storage account.
     *
     * @param {string} parameters.services The signed services accessible with the
     * account SAS. Possible values include: Blob (b), Queue (q), Table (t), File
     * (f). Possible values include: 'b', 'q', 't', 'f'
     *
     * @param {string} parameters.resourceTypes The signed resource types that are
     * accessible with the account SAS. Service (s): Access to service-level APIs;
     * Container (c): Access to container-level APIs; Object (o): Access to
     * object-level APIs for blobs, queue messages, table entities, and files.
     * Possible values include: 's', 'c', 'o'
     *
     * @param {string} parameters.permissions The signed permissions for the
     * account SAS. Possible values include: Read (r), Write (w), Delete (d), List
     * (l), Add (a), Create (c), Update (u) and Process (p). Possible values
     * include: 'r', 'd', 'w', 'l', 'a', 'c', 'u', 'p'
     *
     * @param {string} [parameters.iPAddressOrRange] An IP address or a range of IP
     * addresses from which to accept requests.
     *
     * @param {string} [parameters.protocols] The protocol permitted for a request
     * made with the account SAS. Possible values include: 'https,http', 'https'
     *
     * @param {date} [parameters.sharedAccessStartTime] The time at which the SAS
     * becomes valid.
     *
     * @param {date} parameters.sharedAccessExpiryTime The time at which the shared
     * access signature becomes invalid.
     *
     * @param {string} [parameters.keyToSign] The key to sign the account SAS token
     * with.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {ListAccountSasResponse} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link ListAccountSasResponse} for more
     *                      information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    listAccountSAS(resourceGroupName, accountName, parameters, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._listAccountSAS(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._listAccountSAS(resourceGroupName, accountName, parameters, options, optionalCallback);
      }
    }
  
    /**
     * List service SAS credentials of a specific resource.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide to list service SAS
     * credentials.
     *
     * @param {string} parameters.canonicalizedResource The canonical path to the
     * signed resource.
     *
     * @param {string} [parameters.resource] The signed services accessible with
     * the service SAS. Possible values include: Blob (b), Container (c), File (f),
     * Share (s). Possible values include: 'b', 'c', 'f', 's'
     *
     * @param {string} [parameters.permissions] The signed permissions for the
     * service SAS. Possible values include: Read (r), Write (w), Delete (d), List
     * (l), Add (a), Create (c), Update (u) and Process (p). Possible values
     * include: 'r', 'd', 'w', 'l', 'a', 'c', 'u', 'p'
     *
     * @param {string} [parameters.iPAddressOrRange] An IP address or a range of IP
     * addresses from which to accept requests.
     *
     * @param {string} [parameters.protocols] The protocol permitted for a request
     * made with the account SAS. Possible values include: 'https,http', 'https'
     *
     * @param {date} [parameters.sharedAccessStartTime] The time at which the SAS
     * becomes valid.
     *
     * @param {date} [parameters.sharedAccessExpiryTime] The time at which the
     * shared access signature becomes invalid.
     *
     * @param {string} [parameters.identifier] A unique value up to 64 characters
     * in length that correlates to an access policy specified for the container,
     * queue, or table.
     *
     * @param {string} [parameters.partitionKeyStart] The start of partition key.
     *
     * @param {string} [parameters.partitionKeyEnd] The end of partition key.
     *
     * @param {string} [parameters.rowKeyStart] The start of row key.
     *
     * @param {string} [parameters.rowKeyEnd] The end of row key.
     *
     * @param {string} [parameters.keyToSign] The key to sign the account SAS token
     * with.
     *
     * @param {string} [parameters.cacheControl] The response header override for
     * cache control.
     *
     * @param {string} [parameters.contentDisposition] The response header override
     * for content disposition.
     *
     * @param {string} [parameters.contentEncoding] The response header override
     * for content encoding.
     *
     * @param {string} [parameters.contentLanguage] The response header override
     * for content language.
     *
     * @param {string} [parameters.contentType] The response header override for
     * content type.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<ListServiceSasResponse>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    listServiceSASWithHttpOperationResponse(resourceGroupName, accountName, parameters, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._listServiceSAS(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * List service SAS credentials of a specific resource.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide to list service SAS
     * credentials.
     *
     * @param {string} parameters.canonicalizedResource The canonical path to the
     * signed resource.
     *
     * @param {string} [parameters.resource] The signed services accessible with
     * the service SAS. Possible values include: Blob (b), Container (c), File (f),
     * Share (s). Possible values include: 'b', 'c', 'f', 's'
     *
     * @param {string} [parameters.permissions] The signed permissions for the
     * service SAS. Possible values include: Read (r), Write (w), Delete (d), List
     * (l), Add (a), Create (c), Update (u) and Process (p). Possible values
     * include: 'r', 'd', 'w', 'l', 'a', 'c', 'u', 'p'
     *
     * @param {string} [parameters.iPAddressOrRange] An IP address or a range of IP
     * addresses from which to accept requests.
     *
     * @param {string} [parameters.protocols] The protocol permitted for a request
     * made with the account SAS. Possible values include: 'https,http', 'https'
     *
     * @param {date} [parameters.sharedAccessStartTime] The time at which the SAS
     * becomes valid.
     *
     * @param {date} [parameters.sharedAccessExpiryTime] The time at which the
     * shared access signature becomes invalid.
     *
     * @param {string} [parameters.identifier] A unique value up to 64 characters
     * in length that correlates to an access policy specified for the container,
     * queue, or table.
     *
     * @param {string} [parameters.partitionKeyStart] The start of partition key.
     *
     * @param {string} [parameters.partitionKeyEnd] The end of partition key.
     *
     * @param {string} [parameters.rowKeyStart] The start of row key.
     *
     * @param {string} [parameters.rowKeyEnd] The end of row key.
     *
     * @param {string} [parameters.keyToSign] The key to sign the account SAS token
     * with.
     *
     * @param {string} [parameters.cacheControl] The response header override for
     * cache control.
     *
     * @param {string} [parameters.contentDisposition] The response header override
     * for content disposition.
     *
     * @param {string} [parameters.contentEncoding] The response header override
     * for content encoding.
     *
     * @param {string} [parameters.contentLanguage] The response header override
     * for content language.
     *
     * @param {string} [parameters.contentType] The response header override for
     * content type.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {ListServiceSasResponse} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link ListServiceSasResponse} for more
     *                      information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    listServiceSAS(resourceGroupName, accountName, parameters, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._listServiceSAS(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._listServiceSAS(resourceGroupName, accountName, parameters, options, optionalCallback);
      }
    }
  
    /**
     * Failover request can be triggered for a storage account in case of
     * availability issues. The failover occurs from the storage account's primary
     * cluster to secondary cluster for RA-GRS accounts. The secondary cluster will
     * become primary after failover.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<null>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    failoverWithHttpOperationResponse(resourceGroupName, accountName, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._failover(resourceGroupName, accountName, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Failover request can be triggered for a storage account in case of
     * availability issues. The failover occurs from the storage account's primary
     * cluster to secondary cluster for RA-GRS accounts. The secondary cluster will
     * become primary after failover.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {null} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {null} [result]   - The deserialized result object if an error did not occur.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    failover(resourceGroupName, accountName, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._failover(resourceGroupName, accountName, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._failover(resourceGroupName, accountName, options, optionalCallback);
      }
    }
  
    /**
     * Asynchronously creates a new storage account with the specified parameters.
     * If an account is already created and a subsequent create request is issued
     * with different properties, the account properties will be updated. If an
     * account is already created and a subsequent create or update request is
     * issued with the exact same set of properties, the request will succeed.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide for the created
     * account.
     *
     * @param {object} parameters.sku Required. Gets or sets the sku name.
     *
     * @param {string} parameters.sku.name Gets or sets the sku name. Required for
     * account creation; optional for update. Note that in older versions, sku name
     * was called accountType. Possible values include: 'Standard_LRS',
     * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
     * 'Premium_ZRS'
     *
     * @param {array} [parameters.sku.restrictions] The restrictions because of
     * which SKU cannot be used. This is empty if there are no restrictions.
     *
     * @param {string} parameters.kind Required. Indicates the type of storage
     * account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage',
     * 'FileStorage', 'BlockBlobStorage'
     *
     * @param {string} parameters.location Required. Gets or sets the location of
     * the resource. This will be one of the supported and registered Azure Geo
     * Regions (e.g. West US, East US, Southeast Asia, etc.). The geo region of a
     * resource cannot be changed once it is created, but if an identical geo
     * region is specified on update, the request will succeed.
     *
     * @param {object} [parameters.tags] Gets or sets a list of key value pairs
     * that describe the resource. These tags can be used for viewing and grouping
     * this resource (across resource groups). A maximum of 15 tags can be provided
     * for a resource. Each tag must have a key with a length no greater than 128
     * characters and a value with a length no greater than 256 characters.
     *
     * @param {object} [parameters.identity] The identity of the resource.
     *
     * @param {object} [parameters.customDomain] User domain assigned to the
     * storage account. Name is the CNAME source. Only one custom domain is
     * supported per storage account at this time. To clear the existing custom
     * domain, use an empty string for the custom domain name property.
     *
     * @param {string} parameters.customDomain.name Gets or sets the custom domain
     * name assigned to the storage account. Name is the CNAME source.
     *
     * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
     * indirect CName validation is enabled. Default value is false. This should
     * only be set on updates.
     *
     * @param {object} [parameters.encryption] Provides the encryption settings on
     * the account. If left unspecified the account encryption settings will remain
     * the same. The default setting is unencrypted.
     *
     * @param {object} [parameters.encryption.services] List of services which
     * support encryption.
     *
     * @param {object} [parameters.encryption.services.blob] The encryption
     * function of the blob storage service.
     *
     * @param {object} [parameters.encryption.services.file] The encryption
     * function of the file storage service.
     *
     * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
     * indicating whether or not the service encrypts the data as it is stored.
     *
     * @param {string} parameters.encryption.keySource The encryption keySource
     * (provider). Possible values (case-insensitive):  Microsoft.Storage,
     * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
     * 'Microsoft.Keyvault'
     *
     * @param {object} [parameters.encryption.keyVaultProperties] Properties
     * provided by key vault.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
     * of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
     * version of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
     * Uri of KeyVault.
     *
     * @param {object} [parameters.networkRuleSet] Network rule set
     *
     * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
     * is bypassed for Logging/Metrics/AzureServices. Possible values are any
     * combination of Logging|Metrics|AzureServices (For example, "Logging,
     * Metrics"), or None to bypass none of those traffics. Possible values
     * include: 'None', 'Logging', 'Metrics', 'AzureServices'
     *
     * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
     * virtual network rules
     *
     * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
     *
     * @param {string} parameters.networkRuleSet.defaultAction Specifies the
     * default action of allow or deny when no other rules match. Possible values
     * include: 'Allow', 'Deny'
     *
     * @param {string} [parameters.accessTier] Required for storage accounts where
     * kind = BlobStorage. The access tier used for billing. Possible values
     * include: 'Hot', 'Cool'
     *
     * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
     * Files AAD Integration for SMB if sets to true.
     *
     * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
     * only to storage service if sets to true.
     *
     * @param {boolean} [parameters.isHnsEnabled] Account HierarchicalNamespace
     * enabled if sets to true.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<StorageAccount>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    beginCreateWithHttpOperationResponse(resourceGroupName, accountName, parameters, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._beginCreate(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Asynchronously creates a new storage account with the specified parameters.
     * If an account is already created and a subsequent create request is issued
     * with different properties, the account properties will be updated. If an
     * account is already created and a subsequent create or update request is
     * issued with the exact same set of properties, the request will succeed.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} parameters The parameters to provide for the created
     * account.
     *
     * @param {object} parameters.sku Required. Gets or sets the sku name.
     *
     * @param {string} parameters.sku.name Gets or sets the sku name. Required for
     * account creation; optional for update. Note that in older versions, sku name
     * was called accountType. Possible values include: 'Standard_LRS',
     * 'Standard_GRS', 'Standard_RAGRS', 'Standard_ZRS', 'Premium_LRS',
     * 'Premium_ZRS'
     *
     * @param {array} [parameters.sku.restrictions] The restrictions because of
     * which SKU cannot be used. This is empty if there are no restrictions.
     *
     * @param {string} parameters.kind Required. Indicates the type of storage
     * account. Possible values include: 'Storage', 'StorageV2', 'BlobStorage',
     * 'FileStorage', 'BlockBlobStorage'
     *
     * @param {string} parameters.location Required. Gets or sets the location of
     * the resource. This will be one of the supported and registered Azure Geo
     * Regions (e.g. West US, East US, Southeast Asia, etc.). The geo region of a
     * resource cannot be changed once it is created, but if an identical geo
     * region is specified on update, the request will succeed.
     *
     * @param {object} [parameters.tags] Gets or sets a list of key value pairs
     * that describe the resource. These tags can be used for viewing and grouping
     * this resource (across resource groups). A maximum of 15 tags can be provided
     * for a resource. Each tag must have a key with a length no greater than 128
     * characters and a value with a length no greater than 256 characters.
     *
     * @param {object} [parameters.identity] The identity of the resource.
     *
     * @param {object} [parameters.customDomain] User domain assigned to the
     * storage account. Name is the CNAME source. Only one custom domain is
     * supported per storage account at this time. To clear the existing custom
     * domain, use an empty string for the custom domain name property.
     *
     * @param {string} parameters.customDomain.name Gets or sets the custom domain
     * name assigned to the storage account. Name is the CNAME source.
     *
     * @param {boolean} [parameters.customDomain.useSubDomain] Indicates whether
     * indirect CName validation is enabled. Default value is false. This should
     * only be set on updates.
     *
     * @param {object} [parameters.encryption] Provides the encryption settings on
     * the account. If left unspecified the account encryption settings will remain
     * the same. The default setting is unencrypted.
     *
     * @param {object} [parameters.encryption.services] List of services which
     * support encryption.
     *
     * @param {object} [parameters.encryption.services.blob] The encryption
     * function of the blob storage service.
     *
     * @param {object} [parameters.encryption.services.file] The encryption
     * function of the file storage service.
     *
     * @param {boolean} [parameters.encryption.services.file.enabled] A boolean
     * indicating whether or not the service encrypts the data as it is stored.
     *
     * @param {string} parameters.encryption.keySource The encryption keySource
     * (provider). Possible values (case-insensitive):  Microsoft.Storage,
     * Microsoft.Keyvault. Possible values include: 'Microsoft.Storage',
     * 'Microsoft.Keyvault'
     *
     * @param {object} [parameters.encryption.keyVaultProperties] Properties
     * provided by key vault.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyName] The name
     * of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVersion] The
     * version of KeyVault key.
     *
     * @param {string} [parameters.encryption.keyVaultProperties.keyVaultUri] The
     * Uri of KeyVault.
     *
     * @param {object} [parameters.networkRuleSet] Network rule set
     *
     * @param {string} [parameters.networkRuleSet.bypass] Specifies whether traffic
     * is bypassed for Logging/Metrics/AzureServices. Possible values are any
     * combination of Logging|Metrics|AzureServices (For example, "Logging,
     * Metrics"), or None to bypass none of those traffics. Possible values
     * include: 'None', 'Logging', 'Metrics', 'AzureServices'
     *
     * @param {array} [parameters.networkRuleSet.virtualNetworkRules] Sets the
     * virtual network rules
     *
     * @param {array} [parameters.networkRuleSet.ipRules] Sets the IP ACL rules
     *
     * @param {string} parameters.networkRuleSet.defaultAction Specifies the
     * default action of allow or deny when no other rules match. Possible values
     * include: 'Allow', 'Deny'
     *
     * @param {string} [parameters.accessTier] Required for storage accounts where
     * kind = BlobStorage. The access tier used for billing. Possible values
     * include: 'Hot', 'Cool'
     *
     * @param {boolean} [parameters.enableAzureFilesAadIntegration] Enables Azure
     * Files AAD Integration for SMB if sets to true.
     *
     * @param {boolean} [parameters.enableHttpsTrafficOnly] Allows https traffic
     * only to storage service if sets to true.
     *
     * @param {boolean} [parameters.isHnsEnabled] Account HierarchicalNamespace
     * enabled if sets to true.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {StorageAccount} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {object} [result]   - The deserialized result object if an error did not occur.
     *                      See {@link StorageAccount} for more information.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    beginCreate(resourceGroupName, accountName, parameters, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._beginCreate(resourceGroupName, accountName, parameters, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._beginCreate(resourceGroupName, accountName, parameters, options, optionalCallback);
      }
    }
  
    /**
     * Failover request can be triggered for a storage account in case of
     * availability issues. The failover occurs from the storage account's primary
     * cluster to secondary cluster for RA-GRS accounts. The secondary cluster will
     * become primary after failover.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @returns {Promise} A promise is returned
     *
     * @resolve {HttpOperationResponse<null>} - The deserialized result object.
     *
     * @reject {Error} - The error object.
     */
    beginFailoverWithHttpOperationResponse(resourceGroupName, accountName, options) {
      let client = this.client;
      let self = this;
      return new Promise((resolve, reject) => {
        self._beginFailover(resourceGroupName, accountName, options, (err, result, request, response) => {
          let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
          httpOperationResponse.body = result;
          if (err) { reject(err); }
          else { resolve(httpOperationResponse); }
          return;
        });
      });
    }
  
    /**
     * Failover request can be triggered for a storage account in case of
     * availability issues. The failover occurs from the storage account's primary
     * cluster to secondary cluster for RA-GRS accounts. The secondary cluster will
     * become primary after failover.
     *
     * @param {string} resourceGroupName The name of the resource group within the
     * user's subscription. The name is case insensitive.
     *
     * @param {string} accountName The name of the storage account within the
     * specified resource group. Storage account names must be between 3 and 24
     * characters in length and use numbers and lower-case letters only.
     *
     * @param {object} [options] Optional Parameters.
     *
     * @param {object} [options.customHeaders] Headers that will be added to the
     * request
     *
     * @param {function} [optionalCallback] - The optional callback.
     *
     * @returns {function|Promise} If a callback was passed as the last parameter
     * then it returns the callback else returns a Promise.
     *
     * {Promise} A promise is returned
     *
     *                      @resolve {null} - The deserialized result object.
     *
     *                      @reject {Error} - The error object.
     *
     * {function} optionalCallback(err, result, request, response)
     *
     *                      {Error}  err        - The Error object if an error occurred, null otherwise.
     *
     *                      {null} [result]   - The deserialized result object if an error did not occur.
     *
     *                      {object} [request]  - The HTTP Request object if an error did not occur.
     *
     *                      {stream} [response] - The HTTP Response stream if an error did not occur.
     */
    beginFailover(resourceGroupName, accountName, options, optionalCallback) {
      let client = this.client;
      let self = this;
      if (!optionalCallback && typeof options === 'function') {
        optionalCallback = options;
        options = null;
      }
      if (!optionalCallback) {
        return new Promise((resolve, reject) => {
          self._beginFailover(resourceGroupName, accountName, options, (err, result, request, response) => {
            if (err) { reject(err); }
            else { resolve(result); }
            return;
          });
        });
      } else {
        return self._beginFailover(resourceGroupName, accountName, options, optionalCallback);
      }
    }
  
  }
  
  module.exports = StorageAccounts;
  