/*
 * Code generated by Microsoft (R) AutoRest Code Generator.
 * Changes may cause incorrect behavior and will be lost if the code is
 * regenerated.
 */

'use strict';

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

/**
 * Count of active devices by interval in the time range.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 ActiveDeviceCounts} 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 _deviceCounts(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/active_device_counts';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['ActiveDeviceCounts']().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);
  });
}

/**
 * Get list of audiences.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {boolean} [options.includeDisabled] Include disabled audience
 * definitions
 *
 * @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 AudienceListResult} 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 _listAudiences(appName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let includeDisabled = (options && options.includeDisabled !== undefined) ? options.includeDisabled : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (includeDisabled !== null && includeDisabled !== undefined && typeof includeDisabled !== 'boolean') {
      throw new Error('includeDisabled must be of type boolean.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (includeDisabled !== null && includeDisabled !== undefined) {
    queryParameters.push('include_disabled=' + encodeURIComponent(includeDisabled.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(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;
        }
      } 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['AudienceListResult']().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);
  });
}

/**
 * Tests audience definition.
 *
 * @param {string} appName The name of the application
 *
 * @param {object} audience Audience definition
 *
 * @param {string} [audience.description] Audience description.
 *
 * @param {string} audience.definition Audience definition in OData format.
 *
 * @param {boolean} [audience.enabled]
 *
 * @param {object} [audience.customProperties] Custom properties used in the
 * definition.
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 AudienceTestResult} 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 _testAudience(appName, audience, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (audience === null || audience === undefined) {
      throw new Error('audience cannot be null or undefined.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/definition/test';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // 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(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 (audience !== null && audience !== undefined) {
      let requestModelMapper = new client.models['AudienceDefinition']().mapper();
      requestModel = client.serialize(requestModelMapper, audience, 'audience');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(audience, 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;
        }
      } 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['AudienceTestResult']().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);
  });
}

/**
 * Get list of custom properties.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 AudienceDevicePropertiesListResult} 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 _listCustomProperties(appName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/metadata/custom_properties';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

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

/**
 * Get list of device properties.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 AudienceDevicePropertiesListResult} 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 _listDeviceProperties(appName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/metadata/device_properties';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

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

/**
 * Get list of device property values.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {string} propertyName Device property
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.contains] Contains string
 *
 * @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 AudienceDevicePropertyValuesListResult} 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 _listDevicePropertyValues(appName, ownerName, propertyName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let contains = (options && options.contains !== undefined) ? options.contains : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (contains !== null && contains !== undefined && typeof contains.valueOf() !== 'string') {
      throw new Error('contains must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if (propertyName === null || propertyName === undefined || typeof propertyName.valueOf() !== 'string') {
      throw new Error('propertyName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/metadata/device_properties/{property_name}/values';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  requestUrl = requestUrl.replace('{property_name}', encodeURIComponent(propertyName));
  let queryParameters = [];
  if (contains !== null && contains !== undefined) {
    queryParameters.push('contains=' + encodeURIComponent(contains));
  }
  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(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;
        }
      } 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['AudienceDevicePropertyValuesListResult']().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);
  });
}

/**
 * Returns whether audience definition exists.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} audienceName The name of the audience
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 _audienceNameExists(appName, audienceName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (audienceName === null || audienceName === undefined || typeof audienceName.valueOf() !== 'string') {
      throw new Error('audienceName cannot be null or undefined and it must be of type string.');
    }
    if (audienceName !== null && audienceName !== undefined) {
      if (audienceName.length > 64)
      {
        throw new Error('"audienceName" should satisfy the constraint - "MaxLength": 64');
      }
      if (audienceName.match(/[^\/]+/) === null)
      {
        throw new Error('"audienceName" should satisfy the constraint - "Pattern": /[^\/]+/');
      }
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/{audience_name}';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{audience_name}', encodeURIComponent(audienceName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'HEAD';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode < 200 || statusCode >= 300) {
      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;
        }
      } 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);
  });
}

/**
 * Deletes audience definition.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} audienceName The name of the audience
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 _deleteAudience(appName, audienceName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (audienceName === null || audienceName === undefined || typeof audienceName.valueOf() !== 'string') {
      throw new Error('audienceName cannot be null or undefined and it must be of type string.');
    }
    if (audienceName !== null && audienceName !== undefined) {
      if (audienceName.length > 64)
      {
        throw new Error('"audienceName" should satisfy the constraint - "MaxLength": 64');
      }
      if (audienceName.match(/[^\/]+/) === null)
      {
        throw new Error('"audienceName" should satisfy the constraint - "Pattern": /[^\/]+/');
      }
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/{audience_name}';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{audience_name}', encodeURIComponent(audienceName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // 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(options) {
    for(let headerName in options['customHeaders']) {
      if (options['customHeaders'].hasOwnProperty(headerName)) {
        httpRequest.headers[headerName] = options['customHeaders'][headerName];
      }
    }
  }
  httpRequest.body = null;
  // Send Request
  return client.pipeline(httpRequest, (err, response, responseBody) => {
    if (err) {
      return callback(err);
    }
    let statusCode = response.statusCode;
    if (statusCode < 200 || statusCode >= 300) {
      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;
        }
      } catch (defaultError) {
        error.message = `Error "${defaultError.message}" occurred in deserializing the responseBody ` +
                         `- "${responseBody}" for the default response.`;
        return callback(error);
      }
      return callback(error);
    }
    // Create Result
    let result = null;
    if (responseBody === '') responseBody = null;

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

/**
 * Gets audience definition.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} audienceName The name of the audience
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 Audience} 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 _getAudience(appName, audienceName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (audienceName === null || audienceName === undefined || typeof audienceName.valueOf() !== 'string') {
      throw new Error('audienceName cannot be null or undefined and it must be of type string.');
    }
    if (audienceName !== null && audienceName !== undefined) {
      if (audienceName.length > 64)
      {
        throw new Error('"audienceName" should satisfy the constraint - "MaxLength": 64');
      }
      if (audienceName.match(/[^\/]+/) === null)
      {
        throw new Error('"audienceName" should satisfy the constraint - "Pattern": /[^\/]+/');
      }
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/{audience_name}';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{audience_name}', encodeURIComponent(audienceName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // 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(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;
        }
      } 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['Audience']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Creates or updates audience definition.
 *
 * @param {string} appName The name of the application
 *
 * @param {object} audience Audience definition
 *
 * @param {string} [audience.description] Audience description.
 *
 * @param {string} audience.definition Audience definition in OData format.
 *
 * @param {boolean} [audience.enabled]
 *
 * @param {object} [audience.customProperties] Custom properties used in the
 * definition.
 *
 * @param {string} audienceName The name of the audience
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 Audience} 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 _createOrUpdateAudience(appName, audience, audienceName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (audience === null || audience === undefined) {
      throw new Error('audience cannot be null or undefined.');
    }
    if (audienceName === null || audienceName === undefined || typeof audienceName.valueOf() !== 'string') {
      throw new Error('audienceName cannot be null or undefined and it must be of type string.');
    }
    if (audienceName !== null && audienceName !== undefined) {
      if (audienceName.length > 64)
      {
        throw new Error('"audienceName" should satisfy the constraint - "MaxLength": 64');
      }
      if (audienceName.match(/[^\/]+/) === null)
      {
        throw new Error('"audienceName" should satisfy the constraint - "Pattern": /[^\/]+/');
      }
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/audiences/{audience_name}';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{audience_name}', encodeURIComponent(audienceName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // Create HTTP transport objects
  let httpRequest = new WebResource();
  httpRequest.method = 'PUT';
  httpRequest.url = requestUrl;
  httpRequest.headers = {};
  // Set Headers
  httpRequest.headers['Content-Type'] = 'application/json; charset=utf-8';
  if(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 (audience !== null && audience !== undefined) {
      let requestModelMapper = new client.models['AudienceDefinition']().mapper();
      requestModel = client.serialize(requestModelMapper, audience, 'audience');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(audience, 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;
        }
      } 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['Audience']().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);
  });
}

/**
 * Count of crashes by day in the time range based the selected versions.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 CrashCounts} 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 _crashCountsMethod(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/crash_counts';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['CrashCounts']().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);
  });
}

/**
 * Overall crashes and affected users count of the selected crash groups with
 * selected versions
 *
 * @param {string} appName The name of the application
 *
 * @param {object} crashGroups
 *
 * @param {array} crashGroups.crashGroups
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 _crashGroupsTotals(appName, crashGroups, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (crashGroups === null || crashGroups === undefined) {
      throw new Error('crashGroups cannot be null or undefined.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/crash_groups';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // 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(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 (crashGroups !== null && crashGroups !== undefined) {
      let requestModelMapper = new client.models['CrashGroupContainer']().mapper();
      requestModel = client.serialize(requestModelMapper, crashGroups, 'crashGroups');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(crashGroups, 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;
        }
      } 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: 'CrashesOverallItemElementType',
                  type: {
                    name: 'Composite',
                    className: 'CrashesOverallItem'
                  }
              }
            }
          };
          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);
  });
}

/**
 * Count of crashes by day in the time range of the selected crash group with
 * selected version
 *
 * @param {string} appName The name of the application
 *
 * @param {string} crashGroupId The id of the crash group
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {string} version
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @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 CrashCounts} 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 _crashGroupCounts(appName, crashGroupId, ownerName, start, version, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (crashGroupId === null || crashGroupId === undefined || typeof crashGroupId.valueOf() !== 'string') {
      throw new Error('crashGroupId cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (version === null || version === undefined || typeof version.valueOf() !== 'string') {
      throw new Error('version cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/crash_groups/{crash_group_id}/crash_counts';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{crash_group_id}', encodeURIComponent(crashGroupId));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  queryParameters.push('version=' + encodeURIComponent(version));
  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(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;
        }
      } 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['CrashCounts']().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);
  });
}

/**
 * top models of the selected crash group with selected version
 *
 * @param {string} appName The name of the application
 *
 * @param {string} crashGroupId The id of the crash group
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {string} version
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @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 CrashGroupModels} 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 _crashGroupModelCounts(appName, crashGroupId, ownerName, version, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let top = (options && options.top !== undefined) ? options.top : 30;
  // Validate
  try {
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (crashGroupId === null || crashGroupId === undefined || typeof crashGroupId.valueOf() !== 'string') {
      throw new Error('crashGroupId cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if (version === null || version === undefined || typeof version.valueOf() !== 'string') {
      throw new Error('version cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/crash_groups/{crash_group_id}/models';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{crash_group_id}', encodeURIComponent(crashGroupId));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  queryParameters.push('version=' + encodeURIComponent(version));
  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(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;
        }
      } 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['CrashGroupModels']().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);
  });
}

/**
 * top OSes of the selected crash group with selected version
 *
 * @param {string} appName The name of the application
 *
 * @param {string} crashGroupId The id of the crash group
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {string} version
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @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 CrashGroupOperatingSystems} 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 _crashGroupOperatingSystemCounts(appName, crashGroupId, ownerName, version, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let top = (options && options.top !== undefined) ? options.top : 30;
  // Validate
  try {
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (crashGroupId === null || crashGroupId === undefined || typeof crashGroupId.valueOf() !== 'string') {
      throw new Error('crashGroupId cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if (version === null || version === undefined || typeof version.valueOf() !== 'string') {
      throw new Error('version cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/crash_groups/{crash_group_id}/operating_systems';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{crash_group_id}', encodeURIComponent(crashGroupId));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  queryParameters.push('version=' + encodeURIComponent(version));
  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(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;
        }
      } 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['CrashGroupOperatingSystems']().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);
  });
}

/**
 * Overall crashes and affected users count of the selected crash group with
 * selected version
 *
 * @param {string} appName The name of the application
 *
 * @param {string} crashGroupId The id of the crash group
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {string} version
 *
 * @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 CrashOverall} 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 _crashGroupTotals(appName, crashGroupId, ownerName, version, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (crashGroupId === null || crashGroupId === undefined || typeof crashGroupId.valueOf() !== 'string') {
      throw new Error('crashGroupId cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if (version === null || version === undefined || typeof version.valueOf() !== 'string') {
      throw new Error('version cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/crash_groups/{crash_group_id}/overall';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{crash_group_id}', encodeURIComponent(crashGroupId));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  queryParameters.push('version=' + encodeURIComponent(version));
  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(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;
        }
      } 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['CrashOverall']().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);
  });
}

/**
 * Percentage of crash-free device by day in the time range based on the
 * selected versions. Api will return -1 if crash devices is greater than
 * active devices
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 CrashFreeDevicePercentages} 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 _crashFreeDevicePercentagesMethod(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/crashfree_device_percentages';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['CrashFreeDevicePercentages']().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);
  });
}

/**
 * Count of total downloads for the provided distribution releases.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {object} releases The releases to retrieve.
 *
 * @param {array} releases.releases
 *
 * @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 ReleaseCounts} 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 _distributionReleaseCounts(appName, ownerName, releases, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if (releases === null || releases === undefined) {
      throw new Error('releases cannot be null or undefined.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/distribution/release_counts';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // 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(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 (releases !== null && releases !== undefined) {
      let requestModelMapper = new client.models['GetReleasesContainer']().mapper();
      requestModel = client.serialize(requestModelMapper, releases, 'releases');
      requestContent = JSON.stringify(requestModel);
    }
  } catch (error) {
    let serializationError = new Error(`Error "${error.message}" occurred in serializing the ` +
        `payload - ${JSON.stringify(releases, 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;
        }
      } 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['ReleaseCounts']().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);
  });
}

/**
 * Delete the set of Events with the specified event names
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 _eventsDeleteLogs(appName, eventName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/event_logs/{event_name}';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // 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(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;
        }
      } 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);
  });
}

/**
 * Count of active events in the time range ordered by event.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.inlinecount] Controls whether or not to include a
 * count of all the items accross all pages. Possible values include:
 * 'allpages', 'none'
 *
 * @param {string} [options.orderby] controls the sorting order and sorting
 * based on which column
 *
 * @param {number} [options.skip] The offset (starting at 0) of the first
 * result to return. This parameter along with limit is used to perform
 * pagination.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.eventName] to select the specific events
 *
 * @param {array} [options.versions]
 *
 * @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 Events} 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 _eventsMethod(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let inlinecount = (options && options.inlinecount !== undefined) ? options.inlinecount : 'none';
  let orderby = (options && options.orderby !== undefined) ? options.orderby : 'count desc';
  let skip = (options && options.skip !== undefined) ? options.skip : 0;
  let top = (options && options.top !== undefined) ? options.top : 30;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let eventName = (options && options.eventName !== undefined) ? options.eventName : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (inlinecount !== null && inlinecount !== undefined && typeof inlinecount.valueOf() !== 'string') {
      throw new Error('inlinecount must be of type string.');
    }
    if (orderby !== null && orderby !== undefined && typeof orderby.valueOf() !== 'string') {
      throw new Error('orderby must be of type string.');
    }
    if (skip !== null && skip !== undefined && typeof skip !== 'number') {
      throw new Error('skip must be of type number.');
    }
    if (skip !== null && skip !== undefined) {
      if (skip < 0)
      {
        throw new Error('"skip" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (Array.isArray(eventName)) {
      for (let i = 0; i < eventName.length; i++) {
        if (eventName[i] !== null && eventName[i] !== undefined && typeof eventName[i].valueOf() !== 'string') {
          throw new Error('eventName[i] must be of type string.');
        }
      }
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i1 = 0; i1 < versions.length; i1++) {
        if (versions[i1] !== null && versions[i1] !== undefined && typeof versions[i1].valueOf() !== 'string') {
          throw new Error('versions[i1] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (inlinecount !== null && inlinecount !== undefined) {
    queryParameters.push('$inlinecount=' + encodeURIComponent(inlinecount));
  }
  if (orderby !== null && orderby !== undefined) {
    queryParameters.push('$orderby=' + encodeURIComponent(orderby));
  }
  if (skip !== null && skip !== undefined) {
    queryParameters.push('$skip=' + encodeURIComponent(skip.toString()));
  }
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  if (eventName !== null && eventName !== undefined) {
    queryParameters.push('event_name=' + encodeURIComponent(eventName.join('|')));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['Events']().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);
  });
}

/**
 * Delete the set of Events with the specified event names
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 _eventsDelete(appName, eventName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events/{event_name}';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

  // 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(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;
        }
      } 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);
  });
}

/**
 * Count of events per device by interval in the time range.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 EventCountPerDevice} 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 _eventPerDeviceCount(appName, eventName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events/{event_name}/count_per_device';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['EventCountPerDevice']().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);
  });
}

/**
 * Count of events per session by interval in the time range.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 EventCountPerSession} 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 _eventPerSessionCount(appName, eventName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events/{event_name}/count_per_session';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['EventCountPerSession']().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);
  });
}

/**
 * Count of devices for an event by interval in the time range.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 EventDeviceCount} 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 _eventDeviceCountMethod(appName, eventName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events/{event_name}/device_count';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['EventDeviceCount']().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);
  });
}

/**
 * Count of events by interval in the time range.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 EventCount} 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 _eventCountMethod(appName, eventName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events/{event_name}/event_count';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['EventCount']().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);
  });
}

/**
 * Event properties.  Up to the first 5 received properties.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 EventProperties} 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 _eventPropertiesMethod(appName, eventName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events/{event_name}/properties';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));

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

/**
 * Event properties value counts during the time range in descending order.
 * Limited up to 5 values.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} eventName The id of the event
 *
 * @param {string} eventPropertyName The id of the event property
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.count] The number of property values to return
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 EventPropertyValues} 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 _eventPropertyCounts(appName, eventName, eventPropertyName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let count = (options && options.count !== undefined) ? options.count : 5;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (count !== null && count !== undefined && typeof count !== 'number') {
      throw new Error('count must be of type number.');
    }
    if (count !== null && count !== undefined) {
      if (count > 10)
      {
        throw new Error('"count" should satisfy the constraint - "InclusiveMaximum": 10');
      }
      if (count < 1)
      {
        throw new Error('"count" should satisfy the constraint - "InclusiveMinimum": 1');
      }
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (eventName === null || eventName === undefined || typeof eventName.valueOf() !== 'string') {
      throw new Error('eventName cannot be null or undefined and it must be of type string.');
    }
    if (eventPropertyName === null || eventPropertyName === undefined || typeof eventPropertyName.valueOf() !== 'string') {
      throw new Error('eventPropertyName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/events/{event_name}/properties/{event_property_name}/counts';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{event_name}', encodeURIComponent(eventName));
  requestUrl = requestUrl.replace('{event_property_name}', encodeURIComponent(eventPropertyName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (count !== null && count !== undefined) {
    queryParameters.push('count=' + encodeURIComponent(count.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['EventPropertyValues']().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);
  });
}

/**
 * Logs received between the specified start time and the current time. The API
 * will return a maximum of 100 logs per call.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.start] Start date time in data in ISO 8601 date time
 * format. It must be within the current day in the UTC timezone. The default
 * value is the start time of the current day in UTC timezone.
 *
 * @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 LogFlowGenericLogContainer} 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 _genericLogFlow(appName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let start = (options && options.start !== undefined) ? options.start : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if (start && !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start must be of type date.');
        }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/generic_log_flow';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (start !== null && start !== undefined) {
    queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  }
  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(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;
        }
      } 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['LogFlowGenericLogContainer']().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);
  });
}

/**
 * languages in the time range
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 Languages} 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 _languageCounts(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let top = (options && options.top !== undefined) ? options.top : 30;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/languages';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['Languages']().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);
  });
}

/**
 * Logs received between the specified start time and the current time. The API
 * will return a maximum of 100 logs per call.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.start] Start date time in data in ISO 8601 date time
 * format. It must be within the current day in the UTC timezone. The default
 * value is the start time of the current day in UTC timezone.
 *
 * @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 LogFlowLogContainer} 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 _logFlow(appName, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let start = (options && options.start !== undefined) ? options.start : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if (start && !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start must be of type date.');
        }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/log_flow';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (start !== null && start !== undefined) {
    queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  }
  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(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;
        }
      } 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['LogFlowLogContainer']().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);
  });
}

/**
 * models in the time range
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 AnalyticsModels} 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 _modelCounts(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let top = (options && options.top !== undefined) ? options.top : 30;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/models';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['AnalyticsModels']().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);
  });
}

/**
 * OSes in the time range
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 OSes} 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 _operatingSystemCounts(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let top = (options && options.top !== undefined) ? options.top : 30;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/oses';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['OSes']().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);
  });
}

/**
 * Places in the time range
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 Places} 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 _placeCounts(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let top = (options && options.top !== undefined) ? options.top : 30;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/places';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['Places']().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);
  });
}

/**
 * Count of sessions in the time range.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} interval Size of interval in ISO 8601 duration format.
 * (PnYnMnDTnHnMnS|PnW|P<date>T<time>). The valid durations are 1 day (P1D), 1
 * week (P1W), and 30 days (P30D).
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 _sessionCounts(appName, interval, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (interval === null || interval === undefined || typeof interval.valueOf() !== 'string') {
      throw new Error('interval cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/session_counts';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('interval=' + encodeURIComponent(interval));
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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: 'DateTimeCountsElementType',
                  type: {
                    name: 'Composite',
                    className: 'DateTimeCounts'
                  }
              }
            }
          };
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * Gets session duration .
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 SessionDurationsDistribution} 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 _sessionDurationsDistributionMethod(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/session_durations_distribution';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['SessionDurationsDistribution']().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);
  });
}

/**
 * Count of sessions per device in the time range
 *
 * @param {string} appName The name of the application
 *
 * @param {string} interval Size of interval in ISO 8601 duration format.
 * (PnYnMnDTnHnMnS|PnW|P<date>T<time>). The valid durations are 1 day (P1D), 1
 * week (P1W), and 30 days (P30D).
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 SessionsPerDevice} 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 _perDeviceCounts(appName, interval, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (interval === null || interval === undefined || typeof interval.valueOf() !== 'string') {
      throw new Error('interval cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/sessions_per_device';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('interval=' + encodeURIComponent(interval));
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['SessionsPerDevice']().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);
  });
}

/**
 * Count of active versions in the time range ordered by version.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {array} [options.versions]
 *
 * @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 Versions} 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 _versionsMethod(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let top = (options && options.top !== undefined) ? options.top : 30;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let versions = (options && options.versions !== undefined) ? options.versions : undefined;
  // Validate
  try {
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (Array.isArray(versions)) {
      for (let i = 0; i < versions.length; i++) {
        if (versions[i] !== null && versions[i] !== undefined && typeof versions[i].valueOf() !== 'string') {
          throw new Error('versions[i] must be of type string.');
        }
      }
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/analytics/versions';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (versions !== null && versions !== undefined) {
    queryParameters.push('versions=' + encodeURIComponent(versions.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(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;
        }
      } 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['Versions']().mapper();
          result = client.deserialize(resultMapper, parsedResponse, 'result');
        }
      } catch (error) {
        let deserializationError = new Error(`Error ${error} occurred in deserializing the responseBody - ${responseBody}`);
        deserializationError.request = msRest.stripRequest(httpRequest);
        deserializationError.response = msRest.stripResponse(response);
        return callback(deserializationError);
      }
    }

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

/**
 * List of error groups
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {string} [options.orderby] controls the sorting order and sorting
 * based on which column
 *
 * @param {number} [options.top] The maximum number of results to return. (0
 * will fetch all results)
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {string} [options.groupStatus]
 *
 * @param {string} [options.version]
 *
 * @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 ErrorGroups} 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 _errorGroupList(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let orderby = (options && options.orderby !== undefined) ? options.orderby : 'count desc';
  let top = (options && options.top !== undefined) ? options.top : 30;
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let groupStatus = (options && options.groupStatus !== undefined) ? options.groupStatus : undefined;
  let version = (options && options.version !== undefined) ? options.version : undefined;
  // Validate
  try {
    if (orderby !== null && orderby !== undefined && typeof orderby.valueOf() !== 'string') {
      throw new Error('orderby must be of type string.');
    }
    if (top !== null && top !== undefined && typeof top !== 'number') {
      throw new Error('top must be of type number.');
    }
    if (top !== null && top !== undefined) {
      if (top > 2000)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMaximum": 2000');
      }
      if (top < 0)
      {
        throw new Error('"top" should satisfy the constraint - "InclusiveMinimum": 0');
      }
    }
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (groupStatus !== null && groupStatus !== undefined && typeof groupStatus.valueOf() !== 'string') {
      throw new Error('groupStatus must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (version !== null && version !== undefined && typeof version.valueOf() !== 'string') {
      throw new Error('version must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/errors/error_groups';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (orderby !== null && orderby !== undefined) {
    queryParameters.push('$orderby=' + encodeURIComponent(orderby));
  }
  if (top !== null && top !== undefined) {
    queryParameters.push('$top=' + encodeURIComponent(top.toString()));
  }
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  if (groupStatus !== null && groupStatus !== undefined) {
    queryParameters.push('group_status=' + encodeURIComponent(groupStatus));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (version !== null && version !== undefined) {
    queryParameters.push('version=' + encodeURIComponent(version));
  }
  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(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;
        }
      } 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['ErrorGroups']().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);
  });
}

/**
 * Count of errors by day in the time range based the selected versions.
 *
 * @param {string} appName The name of the application
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {string} [options.groupStatus]
 *
 * @param {string} [options.version]
 *
 * @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 ErrorCounts} 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 _errorCountsPerDay(appName, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let groupStatus = (options && options.groupStatus !== undefined) ? options.groupStatus : undefined;
  let version = (options && options.version !== undefined) ? options.version : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (groupStatus !== null && groupStatus !== undefined && typeof groupStatus.valueOf() !== 'string') {
      throw new Error('groupStatus must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (version !== null && version !== undefined && typeof version.valueOf() !== 'string') {
      throw new Error('version must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/errors/error_groups/error_counts_per_day';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  if (groupStatus !== null && groupStatus !== undefined) {
    queryParameters.push('group_status=' + encodeURIComponent(groupStatus));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (version !== null && version !== undefined) {
    queryParameters.push('version=' + encodeURIComponent(version));
  }
  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(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;
        }
      } 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['ErrorCounts']().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);
  });
}

/**
 * Error group details
 *
 * @param {string} appName The name of the application
 *
 * @param {string} errorGroupId The id of the error group
 *
 * @param {string} model
 *
 * @param {string} os
 *
 * @param {string} ownerName The name of the owner
 *
 * @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 ErrorGroup} 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 _errorGroupDetails(appName, errorGroupId, model, os, ownerName, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (errorGroupId === null || errorGroupId === undefined || typeof errorGroupId.valueOf() !== 'string') {
      throw new Error('errorGroupId cannot be null or undefined and it must be of type string.');
    }
    if (model === null || model === undefined || typeof model.valueOf() !== 'string') {
      throw new Error('model cannot be null or undefined and it must be of type string.');
    }
    if (os === null || os === undefined || typeof os.valueOf() !== 'string') {
      throw new Error('os cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/errors/error_groups/{error_group_id}';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{error_group_id}', encodeURIComponent(errorGroupId));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  queryParameters.push('model=' + encodeURIComponent(model));
  queryParameters.push('os=' + encodeURIComponent(os));
  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(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;
        }
      } 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['ErrorGroup']().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);
  });
}

/**
 * Count of errors by day in the time range of the selected error group with
 * selected version
 *
 * @param {string} appName The name of the application
 *
 * @param {string} errorGroupId The id of the error group
 *
 * @param {string} ownerName The name of the owner
 *
 * @param {date} start Start date time in data in ISO 8601 date time format
 *
 * @param {object} [options] Optional Parameters.
 *
 * @param {date} [options.end] Last date time in data in ISO 8601 date time
 * format
 *
 * @param {string} [options.version]
 *
 * @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 ErrorCounts} 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 _errorGroupCountsPerDay(appName, errorGroupId, ownerName, start, options, callback) {
   /* jshint validthis: true */
  let client = this.client;
  if(!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }
  if (!callback) {
    throw new Error('callback cannot be null.');
  }
  let end = (options && options.end !== undefined) ? options.end : undefined;
  let version = (options && options.version !== undefined) ? options.version : undefined;
  // Validate
  try {
    if (appName === null || appName === undefined || typeof appName.valueOf() !== 'string') {
      throw new Error('appName cannot be null or undefined and it must be of type string.');
    }
    if (end && !(end instanceof Date ||
        (typeof end.valueOf() === 'string' && !isNaN(Date.parse(end))))) {
          throw new Error('end must be of type date.');
        }
    if (errorGroupId === null || errorGroupId === undefined || typeof errorGroupId.valueOf() !== 'string') {
      throw new Error('errorGroupId cannot be null or undefined and it must be of type string.');
    }
    if (ownerName === null || ownerName === undefined || typeof ownerName.valueOf() !== 'string') {
      throw new Error('ownerName cannot be null or undefined and it must be of type string.');
    }
    if(!start || !(start instanceof Date ||
        (typeof start.valueOf() === 'string' && !isNaN(Date.parse(start))))) {
          throw new Error('start cannot be null or undefined and it must be of type date.');
        }
    if (version !== null && version !== undefined && typeof version.valueOf() !== 'string') {
      throw new Error('version must be of type string.');
    }
  } catch (error) {
    return callback(error);
  }

  // Construct URL
  let baseUrl = this.client.baseUri;
  let requestUrl = baseUrl + (baseUrl.endsWith('/') ? '' : '/') + 'v0.1/apps/{owner_name}/{app_name}/errors/error_groups/{error_group_id}/error_counts_per_day';
  requestUrl = requestUrl.replace('{app_name}', encodeURIComponent(appName));
  requestUrl = requestUrl.replace('{error_group_id}', encodeURIComponent(errorGroupId));
  requestUrl = requestUrl.replace('{owner_name}', encodeURIComponent(ownerName));
  let queryParameters = [];
  if (end !== null && end !== undefined) {
    queryParameters.push('end=' + encodeURIComponent(client.serializeObject(end)));
  }
  queryParameters.push('start=' + encodeURIComponent(client.serializeObject(start)));
  if (version !== null && version !== undefined) {
    queryParameters.push('version=' + encodeURIComponent(version));
  }
  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(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;
        }
      } 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['ErrorCounts']().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 Analytics. */
