/*
 * 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;


/**
 * Deletes the specified application gateway.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @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, applicationGatewayName, 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.beginDeleteMethod(resourceGroupName, applicationGatewayName, 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);
    });
  });
}

/**
 * Gets the specified application gateway.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @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 ApplicationGateway} 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 _get(resourceGroupName, applicationGatewayName, 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 = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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.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.Network/applicationGateways/{applicationGatewayName}';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  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['ApplicationGateway']().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);
  });
}


/**
 * Creates or updates the specified application gateway.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} parameters Parameters supplied to the create or update
 * application gateway operation.
 *
 * @param {object} [parameters.sku] SKU of the application gateway resource.
 *
 * @param {string} [parameters.sku.name] Name of an application gateway SKU.
 * Possible values include: 'Standard_Small', 'Standard_Medium',
 * 'Standard_Large', 'WAF_Medium', 'WAF_Large', 'Standard_v2', 'WAF_v2'
 *
 * @param {string} [parameters.sku.tier] Tier of an application gateway.
 * Possible values include: 'Standard', 'WAF', 'Standard_v2', 'WAF_v2'
 *
 * @param {number} [parameters.sku.capacity] Capacity (instance count) of an
 * application gateway.
 *
 * @param {object} [parameters.sslPolicy] SSL policy of the application gateway
 * resource.
 *
 * @param {array} [parameters.sslPolicy.disabledSslProtocols] Ssl protocols to
 * be disabled on application gateway.
 *
 * @param {string} [parameters.sslPolicy.policyType] Type of Ssl Policy.
 * Possible values include: 'Predefined', 'Custom'
 *
 * @param {string} [parameters.sslPolicy.policyName] Name of Ssl predefined
 * policy. Possible values include: 'AppGwSslPolicy20150501',
 * 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
 *
 * @param {array} [parameters.sslPolicy.cipherSuites] Ssl cipher suites to be
 * enabled in the specified order to application gateway.
 *
 * @param {string} [parameters.sslPolicy.minProtocolVersion] Minimum version of
 * Ssl protocol to be supported on application gateway. Possible values
 * include: 'TLSv1_0', 'TLSv1_1', 'TLSv1_2'
 *
 * @param {array} [parameters.gatewayIPConfigurations] Subnets of the
 * application gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.authenticationCertificates] Authentication
 * certificates of the application gateway resource. For default limits, see
 * [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.trustedRootCertificates] Trusted Root
 * certificates of the application gateway resource. For default limits, see
 * [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.sslCertificates] SSL certificates of the
 * application gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.frontendIPConfigurations] Frontend IP addresses
 * of the application gateway resource. For default limits, see [Application
 * Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.frontendPorts] Frontend ports of the application
 * gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.probes] Probes of the application gateway
 * resource.
 *
 * @param {array} [parameters.backendAddressPools] Backend address pool of the
 * application gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.backendHttpSettingsCollection] Backend http
 * settings of the application gateway resource. For default limits, see
 * [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.httpListeners] Http listeners of the application
 * gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.urlPathMaps] URL path map of the application
 * gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.requestRoutingRules] Request routing rules of the
 * application gateway resource.
 *
 * @param {array} [parameters.rewriteRuleSets] Rewrite rules for the
 * application gateway resource.
 *
 * @param {array} [parameters.redirectConfigurations] Redirect configurations
 * of the application gateway resource. For default limits, see [Application
 * Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {object} [parameters.webApplicationFirewallConfiguration] Web
 * application firewall configuration.
 *
 * @param {boolean} parameters.webApplicationFirewallConfiguration.enabled
 * Whether the web application firewall is enabled or not.
 *
 * @param {string} parameters.webApplicationFirewallConfiguration.firewallMode
 * Web application firewall mode. Possible values include: 'Detection',
 * 'Prevention'
 *
 * @param {string} parameters.webApplicationFirewallConfiguration.ruleSetType
 * The type of the web application firewall rule set. Possible values are:
 * 'OWASP'.
 *
 * @param {string}
 * parameters.webApplicationFirewallConfiguration.ruleSetVersion The version of
 * the rule set type.
 *
 * @param {array}
 * [parameters.webApplicationFirewallConfiguration.disabledRuleGroups] The
 * disabled rule groups.
 *
 * @param {boolean}
 * [parameters.webApplicationFirewallConfiguration.requestBodyCheck] Whether
 * allow WAF to check request Body.
 *
 * @param {number}
 * [parameters.webApplicationFirewallConfiguration.maxRequestBodySize] Maximum
 * request body size for WAF.
 *
 * @param {number}
 * [parameters.webApplicationFirewallConfiguration.maxRequestBodySizeInKb]
 * Maximum request body size in Kb for WAF.
 *
 * @param {number}
 * [parameters.webApplicationFirewallConfiguration.fileUploadLimitInMb] Maximum
 * file upload size in Mb for WAF.
 *
 * @param {array} [parameters.webApplicationFirewallConfiguration.exclusions]
 * The exclusion list.
 *
 * @param {object} [parameters.firewallPolicy] Reference of the FirewallPolicy
 * resource.
 *
 * @param {string} [parameters.firewallPolicy.id] Resource ID.
 *
 * @param {boolean} [parameters.enableHttp2] Whether HTTP2 is enabled on the
 * application gateway resource.
 *
 * @param {boolean} [parameters.enableFips] Whether FIPS is enabled on the
 * application gateway resource.
 *
 * @param {object} [parameters.autoscaleConfiguration] Autoscale Configuration.
 *
 * @param {number} parameters.autoscaleConfiguration.minCapacity Lower bound on
 * number of Application Gateway capacity
 *
 * @param {number} [parameters.autoscaleConfiguration.maxCapacity] Upper bound
 * on number of Application Gateway capacity
 *
 * @param {string} [parameters.resourceGuid] Resource GUID property of the
 * application gateway resource.
 *
 * @param {string} [parameters.provisioningState] Provisioning state of the
 * application gateway resource. Possible values are: 'Updating', 'Deleting',
 * and 'Failed'.
 *
 * @param {array} [parameters.customErrorConfigurations] Custom error
 * configurations of the application gateway resource.
 *
 * @param {string} [parameters.etag] A unique read-only string that changes
 * whenever the resource is updated.
 *
 * @param {array} [parameters.zones] A list of availability zones denoting
 * where the resource needs to come from.
 *
 * @param {object} [parameters.identity] The identity of the application
 * gateway, if configured.
 *
 * @param {string} [parameters.identity.type] The type of identity used for the
 * resource. The type 'SystemAssigned, UserAssigned' includes both an
 * implicitly created identity and a set of user assigned identities. The type
 * 'None' will remove any identities from the virtual machine. Possible values
 * include: 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned',
 * 'None'
 *
 * @param {object} [parameters.identity.userAssignedIdentities] The list of
 * user identities associated with resource. The user identity dictionary key
 * references will be ARM resource ids in the form:
 * '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.
 *
 * @param {string} [parameters.id] Resource ID.
 *
 * @param {string} [parameters.location] Resource location.
 *
 * @param {object} [parameters.tags] Resource tags.
 *
 * @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 ApplicationGateway} 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 _createOrUpdate(resourceGroupName, applicationGatewayName, 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.beginCreateOrUpdate(resourceGroupName, applicationGatewayName, 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['ApplicationGateway']().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);
    });
  });
}


/**
 * Updates the specified application gateway tags.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} parameters Parameters supplied to update application gateway
 * tags.
 *
 * @param {object} [parameters.tags] Resource tags.
 *
 * @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 ApplicationGateway} 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 _updateTags(resourceGroupName, applicationGatewayName, 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.beginUpdateTags(resourceGroupName, applicationGatewayName, 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['ApplicationGateway']().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 application gateways in a resource group.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @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 ApplicationGatewayListResult} 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(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 = '2019-02-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 (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.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.Network/applicationGateways';
  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['ApplicationGatewayListResult']().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);
  });
}

/**
 * Gets all the application gateways in a subscription.
 *
 * @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 ApplicationGatewayListResult} 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 _listAll(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 = '2019-02-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.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.Network/applicationGateways';
  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['ApplicationGatewayListResult']().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);
  });
}


/**
 * Starts the specified application gateway.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @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 _start(resourceGroupName, applicationGatewayName, 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.beginStart(resourceGroupName, applicationGatewayName, 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);
    });
  });
}


/**
 * Stops the specified application gateway in a resource group.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @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 _stop(resourceGroupName, applicationGatewayName, 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.beginStop(resourceGroupName, applicationGatewayName, 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);
    });
  });
}


/**
 * Gets the backend health of the specified application gateway in a resource
 * group.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.expand] Expands BackendAddressPool and
 * BackendHttpSettings referenced in backend health.
 *
 * @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 ApplicationGatewayBackendHealth} 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 _backendHealth(resourceGroupName, applicationGatewayName, 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.beginBackendHealth(resourceGroupName, applicationGatewayName, 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['ApplicationGatewayBackendHealth']().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);
    });
  });
}


/**
 * Gets the backend health for given combination of backend pool and http
 * setting of the specified application gateway in a resource group.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} probeRequest Request body for on-demand test probe
 * operation.
 *
 * @param {string} [probeRequest.protocol] The protocol used for the probe.
 * Possible values include: 'Http', 'Https'
 *
 * @param {string} [probeRequest.host] Host name to send the probe to.
 *
 * @param {string} [probeRequest.path] Relative path of probe. Valid path
 * starts from '/'. Probe is sent to <Protocol>://<host>:<port><path>
 *
 * @param {number} [probeRequest.timeout] The probe timeout in seconds. Probe
 * marked as failed if valid response is not received with this timeout period.
 * Acceptable values are from 1 second to 86400 seconds.
 *
 * @param {boolean} [probeRequest.pickHostNameFromBackendHttpSettings] Whether
 * the host header should be picked from the backend http settings. Default
 * value is false.
 *
 * @param {object} [probeRequest.match] Criterion for classifying a healthy
 * probe response.
 *
 * @param {string} [probeRequest.match.body] Body that must be contained in the
 * health response. Default value is empty.
 *
 * @param {array} [probeRequest.match.statusCodes] Allowed ranges of healthy
 * status codes. Default range of healthy status codes is 200-399.
 *
 * @param {string} [probeRequest.backendPoolName] Name of backend pool of
 * application gateway to which probe request will be sent.
 *
 * @param {string} [probeRequest.backendHttpSettingName] Name of backend http
 * setting of application gateway to be used for test probe
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.expand] Expands BackendAddressPool and
 * BackendHttpSettings referenced in backend health.
 *
 * @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 ApplicationGatewayBackendHealthOnDemand} 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 _backendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, 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.beginBackendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, 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['ApplicationGatewayBackendHealthOnDemand']().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 available server variables.
 *
 * @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.
 *
 *                      {array} [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 _listAvailableServerVariables(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 = '2019-02-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.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.Network/applicationGatewayAvailableServerVariables';
  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) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['ErrorModel']().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 = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'StringElementType',
                  type: {
                    name: 'String'
                  }
              }
            }
          };
          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 available request headers.
 *
 * @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.
 *
 *                      {array} [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 _listAvailableRequestHeaders(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 = '2019-02-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.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.Network/applicationGatewayAvailableRequestHeaders';
  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) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['ErrorModel']().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 = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'StringElementType',
                  type: {
                    name: 'String'
                  }
              }
            }
          };
          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 available response headers.
 *
 * @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.
 *
 *                      {array} [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 _listAvailableResponseHeaders(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 = '2019-02-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.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.Network/applicationGatewayAvailableResponseHeaders';
  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) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['ErrorModel']().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 = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'StringElementType',
                  type: {
                    name: 'String'
                  }
              }
            }
          };
          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 available web application firewall rule sets.
 *
 * @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
 *                      ApplicationGatewayAvailableWafRuleSetsResult} 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 _listAvailableWafRuleSets(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 = '2019-02-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.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.Network/applicationGatewayAvailableWafRuleSets';
  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['ApplicationGatewayAvailableWafRuleSetsResult']().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 available Ssl options for configuring Ssl policy.
 *
 * @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 ApplicationGatewayAvailableSslOptions} 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 _listAvailableSslOptions(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 = '2019-02-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.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.Network/applicationGatewayAvailableSslOptions/default';
  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['ApplicationGatewayAvailableSslOptions']().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 SSL predefined policies for configuring Ssl policy.
 *
 * @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
 *                      ApplicationGatewayAvailableSslPredefinedPolicies} 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 _listAvailableSslPredefinedPolicies(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 = '2019-02-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.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.Network/applicationGatewayAvailableSslOptions/default/predefinedPolicies';
  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['ApplicationGatewayAvailableSslPredefinedPolicies']().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);
  });
}

/**
 * Gets Ssl predefined policy with the specified policy name.
 *
 * @param {string} predefinedPolicyName Name of Ssl predefined policy.
 *
 * @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 ApplicationGatewaySslPredefinedPolicy} 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 _getSslPredefinedPolicy(predefinedPolicyName, 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 = '2019-02-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 (predefinedPolicyName === null || predefinedPolicyName === undefined || typeof predefinedPolicyName.valueOf() !== 'string') {
      throw new Error('predefinedPolicyName 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);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/providers/Microsoft.Network/applicationGatewayAvailableSslOptions/default/predefinedPolicies/{predefinedPolicyName}';
  requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
  requestUrl = requestUrl.replace('{predefinedPolicyName}', encodeURIComponent(predefinedPolicyName));
  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['ApplicationGatewaySslPredefinedPolicy']().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 the specified application gateway.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @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 _beginDeleteMethod(resourceGroupName, applicationGatewayName, 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 = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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.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.Network/applicationGateways/{applicationGatewayName}';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  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 !== 202 && 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);
  });
}

/**
 * Creates or updates the specified application gateway.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} parameters Parameters supplied to the create or update
 * application gateway operation.
 *
 * @param {object} [parameters.sku] SKU of the application gateway resource.
 *
 * @param {string} [parameters.sku.name] Name of an application gateway SKU.
 * Possible values include: 'Standard_Small', 'Standard_Medium',
 * 'Standard_Large', 'WAF_Medium', 'WAF_Large', 'Standard_v2', 'WAF_v2'
 *
 * @param {string} [parameters.sku.tier] Tier of an application gateway.
 * Possible values include: 'Standard', 'WAF', 'Standard_v2', 'WAF_v2'
 *
 * @param {number} [parameters.sku.capacity] Capacity (instance count) of an
 * application gateway.
 *
 * @param {object} [parameters.sslPolicy] SSL policy of the application gateway
 * resource.
 *
 * @param {array} [parameters.sslPolicy.disabledSslProtocols] Ssl protocols to
 * be disabled on application gateway.
 *
 * @param {string} [parameters.sslPolicy.policyType] Type of Ssl Policy.
 * Possible values include: 'Predefined', 'Custom'
 *
 * @param {string} [parameters.sslPolicy.policyName] Name of Ssl predefined
 * policy. Possible values include: 'AppGwSslPolicy20150501',
 * 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
 *
 * @param {array} [parameters.sslPolicy.cipherSuites] Ssl cipher suites to be
 * enabled in the specified order to application gateway.
 *
 * @param {string} [parameters.sslPolicy.minProtocolVersion] Minimum version of
 * Ssl protocol to be supported on application gateway. Possible values
 * include: 'TLSv1_0', 'TLSv1_1', 'TLSv1_2'
 *
 * @param {array} [parameters.gatewayIPConfigurations] Subnets of the
 * application gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.authenticationCertificates] Authentication
 * certificates of the application gateway resource. For default limits, see
 * [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.trustedRootCertificates] Trusted Root
 * certificates of the application gateway resource. For default limits, see
 * [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.sslCertificates] SSL certificates of the
 * application gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.frontendIPConfigurations] Frontend IP addresses
 * of the application gateway resource. For default limits, see [Application
 * Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.frontendPorts] Frontend ports of the application
 * gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.probes] Probes of the application gateway
 * resource.
 *
 * @param {array} [parameters.backendAddressPools] Backend address pool of the
 * application gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.backendHttpSettingsCollection] Backend http
 * settings of the application gateway resource. For default limits, see
 * [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.httpListeners] Http listeners of the application
 * gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.urlPathMaps] URL path map of the application
 * gateway resource. For default limits, see [Application Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {array} [parameters.requestRoutingRules] Request routing rules of the
 * application gateway resource.
 *
 * @param {array} [parameters.rewriteRuleSets] Rewrite rules for the
 * application gateway resource.
 *
 * @param {array} [parameters.redirectConfigurations] Redirect configurations
 * of the application gateway resource. For default limits, see [Application
 * Gateway
 * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
 *
 * @param {object} [parameters.webApplicationFirewallConfiguration] Web
 * application firewall configuration.
 *
 * @param {boolean} parameters.webApplicationFirewallConfiguration.enabled
 * Whether the web application firewall is enabled or not.
 *
 * @param {string} parameters.webApplicationFirewallConfiguration.firewallMode
 * Web application firewall mode. Possible values include: 'Detection',
 * 'Prevention'
 *
 * @param {string} parameters.webApplicationFirewallConfiguration.ruleSetType
 * The type of the web application firewall rule set. Possible values are:
 * 'OWASP'.
 *
 * @param {string}
 * parameters.webApplicationFirewallConfiguration.ruleSetVersion The version of
 * the rule set type.
 *
 * @param {array}
 * [parameters.webApplicationFirewallConfiguration.disabledRuleGroups] The
 * disabled rule groups.
 *
 * @param {boolean}
 * [parameters.webApplicationFirewallConfiguration.requestBodyCheck] Whether
 * allow WAF to check request Body.
 *
 * @param {number}
 * [parameters.webApplicationFirewallConfiguration.maxRequestBodySize] Maximum
 * request body size for WAF.
 *
 * @param {number}
 * [parameters.webApplicationFirewallConfiguration.maxRequestBodySizeInKb]
 * Maximum request body size in Kb for WAF.
 *
 * @param {number}
 * [parameters.webApplicationFirewallConfiguration.fileUploadLimitInMb] Maximum
 * file upload size in Mb for WAF.
 *
 * @param {array} [parameters.webApplicationFirewallConfiguration.exclusions]
 * The exclusion list.
 *
 * @param {object} [parameters.firewallPolicy] Reference of the FirewallPolicy
 * resource.
 *
 * @param {string} [parameters.firewallPolicy.id] Resource ID.
 *
 * @param {boolean} [parameters.enableHttp2] Whether HTTP2 is enabled on the
 * application gateway resource.
 *
 * @param {boolean} [parameters.enableFips] Whether FIPS is enabled on the
 * application gateway resource.
 *
 * @param {object} [parameters.autoscaleConfiguration] Autoscale Configuration.
 *
 * @param {number} parameters.autoscaleConfiguration.minCapacity Lower bound on
 * number of Application Gateway capacity
 *
 * @param {number} [parameters.autoscaleConfiguration.maxCapacity] Upper bound
 * on number of Application Gateway capacity
 *
 * @param {string} [parameters.resourceGuid] Resource GUID property of the
 * application gateway resource.
 *
 * @param {string} [parameters.provisioningState] Provisioning state of the
 * application gateway resource. Possible values are: 'Updating', 'Deleting',
 * and 'Failed'.
 *
 * @param {array} [parameters.customErrorConfigurations] Custom error
 * configurations of the application gateway resource.
 *
 * @param {string} [parameters.etag] A unique read-only string that changes
 * whenever the resource is updated.
 *
 * @param {array} [parameters.zones] A list of availability zones denoting
 * where the resource needs to come from.
 *
 * @param {object} [parameters.identity] The identity of the application
 * gateway, if configured.
 *
 * @param {string} [parameters.identity.type] The type of identity used for the
 * resource. The type 'SystemAssigned, UserAssigned' includes both an
 * implicitly created identity and a set of user assigned identities. The type
 * 'None' will remove any identities from the virtual machine. Possible values
 * include: 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned',
 * 'None'
 *
 * @param {object} [parameters.identity.userAssignedIdentities] The list of
 * user identities associated with resource. The user identity dictionary key
 * references will be ARM resource ids in the form:
 * '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.
 *
 * @param {string} [parameters.id] Resource ID.
 *
 * @param {string} [parameters.location] Resource location.
 *
 * @param {object} [parameters.tags] Resource tags.
 *
 * @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 ApplicationGateway} 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 _beginCreateOrUpdate(resourceGroupName, applicationGatewayName, 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 = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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.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.Network/applicationGateways/{applicationGatewayName}';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  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['ApplicationGateway']().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 !== 201) {
      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['ApplicationGateway']().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);
      }
    }
    // Deserialize Response
    if (statusCode === 201) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ApplicationGateway']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError1 = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError1.request = msRest.stripRequest(httpRequest);
        deserializationError1.response = msRest.stripResponse(response);
        return callback(deserializationError1);
      }
    }

    return callback(null, result, httpRequest, response);
  });
}

/**
 * Updates the specified application gateway tags.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} parameters Parameters supplied to update application gateway
 * tags.
 *
 * @param {object} [parameters.tags] Resource tags.
 *
 * @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 ApplicationGateway} 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 _beginUpdateTags(resourceGroupName, applicationGatewayName, 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 = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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.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.Network/applicationGateways/{applicationGatewayName}';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  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['TagsObject']().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['ApplicationGateway']().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);
  });
}

/**
 * Starts the specified application gateway.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @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 _beginStart(resourceGroupName, applicationGatewayName, 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 = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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.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.Network/applicationGateways/{applicationGatewayName}/start';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  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);
  });
}

/**
 * Stops the specified application gateway in a resource group.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @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 _beginStop(resourceGroupName, applicationGatewayName, 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 = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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.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.Network/applicationGateways/{applicationGatewayName}/stop';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  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);
  });
}

/**
 * Gets the backend health of the specified application gateway in a resource
 * group.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.expand] Expands BackendAddressPool and
 * BackendHttpSettings referenced in backend health.
 *
 * @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 ApplicationGatewayBackendHealth} 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 _beginBackendHealth(resourceGroupName, applicationGatewayName, 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 expand = (options && options.expand !== undefined) ? options.expand : undefined;
  let apiVersion = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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 (expand !== null && expand !== undefined && typeof expand.valueOf() !== 'string') {
      throw new Error('expand 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);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/applicationGateways/{applicationGatewayName}/backendhealth';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
  let queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
  if (expand !== null && expand !== undefined) {
    queryParameters.push('$expand=' + encodeURIComponent(expand));
  }
  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;
    // 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['ApplicationGatewayBackendHealth']().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);
  });
}

/**
 * Gets the backend health for given combination of backend pool and http
 * setting of the specified application gateway in a resource group.
 *
 * @param {string} resourceGroupName The name of the resource group.
 *
 * @param {string} applicationGatewayName The name of the application gateway.
 *
 * @param {object} probeRequest Request body for on-demand test probe
 * operation.
 *
 * @param {string} [probeRequest.protocol] The protocol used for the probe.
 * Possible values include: 'Http', 'Https'
 *
 * @param {string} [probeRequest.host] Host name to send the probe to.
 *
 * @param {string} [probeRequest.path] Relative path of probe. Valid path
 * starts from '/'. Probe is sent to <Protocol>://<host>:<port><path>
 *
 * @param {number} [probeRequest.timeout] The probe timeout in seconds. Probe
 * marked as failed if valid response is not received with this timeout period.
 * Acceptable values are from 1 second to 86400 seconds.
 *
 * @param {boolean} [probeRequest.pickHostNameFromBackendHttpSettings] Whether
 * the host header should be picked from the backend http settings. Default
 * value is false.
 *
 * @param {object} [probeRequest.match] Criterion for classifying a healthy
 * probe response.
 *
 * @param {string} [probeRequest.match.body] Body that must be contained in the
 * health response. Default value is empty.
 *
 * @param {array} [probeRequest.match.statusCodes] Allowed ranges of healthy
 * status codes. Default range of healthy status codes is 200-399.
 *
 * @param {string} [probeRequest.backendPoolName] Name of backend pool of
 * application gateway to which probe request will be sent.
 *
 * @param {string} [probeRequest.backendHttpSettingName] Name of backend http
 * setting of application gateway to be used for test probe
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.expand] Expands BackendAddressPool and
 * BackendHttpSettings referenced in backend health.
 *
 * @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 ApplicationGatewayBackendHealthOnDemand} 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 _beginBackendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, 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 expand = (options && options.expand !== undefined) ? options.expand : undefined;
  let apiVersion = '2019-02-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 (applicationGatewayName === null || applicationGatewayName === undefined || typeof applicationGatewayName.valueOf() !== 'string') {
      throw new Error('applicationGatewayName cannot be null or undefined and it must be of type string.');
    }
    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 (expand !== null && expand !== undefined && typeof expand.valueOf() !== 'string') {
      throw new Error('expand must be of type string.');
    }
    if (probeRequest === null || probeRequest === undefined) {
      throw new Error('probeRequest cannot be null or undefined.');
    }
    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.Network/applicationGateways/{applicationGatewayName}/getBackendHealthOnDemand';
  requestUrl = requestUrl.replace('{resourceGroupName}', encodeURIComponent(resourceGroupName));
  requestUrl = requestUrl.replace('{applicationGatewayName}', encodeURIComponent(applicationGatewayName));
  requestUrl = requestUrl.replace('{subscriptionId}', encodeURIComponent(this.client.subscriptionId));
  let queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(apiVersion));
  if (expand !== null && expand !== undefined) {
    queryParameters.push('$expand=' + encodeURIComponent(expand));
  }
  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 (probeRequest !== null && probeRequest !== undefined) {
      let requestModelMapper = new client.models['ApplicationGatewayOnDemandProbe']().mapper();
      requestModel = client.serialize(requestModelMapper, probeRequest, 'probeRequest');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(probeRequest, 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['ApplicationGatewayBackendHealthOnDemand']().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 application gateways in a resource group.
 *
 * @param {string} nextPageLink The NextLink from the previous successful call
 * to List operation.
 *
 * @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 ApplicationGatewayListResult} 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 _listNext(nextPageLink, 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.');
  }
  // Validate
  try {
    if (nextPageLink === null || nextPageLink === undefined || typeof nextPageLink.valueOf() !== 'string') {
      throw new Error('nextPageLink 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);
  }

  // Construct URL
  let requestUrl = '{nextLink}';
  requestUrl = requestUrl.replace('{nextLink}', nextPageLink);

  // 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['ApplicationGatewayListResult']().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);
  });
}

/**
 * Gets all the application gateways in a subscription.
 *
 * @param {string} nextPageLink The NextLink from the previous successful call
 * to List operation.
 *
 * @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 ApplicationGatewayListResult} 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 _listAllNext(nextPageLink, 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.');
  }
  // Validate
  try {
    if (nextPageLink === null || nextPageLink === undefined || typeof nextPageLink.valueOf() !== 'string') {
      throw new Error('nextPageLink 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);
  }

  // Construct URL
  let requestUrl = '{nextLink}';
  requestUrl = requestUrl.replace('{nextLink}', nextPageLink);

  // 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['ApplicationGatewayListResult']().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 SSL predefined policies for configuring Ssl policy.
 *
 * @param {string} nextPageLink The NextLink from the previous successful call
 * to List operation.
 *
 * @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
 *                      ApplicationGatewayAvailableSslPredefinedPolicies} 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 _listAvailableSslPredefinedPoliciesNext(nextPageLink, 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.');
  }
  // Validate
  try {
    if (nextPageLink === null || nextPageLink === undefined || typeof nextPageLink.valueOf() !== 'string') {
      throw new Error('nextPageLink 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);
  }

  // Construct URL
  let requestUrl = '{nextLink}';
  requestUrl = requestUrl.replace('{nextLink}', nextPageLink);

  // 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['ApplicationGatewayAvailableSslPredefinedPolicies']().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);
  });
}

/** Class representing a ApplicationGateways. */
class ApplicationGateways {
  /**
   * Create a ApplicationGateways.
   * @param {NetworkManagementClient} client Reference to the service client.
   */
  constructor(client) {
    this.client = client;
    this._deleteMethod = _deleteMethod;
    this._get = _get;
    this._createOrUpdate = _createOrUpdate;
    this._updateTags = _updateTags;
    this._list = _list;
    this._listAll = _listAll;
    this._start = _start;
    this._stop = _stop;
    this._backendHealth = _backendHealth;
    this._backendHealthOnDemand = _backendHealthOnDemand;
    this._listAvailableServerVariables = _listAvailableServerVariables;
    this._listAvailableRequestHeaders = _listAvailableRequestHeaders;
    this._listAvailableResponseHeaders = _listAvailableResponseHeaders;
    this._listAvailableWafRuleSets = _listAvailableWafRuleSets;
    this._listAvailableSslOptions = _listAvailableSslOptions;
    this._listAvailableSslPredefinedPolicies = _listAvailableSslPredefinedPolicies;
    this._getSslPredefinedPolicy = _getSslPredefinedPolicy;
    this._beginDeleteMethod = _beginDeleteMethod;
    this._beginCreateOrUpdate = _beginCreateOrUpdate;
    this._beginUpdateTags = _beginUpdateTags;
    this._beginStart = _beginStart;
    this._beginStop = _beginStop;
    this._beginBackendHealth = _beginBackendHealth;
    this._beginBackendHealthOnDemand = _beginBackendHealthOnDemand;
    this._listNext = _listNext;
    this._listAllNext = _listAllNext;
    this._listAvailableSslPredefinedPoliciesNext = _listAvailableSslPredefinedPoliciesNext;
  }

