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

var util = require('util');
var msRest = require('ms-rest');
var msRestAzure = require('ms-rest-azure');
var WebResource = msRest.WebResource;
var moment = require('moment');

/**
 * @class
 * Pool
 * __NOTE__: An instance of this class is automatically created for an
 * instance of the BatchServiceClient.
 * Initializes a new instance of the Pool class.
 * @constructor
 *
 * @param {BatchServiceClient} client Reference to the service client.
 */
function Pool(client) {
  this.client = client;
}

/**
 * Lists the usage metrics, aggregated by pool across individual time
 * intervals, for the specified account.
 *
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolListPoolUsageMetricsOptions] Additional
 * parameters for the operation
 * 
 * @param {date} [options.poolListPoolUsageMetricsOptions.startTime] The
 * earliest time from which to include metrics. This must be at least two and
 * a half hours before the current time.
 * 
 * @param {date} [options.poolListPoolUsageMetricsOptions.endTime] The latest
 * time from which to include metrics. This must be at least two hours before
 * the current time.
 * 
 * @param {string} [options.poolListPoolUsageMetricsOptions.filter] An OData
 * $filter clause.
 * 
 * @param {number} [options.poolListPoolUsageMetricsOptions.maxResults] The
 * maximum number of items to return in the response.
 * 
 * @param {number} [options.poolListPoolUsageMetricsOptions.timeout] The
 * maximum time that the server can spend processing the request, in seconds.
 * The default is 30 seconds.
 * 
 * @param {string} [options.poolListPoolUsageMetricsOptions.clientRequestId]
 * The caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean}
 * [options.poolListPoolUsageMetricsOptions.returnClientRequestId] Whether
 * the server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolListPoolUsageMetricsOptions.ocpDate] The time
 * the request was issued. If not specified, this header will be
 * automatically populated with the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *                      See {@link PoolListPoolUsageMetricsResult} 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.
 */
Pool.prototype.listPoolUsageMetrics = function (options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolListPoolUsageMetricsOptions = (options && options.poolListPoolUsageMetricsOptions !== undefined) ? options.poolListPoolUsageMetricsOptions : undefined;
  // Validate
  try {
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var startTime;
  var endTime;
  var filter;
  var maxResults;
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      startTime = poolListPoolUsageMetricsOptions.startTime;
      if (startTime && !(startTime instanceof Date || 
          (typeof startTime.valueOf() === 'string' && !isNaN(Date.parse(startTime))))) {
            throw new Error('startTime must be of type date.');
          }
    }
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      endTime = poolListPoolUsageMetricsOptions.endTime;
      if (endTime && !(endTime instanceof Date || 
          (typeof endTime.valueOf() === 'string' && !isNaN(Date.parse(endTime))))) {
            throw new Error('endTime must be of type date.');
          }
    }
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      filter = poolListPoolUsageMetricsOptions.filter;
      if (filter !== null && filter !== undefined && typeof filter.valueOf() !== 'string') {
        throw new Error('filter must be of type string.');
      }
    }
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      maxResults = poolListPoolUsageMetricsOptions.maxResults;
      if (maxResults !== null && maxResults !== undefined && typeof maxResults !== 'number') {
        throw new Error('maxResults must be of type number.');
      }
    }
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      timeout = poolListPoolUsageMetricsOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      clientRequestId = poolListPoolUsageMetricsOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      returnClientRequestId = poolListPoolUsageMetricsOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolListPoolUsageMetricsOptions !== null && poolListPoolUsageMetricsOptions !== undefined)
    {
      ocpDate = poolListPoolUsageMetricsOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//poolusagemetrics';
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (startTime !== null && startTime !== undefined) {
    queryParameters.push('starttime=' + encodeURIComponent(client.serializeObject(startTime)));
  }
  if (endTime !== null && endTime !== undefined) {
    queryParameters.push('endtime=' + encodeURIComponent(client.serializeObject(endTime)));
  }
  if (filter !== null && filter !== undefined) {
    queryParameters.push('$filter=' + encodeURIComponent(filter));
  }
  if (maxResults !== null && maxResults !== undefined) {
    queryParameters.push('maxresults=' + encodeURIComponent(maxResults.toString()));
  }
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      var parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          var resultMapper = new client.models['PoolListPoolUsageMetricsResult']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody));
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Gets lifetime summary statistics for all of the pools in the specified
 * account. Statistics are aggregated across all pools that have ever existed
 * in the account, from account creation to the last update time of the
 * statistics.
 *
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolGetAllPoolsLifetimeStatisticsOptions]
 * Additional parameters for the operation
 * 
 * @param {number} [options.poolGetAllPoolsLifetimeStatisticsOptions.timeout]
 * The maximum time that the server can spend processing the request, in
 * seconds. The default is 30 seconds.
 * 
 * @param {string}
 * [options.poolGetAllPoolsLifetimeStatisticsOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean}
 * [options.poolGetAllPoolsLifetimeStatisticsOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolGetAllPoolsLifetimeStatisticsOptions.ocpDate]
 * The time the request was issued. If not specified, this header will be
 * automatically populated with the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *                      See {@link PoolStatistics} 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.
 */