class Analytics {
  /**
   * Create a Analytics.
   * @param {AnalyticsClient} client Reference to the service client.
   */
  constructor(client) {
    this.client = client;
    this._deviceCounts = _deviceCounts;
    this._listAudiences = _listAudiences;
    this._testAudience = _testAudience;
    this._listCustomProperties = _listCustomProperties;
    this._listDeviceProperties = _listDeviceProperties;
    this._listDevicePropertyValues = _listDevicePropertyValues;
    this._audienceNameExists = _audienceNameExists;
    this._deleteAudience = _deleteAudience;
    this._getAudience = _getAudience;
    this._createOrUpdateAudience = _createOrUpdateAudience;
    this._crashCountsMethod = _crashCountsMethod;
    this._crashGroupsTotals = _crashGroupsTotals;
    this._crashGroupCounts = _crashGroupCounts;
    this._crashGroupModelCounts = _crashGroupModelCounts;
    this._crashGroupOperatingSystemCounts = _crashGroupOperatingSystemCounts;
    this._crashGroupTotals = _crashGroupTotals;
    this._crashFreeDevicePercentagesMethod = _crashFreeDevicePercentagesMethod;
    this._distributionReleaseCounts = _distributionReleaseCounts;
    this._eventsDeleteLogs = _eventsDeleteLogs;
    this._eventsMethod = _eventsMethod;
    this._eventsDelete = _eventsDelete;
    this._eventPerDeviceCount = _eventPerDeviceCount;
    this._eventPerSessionCount = _eventPerSessionCount;
    this._eventDeviceCountMethod = _eventDeviceCountMethod;
    this._eventCountMethod = _eventCountMethod;
    this._eventPropertiesMethod = _eventPropertiesMethod;
    this._eventPropertyCounts = _eventPropertyCounts;
    this._genericLogFlow = _genericLogFlow;
    this._languageCounts = _languageCounts;
    this._logFlow = _logFlow;
    this._modelCounts = _modelCounts;
    this._operatingSystemCounts = _operatingSystemCounts;
    this._placeCounts = _placeCounts;
    this._sessionCounts = _sessionCounts;
    this._sessionDurationsDistributionMethod = _sessionDurationsDistributionMethod;
    this._perDeviceCounts = _perDeviceCounts;
    this._versionsMethod = _versionsMethod;
    this._errorGroupList = _errorGroupList;
    this._errorCountsPerDay = _errorCountsPerDay;
    this._errorGroupDetails = _errorGroupDetails;
    this._errorGroupCountsPerDay = _errorGroupCountsPerDay;
  }