  /**
   * Deletes the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteMethod(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Deletes the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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, applicationGatewayName, 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, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteMethod(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Gets the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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<ApplicationGateway>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._get(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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 {ApplicationGateway} - 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 ApplicationGateway} 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.
   */
  get(resourceGroupName, applicationGatewayName, 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._get(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._get(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Creates or updates the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to the create or update
   * application gateway operation.
   *
   * @param {object} [parameters.sku] SKU of the application gateway resource.
   *
   * @param {string} [parameters.sku.name] Name of an application gateway SKU.
   * Possible values include: 'Standard_Small', 'Standard_Medium',
   * 'Standard_Large', 'WAF_Medium', 'WAF_Large', 'Standard_v2', 'WAF_v2'
   *
   * @param {string} [parameters.sku.tier] Tier of an application gateway.
   * Possible values include: 'Standard', 'WAF', 'Standard_v2', 'WAF_v2'
   *
   * @param {number} [parameters.sku.capacity] Capacity (instance count) of an
   * application gateway.
   *
   * @param {object} [parameters.sslPolicy] SSL policy of the application gateway
   * resource.
   *
   * @param {array} [parameters.sslPolicy.disabledSslProtocols] Ssl protocols to
   * be disabled on application gateway.
   *
   * @param {string} [parameters.sslPolicy.policyType] Type of Ssl Policy.
   * Possible values include: 'Predefined', 'Custom'
   *
   * @param {string} [parameters.sslPolicy.policyName] Name of Ssl predefined
   * policy. Possible values include: 'AppGwSslPolicy20150501',
   * 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
   *
   * @param {array} [parameters.sslPolicy.cipherSuites] Ssl cipher suites to be
   * enabled in the specified order to application gateway.
   *
   * @param {string} [parameters.sslPolicy.minProtocolVersion] Minimum version of
   * Ssl protocol to be supported on application gateway. Possible values
   * include: 'TLSv1_0', 'TLSv1_1', 'TLSv1_2'
   *
   * @param {array} [parameters.gatewayIPConfigurations] Subnets of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.authenticationCertificates] Authentication
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.trustedRootCertificates] Trusted Root
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.sslCertificates] SSL certificates of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendIPConfigurations] Frontend IP addresses
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendPorts] Frontend ports of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.probes] Probes of the application gateway
   * resource.
   *
   * @param {array} [parameters.backendAddressPools] Backend address pool of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.backendHttpSettingsCollection] Backend http
   * settings of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.httpListeners] Http listeners of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.urlPathMaps] URL path map of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.requestRoutingRules] Request routing rules of the
   * application gateway resource.
   *
   * @param {array} [parameters.rewriteRuleSets] Rewrite rules for the
   * application gateway resource.
   *
   * @param {array} [parameters.redirectConfigurations] Redirect configurations
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {object} [parameters.webApplicationFirewallConfiguration] Web
   * application firewall configuration.
   *
   * @param {boolean} parameters.webApplicationFirewallConfiguration.enabled
   * Whether the web application firewall is enabled or not.
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.firewallMode
   * Web application firewall mode. Possible values include: 'Detection',
   * 'Prevention'
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.ruleSetType
   * The type of the web application firewall rule set. Possible values are:
   * 'OWASP'.
   *
   * @param {string}
   * parameters.webApplicationFirewallConfiguration.ruleSetVersion The version of
   * the rule set type.
   *
   * @param {array}
   * [parameters.webApplicationFirewallConfiguration.disabledRuleGroups] The
   * disabled rule groups.
   *
   * @param {boolean}
   * [parameters.webApplicationFirewallConfiguration.requestBodyCheck] Whether
   * allow WAF to check request Body.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySize] Maximum
   * request body size for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySizeInKb]
   * Maximum request body size in Kb for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.fileUploadLimitInMb] Maximum
   * file upload size in Mb for WAF.
   *
   * @param {array} [parameters.webApplicationFirewallConfiguration.exclusions]
   * The exclusion list.
   *
   * @param {object} [parameters.firewallPolicy] Reference of the FirewallPolicy
   * resource.
   *
   * @param {string} [parameters.firewallPolicy.id] Resource ID.
   *
   * @param {boolean} [parameters.enableHttp2] Whether HTTP2 is enabled on the
   * application gateway resource.
   *
   * @param {boolean} [parameters.enableFips] Whether FIPS is enabled on the
   * application gateway resource.
   *
   * @param {object} [parameters.autoscaleConfiguration] Autoscale Configuration.
   *
   * @param {number} parameters.autoscaleConfiguration.minCapacity Lower bound on
   * number of Application Gateway capacity
   *
   * @param {number} [parameters.autoscaleConfiguration.maxCapacity] Upper bound
   * on number of Application Gateway capacity
   *
   * @param {string} [parameters.resourceGuid] Resource GUID property of the
   * application gateway resource.
   *
   * @param {string} [parameters.provisioningState] Provisioning state of the
   * application gateway resource. Possible values are: 'Updating', 'Deleting',
   * and 'Failed'.
   *
   * @param {array} [parameters.customErrorConfigurations] Custom error
   * configurations of the application gateway resource.
   *
   * @param {string} [parameters.etag] A unique read-only string that changes
   * whenever the resource is updated.
   *
   * @param {array} [parameters.zones] A list of availability zones denoting
   * where the resource needs to come from.
   *
   * @param {object} [parameters.identity] The identity of the application
   * gateway, if configured.
   *
   * @param {string} [parameters.identity.type] The type of identity used for the
   * resource. The type 'SystemAssigned, UserAssigned' includes both an
   * implicitly created identity and a set of user assigned identities. The type
   * 'None' will remove any identities from the virtual machine. Possible values
   * include: 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned',
   * 'None'
   *
   * @param {object} [parameters.identity.userAssignedIdentities] The list of
   * user identities associated with resource. The user identity dictionary key
   * references will be ARM resource ids in the form:
   * '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.
   *
   * @param {string} [parameters.id] Resource ID.
   *
   * @param {string} [parameters.location] Resource location.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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<ApplicationGateway>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createOrUpdateWithHttpOperationResponse(resourceGroupName, applicationGatewayName, parameters, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createOrUpdate(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Creates or updates the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to the create or update
   * application gateway operation.
   *
   * @param {object} [parameters.sku] SKU of the application gateway resource.
   *
   * @param {string} [parameters.sku.name] Name of an application gateway SKU.
   * Possible values include: 'Standard_Small', 'Standard_Medium',
   * 'Standard_Large', 'WAF_Medium', 'WAF_Large', 'Standard_v2', 'WAF_v2'
   *
   * @param {string} [parameters.sku.tier] Tier of an application gateway.
   * Possible values include: 'Standard', 'WAF', 'Standard_v2', 'WAF_v2'
   *
   * @param {number} [parameters.sku.capacity] Capacity (instance count) of an
   * application gateway.
   *
   * @param {object} [parameters.sslPolicy] SSL policy of the application gateway
   * resource.
   *
   * @param {array} [parameters.sslPolicy.disabledSslProtocols] Ssl protocols to
   * be disabled on application gateway.
   *
   * @param {string} [parameters.sslPolicy.policyType] Type of Ssl Policy.
   * Possible values include: 'Predefined', 'Custom'
   *
   * @param {string} [parameters.sslPolicy.policyName] Name of Ssl predefined
   * policy. Possible values include: 'AppGwSslPolicy20150501',
   * 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
   *
   * @param {array} [parameters.sslPolicy.cipherSuites] Ssl cipher suites to be
   * enabled in the specified order to application gateway.
   *
   * @param {string} [parameters.sslPolicy.minProtocolVersion] Minimum version of
   * Ssl protocol to be supported on application gateway. Possible values
   * include: 'TLSv1_0', 'TLSv1_1', 'TLSv1_2'
   *
   * @param {array} [parameters.gatewayIPConfigurations] Subnets of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.authenticationCertificates] Authentication
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.trustedRootCertificates] Trusted Root
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.sslCertificates] SSL certificates of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendIPConfigurations] Frontend IP addresses
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendPorts] Frontend ports of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.probes] Probes of the application gateway
   * resource.
   *
   * @param {array} [parameters.backendAddressPools] Backend address pool of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.backendHttpSettingsCollection] Backend http
   * settings of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.httpListeners] Http listeners of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.urlPathMaps] URL path map of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.requestRoutingRules] Request routing rules of the
   * application gateway resource.
   *
   * @param {array} [parameters.rewriteRuleSets] Rewrite rules for the
   * application gateway resource.
   *
   * @param {array} [parameters.redirectConfigurations] Redirect configurations
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {object} [parameters.webApplicationFirewallConfiguration] Web
   * application firewall configuration.
   *
   * @param {boolean} parameters.webApplicationFirewallConfiguration.enabled
   * Whether the web application firewall is enabled or not.
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.firewallMode
   * Web application firewall mode. Possible values include: 'Detection',
   * 'Prevention'
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.ruleSetType
   * The type of the web application firewall rule set. Possible values are:
   * 'OWASP'.
   *
   * @param {string}
   * parameters.webApplicationFirewallConfiguration.ruleSetVersion The version of
   * the rule set type.
   *
   * @param {array}
   * [parameters.webApplicationFirewallConfiguration.disabledRuleGroups] The
   * disabled rule groups.
   *
   * @param {boolean}
   * [parameters.webApplicationFirewallConfiguration.requestBodyCheck] Whether
   * allow WAF to check request Body.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySize] Maximum
   * request body size for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySizeInKb]
   * Maximum request body size in Kb for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.fileUploadLimitInMb] Maximum
   * file upload size in Mb for WAF.
   *
   * @param {array} [parameters.webApplicationFirewallConfiguration.exclusions]
   * The exclusion list.
   *
   * @param {object} [parameters.firewallPolicy] Reference of the FirewallPolicy
   * resource.
   *
   * @param {string} [parameters.firewallPolicy.id] Resource ID.
   *
   * @param {boolean} [parameters.enableHttp2] Whether HTTP2 is enabled on the
   * application gateway resource.
   *
   * @param {boolean} [parameters.enableFips] Whether FIPS is enabled on the
   * application gateway resource.
   *
   * @param {object} [parameters.autoscaleConfiguration] Autoscale Configuration.
   *
   * @param {number} parameters.autoscaleConfiguration.minCapacity Lower bound on
   * number of Application Gateway capacity
   *
   * @param {number} [parameters.autoscaleConfiguration.maxCapacity] Upper bound
   * on number of Application Gateway capacity
   *
   * @param {string} [parameters.resourceGuid] Resource GUID property of the
   * application gateway resource.
   *
   * @param {string} [parameters.provisioningState] Provisioning state of the
   * application gateway resource. Possible values are: 'Updating', 'Deleting',
   * and 'Failed'.
   *
   * @param {array} [parameters.customErrorConfigurations] Custom error
   * configurations of the application gateway resource.
   *
   * @param {string} [parameters.etag] A unique read-only string that changes
   * whenever the resource is updated.
   *
   * @param {array} [parameters.zones] A list of availability zones denoting
   * where the resource needs to come from.
   *
   * @param {object} [parameters.identity] The identity of the application
   * gateway, if configured.
   *
   * @param {string} [parameters.identity.type] The type of identity used for the
   * resource. The type 'SystemAssigned, UserAssigned' includes both an
   * implicitly created identity and a set of user assigned identities. The type
   * 'None' will remove any identities from the virtual machine. Possible values
   * include: 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned',
   * 'None'
   *
   * @param {object} [parameters.identity.userAssignedIdentities] The list of
   * user identities associated with resource. The user identity dictionary key
   * references will be ARM resource ids in the form:
   * '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.
   *
   * @param {string} [parameters.id] Resource ID.
   *
   * @param {string} [parameters.location] Resource location.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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 {ApplicationGateway} - 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 ApplicationGateway} 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.
   */
  createOrUpdate(resourceGroupName, applicationGatewayName, 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._createOrUpdate(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createOrUpdate(resourceGroupName, applicationGatewayName, parameters, options, optionalCallback);
    }
  }

  /**
   * Updates the specified application gateway tags.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to update application gateway
   * tags.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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<ApplicationGateway>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  updateTagsWithHttpOperationResponse(resourceGroupName, applicationGatewayName, parameters, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._updateTags(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Updates the specified application gateway tags.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to update application gateway
   * tags.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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 {ApplicationGateway} - 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 ApplicationGateway} 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.
   */
  updateTags(resourceGroupName, applicationGatewayName, 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._updateTags(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._updateTags(resourceGroupName, applicationGatewayName, parameters, options, optionalCallback);
    }
  }

  /**
   * Lists all application gateways in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @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<ApplicationGatewayListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listWithHttpOperationResponse(resourceGroupName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._list(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 application gateways in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @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 {ApplicationGatewayListResult} - 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 ApplicationGatewayListResult} 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(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._list(resourceGroupName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._list(resourceGroupName, options, optionalCallback);
    }
  }

  /**
   * Gets all the application gateways in a subscription.
   *
   * @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<ApplicationGatewayListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAllWithHttpOperationResponse(options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAll(options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets all the application gateways in a subscription.
   *
   * @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 {ApplicationGatewayListResult} - 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 ApplicationGatewayListResult} 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.
   */
  listAll(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._listAll(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAll(options, optionalCallback);
    }
  }

  /**
   * Starts the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  startWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._start(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Starts the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  start(resourceGroupName, applicationGatewayName, 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._start(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._start(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Stops the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  stopWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._stop(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Stops the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  stop(resourceGroupName, applicationGatewayName, 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._stop(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._stop(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Gets the backend health of the specified application gateway in a resource
   * group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ApplicationGatewayBackendHealth>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  backendHealthWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._backendHealth(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets the backend health of the specified application gateway in a resource
   * group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @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 {ApplicationGatewayBackendHealth} - 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 ApplicationGatewayBackendHealth} 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.
   */
  backendHealth(resourceGroupName, applicationGatewayName, 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._backendHealth(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._backendHealth(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Gets the backend health for given combination of backend pool and http
   * setting of the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} probeRequest Request body for on-demand test probe
   * operation.
   *
   * @param {string} [probeRequest.protocol] The protocol used for the probe.
   * Possible values include: 'Http', 'Https'
   *
   * @param {string} [probeRequest.host] Host name to send the probe to.
   *
   * @param {string} [probeRequest.path] Relative path of probe. Valid path
   * starts from '/'. Probe is sent to <Protocol>://<host>:<port><path>
   *
   * @param {number} [probeRequest.timeout] The probe timeout in seconds. Probe
   * marked as failed if valid response is not received with this timeout period.
   * Acceptable values are from 1 second to 86400 seconds.
   *
   * @param {boolean} [probeRequest.pickHostNameFromBackendHttpSettings] Whether
   * the host header should be picked from the backend http settings. Default
   * value is false.
   *
   * @param {object} [probeRequest.match] Criterion for classifying a healthy
   * probe response.
   *
   * @param {string} [probeRequest.match.body] Body that must be contained in the
   * health response. Default value is empty.
   *
   * @param {array} [probeRequest.match.statusCodes] Allowed ranges of healthy
   * status codes. Default range of healthy status codes is 200-399.
   *
   * @param {string} [probeRequest.backendPoolName] Name of backend pool of
   * application gateway to which probe request will be sent.
   *
   * @param {string} [probeRequest.backendHttpSettingName] Name of backend http
   * setting of application gateway to be used for test probe
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ApplicationGatewayBackendHealthOnDemand>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  backendHealthOnDemandWithHttpOperationResponse(resourceGroupName, applicationGatewayName, probeRequest, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._backendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets the backend health for given combination of backend pool and http
   * setting of the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} probeRequest Request body for on-demand test probe
   * operation.
   *
   * @param {string} [probeRequest.protocol] The protocol used for the probe.
   * Possible values include: 'Http', 'Https'
   *
   * @param {string} [probeRequest.host] Host name to send the probe to.
   *
   * @param {string} [probeRequest.path] Relative path of probe. Valid path
   * starts from '/'. Probe is sent to <Protocol>://<host>:<port><path>
   *
   * @param {number} [probeRequest.timeout] The probe timeout in seconds. Probe
   * marked as failed if valid response is not received with this timeout period.
   * Acceptable values are from 1 second to 86400 seconds.
   *
   * @param {boolean} [probeRequest.pickHostNameFromBackendHttpSettings] Whether
   * the host header should be picked from the backend http settings. Default
   * value is false.
   *
   * @param {object} [probeRequest.match] Criterion for classifying a healthy
   * probe response.
   *
   * @param {string} [probeRequest.match.body] Body that must be contained in the
   * health response. Default value is empty.
   *
   * @param {array} [probeRequest.match.statusCodes] Allowed ranges of healthy
   * status codes. Default range of healthy status codes is 200-399.
   *
   * @param {string} [probeRequest.backendPoolName] Name of backend pool of
   * application gateway to which probe request will be sent.
   *
   * @param {string} [probeRequest.backendHttpSettingName] Name of backend http
   * setting of application gateway to be used for test probe
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @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 {ApplicationGatewayBackendHealthOnDemand} - 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 ApplicationGatewayBackendHealthOnDemand} 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.
   */
  backendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, 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._backendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._backendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, options, optionalCallback);
    }
  }

  /**
   * Lists all available server variables.
   *
   * @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<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAvailableServerVariablesWithHttpOperationResponse(options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAvailableServerVariables(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 available server variables.
   *
   * @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 {Array} - 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.
   *
   *                      {array} [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.
   */
  listAvailableServerVariables(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._listAvailableServerVariables(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAvailableServerVariables(options, optionalCallback);
    }
  }

  /**
   * Lists all available request headers.
   *
   * @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<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAvailableRequestHeadersWithHttpOperationResponse(options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAvailableRequestHeaders(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 available request headers.
   *
   * @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 {Array} - 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.
   *
   *                      {array} [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.
   */
  listAvailableRequestHeaders(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._listAvailableRequestHeaders(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAvailableRequestHeaders(options, optionalCallback);
    }
  }

  /**
   * Lists all available response headers.
   *
   * @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<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAvailableResponseHeadersWithHttpOperationResponse(options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAvailableResponseHeaders(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 available response headers.
   *
   * @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 {Array} - 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.
   *
   *                      {array} [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.
   */
  listAvailableResponseHeaders(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._listAvailableResponseHeaders(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAvailableResponseHeaders(options, optionalCallback);
    }
  }

  /**
   * Lists all available web application firewall rule sets.
   *
   * @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<ApplicationGatewayAvailableWafRuleSetsResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAvailableWafRuleSetsWithHttpOperationResponse(options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAvailableWafRuleSets(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 available web application firewall rule sets.
   *
   * @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 {ApplicationGatewayAvailableWafRuleSetsResult} - 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
   *                      ApplicationGatewayAvailableWafRuleSetsResult} 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.
   */
  listAvailableWafRuleSets(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._listAvailableWafRuleSets(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAvailableWafRuleSets(options, optionalCallback);
    }
  }

  /**
   * Lists available Ssl options for configuring Ssl policy.
   *
   * @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<ApplicationGatewayAvailableSslOptions>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAvailableSslOptionsWithHttpOperationResponse(options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAvailableSslOptions(options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Lists available Ssl options for configuring Ssl policy.
   *
   * @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 {ApplicationGatewayAvailableSslOptions} - 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 ApplicationGatewayAvailableSslOptions} 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.
   */
  listAvailableSslOptions(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._listAvailableSslOptions(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAvailableSslOptions(options, optionalCallback);
    }
  }

  /**
   * Lists all SSL predefined policies for configuring Ssl policy.
   *
   * @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<ApplicationGatewayAvailableSslPredefinedPolicies>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAvailableSslPredefinedPoliciesWithHttpOperationResponse(options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAvailableSslPredefinedPolicies(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 SSL predefined policies for configuring Ssl policy.
   *
   * @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 {ApplicationGatewayAvailableSslPredefinedPolicies} - 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
   *                      ApplicationGatewayAvailableSslPredefinedPolicies} 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.
   */
  listAvailableSslPredefinedPolicies(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._listAvailableSslPredefinedPolicies(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAvailableSslPredefinedPolicies(options, optionalCallback);
    }
  }

  /**
   * Gets Ssl predefined policy with the specified policy name.
   *
   * @param {string} predefinedPolicyName Name of Ssl predefined policy.
   *
   * @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<ApplicationGatewaySslPredefinedPolicy>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getSslPredefinedPolicyWithHttpOperationResponse(predefinedPolicyName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getSslPredefinedPolicy(predefinedPolicyName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets Ssl predefined policy with the specified policy name.
   *
   * @param {string} predefinedPolicyName Name of Ssl predefined policy.
   *
   * @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 {ApplicationGatewaySslPredefinedPolicy} - 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 ApplicationGatewaySslPredefinedPolicy} 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.
   */
  getSslPredefinedPolicy(predefinedPolicyName, 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._getSslPredefinedPolicy(predefinedPolicyName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getSslPredefinedPolicy(predefinedPolicyName, options, optionalCallback);
    }
  }

  /**
   * Deletes the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  beginDeleteMethodWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._beginDeleteMethod(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Deletes the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  beginDeleteMethod(resourceGroupName, applicationGatewayName, 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._beginDeleteMethod(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._beginDeleteMethod(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Creates or updates the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to the create or update
   * application gateway operation.
   *
   * @param {object} [parameters.sku] SKU of the application gateway resource.
   *
   * @param {string} [parameters.sku.name] Name of an application gateway SKU.
   * Possible values include: 'Standard_Small', 'Standard_Medium',
   * 'Standard_Large', 'WAF_Medium', 'WAF_Large', 'Standard_v2', 'WAF_v2'
   *
   * @param {string} [parameters.sku.tier] Tier of an application gateway.
   * Possible values include: 'Standard', 'WAF', 'Standard_v2', 'WAF_v2'
   *
   * @param {number} [parameters.sku.capacity] Capacity (instance count) of an
   * application gateway.
   *
   * @param {object} [parameters.sslPolicy] SSL policy of the application gateway
   * resource.
   *
   * @param {array} [parameters.sslPolicy.disabledSslProtocols] Ssl protocols to
   * be disabled on application gateway.
   *
   * @param {string} [parameters.sslPolicy.policyType] Type of Ssl Policy.
   * Possible values include: 'Predefined', 'Custom'
   *
   * @param {string} [parameters.sslPolicy.policyName] Name of Ssl predefined
   * policy. Possible values include: 'AppGwSslPolicy20150501',
   * 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
   *
   * @param {array} [parameters.sslPolicy.cipherSuites] Ssl cipher suites to be
   * enabled in the specified order to application gateway.
   *
   * @param {string} [parameters.sslPolicy.minProtocolVersion] Minimum version of
   * Ssl protocol to be supported on application gateway. Possible values
   * include: 'TLSv1_0', 'TLSv1_1', 'TLSv1_2'
   *
   * @param {array} [parameters.gatewayIPConfigurations] Subnets of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.authenticationCertificates] Authentication
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.trustedRootCertificates] Trusted Root
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.sslCertificates] SSL certificates of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendIPConfigurations] Frontend IP addresses
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendPorts] Frontend ports of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.probes] Probes of the application gateway
   * resource.
   *
   * @param {array} [parameters.backendAddressPools] Backend address pool of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.backendHttpSettingsCollection] Backend http
   * settings of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.httpListeners] Http listeners of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.urlPathMaps] URL path map of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.requestRoutingRules] Request routing rules of the
   * application gateway resource.
   *
   * @param {array} [parameters.rewriteRuleSets] Rewrite rules for the
   * application gateway resource.
   *
   * @param {array} [parameters.redirectConfigurations] Redirect configurations
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {object} [parameters.webApplicationFirewallConfiguration] Web
   * application firewall configuration.
   *
   * @param {boolean} parameters.webApplicationFirewallConfiguration.enabled
   * Whether the web application firewall is enabled or not.
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.firewallMode
   * Web application firewall mode. Possible values include: 'Detection',
   * 'Prevention'
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.ruleSetType
   * The type of the web application firewall rule set. Possible values are:
   * 'OWASP'.
   *
   * @param {string}
   * parameters.webApplicationFirewallConfiguration.ruleSetVersion The version of
   * the rule set type.
   *
   * @param {array}
   * [parameters.webApplicationFirewallConfiguration.disabledRuleGroups] The
   * disabled rule groups.
   *
   * @param {boolean}
   * [parameters.webApplicationFirewallConfiguration.requestBodyCheck] Whether
   * allow WAF to check request Body.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySize] Maximum
   * request body size for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySizeInKb]
   * Maximum request body size in Kb for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.fileUploadLimitInMb] Maximum
   * file upload size in Mb for WAF.
   *
   * @param {array} [parameters.webApplicationFirewallConfiguration.exclusions]
   * The exclusion list.
   *
   * @param {object} [parameters.firewallPolicy] Reference of the FirewallPolicy
   * resource.
   *
   * @param {string} [parameters.firewallPolicy.id] Resource ID.
   *
   * @param {boolean} [parameters.enableHttp2] Whether HTTP2 is enabled on the
   * application gateway resource.
   *
   * @param {boolean} [parameters.enableFips] Whether FIPS is enabled on the
   * application gateway resource.
   *
   * @param {object} [parameters.autoscaleConfiguration] Autoscale Configuration.
   *
   * @param {number} parameters.autoscaleConfiguration.minCapacity Lower bound on
   * number of Application Gateway capacity
   *
   * @param {number} [parameters.autoscaleConfiguration.maxCapacity] Upper bound
   * on number of Application Gateway capacity
   *
   * @param {string} [parameters.resourceGuid] Resource GUID property of the
   * application gateway resource.
   *
   * @param {string} [parameters.provisioningState] Provisioning state of the
   * application gateway resource. Possible values are: 'Updating', 'Deleting',
   * and 'Failed'.
   *
   * @param {array} [parameters.customErrorConfigurations] Custom error
   * configurations of the application gateway resource.
   *
   * @param {string} [parameters.etag] A unique read-only string that changes
   * whenever the resource is updated.
   *
   * @param {array} [parameters.zones] A list of availability zones denoting
   * where the resource needs to come from.
   *
   * @param {object} [parameters.identity] The identity of the application
   * gateway, if configured.
   *
   * @param {string} [parameters.identity.type] The type of identity used for the
   * resource. The type 'SystemAssigned, UserAssigned' includes both an
   * implicitly created identity and a set of user assigned identities. The type
   * 'None' will remove any identities from the virtual machine. Possible values
   * include: 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned',
   * 'None'
   *
   * @param {object} [parameters.identity.userAssignedIdentities] The list of
   * user identities associated with resource. The user identity dictionary key
   * references will be ARM resource ids in the form:
   * '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.
   *
   * @param {string} [parameters.id] Resource ID.
   *
   * @param {string} [parameters.location] Resource location.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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<ApplicationGateway>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  beginCreateOrUpdateWithHttpOperationResponse(resourceGroupName, applicationGatewayName, parameters, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._beginCreateOrUpdate(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Creates or updates the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to the create or update
   * application gateway operation.
   *
   * @param {object} [parameters.sku] SKU of the application gateway resource.
   *
   * @param {string} [parameters.sku.name] Name of an application gateway SKU.
   * Possible values include: 'Standard_Small', 'Standard_Medium',
   * 'Standard_Large', 'WAF_Medium', 'WAF_Large', 'Standard_v2', 'WAF_v2'
   *
   * @param {string} [parameters.sku.tier] Tier of an application gateway.
   * Possible values include: 'Standard', 'WAF', 'Standard_v2', 'WAF_v2'
   *
   * @param {number} [parameters.sku.capacity] Capacity (instance count) of an
   * application gateway.
   *
   * @param {object} [parameters.sslPolicy] SSL policy of the application gateway
   * resource.
   *
   * @param {array} [parameters.sslPolicy.disabledSslProtocols] Ssl protocols to
   * be disabled on application gateway.
   *
   * @param {string} [parameters.sslPolicy.policyType] Type of Ssl Policy.
   * Possible values include: 'Predefined', 'Custom'
   *
   * @param {string} [parameters.sslPolicy.policyName] Name of Ssl predefined
   * policy. Possible values include: 'AppGwSslPolicy20150501',
   * 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
   *
   * @param {array} [parameters.sslPolicy.cipherSuites] Ssl cipher suites to be
   * enabled in the specified order to application gateway.
   *
   * @param {string} [parameters.sslPolicy.minProtocolVersion] Minimum version of
   * Ssl protocol to be supported on application gateway. Possible values
   * include: 'TLSv1_0', 'TLSv1_1', 'TLSv1_2'
   *
   * @param {array} [parameters.gatewayIPConfigurations] Subnets of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.authenticationCertificates] Authentication
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.trustedRootCertificates] Trusted Root
   * certificates of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.sslCertificates] SSL certificates of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendIPConfigurations] Frontend IP addresses
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.frontendPorts] Frontend ports of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.probes] Probes of the application gateway
   * resource.
   *
   * @param {array} [parameters.backendAddressPools] Backend address pool of the
   * application gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.backendHttpSettingsCollection] Backend http
   * settings of the application gateway resource. For default limits, see
   * [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.httpListeners] Http listeners of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.urlPathMaps] URL path map of the application
   * gateway resource. For default limits, see [Application Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {array} [parameters.requestRoutingRules] Request routing rules of the
   * application gateway resource.
   *
   * @param {array} [parameters.rewriteRuleSets] Rewrite rules for the
   * application gateway resource.
   *
   * @param {array} [parameters.redirectConfigurations] Redirect configurations
   * of the application gateway resource. For default limits, see [Application
   * Gateway
   * limits](https://docs.microsoft.com/azure/azure-subscription-service-limits#application-gateway-limits).
   *
   * @param {object} [parameters.webApplicationFirewallConfiguration] Web
   * application firewall configuration.
   *
   * @param {boolean} parameters.webApplicationFirewallConfiguration.enabled
   * Whether the web application firewall is enabled or not.
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.firewallMode
   * Web application firewall mode. Possible values include: 'Detection',
   * 'Prevention'
   *
   * @param {string} parameters.webApplicationFirewallConfiguration.ruleSetType
   * The type of the web application firewall rule set. Possible values are:
   * 'OWASP'.
   *
   * @param {string}
   * parameters.webApplicationFirewallConfiguration.ruleSetVersion The version of
   * the rule set type.
   *
   * @param {array}
   * [parameters.webApplicationFirewallConfiguration.disabledRuleGroups] The
   * disabled rule groups.
   *
   * @param {boolean}
   * [parameters.webApplicationFirewallConfiguration.requestBodyCheck] Whether
   * allow WAF to check request Body.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySize] Maximum
   * request body size for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.maxRequestBodySizeInKb]
   * Maximum request body size in Kb for WAF.
   *
   * @param {number}
   * [parameters.webApplicationFirewallConfiguration.fileUploadLimitInMb] Maximum
   * file upload size in Mb for WAF.
   *
   * @param {array} [parameters.webApplicationFirewallConfiguration.exclusions]
   * The exclusion list.
   *
   * @param {object} [parameters.firewallPolicy] Reference of the FirewallPolicy
   * resource.
   *
   * @param {string} [parameters.firewallPolicy.id] Resource ID.
   *
   * @param {boolean} [parameters.enableHttp2] Whether HTTP2 is enabled on the
   * application gateway resource.
   *
   * @param {boolean} [parameters.enableFips] Whether FIPS is enabled on the
   * application gateway resource.
   *
   * @param {object} [parameters.autoscaleConfiguration] Autoscale Configuration.
   *
   * @param {number} parameters.autoscaleConfiguration.minCapacity Lower bound on
   * number of Application Gateway capacity
   *
   * @param {number} [parameters.autoscaleConfiguration.maxCapacity] Upper bound
   * on number of Application Gateway capacity
   *
   * @param {string} [parameters.resourceGuid] Resource GUID property of the
   * application gateway resource.
   *
   * @param {string} [parameters.provisioningState] Provisioning state of the
   * application gateway resource. Possible values are: 'Updating', 'Deleting',
   * and 'Failed'.
   *
   * @param {array} [parameters.customErrorConfigurations] Custom error
   * configurations of the application gateway resource.
   *
   * @param {string} [parameters.etag] A unique read-only string that changes
   * whenever the resource is updated.
   *
   * @param {array} [parameters.zones] A list of availability zones denoting
   * where the resource needs to come from.
   *
   * @param {object} [parameters.identity] The identity of the application
   * gateway, if configured.
   *
   * @param {string} [parameters.identity.type] The type of identity used for the
   * resource. The type 'SystemAssigned, UserAssigned' includes both an
   * implicitly created identity and a set of user assigned identities. The type
   * 'None' will remove any identities from the virtual machine. Possible values
   * include: 'SystemAssigned', 'UserAssigned', 'SystemAssigned, UserAssigned',
   * 'None'
   *
   * @param {object} [parameters.identity.userAssignedIdentities] The list of
   * user identities associated with resource. The user identity dictionary key
   * references will be ARM resource ids in the form:
   * '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.
   *
   * @param {string} [parameters.id] Resource ID.
   *
   * @param {string} [parameters.location] Resource location.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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 {ApplicationGateway} - 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 ApplicationGateway} 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.
   */
  beginCreateOrUpdate(resourceGroupName, applicationGatewayName, 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._beginCreateOrUpdate(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._beginCreateOrUpdate(resourceGroupName, applicationGatewayName, parameters, options, optionalCallback);
    }
  }

  /**
   * Updates the specified application gateway tags.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to update application gateway
   * tags.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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<ApplicationGateway>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  beginUpdateTagsWithHttpOperationResponse(resourceGroupName, applicationGatewayName, parameters, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._beginUpdateTags(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Updates the specified application gateway tags.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} parameters Parameters supplied to update application gateway
   * tags.
   *
   * @param {object} [parameters.tags] Resource tags.
   *
   * @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 {ApplicationGateway} - 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 ApplicationGateway} 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.
   */
  beginUpdateTags(resourceGroupName, applicationGatewayName, 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._beginUpdateTags(resourceGroupName, applicationGatewayName, parameters, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._beginUpdateTags(resourceGroupName, applicationGatewayName, parameters, options, optionalCallback);
    }
  }

  /**
   * Starts the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  beginStartWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._beginStart(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Starts the specified application gateway.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  beginStart(resourceGroupName, applicationGatewayName, 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._beginStart(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._beginStart(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Stops the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  beginStopWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._beginStop(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Stops the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @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.
   */
  beginStop(resourceGroupName, applicationGatewayName, 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._beginStop(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._beginStop(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Gets the backend health of the specified application gateway in a resource
   * group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ApplicationGatewayBackendHealth>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  beginBackendHealthWithHttpOperationResponse(resourceGroupName, applicationGatewayName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._beginBackendHealth(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets the backend health of the specified application gateway in a resource
   * group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @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 {ApplicationGatewayBackendHealth} - 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 ApplicationGatewayBackendHealth} 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.
   */
  beginBackendHealth(resourceGroupName, applicationGatewayName, 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._beginBackendHealth(resourceGroupName, applicationGatewayName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._beginBackendHealth(resourceGroupName, applicationGatewayName, options, optionalCallback);
    }
  }

  /**
   * Gets the backend health for given combination of backend pool and http
   * setting of the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} probeRequest Request body for on-demand test probe
   * operation.
   *
   * @param {string} [probeRequest.protocol] The protocol used for the probe.
   * Possible values include: 'Http', 'Https'
   *
   * @param {string} [probeRequest.host] Host name to send the probe to.
   *
   * @param {string} [probeRequest.path] Relative path of probe. Valid path
   * starts from '/'. Probe is sent to <Protocol>://<host>:<port><path>
   *
   * @param {number} [probeRequest.timeout] The probe timeout in seconds. Probe
   * marked as failed if valid response is not received with this timeout period.
   * Acceptable values are from 1 second to 86400 seconds.
   *
   * @param {boolean} [probeRequest.pickHostNameFromBackendHttpSettings] Whether
   * the host header should be picked from the backend http settings. Default
   * value is false.
   *
   * @param {object} [probeRequest.match] Criterion for classifying a healthy
   * probe response.
   *
   * @param {string} [probeRequest.match.body] Body that must be contained in the
   * health response. Default value is empty.
   *
   * @param {array} [probeRequest.match.statusCodes] Allowed ranges of healthy
   * status codes. Default range of healthy status codes is 200-399.
   *
   * @param {string} [probeRequest.backendPoolName] Name of backend pool of
   * application gateway to which probe request will be sent.
   *
   * @param {string} [probeRequest.backendHttpSettingName] Name of backend http
   * setting of application gateway to be used for test probe
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ApplicationGatewayBackendHealthOnDemand>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  beginBackendHealthOnDemandWithHttpOperationResponse(resourceGroupName, applicationGatewayName, probeRequest, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._beginBackendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets the backend health for given combination of backend pool and http
   * setting of the specified application gateway in a resource group.
   *
   * @param {string} resourceGroupName The name of the resource group.
   *
   * @param {string} applicationGatewayName The name of the application gateway.
   *
   * @param {object} probeRequest Request body for on-demand test probe
   * operation.
   *
   * @param {string} [probeRequest.protocol] The protocol used for the probe.
   * Possible values include: 'Http', 'Https'
   *
   * @param {string} [probeRequest.host] Host name to send the probe to.
   *
   * @param {string} [probeRequest.path] Relative path of probe. Valid path
   * starts from '/'. Probe is sent to <Protocol>://<host>:<port><path>
   *
   * @param {number} [probeRequest.timeout] The probe timeout in seconds. Probe
   * marked as failed if valid response is not received with this timeout period.
   * Acceptable values are from 1 second to 86400 seconds.
   *
   * @param {boolean} [probeRequest.pickHostNameFromBackendHttpSettings] Whether
   * the host header should be picked from the backend http settings. Default
   * value is false.
   *
   * @param {object} [probeRequest.match] Criterion for classifying a healthy
   * probe response.
   *
   * @param {string} [probeRequest.match.body] Body that must be contained in the
   * health response. Default value is empty.
   *
   * @param {array} [probeRequest.match.statusCodes] Allowed ranges of healthy
   * status codes. Default range of healthy status codes is 200-399.
   *
   * @param {string} [probeRequest.backendPoolName] Name of backend pool of
   * application gateway to which probe request will be sent.
   *
   * @param {string} [probeRequest.backendHttpSettingName] Name of backend http
   * setting of application gateway to be used for test probe
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.expand] Expands BackendAddressPool and
   * BackendHttpSettings referenced in backend health.
   *
   * @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 {ApplicationGatewayBackendHealthOnDemand} - 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 ApplicationGatewayBackendHealthOnDemand} 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.
   */
  beginBackendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, 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._beginBackendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._beginBackendHealthOnDemand(resourceGroupName, applicationGatewayName, probeRequest, options, optionalCallback);
    }
  }

  /**
   * Lists all application gateways in a resource group.
   *
   * @param {string} nextPageLink The NextLink from the previous successful call
   * to List operation.
   *
   * @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<ApplicationGatewayListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listNextWithHttpOperationResponse(nextPageLink, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listNext(nextPageLink, 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 application gateways in a resource group.
   *
   * @param {string} nextPageLink The NextLink from the previous successful call
   * to List operation.
   *
   * @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 {ApplicationGatewayListResult} - 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 ApplicationGatewayListResult} 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.
   */
  listNext(nextPageLink, 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._listNext(nextPageLink, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listNext(nextPageLink, options, optionalCallback);
    }
  }

  /**
   * Gets all the application gateways in a subscription.
   *
   * @param {string} nextPageLink The NextLink from the previous successful call
   * to List operation.
   *
   * @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<ApplicationGatewayListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAllNextWithHttpOperationResponse(nextPageLink, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAllNext(nextPageLink, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets all the application gateways in a subscription.
   *
   * @param {string} nextPageLink The NextLink from the previous successful call
   * to List operation.
   *
   * @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 {ApplicationGatewayListResult} - 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 ApplicationGatewayListResult} 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.
   */
  listAllNext(nextPageLink, 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._listAllNext(nextPageLink, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAllNext(nextPageLink, options, optionalCallback);
    }
  }

  /**
   * Lists all SSL predefined policies for configuring Ssl policy.
   *
   * @param {string} nextPageLink The NextLink from the previous successful call
   * to List operation.
   *
   * @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<ApplicationGatewayAvailableSslPredefinedPolicies>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAvailableSslPredefinedPoliciesNextWithHttpOperationResponse(nextPageLink, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAvailableSslPredefinedPoliciesNext(nextPageLink, 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 SSL predefined policies for configuring Ssl policy.
   *
   * @param {string} nextPageLink The NextLink from the previous successful call
   * to List operation.
   *
   * @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 {ApplicationGatewayAvailableSslPredefinedPolicies} - 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
   *                      ApplicationGatewayAvailableSslPredefinedPolicies} 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.
   */
  listAvailableSslPredefinedPoliciesNext(nextPageLink, 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._listAvailableSslPredefinedPoliciesNext(nextPageLink, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAvailableSslPredefinedPoliciesNext(nextPageLink, options, optionalCallback);
    }
  }

}

module.exports = ApplicationGateways;