Pool.prototype.getAllPoolsLifetimeStatistics = function (options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolGetAllPoolsLifetimeStatisticsOptions = (options && options.poolGetAllPoolsLifetimeStatisticsOptions !== undefined) ? options.poolGetAllPoolsLifetimeStatisticsOptions : undefined;
  // Validate
  try {
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolGetAllPoolsLifetimeStatisticsOptions !== null && poolGetAllPoolsLifetimeStatisticsOptions !== undefined)
    {
      timeout = poolGetAllPoolsLifetimeStatisticsOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolGetAllPoolsLifetimeStatisticsOptions !== null && poolGetAllPoolsLifetimeStatisticsOptions !== undefined)
    {
      clientRequestId = poolGetAllPoolsLifetimeStatisticsOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolGetAllPoolsLifetimeStatisticsOptions !== null && poolGetAllPoolsLifetimeStatisticsOptions !== undefined)
    {
      returnClientRequestId = poolGetAllPoolsLifetimeStatisticsOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolGetAllPoolsLifetimeStatisticsOptions !== null && poolGetAllPoolsLifetimeStatisticsOptions !== undefined)
    {
      ocpDate = poolGetAllPoolsLifetimeStatisticsOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//lifetimepoolstats';
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      var parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          var resultMapper = new client.models['PoolStatistics']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody));
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Adds a pool to the specified account.
 *
 * @param {object} pool The pool to be added.
 * 
 * @param {string} [pool.id] A string that uniquely identifies the pool within
 * the account. The id can contain any combination of alphanumeric characters
 * including hyphens and underscores, and cannot contain more than 64
 * characters.
 * 
 * @param {string} [pool.displayName] The display name for the pool.
 * 
 * @param {string} [pool.vmSize] The size of virtual machines in the pool. All
 * virtual machines in a pool are the same size.
 * 
 * @param {object} [pool.cloudServiceConfiguration] The cloud service
 * configuration for the pool. This property and VirtualMachineConfiguration
 * are mutually exclusive and one of the properties must be specified.
 * 
 * @param {string} [pool.cloudServiceConfiguration.osFamily] The Azure Guest
 * OS family to be installed on the virtual machines in the pool.
 * 
 * @param {string} [pool.cloudServiceConfiguration.targetOSVersion] The Azure
 * Guest OS version to be installed on the virtual machines in the pool. The
 * default value is * which specifies the latest operating system version for
 * the specified OS family.
 * 
 * @param {string} [pool.cloudServiceConfiguration.currentOSVersion] The Azure
 * Guest OS Version currently installed on the virtual machines in the pool.
 * This may differ from TargetOSVersion if the pool state is Upgrading.
 * 
 * @param {object} [pool.virtualMachineConfiguration] The virtual machine
 * configuration for the pool. This property and CloudServiceConfiguration
 * are mutually exclusive and one of the properties must be specified.
 * 
 * @param {object} [pool.virtualMachineConfiguration.imageReference] A
 * reference to the Azure Virtual Machines Marketplace image to use.
 * 
 * @param {string} [pool.virtualMachineConfiguration.imageReference.publisher]
 * The publisher of the Azure Virtual Machines Marketplace image. For
 * example, Canonical or MicrosoftWindowsServer.
 * 
 * @param {string} [pool.virtualMachineConfiguration.imageReference.offer] The
 * offer type of the Azure Virtual Machines Marketplace image. For example,
 * UbuntuServer or WindowsServer.
 * 
 * @param {string} [pool.virtualMachineConfiguration.imageReference.sku] The
 * SKU of the Azure Virtual Machines Marketplace image. For example,
 * 14.04.0-LTS or 2012-R2-Datacenter.
 * 
 * @param {string} [pool.virtualMachineConfiguration.imageReference.version]
 * The version of the Azure Virtual Machines Marketplace image. A value of
 * 'latest' can be specified to select the latest version of an image. If
 * omitted, the default is 'latest'.
 * 
 * @param {string} [pool.virtualMachineConfiguration.nodeAgentSKUId] The SKU
 * of Batch Node Agent to be provisioned on the compute node. The Batch node
 * agent is a program that runs on each node in the pool, and provides the
 * command-and-control interface between the node and the Batch service.
 * There are different implementations of the node agent, known as SKUs, for
 * different operating systems.
 * 
 * @param {object} [pool.virtualMachineConfiguration.windowsConfiguration]
 * Windows operating system settings on the virtual machine. This property
 * must not be specified if the ImageReference property specifies a Linux OS
 * image.
 * 
 * @param {boolean}
 * [pool.virtualMachineConfiguration.windowsConfiguration.enableAutomaticUpdates]
 * Whether automatic updates are enabled on the virtual machine. If omitted,
 * the default value is true.
 * 
 * @param {moment.duration} [pool.resizeTimeout] The timeout for allocation of
 * compute nodes to the pool. In a Get Pool operation, this is the timeout
 * for the most recent resize operation. The default value is 10 minutes.
 * 
 * @param {number} [pool.targetDedicated] The desired number of compute nodes
 * in the pool. This property must have the default value if EnableAutoScale
 * is true. It is required if EnableAutoScale is false.
 * 
 * @param {boolean} [pool.enableAutoScale] Whether the pool size should
 * automatically adjust over time. If true, the AutoScaleFormula property
 * must be set. If false, the TargetDedicated property must be set.
 * 
 * @param {string} [pool.autoScaleFormula] A formula for the desired number of
 * compute nodes in the pool.
 * 
 * @param {moment.duration} [pool.autoScaleEvaluationInterval] A time interval
 * for the desired autoscale evaluation period in the pool.
 * 
 * @param {boolean} [pool.enableInterNodeCommunication] Whether the pool
 * permits direct communication between nodes.
 * 
 * @param {object} [pool.startTask] A task specified to run on each compute
 * node as it joins the pool.
 * 
 * @param {string} [pool.startTask.commandLine] The command line of the start
 * task.
 * 
 * @param {array} [pool.startTask.resourceFiles] A list of files that the
 * Batch service will download to the compute node before running the command
 * line.
 * 
 * @param {array} [pool.startTask.environmentSettings] A list of environment
 * variable settings for the start task.
 * 
 * @param {boolean} [pool.startTask.runElevated] Whether to run the start task
 * in elevated mode. The default value is false.
 * 
 * @param {number} [pool.startTask.maxTaskRetryCount] The maximum number of
 * times the task may be retried.
 * 
 * @param {boolean} [pool.startTask.waitForSuccess] Whether the Batch service
 * should wait for the start task to complete successfully (that is, to exit
 * with exit code 0) before scheduling any tasks on the compute node.
 * 
 * @param {array} [pool.certificateReferences] The list of certificates to be
 * installed on each compute node in the pool.
 * 
 * @param {array} [pool.applicationPackageReferences] The list of application
 * packages to be installed on each compute node in the pool.
 * 
 * @param {number} [pool.maxTasksPerNode] The maximum number of tasks that can
 * run concurrently on a single compute node in the pool.
 * 
 * @param {object} [pool.taskSchedulingPolicy] How the Batch service
 * distributes tasks between compute nodes in the pool.
 * 
 * @param {string} [pool.taskSchedulingPolicy.nodeFillType] How tasks should
 * be distributed across compute nodes. Possible values include: 'spread',
 * 'pack', 'unmapped'
 * 
 * @param {array} [pool.metadata] A list of name-value pairs associated with
 * the pool as metadata.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolAddOptions] Additional parameters for the
 * operation
 * 
 * @param {number} [options.poolAddOptions.timeout] The maximum time that the
 * server can spend processing the request, in seconds. The default is 30
 * seconds.
 * 
 * @param {string} [options.poolAddOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolAddOptions.returnClientRequestId] Whether the
 * server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolAddOptions.ocpDate] The time the request was
 * issued. If not specified, this header will be automatically populated with
 * the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.add = function (pool, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolAddOptions = (options && options.poolAddOptions !== undefined) ? options.poolAddOptions : undefined;
  // Validate
  try {
    if (pool === null || pool === undefined) {
      throw new Error('pool cannot be null or undefined.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolAddOptions !== null && poolAddOptions !== undefined)
    {
      timeout = poolAddOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolAddOptions !== null && poolAddOptions !== undefined)
    {
      clientRequestId = poolAddOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolAddOptions !== null && poolAddOptions !== undefined)
    {
      returnClientRequestId = poolAddOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolAddOptions !== null && poolAddOptions !== undefined)
    {
      ocpDate = poolAddOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools';
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (pool !== null && pool !== undefined) {
      var requestModelMapper = new client.models['PoolAddParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, pool, 'pool');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(pool, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 201) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Lists all of the pools in the specified account.
 *
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolListOptions] Additional parameters for the
 * operation
 * 
 * @param {string} [options.poolListOptions.filter] An OData $filter clause.
 * 
 * @param {string} [options.poolListOptions.select] An OData $select clause.
 * 
 * @param {string} [options.poolListOptions.expand] An OData $expand clause.
 * 
 * @param {number} [options.poolListOptions.maxResults] The maximum number of
 * items to return in the response.
 * 
 * @param {number} [options.poolListOptions.timeout] The maximum time that the
 * server can spend processing the request, in seconds. The default is 30
 * seconds.
 * 
 * @param {string} [options.poolListOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolListOptions.returnClientRequestId] Whether
 * the server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolListOptions.ocpDate] The time the request was
 * issued. If not specified, this header will be automatically populated with
 * the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *                      See {@link CloudPoolListResult} 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.
 */
Pool.prototype.list = function (options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolListOptions = (options && options.poolListOptions !== undefined) ? options.poolListOptions : undefined;
  // Validate
  try {
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var filter;
  var select;
  var expand;
  var maxResults;
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      filter = poolListOptions.filter;
      if (filter !== null && filter !== undefined && typeof filter.valueOf() !== 'string') {
        throw new Error('filter must be of type string.');
      }
    }
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      select = poolListOptions.select;
      if (select !== null && select !== undefined && typeof select.valueOf() !== 'string') {
        throw new Error('select must be of type string.');
      }
    }
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      expand = poolListOptions.expand;
      if (expand !== null && expand !== undefined && typeof expand.valueOf() !== 'string') {
        throw new Error('expand must be of type string.');
      }
    }
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      maxResults = poolListOptions.maxResults;
      if (maxResults !== null && maxResults !== undefined && typeof maxResults !== 'number') {
        throw new Error('maxResults must be of type number.');
      }
    }
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      timeout = poolListOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      clientRequestId = poolListOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      returnClientRequestId = poolListOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolListOptions !== null && poolListOptions !== undefined)
    {
      ocpDate = poolListOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools';
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (filter !== null && filter !== undefined) {
    queryParameters.push('$filter=' + encodeURIComponent(filter));
  }
  if (select !== null && select !== undefined) {
    queryParameters.push('$select=' + encodeURIComponent(select));
  }
  if (expand !== null && expand !== undefined) {
    queryParameters.push('$expand=' + encodeURIComponent(expand));
  }
  if (maxResults !== null && maxResults !== undefined) {
    queryParameters.push('maxresults=' + encodeURIComponent(maxResults.toString()));
  }
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      var parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          var resultMapper = new client.models['CloudPoolListResult']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody));
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Deletes a pool from the specified account.
 *
 * @param {string} poolId The id of the pool to delete.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolDeleteMethodOptions] Additional parameters for
 * the operation
 * 
 * @param {number} [options.poolDeleteMethodOptions.timeout] The maximum time
 * that the server can spend processing the request, in seconds. The default
 * is 30 seconds.
 * 
 * @param {string} [options.poolDeleteMethodOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolDeleteMethodOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolDeleteMethodOptions.ocpDate] The time the
 * request was issued. If not specified, this header will be automatically
 * populated with the current system clock time.
 * 
 * @param {string} [options.poolDeleteMethodOptions.ifMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag is an exact match as specified.
 * 
 * @param {string} [options.poolDeleteMethodOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolDeleteMethodOptions.ifModifiedSince] Specify
 * this header to perform the operation only if the resource has been
 * modified since the specified date/time.
 * 
 * @param {date} [options.poolDeleteMethodOptions.ifUnmodifiedSince] Specify
 * this header to perform the operation only if the resource has not been
 * modified since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.deleteMethod = function (poolId, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolDeleteMethodOptions = (options && options.poolDeleteMethodOptions !== undefined) ? options.poolDeleteMethodOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      timeout = poolDeleteMethodOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      clientRequestId = poolDeleteMethodOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      returnClientRequestId = poolDeleteMethodOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      ocpDate = poolDeleteMethodOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      ifMatch = poolDeleteMethodOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      ifNoneMatch = poolDeleteMethodOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      ifModifiedSince = poolDeleteMethodOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolDeleteMethodOptions !== null && poolDeleteMethodOptions !== undefined)
    {
      ifUnmodifiedSince = poolDeleteMethodOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 202) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Gets basic properties of a pool.
 *
 * @param {string} poolId The id of the pool to get.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolExistsOptions] Additional parameters for the
 * operation
 * 
 * @param {number} [options.poolExistsOptions.timeout] The maximum time that
 * the server can spend processing the request, in seconds. The default is 30
 * seconds.
 * 
 * @param {string} [options.poolExistsOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolExistsOptions.returnClientRequestId] Whether
 * the server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolExistsOptions.ocpDate] The time the request was
 * issued. If not specified, this header will be automatically populated with
 * the current system clock time.
 * 
 * @param {string} [options.poolExistsOptions.ifMatch] An ETag is specified.
 * Specify this header to perform the operation only if the resource's ETag
 * is an exact match as specified.
 * 
 * @param {string} [options.poolExistsOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolExistsOptions.ifModifiedSince] Specify this
 * header to perform the operation only if the resource has been modified
 * since the specified date/time.
 * 
 * @param {date} [options.poolExistsOptions.ifUnmodifiedSince] Specify this
 * header to perform the operation only if the resource has not been modified
 * since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} callback
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {boolean} [result]   - The deserialized result object.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.exists = function (poolId, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolExistsOptions = (options && options.poolExistsOptions !== undefined) ? options.poolExistsOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      timeout = poolExistsOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      clientRequestId = poolExistsOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      returnClientRequestId = poolExistsOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      ocpDate = poolExistsOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      ifMatch = poolExistsOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      ifNoneMatch = poolExistsOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      ifModifiedSince = poolExistsOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolExistsOptions !== null && poolExistsOptions !== undefined)
    {
      ifUnmodifiedSince = poolExistsOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'HEAD';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200 && statusCode !== 404) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    result = (statusCode === 200);

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