  /**
   * Count of active devices by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ActiveDeviceCounts>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  deviceCountsWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deviceCounts(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of active devices by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {ActiveDeviceCounts} - 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 ActiveDeviceCounts} 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.
   */
  deviceCounts(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deviceCounts(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deviceCounts(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Get list of audiences.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {boolean} [options.includeDisabled] Include disabled audience
   * definitions
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<AudienceListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listAudiencesWithHttpOperationResponse(appName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listAudiences(appName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Get list of audiences.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {boolean} [options.includeDisabled] Include disabled audience
   * definitions
   *
   * @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 {AudienceListResult} - 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 AudienceListResult} 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.
   */
  listAudiences(appName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._listAudiences(appName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listAudiences(appName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Tests audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {object} audience Audience definition
   *
   * @param {string} [audience.description] Audience description.
   *
   * @param {string} audience.definition Audience definition in OData format.
   *
   * @param {boolean} [audience.enabled]
   *
   * @param {object} [audience.customProperties] Custom properties used in the
   * definition.
   *
   * @param {string} ownerName The name of the owner
   *
   * @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<AudienceTestResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  testAudienceWithHttpOperationResponse(appName, audience, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._testAudience(appName, audience, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Tests audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {object} audience Audience definition
   *
   * @param {string} [audience.description] Audience description.
   *
   * @param {string} audience.definition Audience definition in OData format.
   *
   * @param {boolean} [audience.enabled]
   *
   * @param {object} [audience.customProperties] Custom properties used in the
   * definition.
   *
   * @param {string} ownerName The name of the owner
   *
   * @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 {AudienceTestResult} - 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 AudienceTestResult} 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.
   */
  testAudience(appName, audience, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._testAudience(appName, audience, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._testAudience(appName, audience, ownerName, options, optionalCallback);
    }
  }

  /**
   * Get list of custom properties.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @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<AudienceDevicePropertiesListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listCustomPropertiesWithHttpOperationResponse(appName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listCustomProperties(appName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Get list of custom properties.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @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 {AudienceDevicePropertiesListResult} - 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 AudienceDevicePropertiesListResult} 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.
   */
  listCustomProperties(appName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._listCustomProperties(appName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listCustomProperties(appName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Get list of device properties.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @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<AudienceDevicePropertiesListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listDevicePropertiesWithHttpOperationResponse(appName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listDeviceProperties(appName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Get list of device properties.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @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 {AudienceDevicePropertiesListResult} - 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 AudienceDevicePropertiesListResult} 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.
   */
  listDeviceProperties(appName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._listDeviceProperties(appName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listDeviceProperties(appName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Get list of device property values.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} propertyName Device property
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.contains] Contains string
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<AudienceDevicePropertyValuesListResult>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  listDevicePropertyValuesWithHttpOperationResponse(appName, ownerName, propertyName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._listDevicePropertyValues(appName, ownerName, propertyName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Get list of device property values.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} propertyName Device property
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.contains] Contains string
   *
   * @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 {AudienceDevicePropertyValuesListResult} - 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 AudienceDevicePropertyValuesListResult} 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.
   */
  listDevicePropertyValues(appName, ownerName, propertyName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._listDevicePropertyValues(appName, ownerName, propertyName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._listDevicePropertyValues(appName, ownerName, propertyName, options, optionalCallback);
    }
  }

  /**
   * Returns whether audience definition exists.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  audienceNameExistsWithHttpOperationResponse(appName, audienceName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._audienceNameExists(appName, audienceName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Returns whether audience definition exists.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  audienceNameExists(appName, audienceName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._audienceNameExists(appName, audienceName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._audienceNameExists(appName, audienceName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Deletes audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  deleteAudienceWithHttpOperationResponse(appName, audienceName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._deleteAudience(appName, audienceName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Deletes audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  deleteAudience(appName, audienceName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._deleteAudience(appName, audienceName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._deleteAudience(appName, audienceName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Gets audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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<Audience>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  getAudienceWithHttpOperationResponse(appName, audienceName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._getAudience(appName, audienceName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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 {Audience} - 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 Audience} 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.
   */
  getAudience(appName, audienceName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._getAudience(appName, audienceName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._getAudience(appName, audienceName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Creates or updates audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {object} audience Audience definition
   *
   * @param {string} [audience.description] Audience description.
   *
   * @param {string} audience.definition Audience definition in OData format.
   *
   * @param {boolean} [audience.enabled]
   *
   * @param {object} [audience.customProperties] Custom properties used in the
   * definition.
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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<Audience>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  createOrUpdateAudienceWithHttpOperationResponse(appName, audience, audienceName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._createOrUpdateAudience(appName, audience, audienceName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Creates or updates audience definition.
   *
   * @param {string} appName The name of the application
   *
   * @param {object} audience Audience definition
   *
   * @param {string} [audience.description] Audience description.
   *
   * @param {string} audience.definition Audience definition in OData format.
   *
   * @param {boolean} [audience.enabled]
   *
   * @param {object} [audience.customProperties] Custom properties used in the
   * definition.
   *
   * @param {string} audienceName The name of the audience
   *
   * @param {string} ownerName The name of the owner
   *
   * @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 {Audience} - 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 Audience} 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.
   */
  createOrUpdateAudience(appName, audience, audienceName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._createOrUpdateAudience(appName, audience, audienceName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._createOrUpdateAudience(appName, audience, audienceName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Count of crashes by day in the time range based the selected versions.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<CrashCounts>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  crashCountsMethodWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._crashCountsMethod(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of crashes by day in the time range based the selected versions.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {CrashCounts} - 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 CrashCounts} 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.
   */
  crashCountsMethod(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._crashCountsMethod(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._crashCountsMethod(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Overall crashes and affected users count of the selected crash groups with
   * selected versions
   *
   * @param {string} appName The name of the application
   *
   * @param {object} crashGroups
   *
   * @param {array} crashGroups.crashGroups
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  crashGroupsTotalsWithHttpOperationResponse(appName, crashGroups, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._crashGroupsTotals(appName, crashGroups, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Overall crashes and affected users count of the selected crash groups with
   * selected versions
   *
   * @param {string} appName The name of the application
   *
   * @param {object} crashGroups
   *
   * @param {array} crashGroups.crashGroups
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  crashGroupsTotals(appName, crashGroups, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._crashGroupsTotals(appName, crashGroups, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._crashGroupsTotals(appName, crashGroups, ownerName, options, optionalCallback);
    }
  }

  /**
   * Count of crashes by day in the time range of the selected crash group with
   * selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {string} version
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<CrashCounts>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  crashGroupCountsWithHttpOperationResponse(appName, crashGroupId, ownerName, start, version, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._crashGroupCounts(appName, crashGroupId, ownerName, start, version, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of crashes by day in the time range of the selected crash group with
   * selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {string} version
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @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 {CrashCounts} - 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 CrashCounts} 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.
   */
  crashGroupCounts(appName, crashGroupId, ownerName, start, version, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._crashGroupCounts(appName, crashGroupId, ownerName, start, version, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._crashGroupCounts(appName, crashGroupId, ownerName, start, version, options, optionalCallback);
    }
  }

  /**
   * top models of the selected crash group with selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} version
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<CrashGroupModels>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  crashGroupModelCountsWithHttpOperationResponse(appName, crashGroupId, ownerName, version, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._crashGroupModelCounts(appName, crashGroupId, ownerName, version, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * top models of the selected crash group with selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} version
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @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 {CrashGroupModels} - 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 CrashGroupModels} 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.
   */
  crashGroupModelCounts(appName, crashGroupId, ownerName, version, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._crashGroupModelCounts(appName, crashGroupId, ownerName, version, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._crashGroupModelCounts(appName, crashGroupId, ownerName, version, options, optionalCallback);
    }
  }

  /**
   * top OSes of the selected crash group with selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} version
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<CrashGroupOperatingSystems>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  crashGroupOperatingSystemCountsWithHttpOperationResponse(appName, crashGroupId, ownerName, version, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._crashGroupOperatingSystemCounts(appName, crashGroupId, ownerName, version, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * top OSes of the selected crash group with selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} version
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @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 {CrashGroupOperatingSystems} - 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 CrashGroupOperatingSystems} 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.
   */
  crashGroupOperatingSystemCounts(appName, crashGroupId, ownerName, version, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._crashGroupOperatingSystemCounts(appName, crashGroupId, ownerName, version, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._crashGroupOperatingSystemCounts(appName, crashGroupId, ownerName, version, options, optionalCallback);
    }
  }

  /**
   * Overall crashes and affected users count of the selected crash group with
   * selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} version
   *
   * @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<CrashOverall>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  crashGroupTotalsWithHttpOperationResponse(appName, crashGroupId, ownerName, version, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._crashGroupTotals(appName, crashGroupId, ownerName, version, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Overall crashes and affected users count of the selected crash group with
   * selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} crashGroupId The id of the crash group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {string} version
   *
   * @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 {CrashOverall} - 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 CrashOverall} 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.
   */
  crashGroupTotals(appName, crashGroupId, ownerName, version, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._crashGroupTotals(appName, crashGroupId, ownerName, version, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._crashGroupTotals(appName, crashGroupId, ownerName, version, options, optionalCallback);
    }
  }

  /**
   * Percentage of crash-free device by day in the time range based on the
   * selected versions. Api will return -1 if crash devices is greater than
   * active devices
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<CrashFreeDevicePercentages>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  crashFreeDevicePercentagesMethodWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._crashFreeDevicePercentagesMethod(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Percentage of crash-free device by day in the time range based on the
   * selected versions. Api will return -1 if crash devices is greater than
   * active devices
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {CrashFreeDevicePercentages} - 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 CrashFreeDevicePercentages} 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.
   */
  crashFreeDevicePercentagesMethod(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._crashFreeDevicePercentagesMethod(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._crashFreeDevicePercentagesMethod(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of total downloads for the provided distribution releases.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} releases The releases to retrieve.
   *
   * @param {array} releases.releases
   *
   * @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<ReleaseCounts>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  distributionReleaseCountsWithHttpOperationResponse(appName, ownerName, releases, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._distributionReleaseCounts(appName, ownerName, releases, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of total downloads for the provided distribution releases.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} releases The releases to retrieve.
   *
   * @param {array} releases.releases
   *
   * @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 {ReleaseCounts} - 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 ReleaseCounts} 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.
   */
  distributionReleaseCounts(appName, ownerName, releases, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._distributionReleaseCounts(appName, ownerName, releases, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._distributionReleaseCounts(appName, ownerName, releases, options, optionalCallback);
    }
  }

  /**
   * Delete the set of Events with the specified event names
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  eventsDeleteLogsWithHttpOperationResponse(appName, eventName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventsDeleteLogs(appName, eventName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Delete the set of Events with the specified event names
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  eventsDeleteLogs(appName, eventName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventsDeleteLogs(appName, eventName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventsDeleteLogs(appName, eventName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Count of active events in the time range ordered by event.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.inlinecount] Controls whether or not to include a
   * count of all the items accross all pages. Possible values include:
   * 'allpages', 'none'
   *
   * @param {string} [options.orderby] controls the sorting order and sorting
   * based on which column
   *
   * @param {number} [options.skip] The offset (starting at 0) of the first
   * result to return. This parameter along with limit is used to perform
   * pagination.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.eventName] to select the specific events
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Events>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  eventsMethodWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventsMethod(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of active events in the time range ordered by event.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.inlinecount] Controls whether or not to include a
   * count of all the items accross all pages. Possible values include:
   * 'allpages', 'none'
   *
   * @param {string} [options.orderby] controls the sorting order and sorting
   * based on which column
   *
   * @param {number} [options.skip] The offset (starting at 0) of the first
   * result to return. This parameter along with limit is used to perform
   * pagination.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.eventName] to select the specific events
   *
   * @param {array} [options.versions]
   *
   * @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 {Events} - 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 Events} 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.
   */
  eventsMethod(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventsMethod(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventsMethod(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Delete the set of Events with the specified event names
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  eventsDeleteWithHttpOperationResponse(appName, eventName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventsDelete(appName, eventName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Delete the set of Events with the specified event names
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @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.
   */
  eventsDelete(appName, eventName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventsDelete(appName, eventName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventsDelete(appName, eventName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Count of events per device by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<EventCountPerDevice>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  eventPerDeviceCountWithHttpOperationResponse(appName, eventName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventPerDeviceCount(appName, eventName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of events per device by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {EventCountPerDevice} - 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 EventCountPerDevice} 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.
   */
  eventPerDeviceCount(appName, eventName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventPerDeviceCount(appName, eventName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventPerDeviceCount(appName, eventName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of events per session by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<EventCountPerSession>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  eventPerSessionCountWithHttpOperationResponse(appName, eventName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventPerSessionCount(appName, eventName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of events per session by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {EventCountPerSession} - 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 EventCountPerSession} 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.
   */
  eventPerSessionCount(appName, eventName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventPerSessionCount(appName, eventName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventPerSessionCount(appName, eventName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of devices for an event by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<EventDeviceCount>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  eventDeviceCountMethodWithHttpOperationResponse(appName, eventName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventDeviceCountMethod(appName, eventName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of devices for an event by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {EventDeviceCount} - 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 EventDeviceCount} 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.
   */
  eventDeviceCountMethod(appName, eventName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventDeviceCountMethod(appName, eventName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventDeviceCountMethod(appName, eventName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of events by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<EventCount>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  eventCountMethodWithHttpOperationResponse(appName, eventName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventCountMethod(appName, eventName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of events by interval in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {EventCount} - 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 EventCount} 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.
   */
  eventCountMethod(appName, eventName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventCountMethod(appName, eventName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventCountMethod(appName, eventName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Event properties.  Up to the first 5 received properties.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @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<EventProperties>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  eventPropertiesMethodWithHttpOperationResponse(appName, eventName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventPropertiesMethod(appName, eventName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Event properties.  Up to the first 5 received properties.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} ownerName The name of the owner
   *
   * @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 {EventProperties} - 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 EventProperties} 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.
   */
  eventPropertiesMethod(appName, eventName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventPropertiesMethod(appName, eventName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventPropertiesMethod(appName, eventName, ownerName, options, optionalCallback);
    }
  }

  /**
   * Event properties value counts during the time range in descending order.
   * Limited up to 5 values.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} eventPropertyName The id of the event property
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.count] The number of property values to return
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<EventPropertyValues>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  eventPropertyCountsWithHttpOperationResponse(appName, eventName, eventPropertyName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._eventPropertyCounts(appName, eventName, eventPropertyName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Event properties value counts during the time range in descending order.
   * Limited up to 5 values.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} eventName The id of the event
   *
   * @param {string} eventPropertyName The id of the event property
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.count] The number of property values to return
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {EventPropertyValues} - 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 EventPropertyValues} 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.
   */
  eventPropertyCounts(appName, eventName, eventPropertyName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._eventPropertyCounts(appName, eventName, eventPropertyName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._eventPropertyCounts(appName, eventName, eventPropertyName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Logs received between the specified start time and the current time. The API
   * will return a maximum of 100 logs per call.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.start] Start date time in data in ISO 8601 date time
   * format. It must be within the current day in the UTC timezone. The default
   * value is the start time of the current day in UTC timezone.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<LogFlowGenericLogContainer>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  genericLogFlowWithHttpOperationResponse(appName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._genericLogFlow(appName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Logs received between the specified start time and the current time. The API
   * will return a maximum of 100 logs per call.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.start] Start date time in data in ISO 8601 date time
   * format. It must be within the current day in the UTC timezone. The default
   * value is the start time of the current day in UTC timezone.
   *
   * @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 {LogFlowGenericLogContainer} - 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 LogFlowGenericLogContainer} 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.
   */
  genericLogFlow(appName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._genericLogFlow(appName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._genericLogFlow(appName, ownerName, options, optionalCallback);
    }
  }

  /**
   * languages in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Languages>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  languageCountsWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._languageCounts(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * languages in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {Languages} - 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 Languages} 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.
   */
  languageCounts(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._languageCounts(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._languageCounts(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Logs received between the specified start time and the current time. The API
   * will return a maximum of 100 logs per call.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.start] Start date time in data in ISO 8601 date time
   * format. It must be within the current day in the UTC timezone. The default
   * value is the start time of the current day in UTC timezone.
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<LogFlowLogContainer>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  logFlowWithHttpOperationResponse(appName, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._logFlow(appName, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Logs received between the specified start time and the current time. The API
   * will return a maximum of 100 logs per call.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.start] Start date time in data in ISO 8601 date time
   * format. It must be within the current day in the UTC timezone. The default
   * value is the start time of the current day in UTC timezone.
   *
   * @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 {LogFlowLogContainer} - 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 LogFlowLogContainer} 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.
   */
  logFlow(appName, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._logFlow(appName, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._logFlow(appName, ownerName, options, optionalCallback);
    }
  }

  /**
   * models in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<AnalyticsModels>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  modelCountsWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._modelCounts(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * models in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {AnalyticsModels} - 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 AnalyticsModels} 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.
   */
  modelCounts(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._modelCounts(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._modelCounts(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * OSes in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<OSes>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  operatingSystemCountsWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._operatingSystemCounts(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * OSes in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {OSes} - 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 OSes} 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.
   */
  operatingSystemCounts(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._operatingSystemCounts(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._operatingSystemCounts(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Places in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Places>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  placeCountsWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._placeCounts(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Places in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {Places} - 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 Places} 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.
   */
  placeCounts(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._placeCounts(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._placeCounts(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of sessions in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} interval Size of interval in ISO 8601 duration format.
   * (PnYnMnDTnHnMnS|PnW|P<date>T<time>). The valid durations are 1 day (P1D), 1
   * week (P1W), and 30 days (P30D).
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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.
   */
  sessionCountsWithHttpOperationResponse(appName, interval, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._sessionCounts(appName, interval, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of sessions in the time range.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} interval Size of interval in ISO 8601 duration format.
   * (PnYnMnDTnHnMnS|PnW|P<date>T<time>). The valid durations are 1 day (P1D), 1
   * week (P1W), and 30 days (P30D).
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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.
   */
  sessionCounts(appName, interval, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._sessionCounts(appName, interval, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._sessionCounts(appName, interval, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Gets session duration .
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<SessionDurationsDistribution>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  sessionDurationsDistributionMethodWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._sessionDurationsDistributionMethod(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Gets session duration .
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {SessionDurationsDistribution} - 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 SessionDurationsDistribution} 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.
   */
  sessionDurationsDistributionMethod(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._sessionDurationsDistributionMethod(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._sessionDurationsDistributionMethod(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of sessions per device in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} interval Size of interval in ISO 8601 duration format.
   * (PnYnMnDTnHnMnS|PnW|P<date>T<time>). The valid durations are 1 day (P1D), 1
   * week (P1W), and 30 days (P30D).
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<SessionsPerDevice>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  perDeviceCountsWithHttpOperationResponse(appName, interval, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._perDeviceCounts(appName, interval, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of sessions per device in the time range
   *
   * @param {string} appName The name of the application
   *
   * @param {string} interval Size of interval in ISO 8601 duration format.
   * (PnYnMnDTnHnMnS|PnW|P<date>T<time>). The valid durations are 1 day (P1D), 1
   * week (P1W), and 30 days (P30D).
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {SessionsPerDevice} - 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 SessionsPerDevice} 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.
   */
  perDeviceCounts(appName, interval, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._perDeviceCounts(appName, interval, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._perDeviceCounts(appName, interval, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of active versions in the time range ordered by version.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<Versions>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  versionsMethodWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._versionsMethod(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of active versions in the time range ordered by version.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {array} [options.versions]
   *
   * @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 {Versions} - 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 Versions} 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.
   */
  versionsMethod(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._versionsMethod(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._versionsMethod(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * List of error groups
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.orderby] controls the sorting order and sorting
   * based on which column
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {string} [options.groupStatus]
   *
   * @param {string} [options.version]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ErrorGroups>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  errorGroupListWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._errorGroupList(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * List of error groups
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {string} [options.orderby] controls the sorting order and sorting
   * based on which column
   *
   * @param {number} [options.top] The maximum number of results to return. (0
   * will fetch all results)
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {string} [options.groupStatus]
   *
   * @param {string} [options.version]
   *
   * @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 {ErrorGroups} - 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 ErrorGroups} 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.
   */
  errorGroupList(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._errorGroupList(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._errorGroupList(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Count of errors by day in the time range based the selected versions.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {string} [options.groupStatus]
   *
   * @param {string} [options.version]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ErrorCounts>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  errorCountsPerDayWithHttpOperationResponse(appName, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._errorCountsPerDay(appName, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of errors by day in the time range based the selected versions.
   *
   * @param {string} appName The name of the application
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {string} [options.groupStatus]
   *
   * @param {string} [options.version]
   *
   * @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 {ErrorCounts} - 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 ErrorCounts} 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.
   */
  errorCountsPerDay(appName, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._errorCountsPerDay(appName, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._errorCountsPerDay(appName, ownerName, start, options, optionalCallback);
    }
  }

  /**
   * Error group details
   *
   * @param {string} appName The name of the application
   *
   * @param {string} errorGroupId The id of the error group
   *
   * @param {string} model
   *
   * @param {string} os
   *
   * @param {string} ownerName The name of the owner
   *
   * @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<ErrorGroup>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  errorGroupDetailsWithHttpOperationResponse(appName, errorGroupId, model, os, ownerName, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._errorGroupDetails(appName, errorGroupId, model, os, ownerName, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Error group details
   *
   * @param {string} appName The name of the application
   *
   * @param {string} errorGroupId The id of the error group
   *
   * @param {string} model
   *
   * @param {string} os
   *
   * @param {string} ownerName The name of the owner
   *
   * @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 {ErrorGroup} - 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 ErrorGroup} 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.
   */
  errorGroupDetails(appName, errorGroupId, model, os, ownerName, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._errorGroupDetails(appName, errorGroupId, model, os, ownerName, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._errorGroupDetails(appName, errorGroupId, model, os, ownerName, options, optionalCallback);
    }
  }

  /**
   * Count of errors by day in the time range of the selected error group with
   * selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} errorGroupId The id of the error group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {string} [options.version]
   *
   * @param {object} [options.customHeaders] Headers that will be added to the
   * request
   *
   * @returns {Promise} A promise is returned
   *
   * @resolve {HttpOperationResponse<ErrorCounts>} - The deserialized result object.
   *
   * @reject {Error} - The error object.
   */
  errorGroupCountsPerDayWithHttpOperationResponse(appName, errorGroupId, ownerName, start, options) {
    let client = this.client;
    let self = this;
    return new Promise((resolve, reject) => {
      self._errorGroupCountsPerDay(appName, errorGroupId, ownerName, start, options, (err, result, request, response) => {
        let httpOperationResponse = new msRest.HttpOperationResponse(request, response);
        httpOperationResponse.body = result;
        if (err) { reject(err); }
        else { resolve(httpOperationResponse); }
        return;
      });
    });
  }

  /**
   * Count of errors by day in the time range of the selected error group with
   * selected version
   *
   * @param {string} appName The name of the application
   *
   * @param {string} errorGroupId The id of the error group
   *
   * @param {string} ownerName The name of the owner
   *
   * @param {date} start Start date time in data in ISO 8601 date time format
   *
   * @param {object} [options] Optional Parameters.
   *
   * @param {date} [options.end] Last date time in data in ISO 8601 date time
   * format
   *
   * @param {string} [options.version]
   *
   * @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 {ErrorCounts} - 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 ErrorCounts} 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.
   */
  errorGroupCountsPerDay(appName, errorGroupId, ownerName, start, options, optionalCallback) {
    let client = this.client;
    let self = this;
    if (!optionalCallback && typeof options === 'function') {
      optionalCallback = options;
      options = null;
    }
    if (!optionalCallback) {
      return new Promise((resolve, reject) => {
        self._errorGroupCountsPerDay(appName, errorGroupId, ownerName, start, options, (err, result, request, response) => {
          if (err) { reject(err); }
          else { resolve(result); }
          return;
        });
      });
    } else {
      return self._errorGroupCountsPerDay(appName, errorGroupId, ownerName, start, options, optionalCallback);
    }
  }

}

module.exports = Analytics;
