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

/* jshint latedef:false */
/* jshint forin:false */
/* jshint noempty:false */

'use strict';

const msRest = require('ms-rest');
const ServiceClient = msRest.ServiceClient;
const WebResource = msRest.WebResource;

const models = require('./models');


/**
 * @summary Get a list of the available domains.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getDomains(options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'domains';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'DomainElementType',
                  type: {
                    name: 'Composite',
                    className: 'Domain'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get information about a specific domain.
 *
 * @param {uuid} domainId The id of the domain to get information about.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Domain} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getDomain(domainId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (domainId === null || domainId === undefined || typeof domainId.valueOf() !== 'string' || !msRest.isValidUuid(domainId)) {
      throw new Error('domainId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'domains/{domainId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{domainId}', encodeURIComponent(domainId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Domain']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Gets the number of images tagged with the provided {tagIds}.
 *
 * The filtering is on an and/or relationship. For example, if the provided tag
 * ids are for the "Dog" and
 * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
 *
 * @param {array} [options.tagIds] A list of tags ids to filter the images to
 * count. Defaults to all tags when null.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {number} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getTaggedImageCount(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  let tagIds = (options && options.tagIds !== undefined) ? options.tagIds : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (Array.isArray(tagIds)) {
      for (let i = 0; i < tagIds.length; i++) {
        if (tagIds[i] !== null && tagIds[i] !== undefined && !(typeof tagIds[i].valueOf() === 'string' && msRest.isValidUuid(tagIds[i]))) {
          throw new Error('tagIds[i] must be of type string and must be a valid uuid.');
        }
      }
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/tagged/count';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (tagIds !== null && tagIds !== undefined) {
    queryParameters.push('tagIds=' + encodeURIComponent(tagIds.join(',')));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Number'
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Gets the number of untagged images.
 *
 * This API returns the images which have no tags for a given project and
 * optionally an iteration. If no iteration is specified the
 * current workspace is used.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {number} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getUntaggedImageCount(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/untagged/count';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Number'
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Associate a set of images with a set of tags.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} batch Batch of image tags. Limited to 128 tags per batch.
 *
 * @param {array} [batch.tags] Image Tag entries to include in this batch.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImageTagCreateSummary} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createImageTags(projectId, batch, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (batch === null || batch === undefined) {
      throw new Error('batch cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/tags';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (batch !== null && batch !== undefined) {
      let requestModelMapper = new client.models['ImageTagCreateBatch']().mapper();
      requestModel = client.serialize(requestModelMapper, batch, 'batch');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(batch, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImageTagCreateSummary']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Remove a set of tags from a set of images.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {array} imageIds Image ids. Limited to 64 images.
 *
 * @param {array} tagIds Tags to be deleted from the specified images. Limited
 * to 20 tags.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _deleteImageTags(projectId, imageIds, tagIds, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (!Array.isArray(imageIds)) {
      throw new Error('imageIds cannot be null or undefined and it must be of type array.');
    }
    for (let i = 0; i < imageIds.length; i++) {
      if (imageIds[i] !== null && imageIds[i] !== undefined && !(typeof imageIds[i].valueOf() === 'string' && msRest.isValidUuid(imageIds[i]))) {
        throw new Error('imageIds[i] must be of type string and must be a valid uuid.');
      }
    }
    if (imageIds !== null && imageIds !== undefined) {
      if (imageIds.length > 64)
      {
        throw new Error('"imageIds" should satisfy the constraint - "MaxItems": 64');
      }
      if (imageIds.length < 0)
      {
        throw new Error('"imageIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (!Array.isArray(tagIds)) {
      throw new Error('tagIds cannot be null or undefined and it must be of type array.');
    }
    for (let i1 = 0; i1 < tagIds.length; i1++) {
      if (tagIds[i1] !== null && tagIds[i1] !== undefined && !(typeof tagIds[i1].valueOf() === 'string' && msRest.isValidUuid(tagIds[i1]))) {
        throw new Error('tagIds[i1] must be of type string and must be a valid uuid.');
      }
    }
    if (tagIds !== null && tagIds !== undefined) {
      if (tagIds.length > 20)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MaxItems": 20');
      }
      if (tagIds.length < 0)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/tags';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  queryParameters.push('imageIds=' + encodeURIComponent(imageIds.join(',')));
  queryParameters.push('tagIds=' + encodeURIComponent(tagIds.join(',')));
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Create a set of image regions.
 *
 * This API accepts a batch of image regions, and optionally tags, to update
 * existing images with region information.
 * There is a limit of 64 entries in the batch.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} batch Batch of image regions which include a tag and
 * bounding box. Limited to 64.
 *
 * @param {array} [batch.regions]
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImageRegionCreateSummary} for more
 *                      information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createImageRegions(projectId, batch, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (batch === null || batch === undefined) {
      throw new Error('batch cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/regions';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (batch !== null && batch !== undefined) {
      let requestModelMapper = new client.models['ImageRegionCreateBatch']().mapper();
      requestModel = client.serialize(requestModelMapper, batch, 'batch');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(batch, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImageRegionCreateSummary']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Delete a set of image regions.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {array} regionIds Regions to delete. Limited to 64.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _deleteImageRegions(projectId, regionIds, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (!Array.isArray(regionIds)) {
      throw new Error('regionIds cannot be null or undefined and it must be of type array.');
    }
    for (let i = 0; i < regionIds.length; i++) {
      if (regionIds[i] !== null && regionIds[i] !== undefined && !(typeof regionIds[i].valueOf() === 'string' && msRest.isValidUuid(regionIds[i]))) {
        throw new Error('regionIds[i] must be of type string and must be a valid uuid.');
      }
    }
    if (regionIds !== null && regionIds !== undefined) {
      if (regionIds.length > 64)
      {
        throw new Error('"regionIds" should satisfy the constraint - "MaxItems": 64');
      }
      if (regionIds.length < 0)
      {
        throw new Error('"regionIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/regions';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  queryParameters.push('regionIds=' + encodeURIComponent(regionIds.join(',')));
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Get tagged images for a given project iteration.
 *
 * This API supports batching and range selection. By default it will only
 * return first 50 images matching images.
 * Use the {take} and {skip} parameters to control how many images to return in
 * a given batch.
 * The filtering is on an and/or relationship. For example, if the provided tag
 * ids are for the "Dog" and
 * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
 *
 * @param {array} [options.tagIds] A list of tags ids to filter the images.
 * Defaults to all tagged images when null. Limited to 20.
 *
 * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
 * values include: 'Newest', 'Oldest'
 *
 * @param {number} [options.take] Maximum number of images to return. Defaults
 * to 50, limited to 256.
 *
 * @param {number} [options.skip] Number of images to skip before beginning the
 * image batch. Defaults to 0.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getTaggedImages(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  let tagIds = (options && options.tagIds !== undefined) ? options.tagIds : undefined;
  let orderBy = (options && options.orderBy !== undefined) ? options.orderBy : undefined;
  let take = (options && options.take !== undefined) ? options.take : 50;
  let skip = (options && options.skip !== undefined) ? options.skip : 0;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (Array.isArray(tagIds)) {
      for (let i = 0; i < tagIds.length; i++) {
        if (tagIds[i] !== null && tagIds[i] !== undefined && !(typeof tagIds[i].valueOf() === 'string' && msRest.isValidUuid(tagIds[i]))) {
          throw new Error('tagIds[i] must be of type string and must be a valid uuid.');
        }
      }
    }
    if (tagIds !== null && tagIds !== undefined) {
      if (tagIds.length > 20)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MaxItems": 20');
      }
      if (tagIds.length < 0)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (orderBy !== null && orderBy !== undefined && typeof orderBy.valueOf() !== 'string') {
      throw new Error('orderBy must be of type string.');
    }
    if (take !== null && take !== undefined && typeof take !== 'number') {
      throw new Error('take must be of type number.');
    }
    if (take !== null && take !== undefined) {
      if (take > 256)
      {
        throw new Error('"take" should satisfy the constraint - "InclusiveMaximum": 256');
      }
      if (take < 0)
      {
        throw new Error('"take" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (skip !== null && skip !== undefined && typeof skip !== 'number') {
      throw new Error('skip must be of type number.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/tagged';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (tagIds !== null && tagIds !== undefined) {
    queryParameters.push('tagIds=' + encodeURIComponent(tagIds.join(',')));
  }
  if (orderBy !== null && orderBy !== undefined) {
    queryParameters.push('orderBy=' + encodeURIComponent(orderBy));
  }
  if (take !== null && take !== undefined) {
    queryParameters.push('take=' + encodeURIComponent(take.toString()));
  }
  if (skip !== null && skip !== undefined) {
    queryParameters.push('skip=' + encodeURIComponent(skip.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'ImageElementType',
                  type: {
                    name: 'Composite',
                    className: 'Image'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get untagged images for a given project iteration.
 *
 * This API supports batching and range selection. By default it will only
 * return first 50 images matching images.
 * Use the {take} and {skip} parameters to control how many images to return in
 * a given batch.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
 *
 * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
 * values include: 'Newest', 'Oldest'
 *
 * @param {number} [options.take] Maximum number of images to return. Defaults
 * to 50, limited to 256.
 *
 * @param {number} [options.skip] Number of images to skip before beginning the
 * image batch. Defaults to 0.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getUntaggedImages(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  let orderBy = (options && options.orderBy !== undefined) ? options.orderBy : undefined;
  let take = (options && options.take !== undefined) ? options.take : 50;
  let skip = (options && options.skip !== undefined) ? options.skip : 0;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (orderBy !== null && orderBy !== undefined && typeof orderBy.valueOf() !== 'string') {
      throw new Error('orderBy must be of type string.');
    }
    if (take !== null && take !== undefined && typeof take !== 'number') {
      throw new Error('take must be of type number.');
    }
    if (take !== null && take !== undefined) {
      if (take > 256)
      {
        throw new Error('"take" should satisfy the constraint - "InclusiveMaximum": 256');
      }
      if (take < 0)
      {
        throw new Error('"take" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (skip !== null && skip !== undefined && typeof skip !== 'number') {
      throw new Error('skip must be of type number.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/untagged';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (orderBy !== null && orderBy !== undefined) {
    queryParameters.push('orderBy=' + encodeURIComponent(orderBy));
  }
  if (take !== null && take !== undefined) {
    queryParameters.push('take=' + encodeURIComponent(take.toString()));
  }
  if (skip !== null && skip !== undefined) {
    queryParameters.push('skip=' + encodeURIComponent(skip.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'ImageElementType',
                  type: {
                    name: 'Composite',
                    className: 'Image'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get images by id for a given project iteration.
 *
 * This API will return a set of Images for the specified tags and optionally
 * iteration. If no iteration is specified the
 * current workspace is used.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {array} [options.imageIds] The list of image ids to retrieve. Limited
 * to 256.
 *
 * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getImagesByIds(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let imageIds = (options && options.imageIds !== undefined) ? options.imageIds : undefined;
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (Array.isArray(imageIds)) {
      for (let i = 0; i < imageIds.length; i++) {
        if (imageIds[i] !== null && imageIds[i] !== undefined && !(typeof imageIds[i].valueOf() === 'string' && msRest.isValidUuid(imageIds[i]))) {
          throw new Error('imageIds[i] must be of type string and must be a valid uuid.');
        }
      }
    }
    if (imageIds !== null && imageIds !== undefined) {
      if (imageIds.length > 256)
      {
        throw new Error('"imageIds" should satisfy the constraint - "MaxItems": 256');
      }
      if (imageIds.length < 0)
      {
        throw new Error('"imageIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/id';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (imageIds !== null && imageIds !== undefined) {
    queryParameters.push('imageIds=' + encodeURIComponent(imageIds.join(',')));
  }
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'ImageElementType',
                  type: {
                    name: 'Composite',
                    className: 'Image'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Add the provided images to the set of training images.
 *
 * This API accepts body content as multipart/form-data and
 * application/octet-stream. When using multipart
 * multiple image files can be sent at once, with a maximum of 64 files
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} imageData Binary image data. Supported formats are JPEG,
 * GIF, PNG, and BMP. Supports images up to 6MB.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {array} [options.tagIds] The tags ids with which to tag each image.
 * Limited to 20.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImageCreateSummary} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createImagesFromData(projectId, imageData, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let tagIds = (options && options.tagIds !== undefined) ? options.tagIds : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (Array.isArray(tagIds)) {
      for (let i = 0; i < tagIds.length; i++) {
        if (tagIds[i] !== null && tagIds[i] !== undefined && !(typeof tagIds[i].valueOf() === 'string' && msRest.isValidUuid(tagIds[i]))) {
          throw new Error('tagIds[i] must be of type string and must be a valid uuid.');
        }
      }
    }
    if (tagIds !== null && tagIds !== undefined) {
      if (tagIds.length > 20)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MaxItems": 20');
      }
      if (tagIds.length < 0)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (imageData === null || imageData === undefined) {
      throw new Error('imageData cannot be null or undefined and it must be of type object.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (tagIds !== null && tagIds !== undefined) {
    queryParameters.push('tagIds=' + encodeURIComponent(tagIds.join(',')));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'multipart/form-data';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let formData = {};
  if (imageData !== undefined && imageData !== null) {
    formData['imageData'] = imageData;
  }
  httpRequest.formData = formData;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImageCreateSummary']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Delete images from the set of training images.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {array} imageIds Ids of the images to be deleted. Limited to 256
 * images per batch.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _deleteImages(projectId, imageIds, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (!Array.isArray(imageIds)) {
      throw new Error('imageIds cannot be null or undefined and it must be of type array.');
    }
    for (let i = 0; i < imageIds.length; i++) {
      if (imageIds[i] !== null && imageIds[i] !== undefined && !(typeof imageIds[i].valueOf() === 'string' && msRest.isValidUuid(imageIds[i]))) {
        throw new Error('imageIds[i] must be of type string and must be a valid uuid.');
      }
    }
    if (imageIds !== null && imageIds !== undefined) {
      if (imageIds.length > 256)
      {
        throw new Error('"imageIds" should satisfy the constraint - "MaxItems": 256');
      }
      if (imageIds.length < 0)
      {
        throw new Error('"imageIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  queryParameters.push('imageIds=' + encodeURIComponent(imageIds.join(',')));
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Add the provided batch of images to the set of training images.
 *
 * This API accepts a batch of files, and optionally tags, to create images.
 * There is a limit of 64 images and 20 tags.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} batch The batch of image files to add. Limited to 64 images
 * and 20 tags per batch.
 *
 * @param {array} [batch.images]
 *
 * @param {array} [batch.tagIds]
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImageCreateSummary} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createImagesFromFiles(projectId, batch, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (batch === null || batch === undefined) {
      throw new Error('batch cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/files';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (batch !== null && batch !== undefined) {
      let requestModelMapper = new client.models['ImageFileCreateBatch']().mapper();
      requestModel = client.serialize(requestModelMapper, batch, 'batch');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(batch, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImageCreateSummary']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Add the provided images urls to the set of training images.
 *
 * This API accepts a batch of urls, and optionally tags, to create images.
 * There is a limit of 64 images and 20 tags.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} batch Image urls and tag ids. Limited to 64 images and 20
 * tags per batch.
 *
 * @param {array} [batch.images]
 *
 * @param {array} [batch.tagIds]
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImageCreateSummary} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createImagesFromUrls(projectId, batch, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (batch === null || batch === undefined) {
      throw new Error('batch cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/urls';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (batch !== null && batch !== undefined) {
      let requestModelMapper = new client.models['ImageUrlCreateBatch']().mapper();
      requestModel = client.serialize(requestModelMapper, batch, 'batch');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(batch, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImageCreateSummary']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Add the specified predicted images to the set of training images.
 *
 * This API creates a batch of images from predicted images specified. There is
 * a limit of 64 images and 20 tags.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} batch Image and tag ids. Limited to 64 images and 20 tags
 * per batch.
 *
 * @param {array} [batch.images]
 *
 * @param {array} [batch.tagIds]
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImageCreateSummary} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createImagesFromPredictions(projectId, batch, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (batch === null || batch === undefined) {
      throw new Error('batch cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/predictions';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (batch !== null && batch !== undefined) {
      let requestModelMapper = new client.models['ImageIdCreateBatch']().mapper();
      requestModel = client.serialize(requestModelMapper, batch, 'batch');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(batch, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImageCreateSummary']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get region proposals for an image. Returns empty array if no
 * proposals are found.
 *
 * This API will get region proposals for an image along with confidences for
 * the region. It returns an empty array if no proposals are found.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} imageId The image id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImageRegionProposal} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getImageRegionProposals(projectId, imageId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (imageId === null || imageId === undefined || typeof imageId.valueOf() !== 'string' || !msRest.isValidUuid(imageId)) {
      throw new Error('imageId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/images/{imageId}/regionproposals';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{imageId}', encodeURIComponent(imageId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImageRegionProposal']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Delete a set of predicted images and their associated prediction
 * results.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {array} ids The prediction ids. Limited to 64.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _deletePrediction(projectId, ids, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (!Array.isArray(ids)) {
      throw new Error('ids cannot be null or undefined and it must be of type array.');
    }
    for (let i = 0; i < ids.length; i++) {
      if (ids[i] !== null && ids[i] !== undefined && !(typeof ids[i].valueOf() === 'string' && msRest.isValidUuid(ids[i]))) {
        throw new Error('ids[i] must be of type string and must be a valid uuid.');
      }
    }
    if (ids !== null && ids !== undefined) {
      if (ids.length > 64)
      {
        throw new Error('"ids" should satisfy the constraint - "MaxItems": 64');
      }
      if (ids.length < 0)
      {
        throw new Error('"ids" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/predictions';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  queryParameters.push('ids=' + encodeURIComponent(ids.join(',')));
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Quick test an image url.
 *
 * @param {uuid} projectId The project to evaluate against.
 *
 * @param {object} imageUrl An ImageUrl that contains the url of the image to
 * be evaluated.
 *
 * @param {string} imageUrl.url Url of the image.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] Optional. Specifies the id of a
 * particular iteration to evaluate against.
 * The default iteration for the project will be used when not specified.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImagePrediction} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _quickTestImageUrl(projectId, imageUrl, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (imageUrl === null || imageUrl === undefined) {
      throw new Error('imageUrl cannot be null or undefined.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/quicktest/url';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (imageUrl !== null && imageUrl !== undefined) {
      let requestModelMapper = new client.models['ImageUrl']().mapper();
      requestModel = client.serialize(requestModelMapper, imageUrl, 'imageUrl');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(imageUrl, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImagePrediction']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Quick test an image.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} imageData Binary image data. Supported formats are JPEG,
 * GIF, PNG, and BMP. Supports images up to 6MB.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] Optional. Specifies the id of a
 * particular iteration to evaluate against.
 * The default iteration for the project will be used when not specified.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ImagePrediction} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _quickTestImage(projectId, imageData, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (imageData === null || imageData === undefined) {
      throw new Error('imageData cannot be null or undefined and it must be of type object.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/quicktest/image';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'multipart/form-data';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let formData = {};
  if (imageData !== undefined && imageData !== null) {
    formData['imageData'] = imageData;
  }
  httpRequest.formData = formData;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ImagePrediction']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get images that were sent to your prediction endpoint.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} query Parameters used to query the predictions. Limited to
 * combining 2 tags.
 *
 * @param {string} [query.session]
 *
 * @param {string} [query.continuation]
 *
 * @param {number} [query.maxCount]
 *
 * @param {string} [query.orderBy] Possible values include: 'Newest', 'Oldest',
 * 'Suggested'
 *
 * @param {array} [query.tags]
 *
 * @param {uuid} [query.iterationId]
 *
 * @param {date} [query.startTime]
 *
 * @param {date} [query.endTime]
 *
 * @param {string} [query.application]
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link PredictionQueryResult} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _queryPredictions(projectId, query, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (query === null || query === undefined) {
      throw new Error('query cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/predictions/query';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (query !== null && query !== undefined) {
      let requestModelMapper = new client.models['PredictionQueryToken']().mapper();
      requestModel = client.serialize(requestModelMapper, query, 'query');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(query, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['PredictionQueryResult']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get detailed performance information about an iteration.
 *
 * @param {uuid} projectId The id of the project the iteration belongs to.
 *
 * @param {uuid} iterationId The id of the iteration to get.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.threshold] The threshold used to determine true
 * predictions.
 *
 * @param {number} [options.overlapThreshold] If applicable, the bounding box
 * overlap threshold used to determine true predictions.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link IterationPerformance} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getIterationPerformance(projectId, iterationId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let threshold = (options && options.threshold !== undefined) ? options.threshold : undefined;
  let overlapThreshold = (options && options.overlapThreshold !== undefined) ? options.overlapThreshold : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (threshold !== null && threshold !== undefined && typeof threshold !== 'number') {
      throw new Error('threshold must be of type number.');
    }
    if (overlapThreshold !== null && overlapThreshold !== undefined && typeof overlapThreshold !== 'number') {
      throw new Error('overlapThreshold must be of type number.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}/performance';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));
  let queryParameters = [];
  if (threshold !== null && threshold !== undefined) {
    queryParameters.push('threshold=' + encodeURIComponent(threshold.toString()));
  }
  if (overlapThreshold !== null && overlapThreshold !== undefined) {
    queryParameters.push('overlapThreshold=' + encodeURIComponent(overlapThreshold.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['IterationPerformance']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get image with its prediction for a given project iteration.
 *
 * This API supports batching and range selection. By default it will only
 * return first 50 images matching images.
 * Use the {take} and {skip} parameters to control how many images to return in
 * a given batch.
 * The filtering is on an and/or relationship. For example, if the provided tag
 * ids are for the "Dog" and
 * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} iterationId The iteration id. Defaults to workspace.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {array} [options.tagIds] A list of tags ids to filter the images.
 * Defaults to all tagged images when null. Limited to 20.
 *
 * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
 * values include: 'Newest', 'Oldest'
 *
 * @param {number} [options.take] Maximum number of images to return. Defaults
 * to 50, limited to 256.
 *
 * @param {number} [options.skip] Number of images to skip before beginning the
 * image batch. Defaults to 0.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getImagePerformances(projectId, iterationId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let tagIds = (options && options.tagIds !== undefined) ? options.tagIds : undefined;
  let orderBy = (options && options.orderBy !== undefined) ? options.orderBy : undefined;
  let take = (options && options.take !== undefined) ? options.take : 50;
  let skip = (options && options.skip !== undefined) ? options.skip : 0;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (Array.isArray(tagIds)) {
      for (let i = 0; i < tagIds.length; i++) {
        if (tagIds[i] !== null && tagIds[i] !== undefined && !(typeof tagIds[i].valueOf() === 'string' && msRest.isValidUuid(tagIds[i]))) {
          throw new Error('tagIds[i] must be of type string and must be a valid uuid.');
        }
      }
    }
    if (tagIds !== null && tagIds !== undefined) {
      if (tagIds.length > 20)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MaxItems": 20');
      }
      if (tagIds.length < 0)
      {
        throw new Error('"tagIds" should satisfy the constraint - "MinItems": 0');
      }
    }
    if (orderBy !== null && orderBy !== undefined && typeof orderBy.valueOf() !== 'string') {
      throw new Error('orderBy must be of type string.');
    }
    if (take !== null && take !== undefined && typeof take !== 'number') {
      throw new Error('take must be of type number.');
    }
    if (take !== null && take !== undefined) {
      if (take > 256)
      {
        throw new Error('"take" should satisfy the constraint - "InclusiveMaximum": 256');
      }
      if (take < 0)
      {
        throw new Error('"take" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (skip !== null && skip !== undefined && typeof skip !== 'number') {
      throw new Error('skip must be of type number.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}/performance/images';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));
  let queryParameters = [];
  if (tagIds !== null && tagIds !== undefined) {
    queryParameters.push('tagIds=' + encodeURIComponent(tagIds.join(',')));
  }
  if (orderBy !== null && orderBy !== undefined) {
    queryParameters.push('orderBy=' + encodeURIComponent(orderBy));
  }
  if (take !== null && take !== undefined) {
    queryParameters.push('take=' + encodeURIComponent(take.toString()));
  }
  if (skip !== null && skip !== undefined) {
    queryParameters.push('skip=' + encodeURIComponent(skip.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'ImagePerformanceElementType',
                  type: {
                    name: 'Composite',
                    className: 'ImagePerformance'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Gets the number of images tagged with the provided {tagIds} that
 * have prediction results from
 * training for the provided iteration {iterationId}.
 *
 * The filtering is on an and/or relationship. For example, if the provided tag
 * ids are for the "Dog" and
 * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} iterationId The iteration id. Defaults to workspace.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {array} [options.tagIds] A list of tags ids to filter the images to
 * count. Defaults to all tags when null.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {number} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getImagePerformanceCount(projectId, iterationId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let tagIds = (options && options.tagIds !== undefined) ? options.tagIds : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (Array.isArray(tagIds)) {
      for (let i = 0; i < tagIds.length; i++) {
        if (tagIds[i] !== null && tagIds[i] !== undefined && !(typeof tagIds[i].valueOf() === 'string' && msRest.isValidUuid(tagIds[i]))) {
          throw new Error('tagIds[i] must be of type string and must be a valid uuid.');
        }
      }
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}/performance/images/count';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));
  let queryParameters = [];
  if (tagIds !== null && tagIds !== undefined) {
    queryParameters.push('tagIds=' + encodeURIComponent(tagIds.join(',')));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Number'
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get your projects.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getProjects(options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'ProjectElementType',
                  type: {
                    name: 'Composite',
                    className: 'Project'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Create a project.
 *
 * @param {string} name Name of the project.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.description] The description of the project.
 *
 * @param {uuid} [options.domainId] The id of the domain to use for this
 * project. Defaults to General.
 *
 * @param {string} [options.classificationType] The type of classifier to
 * create for this project. Possible values include: 'Multiclass', 'Multilabel'
 *
 * @param {array} [options.targetExportPlatforms] List of platforms the trained
 * model is intending exporting to.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Project} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createProject(name, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let description = (options && options.description !== undefined) ? options.description : undefined;
  let domainId = (options && options.domainId !== undefined) ? options.domainId : undefined;
  let classificationType = (options && options.classificationType !== undefined) ? options.classificationType : undefined;
  let targetExportPlatforms = (options && options.targetExportPlatforms !== undefined) ? options.targetExportPlatforms : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (name === null || name === undefined || typeof name.valueOf() !== 'string') {
      throw new Error('name cannot be null or undefined and it must be of type string.');
    }
    if (description !== null && description !== undefined && typeof description.valueOf() !== 'string') {
      throw new Error('description must be of type string.');
    }
    if (domainId !== null && domainId !== undefined && !(typeof domainId.valueOf() === 'string' && msRest.isValidUuid(domainId))) {
      throw new Error('domainId must be of type string and must be a valid uuid.');
    }
    if (classificationType !== null && classificationType !== undefined && typeof classificationType.valueOf() !== 'string') {
      throw new Error('classificationType must be of type string.');
    }
    if (Array.isArray(targetExportPlatforms)) {
      for (let i = 0; i < targetExportPlatforms.length; i++) {
        if (targetExportPlatforms[i] !== null && targetExportPlatforms[i] !== undefined && typeof targetExportPlatforms[i].valueOf() !== 'string') {
          throw new Error('targetExportPlatforms[i] must be of type string.');
        }
      }
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  let queryParameters = [];
  queryParameters.push('name=' + encodeURIComponent(name));
  if (description !== null && description !== undefined) {
    queryParameters.push('description=' + encodeURIComponent(description));
  }
  if (domainId !== null && domainId !== undefined) {
    queryParameters.push('domainId=' + encodeURIComponent(domainId.toString()));
  }
  if (classificationType !== null && classificationType !== undefined) {
    queryParameters.push('classificationType=' + encodeURIComponent(classificationType));
  }
  if (targetExportPlatforms !== null && targetExportPlatforms !== undefined) {
    queryParameters.push('targetExportPlatforms=' + encodeURIComponent(targetExportPlatforms.join(',')));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Project']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get a specific project.
 *
 * @param {uuid} projectId The id of the project to get.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Project} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getProject(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Project']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Delete a specific project.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _deleteProject(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Update a specific project.
 *
 * @param {uuid} projectId The id of the project to update.
 *
 * @param {object} updatedProject The updated project model.
 *
 * @param {string} updatedProject.name Gets or sets the name of the project.
 *
 * @param {string} updatedProject.description Gets or sets the description of
 * the project.
 *
 * @param {object} updatedProject.settings Gets or sets the project settings.
 *
 * @param {uuid} [updatedProject.settings.domainId] Gets or sets the id of the
 * Domain to use with this project.
 *
 * @param {string} [updatedProject.settings.classificationType] Gets or sets
 * the classification type of the project. Possible values include:
 * 'Multiclass', 'Multilabel'
 *
 * @param {array} [updatedProject.settings.targetExportPlatforms] A list of
 * ExportPlatform that the trained model should be able to support.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Project} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _updateProject(projectId, updatedProject, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (updatedProject === null || updatedProject === undefined) {
      throw new Error('updatedProject cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'PATCH';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (updatedProject !== null && updatedProject !== undefined) {
      let requestModelMapper = new client.models['Project']().mapper();
      requestModel = client.serialize(requestModelMapper, updatedProject, 'updatedProject');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(updatedProject, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Project']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Queues project for training.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.trainingType] The type of training to use to train
 * the project (default: Regular). Possible values include: 'Regular',
 * 'Advanced'
 *
 * @param {number} [options.reservedBudgetInHours] The number of hours reserved
 * as budget for training (if applicable).
 *
 * @param {boolean} [options.forceTrain] Whether to force train even if dataset
 * and configuration does not change (default: false).
 *
 * @param {string} [options.notificationEmailAddress] The email address to send
 * notification to when training finishes (default: null).
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Iteration} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _trainProject(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let trainingType = (options && options.trainingType !== undefined) ? options.trainingType : undefined;
  let reservedBudgetInHours = (options && options.reservedBudgetInHours !== undefined) ? options.reservedBudgetInHours : 0;
  let forceTrain = (options && options.forceTrain !== undefined) ? options.forceTrain : false;
  let notificationEmailAddress = (options && options.notificationEmailAddress !== undefined) ? options.notificationEmailAddress : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (trainingType !== null && trainingType !== undefined && typeof trainingType.valueOf() !== 'string') {
      throw new Error('trainingType must be of type string.');
    }
    if (reservedBudgetInHours !== null && reservedBudgetInHours !== undefined && typeof reservedBudgetInHours !== 'number') {
      throw new Error('reservedBudgetInHours must be of type number.');
    }
    if (forceTrain !== null && forceTrain !== undefined && typeof forceTrain !== 'boolean') {
      throw new Error('forceTrain must be of type boolean.');
    }
    if (notificationEmailAddress !== null && notificationEmailAddress !== undefined && typeof notificationEmailAddress.valueOf() !== 'string') {
      throw new Error('notificationEmailAddress must be of type string.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/train';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (trainingType !== null && trainingType !== undefined) {
    queryParameters.push('trainingType=' + encodeURIComponent(trainingType));
  }
  if (reservedBudgetInHours !== null && reservedBudgetInHours !== undefined) {
    queryParameters.push('reservedBudgetInHours=' + encodeURIComponent(reservedBudgetInHours.toString()));
  }
  if (forceTrain !== null && forceTrain !== undefined) {
    queryParameters.push('forceTrain=' + encodeURIComponent(forceTrain.toString()));
  }
  if (notificationEmailAddress !== null && notificationEmailAddress !== undefined) {
    queryParameters.push('notificationEmailAddress=' + encodeURIComponent(notificationEmailAddress));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Iteration']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get iterations for the project.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getIterations(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'IterationElementType',
                  type: {
                    name: 'Composite',
                    className: 'Iteration'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get a specific iteration.
 *
 * @param {uuid} projectId The id of the project the iteration belongs to.
 *
 * @param {uuid} iterationId The id of the iteration to get.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Iteration} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getIteration(projectId, iterationId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Iteration']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Delete a specific iteration of a project.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} iterationId The iteration id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _deleteIteration(projectId, iterationId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Update a specific iteration.
 *
 * @param {uuid} projectId Project id.
 *
 * @param {uuid} iterationId Iteration id.
 *
 * @param {object} updatedIteration The updated iteration model.
 *
 * @param {string} updatedIteration.name Gets or sets the name of the
 * iteration.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Iteration} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _updateIteration(projectId, iterationId, updatedIteration, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (updatedIteration === null || updatedIteration === undefined) {
      throw new Error('updatedIteration cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'PATCH';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (updatedIteration !== null && updatedIteration !== undefined) {
      let requestModelMapper = new client.models['Iteration']().mapper();
      requestModel = client.serialize(requestModelMapper, updatedIteration, 'updatedIteration');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(updatedIteration, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Iteration']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Publish a specific iteration.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} iterationId The iteration id.
 *
 * @param {string} publishName The name to give the published iteration.
 *
 * @param {string} predictionId The id of the prediction resource to publish
 * to.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {boolean} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _publishIteration(projectId, iterationId, publishName, predictionId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (publishName === null || publishName === undefined || typeof publishName.valueOf() !== 'string') {
      throw new Error('publishName cannot be null or undefined and it must be of type string.');
    }
    if (predictionId === null || predictionId === undefined || typeof predictionId.valueOf() !== 'string') {
      throw new Error('predictionId cannot be null or undefined and it must be of type string.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}/publish';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));
  let queryParameters = [];
  queryParameters.push('publishName=' + encodeURIComponent(publishName));
  queryParameters.push('predictionId=' + encodeURIComponent(predictionId));
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Boolean'
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Unpublish a specific iteration.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} iterationId The iteration id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _unpublishIteration(projectId, iterationId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}/publish';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Get the list of exports for a specific iteration.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} iterationId The iteration id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getExports(projectId, iterationId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}/export';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'ExportModelElementType',
                  type: {
                    name: 'Composite',
                    className: 'ExportModel'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Export a trained iteration.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} iterationId The iteration id.
 *
 * @param {string} platform The target platform. Possible values include:
 * 'CoreML', 'TensorFlow', 'DockerFile', 'ONNX', 'VAIDK'
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.flavor] The flavor of the target platform. Possible
 * values include: 'Linux', 'Windows', 'ONNX10', 'ONNX12', 'ARM'
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link ExportModel} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _exportIteration(projectId, iterationId, platform, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let flavor = (options && options.flavor !== undefined) ? options.flavor : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId === null || iterationId === undefined || typeof iterationId.valueOf() !== 'string' || !msRest.isValidUuid(iterationId)) {
      throw new Error('iterationId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (platform === null || platform === undefined || typeof platform.valueOf() !== 'string') {
      throw new Error('platform cannot be null or undefined and it must be of type string.');
    }
    if (flavor !== null && flavor !== undefined && typeof flavor.valueOf() !== 'string') {
      throw new Error('flavor must be of type string.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/iterations/{iterationId}/export';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{iterationId}', encodeURIComponent(iterationId.toString()));
  let queryParameters = [];
  queryParameters.push('platform=' + encodeURIComponent(platform));
  if (flavor !== null && flavor !== undefined) {
    queryParameters.push('flavor=' + encodeURIComponent(flavor));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['ExportModel']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get information about a specific tag.
 *
 * @param {uuid} projectId The project this tag belongs to.
 *
 * @param {uuid} tagId The tag id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] The iteration to retrieve this tag from.
 * Optional, defaults to current training set.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Tag} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getTag(projectId, tagId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (tagId === null || tagId === undefined || typeof tagId.valueOf() !== 'string' || !msRest.isValidUuid(tagId)) {
      throw new Error('tagId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/tags/{tagId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{tagId}', encodeURIComponent(tagId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Tag']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Delete a tag from the project.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} tagId Id of the tag to be deleted.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {null} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _deleteTag(projectId, tagId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (tagId === null || tagId === undefined || typeof tagId.valueOf() !== 'string' || !msRest.isValidUuid(tagId)) {
      throw new Error('tagId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/tags/{tagId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{tagId}', encodeURIComponent(tagId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'DELETE';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 204) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * @summary Update a tag.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {uuid} tagId The id of the target tag.
 *
 * @param {object} updatedTag The updated tag model.
 *
 * @param {string} updatedTag.name Gets or sets the name of the tag.
 *
 * @param {string} updatedTag.description Gets or sets the description of the
 * tag.
 *
 * @param {string} updatedTag.type Gets or sets the type of the tag. Possible
 * values include: 'Regular', 'Negative'
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Tag} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _updateTag(projectId, tagId, updatedTag, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (tagId === null || tagId === undefined || typeof tagId.valueOf() !== 'string' || !msRest.isValidUuid(tagId)) {
      throw new Error('tagId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (updatedTag === null || updatedTag === undefined) {
      throw new Error('updatedTag cannot be null or undefined.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/tags/{tagId}';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  requestUrl = requestUrl.replace('{tagId}', encodeURIComponent(tagId.toString()));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'PATCH';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  // Serialize Request
  let requestContent = null;
  let requestModel = null;
  try {
    if (updatedTag !== null && updatedTag !== undefined) {
      let requestModelMapper = new client.models['Tag']().mapper();
      requestModel = client.serialize(requestModelMapper, updatedTag, 'updatedTag');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(updatedTag, null, 2)}.`);
    return callback(serializationError);
  }
  httpRequest.body = requestContent;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Tag']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Get the tags for a given project and iteration.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {array} [result]   - The deserialized result object if an error did not occur.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _getTags(projectId, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let iterationId = (options && options.iterationId !== undefined) ? options.iterationId : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (iterationId !== null && iterationId !== undefined && !(typeof iterationId.valueOf() === 'string' && msRest.isValidUuid(iterationId))) {
      throw new Error('iterationId must be of type string and must be a valid uuid.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/tags';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  if (iterationId !== null && iterationId !== undefined) {
    queryParameters.push('iterationId=' + encodeURIComponent(iterationId.toString()));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'GET';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = {
            required: false,
            serializedName: 'parsedResponse',
            type: {
              name: 'Sequence',
              element: {
                  required: false,
                  serializedName: 'TagElementType',
                  type: {
                    name: 'Composite',
                    className: 'Tag'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * @summary Create a tag for the project.
 *
 * @param {uuid} projectId The project id.
 *
 * @param {string} name The tag name.
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.description] Optional description for the tag.
 *
 * @param {string} [options.type] Optional type for the tag. Possible values
 * include: 'Regular', 'Negative'
 *
 * @param {object} [options.customHeaders] Headers that will be added to the
 * request
 *
 * @param {function} callback - The callback.
 *
 * @returns {function} callback(err, result, request, response)
 *
 *                      {Error}  err        - The Error object if an error occurred, null otherwise.
 *
 *                      {object} [result]   - The deserialized result object if an error did not occur.
 *                      See {@link Tag} for more information.
 *
 *                      {object} [request]  - The HTTP Request object if an error did not occur.
 *
 *                      {stream} [response] - The HTTP Response stream if an error did not occur.
 */