/**
 * Gets information about the specified pool.
 *
 * @param {string} poolId The id of the pool to get.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolGetOptions] Additional parameters for the
 * operation
 * 
 * @param {string} [options.poolGetOptions.select] An OData $select clause.
 * 
 * @param {string} [options.poolGetOptions.expand] An OData $expand clause.
 * 
 * @param {number} [options.poolGetOptions.timeout] The maximum time that the
 * server can spend processing the request, in seconds. The default is 30
 * seconds.
 * 
 * @param {string} [options.poolGetOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolGetOptions.returnClientRequestId] Whether the
 * server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolGetOptions.ocpDate] The time the request was
 * issued. If not specified, this header will be automatically populated with
 * the current system clock time.
 * 
 * @param {string} [options.poolGetOptions.ifMatch] An ETag is specified.
 * Specify this header to perform the operation only if the resource's ETag
 * is an exact match as specified.
 * 
 * @param {string} [options.poolGetOptions.ifNoneMatch] An ETag is specified.
 * Specify this header to perform the operation only if the resource's ETag
 * does not match the specified ETag.
 * 
 * @param {date} [options.poolGetOptions.ifModifiedSince] Specify this header
 * to perform the operation only if the resource has been modified since the
 * specified date/time.
 * 
 * @param {date} [options.poolGetOptions.ifUnmodifiedSince] Specify this
 * header to perform the operation only if the resource has not been modified
 * since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *                      See {@link CloudPool} 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.
 */