function _createTag(projectId, name, options, callback) {
   /* jshint validthis: true */
  let client = this;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let description = (options && options.description !== undefined) ? options.description : undefined;
  let type = (options && options.type !== undefined) ? options.type : undefined;
  // Validate
  try {
    if (this.endpoint === null || this.endpoint === undefined || typeof this.endpoint.valueOf() !== 'string') {
      throw new Error('this.endpoint cannot be null or undefined and it must be of type string.');
    }
    if (projectId === null || projectId === undefined || typeof projectId.valueOf() !== 'string' || !msRest.isValidUuid(projectId)) {
      throw new Error('projectId cannot be null or undefined and it must be of type string and must be a valid uuid.');
    }
    if (name === null || name === undefined || typeof name.valueOf() !== 'string') {
      throw new Error('name cannot be null or undefined and it must be of type string.');
    }
    if (description !== null && description !== undefined && typeof description.valueOf() !== 'string') {
      throw new Error('description must be of type string.');
    }
    if (type !== null && type !== undefined && typeof type.valueOf() !== 'string') {
      throw new Error('type must be of type string.');
    }
    if (this.apiKey === null || this.apiKey === undefined || typeof this.apiKey.valueOf() !== 'string') {
      throw new Error('this.apiKey cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'projects/{projectId}/tags';
  requestUrl = requestUrl.replace('{Endpoint}', this.endpoint);
  requestUrl = requestUrl.replace('{projectId}', encodeURIComponent(projectId.toString()));
  let queryParameters = [];
  queryParameters.push('name=' + encodeURIComponent(name));
  if (description !== null && description !== undefined) {
    queryParameters.push('description=' + encodeURIComponent(description));
  }
  if (type !== null && type !== undefined) {
    queryParameters.push('type=' + encodeURIComponent(type));
  }
  if (queryParameters.length > 0) {
    requestUrl += '?' + queryParameters.join('&');
  }

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'POST';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if (this.apiKey !== undefined && this.apiKey !== null) {
    httpRequest.headers['Training-Key'] = this.apiKey;
  }
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode !== 200) {
      let error = new Error(responseBody);
      error.statusCode = response.statusCode;
      error.request = msRest.stripRequest(httpRequest);
      error.response = msRest.stripResponse(response);
      if (responseBody === '') responseBody = null;
      let parsedErrorResponse;
      try {
        parsedErrorResponse = JSON.parse(responseBody);
        if (parsedErrorResponse) {
          let internalError = null;
          if (parsedErrorResponse.error) internalError = parsedErrorResponse.error;
          error.code = internalError ? internalError.code : parsedErrorResponse.code;
          error.message = internalError ? internalError.message : parsedErrorResponse.message;
        }
        if (parsedErrorResponse !== null && parsedErrorResponse !== undefined) {
          let resultMapper = new client.models['CustomVisionError']().mapper();
          error.body = client.deserialize(resultMapper, parsedErrorResponse, 'error.body');
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;
    // Deserialize Response
    if (statusCode === 200) {
      let parsedResponse = null;
      try {
        parsedResponse = JSON.parse(responseBody);
        result = JSON.parse(responseBody);
        if (parsedResponse !== null && parsedResponse !== undefined) {
          let resultMapper = new client.models['Tag']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/** Class representing a TrainingAPIClient. */
class TrainingAPIClient extends ServiceClient {
  /**
   * Create a TrainingAPIClient.
   * @param {string} apiKey - API key.
   * @param {string} endpoint - Supported Cognitive Services endpoints.
   * @param {object} [options] - The parameter options
   * @param {Array} [options.filters] - Filters to be added to the request pipeline
   * @param {object} [options.requestOptions] - Options for the underlying request object
   * {@link https://github.com/request/request#requestoptions-callback Options doc}
   * @param {boolean} [options.noRetryPolicy] - If set to true, turn off default retry policy
   */
  constructor(apiKey, endpoint, options) {
    if (apiKey === null || apiKey === undefined) {
      throw new Error('\'apiKey\' cannot be null.');
    }
    if (endpoint === null || endpoint === undefined) {
      throw new Error('\'endpoint\' cannot be null.');
    }

    if (!options) options = {};

    super(null, options);

    this.baseUri = '{Endpoint}/customvision/v3.0/training';
    this.apiKey = apiKey;
    this.endpoint = endpoint;

    let packageInfo = this.getPackageJsonInfo(__dirname);
    this.addUserAgentInfo(`${packageInfo.name}/${packageInfo.version}`);
    this.models = models;
    this._getDomains = _getDomains;
    this._getDomain = _getDomain;
    this._getTaggedImageCount = _getTaggedImageCount;
    this._getUntaggedImageCount = _getUntaggedImageCount;
    this._createImageTags = _createImageTags;
    this._deleteImageTags = _deleteImageTags;
    this._createImageRegions = _createImageRegions;
    this._deleteImageRegions = _deleteImageRegions;
    this._getTaggedImages = _getTaggedImages;
    this._getUntaggedImages = _getUntaggedImages;
    this._getImagesByIds = _getImagesByIds;
    this._createImagesFromData = _createImagesFromData;
    this._deleteImages = _deleteImages;
    this._createImagesFromFiles = _createImagesFromFiles;
    this._createImagesFromUrls = _createImagesFromUrls;
    this._createImagesFromPredictions = _createImagesFromPredictions;
    this._getImageRegionProposals = _getImageRegionProposals;
    this._deletePrediction = _deletePrediction;
    this._quickTestImageUrl = _quickTestImageUrl;
    this._quickTestImage = _quickTestImage;
    this._queryPredictions = _queryPredictions;
    this._getIterationPerformance = _getIterationPerformance;
    this._getImagePerformances = _getImagePerformances;
    this._getImagePerformanceCount = _getImagePerformanceCount;
    this._getProjects = _getProjects;
    this._createProject = _createProject;
    this._getProject = _getProject;
    this._deleteProject = _deleteProject;
    this._updateProject = _updateProject;
    this._trainProject = _trainProject;
    this._getIterations = _getIterations;
    this._getIteration = _getIteration;
    this._deleteIteration = _deleteIteration;
    this._updateIteration = _updateIteration;
    this._publishIteration = _publishIteration;
    this._unpublishIteration = _unpublishIteration;
    this._getExports = _getExports;
    this._exportIteration = _exportIteration;
    this._getTag = _getTag;
    this._deleteTag = _deleteTag;
    this._updateTag = _updateTag;
    this._getTags = _getTags;
    this._createTag = _createTag;
    msRest.addSerializationMixin(this);
  }

  /**
   * @summary Get a list of the available domains.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getDomainsWithHttpOperationResponse(options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getDomains(options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get a list of the available domains.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getDomains(options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getDomains(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getDomains(options, optionalCallback);
    }
  }

  /**
   * @summary Get information about a specific domain.
   *
   * @param {uuid} domainId The id of the domain to get information about.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Domain>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getDomainWithHttpOperationResponse(domainId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getDomain(domainId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get information about a specific domain.
   *
   * @param {uuid} domainId The id of the domain to get information about.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Domain} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Domain} 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.
   */
  getDomain(domainId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getDomain(domainId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getDomain(domainId, options, optionalCallback);
    }
  }

  /**
   * @summary Gets the number of images tagged with the provided {tagIds}.
   *
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images to
   * count. Defaults to all tags when null.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Number>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getTaggedImageCountWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getTaggedImageCount(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Gets the number of images tagged with the provided {tagIds}.
   *
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images to
   * count. Defaults to all tags when null.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Number} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {number} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getTaggedImageCount(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getTaggedImageCount(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getTaggedImageCount(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Gets the number of untagged images.
   *
   * This API returns the images which have no tags for a given project and
   * optionally an iteration. If no iteration is specified the
   * current workspace is used.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Number>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getUntaggedImageCountWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getUntaggedImageCount(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Gets the number of untagged images.
   *
   * This API returns the images which have no tags for a given project and
   * optionally an iteration. If no iteration is specified the
   * current workspace is used.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Number} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {number} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getUntaggedImageCount(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getUntaggedImageCount(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getUntaggedImageCount(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Associate a set of images with a set of tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Batch of image tags. Limited to 128 tags per batch.
   *
   * @param {array} [batch.tags] Image Tag entries to include in this batch.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImageTagCreateSummary>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createImageTagsWithHttpOperationResponse(projectId, batch, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createImageTags(projectId, batch, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Associate a set of images with a set of tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Batch of image tags. Limited to 128 tags per batch.
   *
   * @param {array} [batch.tags] Image Tag entries to include in this batch.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImageTagCreateSummary} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImageTagCreateSummary} 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.
   */
  createImageTags(projectId, batch, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createImageTags(projectId, batch, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createImageTags(projectId, batch, options, optionalCallback);
    }
  }

  /**
   * @summary Remove a set of tags from a set of images.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} imageIds Image ids. Limited to 64 images.
   *
   * @param {array} tagIds Tags to be deleted from the specified images. Limited
   * to 20 tags.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deleteImageTagsWithHttpOperationResponse(projectId, imageIds, tagIds, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteImageTags(projectId, imageIds, tagIds, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Remove a set of tags from a set of images.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} imageIds Image ids. Limited to 64 images.
   *
   * @param {array} tagIds Tags to be deleted from the specified images. Limited
   * to 20 tags.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  deleteImageTags(projectId, imageIds, tagIds, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deleteImageTags(projectId, imageIds, tagIds, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteImageTags(projectId, imageIds, tagIds, options, optionalCallback);
    }
  }

  /**
   * @summary Create a set of image regions.
   *
   * This API accepts a batch of image regions, and optionally tags, to update
   * existing images with region information.
   * There is a limit of 64 entries in the batch.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Batch of image regions which include a tag and
   * bounding box. Limited to 64.
   *
   * @param {array} [batch.regions]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImageRegionCreateSummary>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createImageRegionsWithHttpOperationResponse(projectId, batch, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createImageRegions(projectId, batch, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Create a set of image regions.
   *
   * This API accepts a batch of image regions, and optionally tags, to update
   * existing images with region information.
   * There is a limit of 64 entries in the batch.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Batch of image regions which include a tag and
   * bounding box. Limited to 64.
   *
   * @param {array} [batch.regions]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImageRegionCreateSummary} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImageRegionCreateSummary} 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.
   */
  createImageRegions(projectId, batch, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createImageRegions(projectId, batch, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createImageRegions(projectId, batch, options, optionalCallback);
    }
  }

  /**
   * @summary Delete a set of image regions.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} regionIds Regions to delete. Limited to 64.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deleteImageRegionsWithHttpOperationResponse(projectId, regionIds, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteImageRegions(projectId, regionIds, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Delete a set of image regions.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} regionIds Regions to delete. Limited to 64.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  deleteImageRegions(projectId, regionIds, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deleteImageRegions(projectId, regionIds, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteImageRegions(projectId, regionIds, options, optionalCallback);
    }
  }

  /**
   * @summary Get tagged images for a given project iteration.
   *
   * This API supports batching and range selection. By default it will only
   * return first 50 images matching images.
   * Use the {take} and {skip} parameters to control how many images to return in
   * a given batch.
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images.
   * Defaults to all tagged images when null. Limited to 20.
   *
   * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
   * values include: 'Newest', 'Oldest'
   *
   * @param {number} [options.take] Maximum number of images to return. Defaults
   * to 50, limited to 256.
   *
   * @param {number} [options.skip] Number of images to skip before beginning the
   * image batch. Defaults to 0.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getTaggedImagesWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getTaggedImages(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get tagged images for a given project iteration.
   *
   * This API supports batching and range selection. By default it will only
   * return first 50 images matching images.
   * Use the {take} and {skip} parameters to control how many images to return in
   * a given batch.
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images.
   * Defaults to all tagged images when null. Limited to 20.
   *
   * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
   * values include: 'Newest', 'Oldest'
   *
   * @param {number} [options.take] Maximum number of images to return. Defaults
   * to 50, limited to 256.
   *
   * @param {number} [options.skip] Number of images to skip before beginning the
   * image batch. Defaults to 0.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getTaggedImages(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getTaggedImages(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getTaggedImages(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Get untagged images for a given project iteration.
   *
   * This API supports batching and range selection. By default it will only
   * return first 50 images matching images.
   * Use the {take} and {skip} parameters to control how many images to return in
   * a given batch.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
   * values include: 'Newest', 'Oldest'
   *
   * @param {number} [options.take] Maximum number of images to return. Defaults
   * to 50, limited to 256.
   *
   * @param {number} [options.skip] Number of images to skip before beginning the
   * image batch. Defaults to 0.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getUntaggedImagesWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getUntaggedImages(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get untagged images for a given project iteration.
   *
   * This API supports batching and range selection. By default it will only
   * return first 50 images matching images.
   * Use the {take} and {skip} parameters to control how many images to return in
   * a given batch.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
   * values include: 'Newest', 'Oldest'
   *
   * @param {number} [options.take] Maximum number of images to return. Defaults
   * to 50, limited to 256.
   *
   * @param {number} [options.skip] Number of images to skip before beginning the
   * image batch. Defaults to 0.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getUntaggedImages(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getUntaggedImages(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getUntaggedImages(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Get images by id for a given project iteration.
   *
   * This API will return a set of Images for the specified tags and optionally
   * iteration. If no iteration is specified the
   * current workspace is used.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.imageIds] The list of image ids to retrieve. Limited
   * to 256.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getImagesByIdsWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getImagesByIds(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get images by id for a given project iteration.
   *
   * This API will return a set of Images for the specified tags and optionally
   * iteration. If no iteration is specified the
   * current workspace is used.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.imageIds] The list of image ids to retrieve. Limited
   * to 256.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getImagesByIds(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getImagesByIds(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getImagesByIds(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Add the provided images to the set of training images.
   *
   * This API accepts body content as multipart/form-data and
   * application/octet-stream. When using multipart
   * multiple image files can be sent at once, with a maximum of 64 files
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} imageData Binary image data. Supported formats are JPEG,
   * GIF, PNG, and BMP. Supports images up to 6MB.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.tagIds] The tags ids with which to tag each image.
   * Limited to 20.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImageCreateSummary>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createImagesFromDataWithHttpOperationResponse(projectId, imageData, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createImagesFromData(projectId, imageData, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Add the provided images to the set of training images.
   *
   * This API accepts body content as multipart/form-data and
   * application/octet-stream. When using multipart
   * multiple image files can be sent at once, with a maximum of 64 files
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} imageData Binary image data. Supported formats are JPEG,
   * GIF, PNG, and BMP. Supports images up to 6MB.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.tagIds] The tags ids with which to tag each image.
   * Limited to 20.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImageCreateSummary} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImageCreateSummary} 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.
   */
  createImagesFromData(projectId, imageData, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createImagesFromData(projectId, imageData, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createImagesFromData(projectId, imageData, options, optionalCallback);
    }
  }

  /**
   * @summary Delete images from the set of training images.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} imageIds Ids of the images to be deleted. Limited to 256
   * images per batch.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deleteImagesWithHttpOperationResponse(projectId, imageIds, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteImages(projectId, imageIds, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Delete images from the set of training images.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} imageIds Ids of the images to be deleted. Limited to 256
   * images per batch.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  deleteImages(projectId, imageIds, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deleteImages(projectId, imageIds, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteImages(projectId, imageIds, options, optionalCallback);
    }
  }

  /**
   * @summary Add the provided batch of images to the set of training images.
   *
   * This API accepts a batch of files, and optionally tags, to create images.
   * There is a limit of 64 images and 20 tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch The batch of image files to add. Limited to 64 images
   * and 20 tags per batch.
   *
   * @param {array} [batch.images]
   *
   * @param {array} [batch.tagIds]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImageCreateSummary>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createImagesFromFilesWithHttpOperationResponse(projectId, batch, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createImagesFromFiles(projectId, batch, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Add the provided batch of images to the set of training images.
   *
   * This API accepts a batch of files, and optionally tags, to create images.
   * There is a limit of 64 images and 20 tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch The batch of image files to add. Limited to 64 images
   * and 20 tags per batch.
   *
   * @param {array} [batch.images]
   *
   * @param {array} [batch.tagIds]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImageCreateSummary} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImageCreateSummary} 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.
   */
  createImagesFromFiles(projectId, batch, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createImagesFromFiles(projectId, batch, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createImagesFromFiles(projectId, batch, options, optionalCallback);
    }
  }

  /**
   * @summary Add the provided images urls to the set of training images.
   *
   * This API accepts a batch of urls, and optionally tags, to create images.
   * There is a limit of 64 images and 20 tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Image urls and tag ids. Limited to 64 images and 20
   * tags per batch.
   *
   * @param {array} [batch.images]
   *
   * @param {array} [batch.tagIds]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImageCreateSummary>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createImagesFromUrlsWithHttpOperationResponse(projectId, batch, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createImagesFromUrls(projectId, batch, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Add the provided images urls to the set of training images.
   *
   * This API accepts a batch of urls, and optionally tags, to create images.
   * There is a limit of 64 images and 20 tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Image urls and tag ids. Limited to 64 images and 20
   * tags per batch.
   *
   * @param {array} [batch.images]
   *
   * @param {array} [batch.tagIds]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImageCreateSummary} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImageCreateSummary} 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.
   */
  createImagesFromUrls(projectId, batch, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createImagesFromUrls(projectId, batch, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createImagesFromUrls(projectId, batch, options, optionalCallback);
    }
  }

  /**
   * @summary Add the specified predicted images to the set of training images.
   *
   * This API creates a batch of images from predicted images specified. There is
   * a limit of 64 images and 20 tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Image and tag ids. Limited to 64 images and 20 tags
   * per batch.
   *
   * @param {array} [batch.images]
   *
   * @param {array} [batch.tagIds]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImageCreateSummary>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createImagesFromPredictionsWithHttpOperationResponse(projectId, batch, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createImagesFromPredictions(projectId, batch, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Add the specified predicted images to the set of training images.
   *
   * This API creates a batch of images from predicted images specified. There is
   * a limit of 64 images and 20 tags.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} batch Image and tag ids. Limited to 64 images and 20 tags
   * per batch.
   *
   * @param {array} [batch.images]
   *
   * @param {array} [batch.tagIds]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImageCreateSummary} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImageCreateSummary} 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.
   */
  createImagesFromPredictions(projectId, batch, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createImagesFromPredictions(projectId, batch, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createImagesFromPredictions(projectId, batch, options, optionalCallback);
    }
  }

  /**
   * @summary Get region proposals for an image. Returns empty array if no
   * proposals are found.
   *
   * This API will get region proposals for an image along with confidences for
   * the region. It returns an empty array if no proposals are found.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} imageId The image id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImageRegionProposal>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getImageRegionProposalsWithHttpOperationResponse(projectId, imageId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getImageRegionProposals(projectId, imageId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get region proposals for an image. Returns empty array if no
   * proposals are found.
   *
   * This API will get region proposals for an image along with confidences for
   * the region. It returns an empty array if no proposals are found.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} imageId The image id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImageRegionProposal} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImageRegionProposal} 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.
   */
  getImageRegionProposals(projectId, imageId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getImageRegionProposals(projectId, imageId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getImageRegionProposals(projectId, imageId, options, optionalCallback);
    }
  }

  /**
   * @summary Delete a set of predicted images and their associated prediction
   * results.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} ids The prediction ids. Limited to 64.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deletePredictionWithHttpOperationResponse(projectId, ids, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deletePrediction(projectId, ids, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Delete a set of predicted images and their associated prediction
   * results.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {array} ids The prediction ids. Limited to 64.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  deletePrediction(projectId, ids, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deletePrediction(projectId, ids, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deletePrediction(projectId, ids, options, optionalCallback);
    }
  }

  /**
   * @summary Quick test an image url.
   *
   * @param {uuid} projectId The project to evaluate against.
   *
   * @param {object} imageUrl An ImageUrl that contains the url of the image to
   * be evaluated.
   *
   * @param {string} imageUrl.url Url of the image.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] Optional. Specifies the id of a
   * particular iteration to evaluate against.
   * The default iteration for the project will be used when not specified.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImagePrediction>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  quickTestImageUrlWithHttpOperationResponse(projectId, imageUrl, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._quickTestImageUrl(projectId, imageUrl, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Quick test an image url.
   *
   * @param {uuid} projectId The project to evaluate against.
   *
   * @param {object} imageUrl An ImageUrl that contains the url of the image to
   * be evaluated.
   *
   * @param {string} imageUrl.url Url of the image.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] Optional. Specifies the id of a
   * particular iteration to evaluate against.
   * The default iteration for the project will be used when not specified.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImagePrediction} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImagePrediction} 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.
   */
  quickTestImageUrl(projectId, imageUrl, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._quickTestImageUrl(projectId, imageUrl, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._quickTestImageUrl(projectId, imageUrl, options, optionalCallback);
    }
  }

  /**
   * @summary Quick test an image.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} imageData Binary image data. Supported formats are JPEG,
   * GIF, PNG, and BMP. Supports images up to 6MB.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] Optional. Specifies the id of a
   * particular iteration to evaluate against.
   * The default iteration for the project will be used when not specified.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ImagePrediction>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  quickTestImageWithHttpOperationResponse(projectId, imageData, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._quickTestImage(projectId, imageData, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Quick test an image.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} imageData Binary image data. Supported formats are JPEG,
   * GIF, PNG, and BMP. Supports images up to 6MB.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] Optional. Specifies the id of a
   * particular iteration to evaluate against.
   * The default iteration for the project will be used when not specified.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ImagePrediction} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ImagePrediction} 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.
   */
  quickTestImage(projectId, imageData, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._quickTestImage(projectId, imageData, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._quickTestImage(projectId, imageData, options, optionalCallback);
    }
  }

  /**
   * @summary Get images that were sent to your prediction endpoint.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} query Parameters used to query the predictions. Limited to
   * combining 2 tags.
   *
   * @param {string} [query.session]
   *
   * @param {string} [query.continuation]
   *
   * @param {number} [query.maxCount]
   *
   * @param {string} [query.orderBy] Possible values include: 'Newest', 'Oldest',
   * 'Suggested'
   *
   * @param {array} [query.tags]
   *
   * @param {uuid} [query.iterationId]
   *
   * @param {date} [query.startTime]
   *
   * @param {date} [query.endTime]
   *
   * @param {string} [query.application]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<PredictionQueryResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  queryPredictionsWithHttpOperationResponse(projectId, query, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._queryPredictions(projectId, query, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get images that were sent to your prediction endpoint.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} query Parameters used to query the predictions. Limited to
   * combining 2 tags.
   *
   * @param {string} [query.session]
   *
   * @param {string} [query.continuation]
   *
   * @param {number} [query.maxCount]
   *
   * @param {string} [query.orderBy] Possible values include: 'Newest', 'Oldest',
   * 'Suggested'
   *
   * @param {array} [query.tags]
   *
   * @param {uuid} [query.iterationId]
   *
   * @param {date} [query.startTime]
   *
   * @param {date} [query.endTime]
   *
   * @param {string} [query.application]
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {PredictionQueryResult} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link PredictionQueryResult} 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.
   */
  queryPredictions(projectId, query, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._queryPredictions(projectId, query, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._queryPredictions(projectId, query, options, optionalCallback);
    }
  }

  /**
   * @summary Get detailed performance information about an iteration.
   *
   * @param {uuid} projectId The id of the project the iteration belongs to.
   *
   * @param {uuid} iterationId The id of the iteration to get.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.threshold] The threshold used to determine true
   * predictions.
   *
   * @param {number} [options.overlapThreshold] If applicable, the bounding box
   * overlap threshold used to determine true predictions.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<IterationPerformance>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getIterationPerformanceWithHttpOperationResponse(projectId, iterationId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getIterationPerformance(projectId, iterationId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get detailed performance information about an iteration.
   *
   * @param {uuid} projectId The id of the project the iteration belongs to.
   *
   * @param {uuid} iterationId The id of the iteration to get.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.threshold] The threshold used to determine true
   * predictions.
   *
   * @param {number} [options.overlapThreshold] If applicable, the bounding box
   * overlap threshold used to determine true predictions.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {IterationPerformance} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link IterationPerformance} 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.
   */
  getIterationPerformance(projectId, iterationId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getIterationPerformance(projectId, iterationId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getIterationPerformance(projectId, iterationId, options, optionalCallback);
    }
  }

  /**
   * @summary Get image with its prediction for a given project iteration.
   *
   * This API supports batching and range selection. By default it will only
   * return first 50 images matching images.
   * Use the {take} and {skip} parameters to control how many images to return in
   * a given batch.
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id. Defaults to workspace.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images.
   * Defaults to all tagged images when null. Limited to 20.
   *
   * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
   * values include: 'Newest', 'Oldest'
   *
   * @param {number} [options.take] Maximum number of images to return. Defaults
   * to 50, limited to 256.
   *
   * @param {number} [options.skip] Number of images to skip before beginning the
   * image batch. Defaults to 0.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getImagePerformancesWithHttpOperationResponse(projectId, iterationId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getImagePerformances(projectId, iterationId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get image with its prediction for a given project iteration.
   *
   * This API supports batching and range selection. By default it will only
   * return first 50 images matching images.
   * Use the {take} and {skip} parameters to control how many images to return in
   * a given batch.
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id. Defaults to workspace.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images.
   * Defaults to all tagged images when null. Limited to 20.
   *
   * @param {string} [options.orderBy] The ordering. Defaults to newest. Possible
   * values include: 'Newest', 'Oldest'
   *
   * @param {number} [options.take] Maximum number of images to return. Defaults
   * to 50, limited to 256.
   *
   * @param {number} [options.skip] Number of images to skip before beginning the
   * image batch. Defaults to 0.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getImagePerformances(projectId, iterationId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getImagePerformances(projectId, iterationId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getImagePerformances(projectId, iterationId, options, optionalCallback);
    }
  }

  /**
   * @summary Gets the number of images tagged with the provided {tagIds} that
   * have prediction results from
   * training for the provided iteration {iterationId}.
   *
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id. Defaults to workspace.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images to
   * count. Defaults to all tags when null.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Number>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getImagePerformanceCountWithHttpOperationResponse(projectId, iterationId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getImagePerformanceCount(projectId, iterationId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Gets the number of images tagged with the provided {tagIds} that
   * have prediction results from
   * training for the provided iteration {iterationId}.
   *
   * The filtering is on an and/or relationship. For example, if the provided tag
   * ids are for the "Dog" and
   * "Cat" tags, then only images tagged with Dog and/or Cat will be returned
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id. Defaults to workspace.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {array} [options.tagIds] A list of tags ids to filter the images to
   * count. Defaults to all tags when null.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Number} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {number} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getImagePerformanceCount(projectId, iterationId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getImagePerformanceCount(projectId, iterationId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getImagePerformanceCount(projectId, iterationId, options, optionalCallback);
    }
  }

  /**
   * @summary Get your projects.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getProjectsWithHttpOperationResponse(options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getProjects(options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get your projects.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getProjects(options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getProjects(options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getProjects(options, optionalCallback);
    }
  }

  /**
   * @summary Create a project.
   *
   * @param {string} name Name of the project.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.description] The description of the project.
   *
   * @param {uuid} [options.domainId] The id of the domain to use for this
   * project. Defaults to General.
   *
   * @param {string} [options.classificationType] The type of classifier to
   * create for this project. Possible values include: 'Multiclass', 'Multilabel'
   *
   * @param {array} [options.targetExportPlatforms] List of platforms the trained
   * model is intending exporting to.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Project>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createProjectWithHttpOperationResponse(name, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createProject(name, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Create a project.
   *
   * @param {string} name Name of the project.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.description] The description of the project.
   *
   * @param {uuid} [options.domainId] The id of the domain to use for this
   * project. Defaults to General.
   *
   * @param {string} [options.classificationType] The type of classifier to
   * create for this project. Possible values include: 'Multiclass', 'Multilabel'
   *
   * @param {array} [options.targetExportPlatforms] List of platforms the trained
   * model is intending exporting to.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Project} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Project} 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.
   */
  createProject(name, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createProject(name, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createProject(name, options, optionalCallback);
    }
  }

  /**
   * @summary Get a specific project.
   *
   * @param {uuid} projectId The id of the project to get.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Project>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getProjectWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getProject(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get a specific project.
   *
   * @param {uuid} projectId The id of the project to get.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Project} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Project} 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.
   */
  getProject(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getProject(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getProject(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Delete a specific project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deleteProjectWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteProject(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Delete a specific project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  deleteProject(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deleteProject(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteProject(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Update a specific project.
   *
   * @param {uuid} projectId The id of the project to update.
   *
   * @param {object} updatedProject The updated project model.
   *
   * @param {string} updatedProject.name Gets or sets the name of the project.
   *
   * @param {string} updatedProject.description Gets or sets the description of
   * the project.
   *
   * @param {object} updatedProject.settings Gets or sets the project settings.
   *
   * @param {uuid} [updatedProject.settings.domainId] Gets or sets the id of the
   * Domain to use with this project.
   *
   * @param {string} [updatedProject.settings.classificationType] Gets or sets
   * the classification type of the project. Possible values include:
   * 'Multiclass', 'Multilabel'
   *
   * @param {array} [updatedProject.settings.targetExportPlatforms] A list of
   * ExportPlatform that the trained model should be able to support.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Project>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  updateProjectWithHttpOperationResponse(projectId, updatedProject, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._updateProject(projectId, updatedProject, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Update a specific project.
   *
   * @param {uuid} projectId The id of the project to update.
   *
   * @param {object} updatedProject The updated project model.
   *
   * @param {string} updatedProject.name Gets or sets the name of the project.
   *
   * @param {string} updatedProject.description Gets or sets the description of
   * the project.
   *
   * @param {object} updatedProject.settings Gets or sets the project settings.
   *
   * @param {uuid} [updatedProject.settings.domainId] Gets or sets the id of the
   * Domain to use with this project.
   *
   * @param {string} [updatedProject.settings.classificationType] Gets or sets
   * the classification type of the project. Possible values include:
   * 'Multiclass', 'Multilabel'
   *
   * @param {array} [updatedProject.settings.targetExportPlatforms] A list of
   * ExportPlatform that the trained model should be able to support.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Project} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Project} 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.
   */
  updateProject(projectId, updatedProject, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._updateProject(projectId, updatedProject, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._updateProject(projectId, updatedProject, options, optionalCallback);
    }
  }

  /**
   * @summary Queues project for training.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.trainingType] The type of training to use to train
   * the project (default: Regular). Possible values include: 'Regular',
   * 'Advanced'
   *
   * @param {number} [options.reservedBudgetInHours] The number of hours reserved
   * as budget for training (if applicable).
   *
   * @param {boolean} [options.forceTrain] Whether to force train even if dataset
   * and configuration does not change (default: false).
   *
   * @param {string} [options.notificationEmailAddress] The email address to send
   * notification to when training finishes (default: null).
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Iteration>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  trainProjectWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._trainProject(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Queues project for training.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.trainingType] The type of training to use to train
   * the project (default: Regular). Possible values include: 'Regular',
   * 'Advanced'
   *
   * @param {number} [options.reservedBudgetInHours] The number of hours reserved
   * as budget for training (if applicable).
   *
   * @param {boolean} [options.forceTrain] Whether to force train even if dataset
   * and configuration does not change (default: false).
   *
   * @param {string} [options.notificationEmailAddress] The email address to send
   * notification to when training finishes (default: null).
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Iteration} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Iteration} 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.
   */
  trainProject(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._trainProject(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._trainProject(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Get iterations for the project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getIterationsWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getIterations(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get iterations for the project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getIterations(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getIterations(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getIterations(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Get a specific iteration.
   *
   * @param {uuid} projectId The id of the project the iteration belongs to.
   *
   * @param {uuid} iterationId The id of the iteration to get.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Iteration>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getIterationWithHttpOperationResponse(projectId, iterationId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getIteration(projectId, iterationId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get a specific iteration.
   *
   * @param {uuid} projectId The id of the project the iteration belongs to.
   *
   * @param {uuid} iterationId The id of the iteration to get.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Iteration} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Iteration} 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.
   */
  getIteration(projectId, iterationId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getIteration(projectId, iterationId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getIteration(projectId, iterationId, options, optionalCallback);
    }
  }

  /**
   * @summary Delete a specific iteration of a project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deleteIterationWithHttpOperationResponse(projectId, iterationId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteIteration(projectId, iterationId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Delete a specific iteration of a project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  deleteIteration(projectId, iterationId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deleteIteration(projectId, iterationId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteIteration(projectId, iterationId, options, optionalCallback);
    }
  }

  /**
   * @summary Update a specific iteration.
   *
   * @param {uuid} projectId Project id.
   *
   * @param {uuid} iterationId Iteration id.
   *
   * @param {object} updatedIteration The updated iteration model.
   *
   * @param {string} updatedIteration.name Gets or sets the name of the
   * iteration.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Iteration>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  updateIterationWithHttpOperationResponse(projectId, iterationId, updatedIteration, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._updateIteration(projectId, iterationId, updatedIteration, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Update a specific iteration.
   *
   * @param {uuid} projectId Project id.
   *
   * @param {uuid} iterationId Iteration id.
   *
   * @param {object} updatedIteration The updated iteration model.
   *
   * @param {string} updatedIteration.name Gets or sets the name of the
   * iteration.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Iteration} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Iteration} 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.
   */
  updateIteration(projectId, iterationId, updatedIteration, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._updateIteration(projectId, iterationId, updatedIteration, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._updateIteration(projectId, iterationId, updatedIteration, options, optionalCallback);
    }
  }

  /**
   * @summary Publish a specific iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {string} publishName The name to give the published iteration.
   *
   * @param {string} predictionId The id of the prediction resource to publish
   * to.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Boolean>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  publishIterationWithHttpOperationResponse(projectId, iterationId, publishName, predictionId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._publishIteration(projectId, iterationId, publishName, predictionId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Publish a specific iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {string} publishName The name to give the published iteration.
   *
   * @param {string} predictionId The id of the prediction resource to publish
   * to.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Boolean} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {boolean} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  publishIteration(projectId, iterationId, publishName, predictionId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._publishIteration(projectId, iterationId, publishName, predictionId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._publishIteration(projectId, iterationId, publishName, predictionId, options, optionalCallback);
    }
  }

  /**
   * @summary Unpublish a specific iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  unpublishIterationWithHttpOperationResponse(projectId, iterationId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._unpublishIteration(projectId, iterationId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Unpublish a specific iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  unpublishIteration(projectId, iterationId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._unpublishIteration(projectId, iterationId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._unpublishIteration(projectId, iterationId, options, optionalCallback);
    }
  }

  /**
   * @summary Get the list of exports for a specific iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getExportsWithHttpOperationResponse(projectId, iterationId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getExports(projectId, iterationId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get the list of exports for a specific iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getExports(projectId, iterationId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getExports(projectId, iterationId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getExports(projectId, iterationId, options, optionalCallback);
    }
  }

  /**
   * @summary Export a trained iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {string} platform The target platform. Possible values include:
   * 'CoreML', 'TensorFlow', 'DockerFile', 'ONNX', 'VAIDK'
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.flavor] The flavor of the target platform. Possible
   * values include: 'Linux', 'Windows', 'ONNX10', 'ONNX12', 'ARM'
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ExportModel>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  exportIterationWithHttpOperationResponse(projectId, iterationId, platform, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._exportIteration(projectId, iterationId, platform, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Export a trained iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} iterationId The iteration id.
   *
   * @param {string} platform The target platform. Possible values include:
   * 'CoreML', 'TensorFlow', 'DockerFile', 'ONNX', 'VAIDK'
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.flavor] The flavor of the target platform. Possible
   * values include: 'Linux', 'Windows', 'ONNX10', 'ONNX12', 'ARM'
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {ExportModel} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link ExportModel} 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.
   */
  exportIteration(projectId, iterationId, platform, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._exportIteration(projectId, iterationId, platform, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._exportIteration(projectId, iterationId, platform, options, optionalCallback);
    }
  }

  /**
   * @summary Get information about a specific tag.
   *
   * @param {uuid} projectId The project this tag belongs to.
   *
   * @param {uuid} tagId The tag id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration to retrieve this tag from.
   * Optional, defaults to current training set.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Tag>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getTagWithHttpOperationResponse(projectId, tagId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getTag(projectId, tagId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get information about a specific tag.
   *
   * @param {uuid} projectId The project this tag belongs to.
   *
   * @param {uuid} tagId The tag id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration to retrieve this tag from.
   * Optional, defaults to current training set.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Tag} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Tag} 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.
   */
  getTag(projectId, tagId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getTag(projectId, tagId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getTag(projectId, tagId, options, optionalCallback);
    }
  }

  /**
   * @summary Delete a tag from the project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} tagId Id of the tag to be deleted.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<null>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deleteTagWithHttpOperationResponse(projectId, tagId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteTag(projectId, tagId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Delete a tag from the project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} tagId Id of the tag to be deleted.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {null} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {null} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  deleteTag(projectId, tagId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deleteTag(projectId, tagId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteTag(projectId, tagId, options, optionalCallback);
    }
  }

  /**
   * @summary Update a tag.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} tagId The id of the target tag.
   *
   * @param {object} updatedTag The updated tag model.
   *
   * @param {string} updatedTag.name Gets or sets the name of the tag.
   *
   * @param {string} updatedTag.description Gets or sets the description of the
   * tag.
   *
   * @param {string} updatedTag.type Gets or sets the type of the tag. Possible
   * values include: 'Regular', 'Negative'
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Tag>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  updateTagWithHttpOperationResponse(projectId, tagId, updatedTag, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._updateTag(projectId, tagId, updatedTag, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Update a tag.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {uuid} tagId The id of the target tag.
   *
   * @param {object} updatedTag The updated tag model.
   *
   * @param {string} updatedTag.name Gets or sets the name of the tag.
   *
   * @param {string} updatedTag.description Gets or sets the description of the
   * tag.
   *
   * @param {string} updatedTag.type Gets or sets the type of the tag. Possible
   * values include: 'Regular', 'Negative'
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Tag} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Tag} 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.
   */
  updateTag(projectId, tagId, updatedTag, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._updateTag(projectId, tagId, updatedTag, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._updateTag(projectId, tagId, updatedTag, options, optionalCallback);
    }
  }

  /**
   * @summary Get the tags for a given project and iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Array>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getTagsWithHttpOperationResponse(projectId, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getTags(projectId, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Get the tags for a given project and iteration.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {uuid} [options.iterationId] The iteration id. Defaults to workspace.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Array} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {array} [result]   - The deserialized result object if an error did not occur.
   *
   *                      {object} [request]  - The HTTP Request object if an error did not occur.
   *
   *                      {stream} [response] - The HTTP Response stream if an error did not occur.
   */
  getTags(projectId, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getTags(projectId, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getTags(projectId, options, optionalCallback);
    }
  }

  /**
   * @summary Create a tag for the project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {string} name The tag name.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.description] Optional description for the tag.
   *
   * @param {string} [options.type] Optional type for the tag. Possible values
   * include: 'Regular', 'Negative'
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Tag>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createTagWithHttpOperationResponse(projectId, name, options) {
    let client = this;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createTag(projectId, name, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * @summary Create a tag for the project.
   *
   * @param {uuid} projectId The project id.
   *
   * @param {string} name The tag name.
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.description] Optional description for the tag.
   *
   * @param {string} [options.type] Optional type for the tag. Possible values
   * include: 'Regular', 'Negative'
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @param {function} [optionalCallback] - The optional callback.
   *
   * @returns {function|Promise} If a callback was passed as the last parameter
   * then it returns the callback else returns a Promise.
   *
   * {Promise} A promise is returned
   *
   *                      @resolve {Tag} - The deserialized result object.
   *
   *                      @reject {Error} - The error object.
   *
   * {function} optionalCallback(err, result, request, response)
   *
   *                      {Error}  err        - The Error object if an error occurred, null otherwise.
   *
   *                      {object} [result]   - The deserialized result object if an error did not occur.
   *                      See {@link Tag} 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.
   */
  createTag(projectId, name, options, optionalCallback) {
    let client = this;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createTag(projectId, name, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createTag(projectId, name, options, optionalCallback);
    }
  }

}

module.exports = TrainingAPIClient;
module.exports['default'] = TrainingAPIClient;
module.exports.TrainingAPIClient = TrainingAPIClient;
module.exports.TrainingAPIModels = models;