Pool.prototype.get = function (poolId, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolGetOptions = (options && options.poolGetOptions !== undefined) ? options.poolGetOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var select;
  var expand;
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      select = poolGetOptions.select;
      if (select !== null && select !== undefined && typeof select.valueOf() !== 'string') {
        throw new Error('select must be of type string.');
      }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      expand = poolGetOptions.expand;
      if (expand !== null && expand !== undefined && typeof expand.valueOf() !== 'string') {
        throw new Error('expand must be of type string.');
      }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      timeout = poolGetOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      clientRequestId = poolGetOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      returnClientRequestId = poolGetOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      ocpDate = poolGetOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      ifMatch = poolGetOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      ifNoneMatch = poolGetOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      ifModifiedSince = poolGetOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolGetOptions !== null && poolGetOptions !== undefined)
    {
      ifUnmodifiedSince = poolGetOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (select !== null && select !== undefined) {
    queryParameters.push('$select=' + encodeURIComponent(select));
  }
  if (expand !== null && expand !== undefined) {
    queryParameters.push('$expand=' + encodeURIComponent(expand));
  }
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      var parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          var resultMapper = new client.models['CloudPool']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody));
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Updates the properties of a pool.
 *
 * @param {string} poolId The id of the pool to update.
 * 
 * @param {object} poolPatchParameter The parameters for the request.
 * 
 * @param {object} [poolPatchParameter.startTask] A task to run on each
 * compute node as it joins the pool. If omitted, any existing start task is
 * left unchanged.
 * 
 * @param {string} [poolPatchParameter.startTask.commandLine] The command line
 * of the start task.
 * 
 * @param {array} [poolPatchParameter.startTask.resourceFiles] A list of files
 * that the Batch service will download to the compute node before running
 * the command line.
 * 
 * @param {array} [poolPatchParameter.startTask.environmentSettings] A list of
 * environment variable settings for the start task.
 * 
 * @param {boolean} [poolPatchParameter.startTask.runElevated] Whether to run
 * the start task in elevated mode. The default value is false.
 * 
 * @param {number} [poolPatchParameter.startTask.maxTaskRetryCount] The
 * maximum number of times the task may be retried.
 * 
 * @param {boolean} [poolPatchParameter.startTask.waitForSuccess] Whether the
 * Batch service should wait for the start task to complete successfully
 * (that is, to exit with exit code 0) before scheduling any tasks on the
 * compute node.
 * 
 * @param {array} [poolPatchParameter.certificateReferences] A list of
 * certificates to be installed on each compute node in the pool. If omitted,
 * any existing certificate references are left unchanged.
 * 
 * @param {array} [poolPatchParameter.applicationPackageReferences] A list of
 * application packages to be installed on each compute node in the pool. If
 * omitted, any existing application package references are left unchanged.
 * 
 * @param {array} [poolPatchParameter.metadata] A list of name-value pairs
 * associated with the pool as metadata. If omitted, any existing metadata is
 * left unchanged.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolPatchOptions] Additional parameters for the
 * operation
 * 
 * @param {number} [options.poolPatchOptions.timeout] The maximum time that
 * the server can spend processing the request, in seconds. The default is 30
 * seconds.
 * 
 * @param {string} [options.poolPatchOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolPatchOptions.returnClientRequestId] Whether
 * the server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolPatchOptions.ocpDate] The time the request was
 * issued. If not specified, this header will be automatically populated with
 * the current system clock time.
 * 
 * @param {string} [options.poolPatchOptions.ifMatch] An ETag is specified.
 * Specify this header to perform the operation only if the resource's ETag
 * is an exact match as specified.
 * 
 * @param {string} [options.poolPatchOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolPatchOptions.ifModifiedSince] Specify this
 * header to perform the operation only if the resource has been modified
 * since the specified date/time.
 * 
 * @param {date} [options.poolPatchOptions.ifUnmodifiedSince] Specify this
 * header to perform the operation only if the resource has not been modified
 * since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.patch = function (poolId, poolPatchParameter, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolPatchOptions = (options && options.poolPatchOptions !== undefined) ? options.poolPatchOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (poolPatchParameter === null || poolPatchParameter === undefined) {
      throw new Error('poolPatchParameter cannot be null or undefined.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      timeout = poolPatchOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      clientRequestId = poolPatchOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      returnClientRequestId = poolPatchOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      ocpDate = poolPatchOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      ifMatch = poolPatchOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      ifNoneMatch = poolPatchOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      ifModifiedSince = poolPatchOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolPatchOptions !== null && poolPatchOptions !== undefined)
    {
      ifUnmodifiedSince = poolPatchOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'PATCH';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (poolPatchParameter !== null && poolPatchParameter !== undefined) {
      var requestModelMapper = new client.models['PoolPatchParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, poolPatchParameter, 'poolPatchParameter');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(poolPatchParameter, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Disables automatic scaling for a pool.
 *
 * @param {string} poolId The id of the pool on which to disable automatic
 * scaling.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolDisableAutoScaleOptions] Additional parameters
 * for the operation
 * 
 * @param {number} [options.poolDisableAutoScaleOptions.timeout] The maximum
 * time that the server can spend processing the request, in seconds. The
 * default is 30 seconds.
 * 
 * @param {string} [options.poolDisableAutoScaleOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean}
 * [options.poolDisableAutoScaleOptions.returnClientRequestId] Whether the
 * server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolDisableAutoScaleOptions.ocpDate] The time the
 * request was issued. If not specified, this header will be automatically
 * populated with the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.disableAutoScale = function (poolId, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolDisableAutoScaleOptions = (options && options.poolDisableAutoScaleOptions !== undefined) ? options.poolDisableAutoScaleOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolDisableAutoScaleOptions !== null && poolDisableAutoScaleOptions !== undefined)
    {
      timeout = poolDisableAutoScaleOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolDisableAutoScaleOptions !== null && poolDisableAutoScaleOptions !== undefined)
    {
      clientRequestId = poolDisableAutoScaleOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolDisableAutoScaleOptions !== null && poolDisableAutoScaleOptions !== undefined)
    {
      returnClientRequestId = poolDisableAutoScaleOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolDisableAutoScaleOptions !== null && poolDisableAutoScaleOptions !== undefined)
    {
      ocpDate = poolDisableAutoScaleOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/disableautoscale';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Enables automatic scaling for a pool.
 *
 * @param {string} poolId The id of the pool on which to enable automatic
 * scaling.
 * 
 * @param {object} poolEnableAutoScaleParameter The parameters for the request.
 * 
 * @param {string} [poolEnableAutoScaleParameter.autoScaleFormula] The formula
 * for the desired number of compute nodes in the pool.
 * 
 * @param {moment.duration}
 * [poolEnableAutoScaleParameter.autoScaleEvaluationInterval] A time interval
 * for the desired autoscale evaluation period in the pool.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolEnableAutoScaleOptions] Additional parameters
 * for the operation
 * 
 * @param {number} [options.poolEnableAutoScaleOptions.timeout] The maximum
 * time that the server can spend processing the request, in seconds. The
 * default is 30 seconds.
 * 
 * @param {string} [options.poolEnableAutoScaleOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolEnableAutoScaleOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolEnableAutoScaleOptions.ocpDate] The time the
 * request was issued. If not specified, this header will be automatically
 * populated with the current system clock time.
 * 
 * @param {string} [options.poolEnableAutoScaleOptions.ifMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag is an exact match as specified.
 * 
 * @param {string} [options.poolEnableAutoScaleOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolEnableAutoScaleOptions.ifModifiedSince] Specify
 * this header to perform the operation only if the resource has been
 * modified since the specified date/time.
 * 
 * @param {date} [options.poolEnableAutoScaleOptions.ifUnmodifiedSince]
 * Specify this header to perform the operation only if the resource has not
 * been modified since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.enableAutoScale = function (poolId, poolEnableAutoScaleParameter, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolEnableAutoScaleOptions = (options && options.poolEnableAutoScaleOptions !== undefined) ? options.poolEnableAutoScaleOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (poolEnableAutoScaleParameter === null || poolEnableAutoScaleParameter === undefined) {
      throw new Error('poolEnableAutoScaleParameter cannot be null or undefined.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      timeout = poolEnableAutoScaleOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      clientRequestId = poolEnableAutoScaleOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      returnClientRequestId = poolEnableAutoScaleOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      ocpDate = poolEnableAutoScaleOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      ifMatch = poolEnableAutoScaleOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      ifNoneMatch = poolEnableAutoScaleOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      ifModifiedSince = poolEnableAutoScaleOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolEnableAutoScaleOptions !== null && poolEnableAutoScaleOptions !== undefined)
    {
      ifUnmodifiedSince = poolEnableAutoScaleOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/enableautoscale';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (poolEnableAutoScaleParameter !== null && poolEnableAutoScaleParameter !== undefined) {
      var requestModelMapper = new client.models['PoolEnableAutoScaleParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, poolEnableAutoScaleParameter, 'poolEnableAutoScaleParameter');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(poolEnableAutoScaleParameter, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Gets the result of evaluating an automatic scaling formula on the pool.
 *
 * @param {string} poolId The id of the pool on which to evaluate the
 * automatic scaling formula.
 * 
 * @param {string} autoScaleFormula A formula for the desired number of
 * compute nodes in the pool.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolEvaluateAutoScaleOptions] Additional
 * parameters for the operation
 * 
 * @param {number} [options.poolEvaluateAutoScaleOptions.timeout] The maximum
 * time that the server can spend processing the request, in seconds. The
 * default is 30 seconds.
 * 
 * @param {string} [options.poolEvaluateAutoScaleOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean}
 * [options.poolEvaluateAutoScaleOptions.returnClientRequestId] Whether the
 * server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolEvaluateAutoScaleOptions.ocpDate] The time the
 * request was issued. If not specified, this header will be automatically
 * populated with the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *                      See {@link AutoScaleRun} 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.
 */
Pool.prototype.evaluateAutoScale = function (poolId, autoScaleFormula, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolEvaluateAutoScaleOptions = (options && options.poolEvaluateAutoScaleOptions !== undefined) ? options.poolEvaluateAutoScaleOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion cannot be null or undefined and it must be of type string.');
    }
    if (autoScaleFormula === null || autoScaleFormula === undefined || typeof autoScaleFormula.valueOf() !== 'string') {
      throw new Error('autoScaleFormula 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var poolEvaluateAutoScaleParameter = new client.models['PoolEvaluateAutoScaleParameter']();
  try {
    if (poolEvaluateAutoScaleOptions !== null && poolEvaluateAutoScaleOptions !== undefined)
    {
      timeout = poolEvaluateAutoScaleOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolEvaluateAutoScaleOptions !== null && poolEvaluateAutoScaleOptions !== undefined)
    {
      clientRequestId = poolEvaluateAutoScaleOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolEvaluateAutoScaleOptions !== null && poolEvaluateAutoScaleOptions !== undefined)
    {
      returnClientRequestId = poolEvaluateAutoScaleOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolEvaluateAutoScaleOptions !== null && poolEvaluateAutoScaleOptions !== undefined)
    {
      ocpDate = poolEvaluateAutoScaleOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (autoScaleFormula !== null && autoScaleFormula !== undefined)
    {
      poolEvaluateAutoScaleParameter.autoScaleFormula = autoScaleFormula;
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/evaluateautoscale';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (poolEvaluateAutoScaleParameter !== null && poolEvaluateAutoScaleParameter !== undefined) {
      var requestModelMapper = new client.models['PoolEvaluateAutoScaleParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, poolEvaluateAutoScaleParameter, 'poolEvaluateAutoScaleParameter');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(poolEvaluateAutoScaleParameter, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      var parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          var resultMapper = new client.models['AutoScaleRun']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody));
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Changes the number of compute nodes that are assigned to a pool.
 *
 * @param {string} poolId The id of the pool to resize.
 * 
 * @param {object} poolResizeParameter The parameters for the request.
 * 
 * @param {number} [poolResizeParameter.targetDedicated] The desired number of
 * compute nodes in the pool.
 * 
 * @param {moment.duration} [poolResizeParameter.resizeTimeout] The timeout
 * for allocation of compute nodes to the pool or removal of compute nodes
 * from the pool. The default value is 10 minutes.
 * 
 * @param {string} [poolResizeParameter.nodeDeallocationOption] When nodes may
 * be removed from the pool, if the pool size is decreasing. Possible values
 * include: 'requeue', 'terminate', 'taskcompletion', 'retaineddata'
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolResizeOptions] Additional parameters for the
 * operation
 * 
 * @param {number} [options.poolResizeOptions.timeout] The maximum time that
 * the server can spend processing the request, in seconds. The default is 30
 * seconds.
 * 
 * @param {string} [options.poolResizeOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolResizeOptions.returnClientRequestId] Whether
 * the server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolResizeOptions.ocpDate] The time the request was
 * issued. If not specified, this header will be automatically populated with
 * the current system clock time.
 * 
 * @param {string} [options.poolResizeOptions.ifMatch] An ETag is specified.
 * Specify this header to perform the operation only if the resource's ETag
 * is an exact match as specified.
 * 
 * @param {string} [options.poolResizeOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolResizeOptions.ifModifiedSince] Specify this
 * header to perform the operation only if the resource has been modified
 * since the specified date/time.
 * 
 * @param {date} [options.poolResizeOptions.ifUnmodifiedSince] Specify this
 * header to perform the operation only if the resource has not been modified
 * since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.resize = function (poolId, poolResizeParameter, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolResizeOptions = (options && options.poolResizeOptions !== undefined) ? options.poolResizeOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (poolResizeParameter === null || poolResizeParameter === undefined) {
      throw new Error('poolResizeParameter cannot be null or undefined.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      timeout = poolResizeOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      clientRequestId = poolResizeOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      returnClientRequestId = poolResizeOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      ocpDate = poolResizeOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      ifMatch = poolResizeOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      ifNoneMatch = poolResizeOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      ifModifiedSince = poolResizeOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolResizeOptions !== null && poolResizeOptions !== undefined)
    {
      ifUnmodifiedSince = poolResizeOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/resize';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (poolResizeParameter !== null && poolResizeParameter !== undefined) {
      var requestModelMapper = new client.models['PoolResizeParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, poolResizeParameter, 'poolResizeParameter');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(poolResizeParameter, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 202) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Stops an ongoing resize operation on the pool. This does not restore the
 * pool to its previous state before the resize operation: it only stops any
 * further changes being made, and the pool maintains its current state.
 *
 * @param {string} poolId The id of the pool whose resizing you want to stop.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolStopResizeOptions] Additional parameters for
 * the operation
 * 
 * @param {number} [options.poolStopResizeOptions.timeout] The maximum time
 * that the server can spend processing the request, in seconds. The default
 * is 30 seconds.
 * 
 * @param {string} [options.poolStopResizeOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolStopResizeOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolStopResizeOptions.ocpDate] The time the request
 * was issued. If not specified, this header will be automatically populated
 * with the current system clock time.
 * 
 * @param {string} [options.poolStopResizeOptions.ifMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag is an exact match as specified.
 * 
 * @param {string} [options.poolStopResizeOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolStopResizeOptions.ifModifiedSince] Specify this
 * header to perform the operation only if the resource has been modified
 * since the specified date/time.
 * 
 * @param {date} [options.poolStopResizeOptions.ifUnmodifiedSince] Specify
 * this header to perform the operation only if the resource has not been
 * modified since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.stopResize = function (poolId, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolStopResizeOptions = (options && options.poolStopResizeOptions !== undefined) ? options.poolStopResizeOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      timeout = poolStopResizeOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      clientRequestId = poolStopResizeOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      returnClientRequestId = poolStopResizeOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      ocpDate = poolStopResizeOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      ifMatch = poolStopResizeOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      ifNoneMatch = poolStopResizeOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      ifModifiedSince = poolStopResizeOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolStopResizeOptions !== null && poolStopResizeOptions !== undefined)
    {
      ifUnmodifiedSince = poolStopResizeOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/stopresize';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 202) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Updates the properties of a pool.
 *
 * @param {string} poolId The id of the pool to update.
 * 
 * @param {object} poolUpdatePropertiesParameter The parameters for the
 * request.
 * 
 * @param {object} [poolUpdatePropertiesParameter.startTask] A task to run on
 * each compute node as it joins the pool. If omitted, any existing start
 * task is removed from the pool.
 * 
 * @param {string} [poolUpdatePropertiesParameter.startTask.commandLine] The
 * command line of the start task.
 * 
 * @param {array} [poolUpdatePropertiesParameter.startTask.resourceFiles] A
 * list of files that the Batch service will download to the compute node
 * before running the command line.
 * 
 * @param {array}
 * [poolUpdatePropertiesParameter.startTask.environmentSettings] A list of
 * environment variable settings for the start task.
 * 
 * @param {boolean} [poolUpdatePropertiesParameter.startTask.runElevated]
 * Whether to run the start task in elevated mode. The default value is false.
 * 
 * @param {number} [poolUpdatePropertiesParameter.startTask.maxTaskRetryCount]
 * The maximum number of times the task may be retried.
 * 
 * @param {boolean} [poolUpdatePropertiesParameter.startTask.waitForSuccess]
 * Whether the Batch service should wait for the start task to complete
 * successfully (that is, to exit with exit code 0) before scheduling any
 * tasks on the compute node.
 * 
 * @param {array} [poolUpdatePropertiesParameter.certificateReferences] A list
 * of certificates to be installed on each compute node in the pool. If you
 * specify an empty collection, any existing certificate references are
 * removed from the pool.
 * 
 * @param {array} [poolUpdatePropertiesParameter.applicationPackageReferences]
 * A list of application packages to be installed on each compute node in the
 * pool. If you specify an empty collection, any existing application
 * packages references are removed from the pool.
 * 
 * @param {array} [poolUpdatePropertiesParameter.metadata] A list of
 * name-value pairs associated with the pool as metadata. If you specify an
 * empty collection, any existing metadata is removed from the pool.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolUpdatePropertiesOptions] Additional parameters
 * for the operation
 * 
 * @param {number} [options.poolUpdatePropertiesOptions.timeout] The maximum
 * time that the server can spend processing the request, in seconds. The
 * default is 30 seconds.
 * 
 * @param {string} [options.poolUpdatePropertiesOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean}
 * [options.poolUpdatePropertiesOptions.returnClientRequestId] Whether the
 * server should return the client-request-id identifier in the response.
 * 
 * @param {date} [options.poolUpdatePropertiesOptions.ocpDate] The time the
 * request was issued. If not specified, this header will be automatically
 * populated with the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.updateProperties = function (poolId, poolUpdatePropertiesParameter, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolUpdatePropertiesOptions = (options && options.poolUpdatePropertiesOptions !== undefined) ? options.poolUpdatePropertiesOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (poolUpdatePropertiesParameter === null || poolUpdatePropertiesParameter === undefined) {
      throw new Error('poolUpdatePropertiesParameter cannot be null or undefined.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolUpdatePropertiesOptions !== null && poolUpdatePropertiesOptions !== undefined)
    {
      timeout = poolUpdatePropertiesOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolUpdatePropertiesOptions !== null && poolUpdatePropertiesOptions !== undefined)
    {
      clientRequestId = poolUpdatePropertiesOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolUpdatePropertiesOptions !== null && poolUpdatePropertiesOptions !== undefined)
    {
      returnClientRequestId = poolUpdatePropertiesOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolUpdatePropertiesOptions !== null && poolUpdatePropertiesOptions !== undefined)
    {
      ocpDate = poolUpdatePropertiesOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/updateproperties';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (poolUpdatePropertiesParameter !== null && poolUpdatePropertiesParameter !== undefined) {
      var requestModelMapper = new client.models['PoolUpdatePropertiesParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, poolUpdatePropertiesParameter, 'poolUpdatePropertiesParameter');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(poolUpdatePropertiesParameter, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 204) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Upgrades the operating system of the specified pool.
 *
 * @param {string} poolId The id of the pool to upgrade.
 * 
 * @param {string} targetOSVersion The Azure Guest OS version to be installed
 * on the virtual machines in the pool.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolUpgradeOSOptions] Additional parameters for
 * the operation
 * 
 * @param {number} [options.poolUpgradeOSOptions.timeout] The maximum time
 * that the server can spend processing the request, in seconds. The default
 * is 30 seconds.
 * 
 * @param {string} [options.poolUpgradeOSOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolUpgradeOSOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolUpgradeOSOptions.ocpDate] The time the request
 * was issued. If not specified, this header will be automatically populated
 * with the current system clock time.
 * 
 * @param {string} [options.poolUpgradeOSOptions.ifMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag is an exact match as specified.
 * 
 * @param {string} [options.poolUpgradeOSOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolUpgradeOSOptions.ifModifiedSince] Specify this
 * header to perform the operation only if the resource has been modified
 * since the specified date/time.
 * 
 * @param {date} [options.poolUpgradeOSOptions.ifUnmodifiedSince] Specify this
 * header to perform the operation only if the resource has not been modified
 * since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.upgradeOS = function (poolId, targetOSVersion, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolUpgradeOSOptions = (options && options.poolUpgradeOSOptions !== undefined) ? options.poolUpgradeOSOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion cannot be null or undefined and it must be of type string.');
    }
    if (targetOSVersion === null || targetOSVersion === undefined || typeof targetOSVersion.valueOf() !== 'string') {
      throw new Error('targetOSVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  var poolUpgradeOSParameter = new client.models['PoolUpgradeOSParameter']();
  try {
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      timeout = poolUpgradeOSOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      clientRequestId = poolUpgradeOSOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      returnClientRequestId = poolUpgradeOSOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      ocpDate = poolUpgradeOSOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      ifMatch = poolUpgradeOSOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      ifNoneMatch = poolUpgradeOSOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      ifModifiedSince = poolUpgradeOSOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolUpgradeOSOptions !== null && poolUpgradeOSOptions !== undefined)
    {
      ifUnmodifiedSince = poolUpgradeOSOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
    if (targetOSVersion !== null && targetOSVersion !== undefined)
    {
      poolUpgradeOSParameter.targetOSVersion = targetOSVersion;
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/upgradeos';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (poolUpgradeOSParameter !== null && poolUpgradeOSParameter !== undefined) {
      var requestModelMapper = new client.models['PoolUpgradeOSParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, poolUpgradeOSParameter, 'poolUpgradeOSParameter');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(poolUpgradeOSParameter, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 202) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Removes compute nodes from the specified pool.
 *
 * @param {string} poolId The id of the pool from which you want to remove
 * nodes.
 * 
 * @param {object} nodeRemoveParameter The parameters for the request.
 * 
 * @param {array} [nodeRemoveParameter.nodeList] A list containing the id of
 * the compute nodes to be removed from the specified pool.
 * 
 * @param {moment.duration} [nodeRemoveParameter.resizeTimeout] The timeout
 * for removal of compute nodes to the pool. The default value is 10 minutes.
 * 
 * @param {string} [nodeRemoveParameter.nodeDeallocationOption] When compute
 * nodes may be removed from the pool. Possible values include: 'requeue',
 * 'terminate', 'taskcompletion', 'retaineddata'
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolRemoveNodesOptions] Additional parameters for
 * the operation
 * 
 * @param {number} [options.poolRemoveNodesOptions.timeout] The maximum time
 * that the server can spend processing the request, in seconds. The default
 * is 30 seconds.
 * 
 * @param {string} [options.poolRemoveNodesOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolRemoveNodesOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolRemoveNodesOptions.ocpDate] The time the request
 * was issued. If not specified, this header will be automatically populated
 * with the current system clock time.
 * 
 * @param {string} [options.poolRemoveNodesOptions.ifMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag is an exact match as specified.
 * 
 * @param {string} [options.poolRemoveNodesOptions.ifNoneMatch] An ETag is
 * specified. Specify this header to perform the operation only if the
 * resource's ETag does not match the specified ETag.
 * 
 * @param {date} [options.poolRemoveNodesOptions.ifModifiedSince] Specify this
 * header to perform the operation only if the resource has been modified
 * since the specified date/time.
 * 
 * @param {date} [options.poolRemoveNodesOptions.ifUnmodifiedSince] Specify
 * this header to perform the operation only if the resource has not been
 * modified since the specified date/time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
Pool.prototype.removeNodes = function (poolId, nodeRemoveParameter, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolRemoveNodesOptions = (options && options.poolRemoveNodesOptions !== undefined) ? options.poolRemoveNodesOptions : undefined;
  // Validate
  try {
    if (poolId === null || poolId === undefined || typeof poolId.valueOf() !== 'string') {
      throw new Error('poolId cannot be null or undefined and it must be of type string.');
    }
    if (nodeRemoveParameter === null || nodeRemoveParameter === undefined) {
      throw new Error('nodeRemoveParameter cannot be null or undefined.');
    }
    if (this.client.apiVersion === null || this.client.apiVersion === undefined || typeof this.client.apiVersion.valueOf() !== 'string') {
      throw new Error('this.client.apiVersion 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);
  }
  var timeout;
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  var ifMatch;
  var ifNoneMatch;
  var ifModifiedSince;
  var ifUnmodifiedSince;
  try {
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      timeout = poolRemoveNodesOptions.timeout;
      if (timeout !== null && timeout !== undefined && typeof timeout !== 'number') {
        throw new Error('timeout must be of type number.');
      }
    }
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      clientRequestId = poolRemoveNodesOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      returnClientRequestId = poolRemoveNodesOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      ocpDate = poolRemoveNodesOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      ifMatch = poolRemoveNodesOptions.ifMatch;
      if (ifMatch !== null && ifMatch !== undefined && typeof ifMatch.valueOf() !== 'string') {
        throw new Error('ifMatch must be of type string.');
      }
    }
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      ifNoneMatch = poolRemoveNodesOptions.ifNoneMatch;
      if (ifNoneMatch !== null && ifNoneMatch !== undefined && typeof ifNoneMatch.valueOf() !== 'string') {
        throw new Error('ifNoneMatch must be of type string.');
      }
    }
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      ifModifiedSince = poolRemoveNodesOptions.ifModifiedSince;
      if (ifModifiedSince && !(ifModifiedSince instanceof Date || 
          (typeof ifModifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifModifiedSince))))) {
            throw new Error('ifModifiedSince must be of type date.');
          }
    }
    if (poolRemoveNodesOptions !== null && poolRemoveNodesOptions !== undefined)
    {
      ifUnmodifiedSince = poolRemoveNodesOptions.ifUnmodifiedSince;
      if (ifUnmodifiedSince && !(ifUnmodifiedSince instanceof Date || 
          (typeof ifUnmodifiedSince.valueOf() === 'string' && !isNaN(Date.parse(ifUnmodifiedSince))))) {
            throw new Error('ifUnmodifiedSince must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = this.client.baseUri +
                   '//pools/{poolId}/removenodes';
  requestUrl = requestUrl.replace('{poolId}', encodeURIComponent(poolId));
  var queryParameters = [];
  queryParameters.push('api-version=' + encodeURIComponent(this.client.apiVersion));
  if (timeout !== null && timeout !== undefined) {
    queryParameters.push('timeout=' + encodeURIComponent(timeout.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if (ifMatch !== undefined && ifMatch !== null) {
    httpRequest.headers['If-Match'] = ifMatch;
  }
  if (ifNoneMatch !== undefined && ifNoneMatch !== null) {
    httpRequest.headers['If-None-Match'] = ifNoneMatch;
  }
  if (ifModifiedSince !== undefined && ifModifiedSince !== null) {
    httpRequest.headers['If-Modified-Since'] = ifModifiedSince.toUTCString();
  }
  if (ifUnmodifiedSince !== undefined && ifUnmodifiedSince !== null) {
    httpRequest.headers['If-Unmodified-Since'] = ifUnmodifiedSince.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  // Serialize Request
  var requestContent = null;
  var requestModel = null;
  try {
    if (nodeRemoveParameter !== null && nodeRemoveParameter !== undefined) {
      var requestModelMapper = new client.models['NodeRemoveParameter']().mapper();
      requestModel = client.serialize(requestModelMapper, nodeRemoveParameter, 'nodeRemoveParameter');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    var serializationError = new Error(util.format('Error "%s" occurred in serializing the ' + 
        'payload - "%s"', error.message, util.inspect(nodeRemoveParameter, {depth: null})));
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 202) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Lists the usage metrics, aggregated by pool across individual time
 * intervals, for the specified account.
 *
 * @param {string} nextPageLink The NextLink from the previous successful call
 * to List operation.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolListPoolUsageMetricsNextOptions] Additional
 * parameters for the operation
 * 
 * @param {string}
 * [options.poolListPoolUsageMetricsNextOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean}
 * [options.poolListPoolUsageMetricsNextOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolListPoolUsageMetricsNextOptions.ocpDate] The
 * time the request was issued. If not specified, this header will be
 * automatically populated with the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *                      See {@link PoolListPoolUsageMetricsResult} 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.
 */
Pool.prototype.listPoolUsageMetricsNext = function (nextPageLink, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolListPoolUsageMetricsNextOptions = (options && options.poolListPoolUsageMetricsNextOptions !== undefined) ? options.poolListPoolUsageMetricsNextOptions : undefined;
  // 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);
  }
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolListPoolUsageMetricsNextOptions !== null && poolListPoolUsageMetricsNextOptions !== undefined)
    {
      clientRequestId = poolListPoolUsageMetricsNextOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolListPoolUsageMetricsNextOptions !== null && poolListPoolUsageMetricsNextOptions !== undefined)
    {
      returnClientRequestId = poolListPoolUsageMetricsNextOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolListPoolUsageMetricsNextOptions !== null && poolListPoolUsageMetricsNextOptions !== undefined)
    {
      ocpDate = poolListPoolUsageMetricsNextOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = '{nextLink}';
  requestUrl = requestUrl.replace('{nextLink}', nextPageLink);
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      var parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          var resultMapper = new client.models['PoolListPoolUsageMetricsResult']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody));
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Lists all of the pools in the specified account.
 *
 * @param {string} nextPageLink The NextLink from the previous successful call
 * to List operation.
 * 
 * @param {object} [options] Optional Parameters.
 * 
 * @param {object} [options.poolListNextOptions] Additional parameters for the
 * operation
 * 
 * @param {string} [options.poolListNextOptions.clientRequestId] The
 * caller-generated request identity, in the form of a GUID with no
 * decoration such as curly braces, e.g. 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0.
 * 
 * @param {boolean} [options.poolListNextOptions.returnClientRequestId]
 * Whether the server should return the client-request-id identifier in the
 * response.
 * 
 * @param {date} [options.poolListNextOptions.ocpDate] The time the request
 * was issued. If not specified, this header will be automatically populated
 * with the current system clock time.
 * 
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 * 
 * @param {function} 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.
 *                      See {@link CloudPoolListResult} 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.
 */
Pool.prototype.listNext = function (nextPageLink, options, callback) {
  var client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  var poolListNextOptions = (options && options.poolListNextOptions !== undefined) ? options.poolListNextOptions : undefined;
  // 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);
  }
  var clientRequestId;
  var returnClientRequestId;
  var ocpDate;
  try {
    if (poolListNextOptions !== null && poolListNextOptions !== undefined)
    {
      clientRequestId = poolListNextOptions.clientRequestId;
      if (clientRequestId !== null && clientRequestId !== undefined && typeof clientRequestId.valueOf() !== 'string') {
        throw new Error('clientRequestId must be of type string.');
      }
    }
    if (poolListNextOptions !== null && poolListNextOptions !== undefined)
    {
      returnClientRequestId = poolListNextOptions.returnClientRequestId;
      if (returnClientRequestId !== null && returnClientRequestId !== undefined && typeof returnClientRequestId !== 'boolean') {
        throw new Error('returnClientRequestId must be of type boolean.');
      }
    }
    if (poolListNextOptions !== null && poolListNextOptions !== undefined)
    {
      ocpDate = poolListNextOptions.ocpDate;
      if (ocpDate && !(ocpDate instanceof Date || 
          (typeof ocpDate.valueOf() === 'string' && !isNaN(Date.parse(ocpDate))))) {
            throw new Error('ocpDate must be of type date.');
          }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  var requestUrl = '{nextLink}';
  requestUrl = requestUrl.replace('{nextLink}', nextPageLink);
  // trim all duplicate forward slashes in the url
  var regex = /([^:]\/)\/+/gi;
  requestUrl = requestUrl.replace(regex, '$1');

  // Create HTTP transport objects
  var httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.headers = {};
  httpRequest.url = requestUrl;
  // Set Headers
  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 (clientRequestId !== undefined && clientRequestId !== null) {
    httpRequest.headers['client-request-id'] = clientRequestId;
  }
  if (returnClientRequestId !== undefined && returnClientRequestId !== null) {
    httpRequest.headers['return-client-request-id'] = returnClientRequestId.toString();
  }
  if (ocpDate !== undefined && ocpDate !== null) {
    httpRequest.headers['ocp-date'] = ocpDate.toUTCString();
  }
  if(options) {
    for(var headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.headers['Content-Type'] = 'application/json; odata=minimalmetadata; charset=utf-8';
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, function (err, response, responseBody) {
    if (err) {
      return callback(err);
    }
    var statusCode = response.statusCode;
    if (statusCode !== 200) {
      var error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      var 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) {
          var resultMapper = new client.models['BatchError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = util.format('Error "%s" occurred in deserializing the responseBody ' + 
                         '- "%s" for the default response.', defaultError.message, responseBody);
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    var result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      var parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          var resultMapper = new client.models['CloudPoolListResult']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        var deserializationError = new Error(util.format('Error "%s" occurred in deserializing the responseBody - "%s"', error, responseBody));
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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


module.exports = Pool;
