library googleapis.analytics.v3;

import "dart:core" as core;
import "dart:collection" as collection;
import "dart:async" as async;
import "dart:convert" as convert;

import "package:crypto/crypto.dart" as crypto;
import 'package:http/http.dart' as http;
import '../src/common_internal.dart' as common_internal;
import '../common/common.dart' as common;

export '../common/common.dart' show ApiRequestError;
export '../common/common.dart' show DetailedApiRequestError;

/** View and manage your Google Analytics data */
class AnalyticsApi {
  /** View and manage your Google Analytics data */
  static const AnalyticsScope = "https://www.googleapis.com/auth/analytics";

  /** Edit Google Analytics management entities */
  static const AnalyticsEditScope = "https://www.googleapis.com/auth/analytics.edit";

  /** Manage Google Analytics Account users by email address */
  static const AnalyticsManageUsersScope = "https://www.googleapis.com/auth/analytics.manage.users";

  /**
   * Create a new Google Analytics account along with its default property and
   * view
   */
  static const AnalyticsProvisionScope = "https://www.googleapis.com/auth/analytics.provision";

  /** View your Google Analytics data */
  static const AnalyticsReadonlyScope = "https://www.googleapis.com/auth/analytics.readonly";


  final common_internal.ApiRequester _requester;

  DataResourceApi get data => new DataResourceApi(_requester);
  ManagementResourceApi get management => new ManagementResourceApi(_requester);
  MetadataResourceApi get metadata => new MetadataResourceApi(_requester);
  ProvisioningResourceApi get provisioning => new ProvisioningResourceApi(_requester);

  AnalyticsApi(http.Client client) : 
      _requester = new common_internal.ApiRequester(client, "https://www.googleapis.com/", "analytics/v3/");
}


/** Not documented yet. */
class DataResourceApi {
  final common_internal.ApiRequester _requester;

  DataGaResourceApi get ga => new DataGaResourceApi(_requester);
  DataMcfResourceApi get mcf => new DataMcfResourceApi(_requester);
  DataRealtimeResourceApi get realtime => new DataRealtimeResourceApi(_requester);

  DataResourceApi(common_internal.ApiRequester client) : 
      _requester = client;
}


/** Not documented yet. */
class DataGaResourceApi {
  final common_internal.ApiRequester _requester;

  DataGaResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Returns Analytics data for a view (profile).
   *
   * Request parameters:
   *
   * [ids] - Unique table ID for retrieving Analytics data. Table ID is of the
   * form ga:XXXX, where XXXX is the Analytics view (profile) ID.
   * Value must have pattern "ga:[0-9]+".
   *
   * [start_date] - Start date for fetching Analytics data. Requests can specify
   * a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today,
   * yesterday, or 7daysAgo). The default value is 7daysAgo.
   * Value must have pattern
   * "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)".
   *
   * [end_date] - End date for fetching Analytics data. Request can should
   * specify an end date formatted as YYYY-MM-DD, or as a relative date (e.g.,
   * today, yesterday, or 7daysAgo). The default value is yesterday.
   * Value must have pattern
   * "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)".
   *
   * [metrics] - A comma-separated list of Analytics metrics. E.g.,
   * 'ga:sessions,ga:pageviews'. At least one metric must be specified.
   * Value must have pattern "ga:.+".
   *
   * [dimensions] - A comma-separated list of Analytics dimensions. E.g.,
   * 'ga:browser,ga:city'.
   * Value must have pattern "(ga:.+)?".
   *
   * [filters] - A comma-separated list of dimension or metric filters to be
   * applied to Analytics data.
   * Value must have pattern "ga:.+".
   *
   * [max_results] - The maximum number of entries to include in this feed.
   *
   * [output] - The selected format for the response. Default format is JSON.
   * Possible string values are:
   * - "dataTable" : Returns the response in Google Charts Data Table format.
   * This is useful in creating visualization using Google Charts.
   * - "json" : Returns the response in standard JSON format.
   *
   * [samplingLevel] - The desired sampling level.
   * Possible string values are:
   * - "DEFAULT" : Returns response with a sample size that balances speed and
   * accuracy.
   * - "FASTER" : Returns a fast response with a smaller sample size.
   * - "HIGHER_PRECISION" : Returns a more accurate response using a large
   * sample size, but this may result in the response being slower.
   *
   * [segment] - An Analytics segment to be applied to data.
   *
   * [sort] - A comma-separated list of dimensions or metrics that determine the
   * sort order for Analytics data.
   * Value must have pattern "(-)?ga:.+".
   *
   * [start_index] - An index of the first entity to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [GaData].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<GaData> get(core.String ids, core.String start_date, core.String end_date, core.String metrics, {core.String dimensions, core.String filters, core.int max_results, core.String output, core.String samplingLevel, core.String segment, core.String sort, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (ids == null) {
      throw new core.ArgumentError("Parameter ids is required.");
    }
    _queryParams["ids"] = [ids];
    if (start_date == null) {
      throw new core.ArgumentError("Parameter start_date is required.");
    }
    _queryParams["start-date"] = [start_date];
    if (end_date == null) {
      throw new core.ArgumentError("Parameter end_date is required.");
    }
    _queryParams["end-date"] = [end_date];
    if (metrics == null) {
      throw new core.ArgumentError("Parameter metrics is required.");
    }
    _queryParams["metrics"] = [metrics];
    if (dimensions != null) {
      _queryParams["dimensions"] = [dimensions];
    }
    if (filters != null) {
      _queryParams["filters"] = [filters];
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (output != null) {
      _queryParams["output"] = [output];
    }
    if (samplingLevel != null) {
      _queryParams["samplingLevel"] = [samplingLevel];
    }
    if (segment != null) {
      _queryParams["segment"] = [segment];
    }
    if (sort != null) {
      _queryParams["sort"] = [sort];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'data/ga';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new GaData.fromJson(data));
  }

}


/** Not documented yet. */
class DataMcfResourceApi {
  final common_internal.ApiRequester _requester;

  DataMcfResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Returns Analytics Multi-Channel Funnels data for a view (profile).
   *
   * Request parameters:
   *
   * [ids] - Unique table ID for retrieving Analytics data. Table ID is of the
   * form ga:XXXX, where XXXX is the Analytics view (profile) ID.
   * Value must have pattern "ga:[0-9]+".
   *
   * [start_date] - Start date for fetching Analytics data. Requests can specify
   * a start date formatted as YYYY-MM-DD, or as a relative date (e.g., today,
   * yesterday, or 7daysAgo). The default value is 7daysAgo.
   * Value must have pattern
   * "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)".
   *
   * [end_date] - End date for fetching Analytics data. Requests can specify a
   * start date formatted as YYYY-MM-DD, or as a relative date (e.g., today,
   * yesterday, or 7daysAgo). The default value is 7daysAgo.
   * Value must have pattern
   * "[0-9]{4}-[0-9]{2}-[0-9]{2}|today|yesterday|[0-9]+(daysAgo)".
   *
   * [metrics] - A comma-separated list of Multi-Channel Funnels metrics. E.g.,
   * 'mcf:totalConversions,mcf:totalConversionValue'. At least one metric must
   * be specified.
   * Value must have pattern "mcf:.+".
   *
   * [dimensions] - A comma-separated list of Multi-Channel Funnels dimensions.
   * E.g., 'mcf:source,mcf:medium'.
   * Value must have pattern "(mcf:.+)?".
   *
   * [filters] - A comma-separated list of dimension or metric filters to be
   * applied to the Analytics data.
   * Value must have pattern "mcf:.+".
   *
   * [max_results] - The maximum number of entries to include in this feed.
   *
   * [samplingLevel] - The desired sampling level.
   * Possible string values are:
   * - "DEFAULT" : Returns response with a sample size that balances speed and
   * accuracy.
   * - "FASTER" : Returns a fast response with a smaller sample size.
   * - "HIGHER_PRECISION" : Returns a more accurate response using a large
   * sample size, but this may result in the response being slower.
   *
   * [sort] - A comma-separated list of dimensions or metrics that determine the
   * sort order for the Analytics data.
   * Value must have pattern "(-)?mcf:.+".
   *
   * [start_index] - An index of the first entity to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [McfData].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<McfData> get(core.String ids, core.String start_date, core.String end_date, core.String metrics, {core.String dimensions, core.String filters, core.int max_results, core.String samplingLevel, core.String sort, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (ids == null) {
      throw new core.ArgumentError("Parameter ids is required.");
    }
    _queryParams["ids"] = [ids];
    if (start_date == null) {
      throw new core.ArgumentError("Parameter start_date is required.");
    }
    _queryParams["start-date"] = [start_date];
    if (end_date == null) {
      throw new core.ArgumentError("Parameter end_date is required.");
    }
    _queryParams["end-date"] = [end_date];
    if (metrics == null) {
      throw new core.ArgumentError("Parameter metrics is required.");
    }
    _queryParams["metrics"] = [metrics];
    if (dimensions != null) {
      _queryParams["dimensions"] = [dimensions];
    }
    if (filters != null) {
      _queryParams["filters"] = [filters];
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (samplingLevel != null) {
      _queryParams["samplingLevel"] = [samplingLevel];
    }
    if (sort != null) {
      _queryParams["sort"] = [sort];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'data/mcf';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new McfData.fromJson(data));
  }

}


/** Not documented yet. */
class DataRealtimeResourceApi {
  final common_internal.ApiRequester _requester;

  DataRealtimeResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Returns real time data for a view (profile).
   *
   * Request parameters:
   *
   * [ids] - Unique table ID for retrieving real time data. Table ID is of the
   * form ga:XXXX, where XXXX is the Analytics view (profile) ID.
   * Value must have pattern "ga:[0-9]+".
   *
   * [metrics] - A comma-separated list of real time metrics. E.g.,
   * 'rt:activeUsers'. At least one metric must be specified.
   * Value must have pattern "(ga:.+)|(rt:.+)".
   *
   * [dimensions] - A comma-separated list of real time dimensions. E.g.,
   * 'rt:medium,rt:city'.
   * Value must have pattern "(ga:.+)|(rt:.+)".
   *
   * [filters] - A comma-separated list of dimension or metric filters to be
   * applied to real time data.
   * Value must have pattern "(ga:.+)|(rt:.+)".
   *
   * [max_results] - The maximum number of entries to include in this feed.
   *
   * [sort] - A comma-separated list of dimensions or metrics that determine the
   * sort order for real time data.
   * Value must have pattern "(-)?((ga:.+)|(rt:.+))".
   *
   * Completes with a [RealtimeData].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<RealtimeData> get(core.String ids, core.String metrics, {core.String dimensions, core.String filters, core.int max_results, core.String sort}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (ids == null) {
      throw new core.ArgumentError("Parameter ids is required.");
    }
    _queryParams["ids"] = [ids];
    if (metrics == null) {
      throw new core.ArgumentError("Parameter metrics is required.");
    }
    _queryParams["metrics"] = [metrics];
    if (dimensions != null) {
      _queryParams["dimensions"] = [dimensions];
    }
    if (filters != null) {
      _queryParams["filters"] = [filters];
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (sort != null) {
      _queryParams["sort"] = [sort];
    }


    _url = 'data/realtime';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new RealtimeData.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementAccountSummariesResourceApi get accountSummaries => new ManagementAccountSummariesResourceApi(_requester);
  ManagementAccountUserLinksResourceApi get accountUserLinks => new ManagementAccountUserLinksResourceApi(_requester);
  ManagementAccountsResourceApi get accounts => new ManagementAccountsResourceApi(_requester);
  ManagementCustomDataSourcesResourceApi get customDataSources => new ManagementCustomDataSourcesResourceApi(_requester);
  ManagementDailyUploadsResourceApi get dailyUploads => new ManagementDailyUploadsResourceApi(_requester);
  ManagementExperimentsResourceApi get experiments => new ManagementExperimentsResourceApi(_requester);
  ManagementFiltersResourceApi get filters => new ManagementFiltersResourceApi(_requester);
  ManagementGoalsResourceApi get goals => new ManagementGoalsResourceApi(_requester);
  ManagementProfileFilterLinksResourceApi get profileFilterLinks => new ManagementProfileFilterLinksResourceApi(_requester);
  ManagementProfileUserLinksResourceApi get profileUserLinks => new ManagementProfileUserLinksResourceApi(_requester);
  ManagementProfilesResourceApi get profiles => new ManagementProfilesResourceApi(_requester);
  ManagementSegmentsResourceApi get segments => new ManagementSegmentsResourceApi(_requester);
  ManagementUnsampledReportsResourceApi get unsampledReports => new ManagementUnsampledReportsResourceApi(_requester);
  ManagementUploadsResourceApi get uploads => new ManagementUploadsResourceApi(_requester);
  ManagementWebPropertyAdWordsLinksResourceApi get webPropertyAdWordsLinks => new ManagementWebPropertyAdWordsLinksResourceApi(_requester);
  ManagementWebpropertiesResourceApi get webproperties => new ManagementWebpropertiesResourceApi(_requester);
  ManagementWebpropertyUserLinksResourceApi get webpropertyUserLinks => new ManagementWebpropertyUserLinksResourceApi(_requester);

  ManagementResourceApi(common_internal.ApiRequester client) : 
      _requester = client;
}


/** Not documented yet. */
class ManagementAccountSummariesResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementAccountSummariesResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Lists account summaries (lightweight tree comprised of
   * accounts/properties/profiles) to which the user has access.
   *
   * Request parameters:
   *
   * [max_results] - The maximum number of account summaries to include in this
   * response, where the largest acceptable value is 1000.
   *
   * [start_index] - An index of the first entity to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [AccountSummaries].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<AccountSummaries> list({core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accountSummaries';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new AccountSummaries.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementAccountUserLinksResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementAccountUserLinksResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Removes a user from the given account.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to delete the user link for.
   *
   * [linkId] - Link ID to delete the user link for.
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/entityUserLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Adds a new user to the given account.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the user link for.
   *
   * Completes with a [EntityUserLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLink> insert(EntityUserLink request, core.String accountId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/entityUserLinks';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLink.fromJson(data));
  }

  /**
   * Lists account-user links for a given account.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve the user links for.
   *
   * [max_results] - The maximum number of account-user links to include in this
   * response.
   *
   * [start_index] - An index of the first account-user link to retrieve. Use
   * this parameter as a pagination mechanism along with the max-results
   * parameter.
   *
   * Completes with a [EntityUserLinks].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLinks> list(core.String accountId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/entityUserLinks';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLinks.fromJson(data));
  }

  /**
   * Updates permissions for an existing user on the given account.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to update the account-user link for.
   *
   * [linkId] - Link ID to update the account-user link for.
   *
   * Completes with a [EntityUserLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLink> update(EntityUserLink request, core.String accountId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/entityUserLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLink.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementAccountsResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementAccountsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Lists all accounts to which the user has access.
   *
   * Request parameters:
   *
   * [max_results] - The maximum number of accounts to include in this response.
   *
   * [start_index] - An index of the first account to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Accounts].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Accounts> list({core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Accounts.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementCustomDataSourcesResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementCustomDataSourcesResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * List custom data sources to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account Id for the custom data sources to retrieve.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id for the custom data sources to retrieve.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [max_results] - The maximum number of custom data sources to include in
   * this response.
   *
   * [start_index] - A 1-based index of the first custom data source to
   * retrieve. Use this parameter as a pagination mechanism along with the
   * max-results parameter.
   *
   * Completes with a [CustomDataSources].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<CustomDataSources> list(core.String accountId, core.String webPropertyId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new CustomDataSources.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementDailyUploadsResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementDailyUploadsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Delete uploaded data for the given date.
   *
   * Request parameters:
   *
   * [accountId] - Account Id associated with daily upload delete.
   * Value must have pattern "[0-9]+".
   *
   * [webPropertyId] - Web property Id associated with daily upload delete.
   * Value must have pattern "UA-[0-9]+-[0-9]+".
   *
   * [customDataSourceId] - Custom data source Id associated with daily upload
   * delete.
   *
   * [date] - Date for which data is to be deleted. Date should be formatted as
   * YYYY-MM-DD.
   * Value must have pattern "[0-9]{4}-[0-9]{2}-[0-9]{2}".
   *
   * [type] - Type of data for this delete.
   * Possible string values are:
   * - "cost" : Value for specifying cost data upload.
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String webPropertyId, core.String customDataSourceId, core.String date, core.String type) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }
    if (date == null) {
      throw new core.ArgumentError("Parameter date is required.");
    }
    if (type == null) {
      throw new core.ArgumentError("Parameter type is required.");
    }
    _queryParams["type"] = [type];

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/dailyUploads/' + common_internal.Escaper.ecapeVariable('$date');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * List daily uploads to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account Id for the daily uploads to retrieve.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id for the daily uploads to retrieve.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [customDataSourceId] - Custom data source Id for daily uploads to retrieve.
   * Value must have pattern ".{22}".
   *
   * [start_date] - Start date of the form YYYY-MM-DD.
   * Value must have pattern "[0-9]{4}-[0-9]{2}-[0-9]{2}".
   *
   * [end_date] - End date of the form YYYY-MM-DD.
   * Value must have pattern "[0-9]{4}-[0-9]{2}-[0-9]{2}".
   *
   * [max_results] - The maximum number of custom data sources to include in
   * this response.
   *
   * [start_index] - A 1-based index of the first daily upload to retrieve. Use
   * this parameter as a pagination mechanism along with the max-results
   * parameter.
   *
   * Completes with a [DailyUploads].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<DailyUploads> list(core.String accountId, core.String webPropertyId, core.String customDataSourceId, core.String start_date, core.String end_date, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }
    if (start_date == null) {
      throw new core.ArgumentError("Parameter start_date is required.");
    }
    _queryParams["start-date"] = [start_date];
    if (end_date == null) {
      throw new core.ArgumentError("Parameter end_date is required.");
    }
    _queryParams["end-date"] = [end_date];
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/dailyUploads';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new DailyUploads.fromJson(data));
  }

  /**
   * Update/Overwrite data for a custom data source.
   *
   * Request parameters:
   *
   * [accountId] - Account Id associated with daily upload.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id associated with daily upload.
   * Value must have pattern "UA-\d+-\d+".
   *
   * [customDataSourceId] - Custom data source Id to which the data being
   * uploaded belongs.
   *
   * [date] - Date for which data is uploaded. Date should be formatted as
   * YYYY-MM-DD.
   * Value must have pattern "[0-9]{4}-[0-9]{2}-[0-9]{2}".
   *
   * [appendNumber] - Append number for this upload indexed from 1.
   * Value must be between "1" and "20".
   *
   * [type] - Type of data for this upload.
   * Possible string values are:
   * - "cost" : Value for specifying cost data upload.
   *
   * [reset] - Reset/Overwrite all previous appends for this date and start over
   * with this file as the first upload.
   *
   * [uploadMedia] - The media to upload.
   *
   * [uploadOptions] - Options for the media upload. Streaming Media without the
   * length being known ahead of time is only supported via resumable uploads.
   *
   * Completes with a [DailyUploadAppend].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<DailyUploadAppend> upload(core.String accountId, core.String webPropertyId, core.String customDataSourceId, core.String date, core.int appendNumber, core.String type, {core.bool reset, common.UploadOptions uploadOptions : common.UploadOptions.Default, common.Media uploadMedia}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }
    if (date == null) {
      throw new core.ArgumentError("Parameter date is required.");
    }
    if (appendNumber == null) {
      throw new core.ArgumentError("Parameter appendNumber is required.");
    }
    _queryParams["appendNumber"] = ["${appendNumber}"];
    if (type == null) {
      throw new core.ArgumentError("Parameter type is required.");
    }
    _queryParams["type"] = [type];
    if (reset != null) {
      _queryParams["reset"] = ["${reset}"];
    }

    _uploadMedia =  uploadMedia;
    _uploadOptions =  uploadOptions;

    if (_uploadMedia == null) {
      _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/dailyUploads/' + common_internal.Escaper.ecapeVariable('$date') + '/uploads';
    } else if (_uploadOptions is common.ResumableUploadOptions) {
      _url = '/resumable/upload/analytics/v3/management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/dailyUploads/' + common_internal.Escaper.ecapeVariable('$date') + '/uploads';
    } else {
      _url = '/upload/analytics/v3/management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/dailyUploads/' + common_internal.Escaper.ecapeVariable('$date') + '/uploads';
    }


    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new DailyUploadAppend.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementExperimentsResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementExperimentsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Delete an experiment.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the experiment belongs
   *
   * [webPropertyId] - Web property ID to which the experiment belongs
   *
   * [profileId] - View (Profile) ID to which the experiment belongs
   *
   * [experimentId] - ID of the experiment to delete
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String webPropertyId, core.String profileId, core.String experimentId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (experimentId == null) {
      throw new core.ArgumentError("Parameter experimentId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/experiments/' + common_internal.Escaper.ecapeVariable('$experimentId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Returns an experiment to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve the experiment for.
   *
   * [webPropertyId] - Web property ID to retrieve the experiment for.
   *
   * [profileId] - View (Profile) ID to retrieve the experiment for.
   *
   * [experimentId] - Experiment ID to retrieve the experiment for.
   *
   * Completes with a [Experiment].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Experiment> get(core.String accountId, core.String webPropertyId, core.String profileId, core.String experimentId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (experimentId == null) {
      throw new core.ArgumentError("Parameter experimentId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/experiments/' + common_internal.Escaper.ecapeVariable('$experimentId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Experiment.fromJson(data));
  }

  /**
   * Create a new experiment.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the experiment for.
   *
   * [webPropertyId] - Web property ID to create the experiment for.
   *
   * [profileId] - View (Profile) ID to create the experiment for.
   *
   * Completes with a [Experiment].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Experiment> insert(Experiment request, core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/experiments';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Experiment.fromJson(data));
  }

  /**
   * Lists experiments to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve experiments for.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property ID to retrieve experiments for.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [profileId] - View (Profile) ID to retrieve experiments for.
   * Value must have pattern "\d+".
   *
   * [max_results] - The maximum number of experiments to include in this
   * response.
   *
   * [start_index] - An index of the first experiment to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Experiments].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Experiments> list(core.String accountId, core.String webPropertyId, core.String profileId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/experiments';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Experiments.fromJson(data));
  }

  /**
   * Update an existing experiment. This method supports patch semantics.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID of the experiment to update.
   *
   * [webPropertyId] - Web property ID of the experiment to update.
   *
   * [profileId] - View (Profile) ID of the experiment to update.
   *
   * [experimentId] - Experiment ID of the experiment to update.
   *
   * Completes with a [Experiment].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Experiment> patch(Experiment request, core.String accountId, core.String webPropertyId, core.String profileId, core.String experimentId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (experimentId == null) {
      throw new core.ArgumentError("Parameter experimentId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/experiments/' + common_internal.Escaper.ecapeVariable('$experimentId');

    var _response = _requester.request(_url,
                                       "PATCH",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Experiment.fromJson(data));
  }

  /**
   * Update an existing experiment.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID of the experiment to update.
   *
   * [webPropertyId] - Web property ID of the experiment to update.
   *
   * [profileId] - View (Profile) ID of the experiment to update.
   *
   * [experimentId] - Experiment ID of the experiment to update.
   *
   * Completes with a [Experiment].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Experiment> update(Experiment request, core.String accountId, core.String webPropertyId, core.String profileId, core.String experimentId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (experimentId == null) {
      throw new core.ArgumentError("Parameter experimentId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/experiments/' + common_internal.Escaper.ecapeVariable('$experimentId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Experiment.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementFiltersResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementFiltersResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Delete a filter.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to delete the filter for.
   *
   * [filterId] - ID of the filter to be deleted.
   *
   * Completes with a [Filter].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Filter> delete(core.String accountId, core.String filterId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (filterId == null) {
      throw new core.ArgumentError("Parameter filterId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/filters/' + common_internal.Escaper.ecapeVariable('$filterId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Filter.fromJson(data));
  }

  /**
   * Returns a filters to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve filters for.
   *
   * [filterId] - Filter ID to retrieve filters for.
   *
   * Completes with a [Filter].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Filter> get(core.String accountId, core.String filterId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (filterId == null) {
      throw new core.ArgumentError("Parameter filterId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/filters/' + common_internal.Escaper.ecapeVariable('$filterId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Filter.fromJson(data));
  }

  /**
   * Create a new filter.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create filter for.
   *
   * Completes with a [Filter].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Filter> insert(Filter request, core.String accountId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/filters';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Filter.fromJson(data));
  }

  /**
   * Lists all filters for an account
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve filters for.
   * Value must have pattern "\d+".
   *
   * [max_results] - The maximum number of filters to include in this response.
   *
   * [start_index] - An index of the first entity to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Filters].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Filters> list(core.String accountId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/filters';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Filters.fromJson(data));
  }

  /**
   * Updates an existing filter. This method supports patch semantics.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the filter belongs.
   *
   * [filterId] - ID of the filter to be updated.
   *
   * Completes with a [Filter].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Filter> patch(Filter request, core.String accountId, core.String filterId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (filterId == null) {
      throw new core.ArgumentError("Parameter filterId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/filters/' + common_internal.Escaper.ecapeVariable('$filterId');

    var _response = _requester.request(_url,
                                       "PATCH",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Filter.fromJson(data));
  }

  /**
   * Updates an existing filter.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the filter belongs.
   *
   * [filterId] - ID of the filter to be updated.
   *
   * Completes with a [Filter].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Filter> update(Filter request, core.String accountId, core.String filterId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (filterId == null) {
      throw new core.ArgumentError("Parameter filterId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/filters/' + common_internal.Escaper.ecapeVariable('$filterId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Filter.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementGoalsResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementGoalsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Gets a goal to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve the goal for.
   *
   * [webPropertyId] - Web property ID to retrieve the goal for.
   *
   * [profileId] - View (Profile) ID to retrieve the goal for.
   *
   * [goalId] - Goal ID to retrieve the goal for.
   *
   * Completes with a [Goal].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Goal> get(core.String accountId, core.String webPropertyId, core.String profileId, core.String goalId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (goalId == null) {
      throw new core.ArgumentError("Parameter goalId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/goals/' + common_internal.Escaper.ecapeVariable('$goalId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Goal.fromJson(data));
  }

  /**
   * Create a new goal.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the goal for.
   *
   * [webPropertyId] - Web property ID to create the goal for.
   *
   * [profileId] - View (Profile) ID to create the goal for.
   *
   * Completes with a [Goal].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Goal> insert(Goal request, core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/goals';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Goal.fromJson(data));
  }

  /**
   * Lists goals to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve goals for. Can either be a specific
   * account ID or '~all', which refers to all the accounts that user has access
   * to.
   *
   * [webPropertyId] - Web property ID to retrieve goals for. Can either be a
   * specific web property ID or '~all', which refers to all the web properties
   * that user has access to.
   *
   * [profileId] - View (Profile) ID to retrieve goals for. Can either be a
   * specific view (profile) ID or '~all', which refers to all the views
   * (profiles) that user has access to.
   *
   * [max_results] - The maximum number of goals to include in this response.
   *
   * [start_index] - An index of the first goal to retrieve. Use this parameter
   * as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Goals].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Goals> list(core.String accountId, core.String webPropertyId, core.String profileId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/goals';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Goals.fromJson(data));
  }

  /**
   * Updates an existing view (profile). This method supports patch semantics.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to update the goal.
   *
   * [webPropertyId] - Web property ID to update the goal.
   *
   * [profileId] - View (Profile) ID to update the goal.
   *
   * [goalId] - Index of the goal to be updated.
   *
   * Completes with a [Goal].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Goal> patch(Goal request, core.String accountId, core.String webPropertyId, core.String profileId, core.String goalId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (goalId == null) {
      throw new core.ArgumentError("Parameter goalId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/goals/' + common_internal.Escaper.ecapeVariable('$goalId');

    var _response = _requester.request(_url,
                                       "PATCH",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Goal.fromJson(data));
  }

  /**
   * Updates an existing view (profile).
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to update the goal.
   *
   * [webPropertyId] - Web property ID to update the goal.
   *
   * [profileId] - View (Profile) ID to update the goal.
   *
   * [goalId] - Index of the goal to be updated.
   *
   * Completes with a [Goal].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Goal> update(Goal request, core.String accountId, core.String webPropertyId, core.String profileId, core.String goalId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (goalId == null) {
      throw new core.ArgumentError("Parameter goalId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/goals/' + common_internal.Escaper.ecapeVariable('$goalId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Goal.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementProfileFilterLinksResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementProfileFilterLinksResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Delete a profile filter link.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the profile filter link belongs.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id to which the profile filter link belongs.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [profileId] - Profile ID to which the filter link belongs.
   * Value must have pattern "\d+".
   *
   * [linkId] - ID of the profile filter link to delete.
   * Value must have pattern "\d+:\d+".
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String webPropertyId, core.String profileId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/profileFilterLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Returns a single profile filter link.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve profile filter link for.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id to retrieve profile filter link for.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [profileId] - Profile ID to retrieve filter link for.
   * Value must have pattern "\d+".
   *
   * [linkId] - ID of the profile filter link.
   * Value must have pattern "\d+:\d+".
   *
   * Completes with a [ProfileFilterLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<ProfileFilterLink> get(core.String accountId, core.String webPropertyId, core.String profileId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/profileFilterLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new ProfileFilterLink.fromJson(data));
  }

  /**
   * Create a new profile filter link.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create profile filter link for.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id to create profile filter link for.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [profileId] - Profile ID to create filter link for.
   * Value must have pattern "\d+".
   *
   * Completes with a [ProfileFilterLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<ProfileFilterLink> insert(ProfileFilterLink request, core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/profileFilterLinks';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new ProfileFilterLink.fromJson(data));
  }

  /**
   * Lists all profile filter links for a profile.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve profile filter links for.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id for profile filter links for. Can either
   * be a specific web property ID or '~all', which refers to all the web
   * properties that user has access to.
   *
   * [profileId] - Profile ID to retrieve filter links for. Can either be a
   * specific profile ID or '~all', which refers to all the profiles that user
   * has access to.
   *
   * [max_results] - The maximum number of profile filter links to include in
   * this response.
   *
   * [start_index] - An index of the first entity to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [ProfileFilterLinks].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<ProfileFilterLinks> list(core.String accountId, core.String webPropertyId, core.String profileId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/profileFilterLinks';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new ProfileFilterLinks.fromJson(data));
  }

  /**
   * Update an existing profile filter link. This method supports patch
   * semantics.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which profile filter link belongs.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id to which profile filter link belongs
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [profileId] - Profile ID to which filter link belongs
   * Value must have pattern "\d+".
   *
   * [linkId] - ID of the profile filter link to be updated.
   * Value must have pattern "\d+:\d+".
   *
   * Completes with a [ProfileFilterLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<ProfileFilterLink> patch(ProfileFilterLink request, core.String accountId, core.String webPropertyId, core.String profileId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/profileFilterLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "PATCH",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new ProfileFilterLink.fromJson(data));
  }

  /**
   * Update an existing profile filter link.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which profile filter link belongs.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id to which profile filter link belongs
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [profileId] - Profile ID to which filter link belongs
   * Value must have pattern "\d+".
   *
   * [linkId] - ID of the profile filter link to be updated.
   * Value must have pattern "\d+:\d+".
   *
   * Completes with a [ProfileFilterLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<ProfileFilterLink> update(ProfileFilterLink request, core.String accountId, core.String webPropertyId, core.String profileId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/profileFilterLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new ProfileFilterLink.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementProfileUserLinksResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementProfileUserLinksResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Removes a user from the given view (profile).
   *
   * Request parameters:
   *
   * [accountId] - Account ID to delete the user link for.
   *
   * [webPropertyId] - Web Property ID to delete the user link for.
   *
   * [profileId] - View (Profile) ID to delete the user link for.
   *
   * [linkId] - Link ID to delete the user link for.
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String webPropertyId, core.String profileId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/entityUserLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Adds a new user to the given view (profile).
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the user link for.
   *
   * [webPropertyId] - Web Property ID to create the user link for.
   *
   * [profileId] - View (Profile) ID to create the user link for.
   *
   * Completes with a [EntityUserLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLink> insert(EntityUserLink request, core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/entityUserLinks';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLink.fromJson(data));
  }

  /**
   * Lists profile-user links for a given view (profile).
   *
   * Request parameters:
   *
   * [accountId] - Account ID which the given view (profile) belongs to.
   *
   * [webPropertyId] - Web Property ID which the given view (profile) belongs
   * to. Can either be a specific web property ID or '~all', which refers to all
   * the web properties that user has access to.
   *
   * [profileId] - View (Profile) ID to retrieve the profile-user links for. Can
   * either be a specific profile ID or '~all', which refers to all the profiles
   * that user has access to.
   *
   * [max_results] - The maximum number of profile-user links to include in this
   * response.
   *
   * [start_index] - An index of the first profile-user link to retrieve. Use
   * this parameter as a pagination mechanism along with the max-results
   * parameter.
   *
   * Completes with a [EntityUserLinks].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLinks> list(core.String accountId, core.String webPropertyId, core.String profileId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/entityUserLinks';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLinks.fromJson(data));
  }

  /**
   * Updates permissions for an existing user on the given view (profile).
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to update the user link for.
   *
   * [webPropertyId] - Web Property ID to update the user link for.
   *
   * [profileId] - View (Profile ID) to update the user link for.
   *
   * [linkId] - Link ID to update the user link for.
   *
   * Completes with a [EntityUserLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLink> update(EntityUserLink request, core.String accountId, core.String webPropertyId, core.String profileId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/entityUserLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLink.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementProfilesResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementProfilesResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Deletes a view (profile).
   *
   * Request parameters:
   *
   * [accountId] - Account ID to delete the view (profile) for.
   *
   * [webPropertyId] - Web property ID to delete the view (profile) for.
   *
   * [profileId] - ID of the view (profile) to be deleted.
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Gets a view (profile) to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve the goal for.
   * Value must have pattern "[0-9]+".
   *
   * [webPropertyId] - Web property ID to retrieve the goal for.
   * Value must have pattern "UA-[0-9]+-[0-9]+".
   *
   * [profileId] - View (Profile) ID to retrieve the goal for.
   * Value must have pattern "[0-9]+".
   *
   * Completes with a [Profile].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Profile> get(core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Profile.fromJson(data));
  }

  /**
   * Create a new view (profile).
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the view (profile) for.
   *
   * [webPropertyId] - Web property ID to create the view (profile) for.
   *
   * Completes with a [Profile].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Profile> insert(Profile request, core.String accountId, core.String webPropertyId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Profile.fromJson(data));
  }

  /**
   * Lists views (profiles) to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID for the view (profiles) to retrieve. Can either be
   * a specific account ID or '~all', which refers to all the accounts to which
   * the user has access.
   *
   * [webPropertyId] - Web property ID for the views (profiles) to retrieve. Can
   * either be a specific web property ID or '~all', which refers to all the web
   * properties to which the user has access.
   *
   * [max_results] - The maximum number of views (profiles) to include in this
   * response.
   *
   * [start_index] - An index of the first entity to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Profiles].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Profiles> list(core.String accountId, core.String webPropertyId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Profiles.fromJson(data));
  }

  /**
   * Updates an existing view (profile). This method supports patch semantics.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the view (profile) belongs
   *
   * [webPropertyId] - Web property ID to which the view (profile) belongs
   *
   * [profileId] - ID of the view (profile) to be updated.
   *
   * Completes with a [Profile].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Profile> patch(Profile request, core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId');

    var _response = _requester.request(_url,
                                       "PATCH",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Profile.fromJson(data));
  }

  /**
   * Updates an existing view (profile).
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the view (profile) belongs
   *
   * [webPropertyId] - Web property ID to which the view (profile) belongs
   *
   * [profileId] - ID of the view (profile) to be updated.
   *
   * Completes with a [Profile].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Profile> update(Profile request, core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Profile.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementSegmentsResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementSegmentsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Lists segments to which the user has access.
   *
   * Request parameters:
   *
   * [max_results] - The maximum number of segments to include in this response.
   *
   * [start_index] - An index of the first segment to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Segments].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Segments> list({core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/segments';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Segments.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementUnsampledReportsResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementUnsampledReportsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Returns a single unsampled report.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve unsampled report for.
   *
   * [webPropertyId] - Web property ID to retrieve unsampled reports for.
   *
   * [profileId] - View (Profile) ID to retrieve unsampled report for.
   *
   * [unsampledReportId] - ID of the unsampled report to retrieve.
   *
   * Completes with a [UnsampledReport].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<UnsampledReport> get(core.String accountId, core.String webPropertyId, core.String profileId, core.String unsampledReportId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (unsampledReportId == null) {
      throw new core.ArgumentError("Parameter unsampledReportId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/unsampledReports/' + common_internal.Escaper.ecapeVariable('$unsampledReportId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new UnsampledReport.fromJson(data));
  }

  /**
   * Create a new unsampled report.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the unsampled report for.
   *
   * [webPropertyId] - Web property ID to create the unsampled report for.
   *
   * [profileId] - View (Profile) ID to create the unsampled report for.
   *
   * Completes with a [UnsampledReport].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<UnsampledReport> insert(UnsampledReport request, core.String accountId, core.String webPropertyId, core.String profileId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/unsampledReports';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new UnsampledReport.fromJson(data));
  }

  /**
   * Lists unsampled reports to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve unsampled reports for. Must be a
   * specific account ID, ~all is not supported.
   *
   * [webPropertyId] - Web property ID to retrieve unsampled reports for. Must
   * be a specific web property ID, ~all is not supported.
   *
   * [profileId] - View (Profile) ID to retrieve unsampled reports for. Must be
   * a specific view (profile) ID, ~all is not supported.
   *
   * [max_results] - The maximum number of unsampled reports to include in this
   * response.
   *
   * [start_index] - An index of the first unsampled report to retrieve. Use
   * this parameter as a pagination mechanism along with the max-results
   * parameter.
   *
   * Completes with a [UnsampledReports].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<UnsampledReports> list(core.String accountId, core.String webPropertyId, core.String profileId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (profileId == null) {
      throw new core.ArgumentError("Parameter profileId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/profiles/' + common_internal.Escaper.ecapeVariable('$profileId') + '/unsampledReports';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new UnsampledReports.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementUploadsResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementUploadsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Delete data associated with a previous upload.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account Id for the uploads to be deleted.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id for the uploads to be deleted.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [customDataSourceId] - Custom data source Id for the uploads to be deleted.
   * Value must have pattern ".{22}".
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future deleteUploadData(AnalyticsDataimportDeleteUploadDataRequest request, core.String accountId, core.String webPropertyId, core.String customDataSourceId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/deleteUploadData';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * List uploads to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account Id for the upload to retrieve.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id for the upload to retrieve.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [customDataSourceId] - Custom data source Id for upload to retrieve.
   * Value must have pattern ".{22}".
   *
   * [uploadId] - Upload Id to retrieve.
   * Value must have pattern ".{22}".
   *
   * Completes with a [Upload].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Upload> get(core.String accountId, core.String webPropertyId, core.String customDataSourceId, core.String uploadId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }
    if (uploadId == null) {
      throw new core.ArgumentError("Parameter uploadId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/uploads/' + common_internal.Escaper.ecapeVariable('$uploadId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Upload.fromJson(data));
  }

  /**
   * List uploads to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account Id for the uploads to retrieve.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id for the uploads to retrieve.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [customDataSourceId] - Custom data source Id for uploads to retrieve.
   * Value must have pattern ".{22}".
   *
   * [max_results] - The maximum number of uploads to include in this response.
   *
   * [start_index] - A 1-based index of the first upload to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Uploads].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Uploads> list(core.String accountId, core.String webPropertyId, core.String customDataSourceId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/uploads';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Uploads.fromJson(data));
  }

  /**
   * Migrate custom data source and data imports to latest version.
   *
   * Request parameters:
   *
   * [accountId] - Account Id for migration.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property Id for migration.
   * Value must have pattern "UA-(\d+)-(\d+)".
   *
   * [customDataSourceId] - Custom data source Id for migration.
   * Value must have pattern ".{22}".
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future migrateDataImport(core.String accountId, core.String webPropertyId, core.String customDataSourceId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/migrateDataImport';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Upload data for a custom data source.
   *
   * Request parameters:
   *
   * [accountId] - Account Id associated with the upload.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property UA-string associated with the upload.
   * Value must have pattern "UA-\d+-\d+".
   *
   * [customDataSourceId] - Custom data source Id to which the data being
   * uploaded belongs.
   *
   * [uploadMedia] - The media to upload.
   *
   * [uploadOptions] - Options for the media upload. Streaming Media without the
   * length being known ahead of time is only supported via resumable uploads.
   *
   * Completes with a [Upload].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Upload> uploadData(core.String accountId, core.String webPropertyId, core.String customDataSourceId, {common.UploadOptions uploadOptions : common.UploadOptions.Default, common.Media uploadMedia}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (customDataSourceId == null) {
      throw new core.ArgumentError("Parameter customDataSourceId is required.");
    }

    _uploadMedia =  uploadMedia;
    _uploadOptions =  uploadOptions;

    if (_uploadMedia == null) {
      _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/uploads';
    } else if (_uploadOptions is common.ResumableUploadOptions) {
      _url = '/resumable/upload/analytics/v3/management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/uploads';
    } else {
      _url = '/upload/analytics/v3/management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/customDataSources/' + common_internal.Escaper.ecapeVariable('$customDataSourceId') + '/uploads';
    }


    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Upload.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementWebPropertyAdWordsLinksResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementWebPropertyAdWordsLinksResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Deletes a web property-AdWords link.
   *
   * Request parameters:
   *
   * [accountId] - ID of the account which the given web property belongs to.
   *
   * [webPropertyId] - Web property ID to delete the AdWords link for.
   *
   * [webPropertyAdWordsLinkId] - Web property AdWords link ID.
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String webPropertyId, core.String webPropertyAdWordsLinkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (webPropertyAdWordsLinkId == null) {
      throw new core.ArgumentError("Parameter webPropertyAdWordsLinkId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityAdWordsLinks/' + common_internal.Escaper.ecapeVariable('$webPropertyAdWordsLinkId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Returns a web property-AdWords link to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - ID of the account which the given web property belongs to.
   *
   * [webPropertyId] - Web property ID to retrieve the AdWords link for.
   *
   * [webPropertyAdWordsLinkId] - Web property-AdWords link ID.
   *
   * Completes with a [EntityAdWordsLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityAdWordsLink> get(core.String accountId, core.String webPropertyId, core.String webPropertyAdWordsLinkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (webPropertyAdWordsLinkId == null) {
      throw new core.ArgumentError("Parameter webPropertyAdWordsLinkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityAdWordsLinks/' + common_internal.Escaper.ecapeVariable('$webPropertyAdWordsLinkId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityAdWordsLink.fromJson(data));
  }

  /**
   * Creates a webProperty-AdWords link.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - ID of the Google Analytics account to create the link for.
   *
   * [webPropertyId] - Web property ID to create the link for.
   *
   * Completes with a [EntityAdWordsLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityAdWordsLink> insert(EntityAdWordsLink request, core.String accountId, core.String webPropertyId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityAdWordsLinks';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityAdWordsLink.fromJson(data));
  }

  /**
   * Lists webProperty-AdWords links for a given web property.
   *
   * Request parameters:
   *
   * [accountId] - ID of the account which the given web property belongs to.
   * Value must have pattern "\d+".
   *
   * [webPropertyId] - Web property ID to retrieve the AdWords links for.
   *
   * [max_results] - The maximum number of webProperty-AdWords links to include
   * in this response.
   *
   * [start_index] - An index of the first webProperty-AdWords link to retrieve.
   * Use this parameter as a pagination mechanism along with the max-results
   * parameter.
   *
   * Completes with a [EntityAdWordsLinks].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityAdWordsLinks> list(core.String accountId, core.String webPropertyId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityAdWordsLinks';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityAdWordsLinks.fromJson(data));
  }

  /**
   * Updates an existing webProperty-AdWords link. This method supports patch
   * semantics.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - ID of the account which the given web property belongs to.
   *
   * [webPropertyId] - Web property ID to retrieve the AdWords link for.
   *
   * [webPropertyAdWordsLinkId] - Web property-AdWords link ID.
   *
   * Completes with a [EntityAdWordsLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityAdWordsLink> patch(EntityAdWordsLink request, core.String accountId, core.String webPropertyId, core.String webPropertyAdWordsLinkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (webPropertyAdWordsLinkId == null) {
      throw new core.ArgumentError("Parameter webPropertyAdWordsLinkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityAdWordsLinks/' + common_internal.Escaper.ecapeVariable('$webPropertyAdWordsLinkId');

    var _response = _requester.request(_url,
                                       "PATCH",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityAdWordsLink.fromJson(data));
  }

  /**
   * Updates an existing webProperty-AdWords link.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - ID of the account which the given web property belongs to.
   *
   * [webPropertyId] - Web property ID to retrieve the AdWords link for.
   *
   * [webPropertyAdWordsLinkId] - Web property-AdWords link ID.
   *
   * Completes with a [EntityAdWordsLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityAdWordsLink> update(EntityAdWordsLink request, core.String accountId, core.String webPropertyId, core.String webPropertyAdWordsLinkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (webPropertyAdWordsLinkId == null) {
      throw new core.ArgumentError("Parameter webPropertyAdWordsLinkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityAdWordsLinks/' + common_internal.Escaper.ecapeVariable('$webPropertyAdWordsLinkId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityAdWordsLink.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementWebpropertiesResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementWebpropertiesResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Gets a web property to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve the web property for.
   * Value must have pattern "[0-9]+".
   *
   * [webPropertyId] - ID to retrieve the web property for.
   * Value must have pattern "UA-[0-9]+-[0-9]+".
   *
   * Completes with a [Webproperty].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Webproperty> get(core.String accountId, core.String webPropertyId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId');

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Webproperty.fromJson(data));
  }

  /**
   * Create a new property if the account has fewer than 20 properties. Web
   * properties are visible in the Google Analytics interface only if they have
   * at least one profile.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the web property for.
   *
   * Completes with a [Webproperty].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Webproperty> insert(Webproperty request, core.String accountId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Webproperty.fromJson(data));
  }

  /**
   * Lists web properties to which the user has access.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to retrieve web properties for. Can either be a
   * specific account ID or '~all', which refers to all the accounts that user
   * has access to.
   *
   * [max_results] - The maximum number of web properties to include in this
   * response.
   *
   * [start_index] - An index of the first entity to retrieve. Use this
   * parameter as a pagination mechanism along with the max-results parameter.
   *
   * Completes with a [Webproperties].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Webproperties> list(core.String accountId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Webproperties.fromJson(data));
  }

  /**
   * Updates an existing web property. This method supports patch semantics.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the web property belongs
   *
   * [webPropertyId] - Web property ID
   *
   * Completes with a [Webproperty].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Webproperty> patch(Webproperty request, core.String accountId, core.String webPropertyId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId');

    var _response = _requester.request(_url,
                                       "PATCH",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Webproperty.fromJson(data));
  }

  /**
   * Updates an existing web property.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to which the web property belongs
   *
   * [webPropertyId] - Web property ID
   *
   * Completes with a [Webproperty].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Webproperty> update(Webproperty request, core.String accountId, core.String webPropertyId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Webproperty.fromJson(data));
  }

}


/** Not documented yet. */
class ManagementWebpropertyUserLinksResourceApi {
  final common_internal.ApiRequester _requester;

  ManagementWebpropertyUserLinksResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Removes a user from the given web property.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to delete the user link for.
   *
   * [webPropertyId] - Web Property ID to delete the user link for.
   *
   * [linkId] - Link ID to delete the user link for.
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future delete(core.String accountId, core.String webPropertyId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }

    _downloadOptions = null;

    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityUserLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "DELETE",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => null);
  }

  /**
   * Adds a new user to the given web property.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to create the user link for.
   *
   * [webPropertyId] - Web Property ID to create the user link for.
   *
   * Completes with a [EntityUserLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLink> insert(EntityUserLink request, core.String accountId, core.String webPropertyId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityUserLinks';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLink.fromJson(data));
  }

  /**
   * Lists webProperty-user links for a given web property.
   *
   * Request parameters:
   *
   * [accountId] - Account ID which the given web property belongs to.
   *
   * [webPropertyId] - Web Property ID for the webProperty-user links to
   * retrieve. Can either be a specific web property ID or '~all', which refers
   * to all the web properties that user has access to.
   *
   * [max_results] - The maximum number of webProperty-user Links to include in
   * this response.
   *
   * [start_index] - An index of the first webProperty-user link to retrieve.
   * Use this parameter as a pagination mechanism along with the max-results
   * parameter.
   *
   * Completes with a [EntityUserLinks].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLinks> list(core.String accountId, core.String webPropertyId, {core.int max_results, core.int start_index}) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (max_results != null) {
      _queryParams["max-results"] = ["${max_results}"];
    }
    if (start_index != null) {
      _queryParams["start-index"] = ["${start_index}"];
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityUserLinks';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLinks.fromJson(data));
  }

  /**
   * Updates permissions for an existing user on the given web property.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * [accountId] - Account ID to update the account-user link for.
   *
   * [webPropertyId] - Web property ID to update the account-user link for.
   *
   * [linkId] - Link ID to update the account-user link for.
   *
   * Completes with a [EntityUserLink].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<EntityUserLink> update(EntityUserLink request, core.String accountId, core.String webPropertyId, core.String linkId) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }
    if (accountId == null) {
      throw new core.ArgumentError("Parameter accountId is required.");
    }
    if (webPropertyId == null) {
      throw new core.ArgumentError("Parameter webPropertyId is required.");
    }
    if (linkId == null) {
      throw new core.ArgumentError("Parameter linkId is required.");
    }


    _url = 'management/accounts/' + common_internal.Escaper.ecapeVariable('$accountId') + '/webproperties/' + common_internal.Escaper.ecapeVariable('$webPropertyId') + '/entityUserLinks/' + common_internal.Escaper.ecapeVariable('$linkId');

    var _response = _requester.request(_url,
                                       "PUT",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new EntityUserLink.fromJson(data));
  }

}


/** Not documented yet. */
class MetadataResourceApi {
  final common_internal.ApiRequester _requester;

  MetadataColumnsResourceApi get columns => new MetadataColumnsResourceApi(_requester);

  MetadataResourceApi(common_internal.ApiRequester client) : 
      _requester = client;
}


/** Not documented yet. */
class MetadataColumnsResourceApi {
  final common_internal.ApiRequester _requester;

  MetadataColumnsResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Lists all columns for a report type
   *
   * Request parameters:
   *
   * [reportType] - Report type. Allowed Values: 'ga'. Where 'ga' corresponds to
   * the Core Reporting API
   * Value must have pattern "ga".
   *
   * Completes with a [Columns].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<Columns> list(core.String reportType) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (reportType == null) {
      throw new core.ArgumentError("Parameter reportType is required.");
    }


    _url = 'metadata/' + common_internal.Escaper.ecapeVariable('$reportType') + '/columns';

    var _response = _requester.request(_url,
                                       "GET",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new Columns.fromJson(data));
  }

}


/** Not documented yet. */
class ProvisioningResourceApi {
  final common_internal.ApiRequester _requester;

  ProvisioningResourceApi(common_internal.ApiRequester client) : 
      _requester = client;

  /**
   * Creates an account ticket.
   *
   * [request] - The metadata request object.
   *
   * Request parameters:
   *
   * Completes with a [AccountTicket].
   *
   * Completes with a [common.ApiRequestError] if the API endpoint returned an
   * error.
   *
   * If the used [http.Client] completes with an error when making a REST call,
   * this method  will complete with the same error.
   */
  async.Future<AccountTicket> createAccountTicket(AccountTicket request) {
    var _url = null;
    var _queryParams = new core.Map();
    var _uploadMedia = null;
    var _uploadOptions = null;
    var _downloadOptions = common.DownloadOptions.Metadata;
    var _body = null;

    if (request != null) {
      _body = convert.JSON.encode((request).toJson());
    }


    _url = 'provisioning/createAccountTicket';

    var _response = _requester.request(_url,
                                       "POST",
                                       body: _body,
                                       queryParams: _queryParams,
                                       uploadOptions: _uploadOptions,
                                       uploadMedia: _uploadMedia,
                                       downloadOptions: _downloadOptions);
    return _response.then((data) => new AccountTicket.fromJson(data));
  }

}



/**
 * Child link for an account entry. Points to the list of web properties for
 * this account.
 */
class AccountChildLink {
  /** Link to the list of web properties for this account. */
  core.String href;

  /** Type of the child link. Its value is "analytics#webproperties". */
  core.String type;


  AccountChildLink();

  AccountChildLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Permissions the user has for this account. */
class AccountPermissions {
  /**
   * All the permissions that the user has for this account. These include any
   * implied permissions (e.g., EDIT implies VIEW).
   */
  core.List<core.String> effective;


  AccountPermissions();

  AccountPermissions.fromJson(core.Map _json) {
    if (_json.containsKey("effective")) {
      effective = _json["effective"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (effective != null) {
      _json["effective"] = effective;
    }
    return _json;
  }
}


/** JSON template for Analytics account entry. */
class Account {
  /**
   * Child link for an account entry. Points to the list of web properties for
   * this account.
   */
  AccountChildLink childLink;

  /** Time the account was created. */
  core.DateTime created;

  /** Account ID. */
  core.String id;

  /** Resource type for Analytics account. */
  core.String kind;

  /** Account name. */
  core.String name;

  /** Permissions the user has for this account. */
  AccountPermissions permissions;

  /** Link for this account. */
  core.String selfLink;

  /** Time the account was last modified. */
  core.DateTime updated;


  Account();

  Account.fromJson(core.Map _json) {
    if (_json.containsKey("childLink")) {
      childLink = new AccountChildLink.fromJson(_json["childLink"]);
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("permissions")) {
      permissions = new AccountPermissions.fromJson(_json["permissions"]);
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (childLink != null) {
      _json["childLink"] = (childLink).toJson();
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (permissions != null) {
      _json["permissions"] = (permissions).toJson();
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    return _json;
  }
}


/** JSON template for a linked account. */
class AccountRef {
  /** Link for this account. */
  core.String href;

  /** Account ID. */
  core.String id;

  /** Analytics account reference. */
  core.String kind;

  /** Account name. */
  core.String name;


  AccountRef();

  AccountRef.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}


/**
 * An AccountSummary collection lists a summary of accounts, properties and
 * views (profiles) to which the user has access. Each resource in the
 * collection corresponds to a single AccountSummary.
 */
class AccountSummaries {
  /** A list of AccountSummaries. */
  core.List<AccountSummary> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this AccountSummary collection. */
  core.String nextLink;

  /** Link to previous page for this AccountSummary collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  AccountSummaries();

  AccountSummaries.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new AccountSummary.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/**
 * JSON template for an Analytics AccountSummary. An AccountSummary is a
 * lightweight tree comprised of properties/profiles.
 */
class AccountSummary {
  /** Account ID. */
  core.String id;

  /** Resource type for Analytics AccountSummary. */
  core.String kind;

  /** Account name. */
  core.String name;

  /** List of web properties under this account. */
  core.List<WebPropertySummary> webProperties;


  AccountSummary();

  AccountSummary.fromJson(core.Map _json) {
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("webProperties")) {
      webProperties = _json["webProperties"].map((value) => new WebPropertySummary.fromJson(value)).toList();
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (webProperties != null) {
      _json["webProperties"] = webProperties.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}


/**
 * JSON template for an Analytics account ticket. The account ticket consists of
 * the ticket ID and the basic information for the account, property and
 * profile.
 */
class AccountTicket {
  /** Account for this ticket. */
  Account account;

  /** Account ticket ID used to access the account ticket. */
  core.String id;

  /** Resource type for account ticket. */
  core.String kind;

  /** View (Profile) for the account. */
  Profile profile;

  /**
   * Redirect URI where the user will be sent after accepting Terms of Service.
   * Must be configured in APIs console as a callback URL.
   */
  core.String redirectUri;

  /** Web property for the account. */
  Webproperty webproperty;


  AccountTicket();

  AccountTicket.fromJson(core.Map _json) {
    if (_json.containsKey("account")) {
      account = new Account.fromJson(_json["account"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("profile")) {
      profile = new Profile.fromJson(_json["profile"]);
    }
    if (_json.containsKey("redirectUri")) {
      redirectUri = _json["redirectUri"];
    }
    if (_json.containsKey("webproperty")) {
      webproperty = new Webproperty.fromJson(_json["webproperty"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (account != null) {
      _json["account"] = (account).toJson();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (profile != null) {
      _json["profile"] = (profile).toJson();
    }
    if (redirectUri != null) {
      _json["redirectUri"] = redirectUri;
    }
    if (webproperty != null) {
      _json["webproperty"] = (webproperty).toJson();
    }
    return _json;
  }
}


/**
 * An account collection provides a list of Analytics accounts to which a user
 * has access. The account collection is the entry point to all management
 * information. Each resource in the collection corresponds to a single
 * Analytics account.
 */
class Accounts {
  /** A list of accounts. */
  core.List<Account> items;

  /**
   * The maximum number of entries the response can contain, regardless of the
   * actual number of entries returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Next link for this account collection. */
  core.String nextLink;

  /** Previous link for this account collection. */
  core.String previousLink;

  /**
   * The starting index of the entries, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  Accounts();

  Accounts.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Account.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** JSON template for an AdWords account. */
class AdWordsAccount {
  /**
   * True if auto-tagging is enabled on the AdWords account. Read-only after the
   * insert operation.
   */
  core.bool autoTaggingEnabled;

  /** Customer ID. This field is required when creating an AdWords link. */
  core.String customerId;

  /** Resource type for AdWords account. */
  core.String kind;


  AdWordsAccount();

  AdWordsAccount.fromJson(core.Map _json) {
    if (_json.containsKey("autoTaggingEnabled")) {
      autoTaggingEnabled = _json["autoTaggingEnabled"];
    }
    if (_json.containsKey("customerId")) {
      customerId = _json["customerId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (autoTaggingEnabled != null) {
      _json["autoTaggingEnabled"] = autoTaggingEnabled;
    }
    if (customerId != null) {
      _json["customerId"] = customerId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    return _json;
  }
}


/** Request template for the delete upload data request. */
class AnalyticsDataimportDeleteUploadDataRequest {
  /** A list of upload UIDs. */
  core.List<core.String> customDataImportUids;


  AnalyticsDataimportDeleteUploadDataRequest();

  AnalyticsDataimportDeleteUploadDataRequest.fromJson(core.Map _json) {
    if (_json.containsKey("customDataImportUids")) {
      customDataImportUids = _json["customDataImportUids"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (customDataImportUids != null) {
      _json["customDataImportUids"] = customDataImportUids;
    }
    return _json;
  }
}


/** JSON template for a metadata column. */
class Column {
  /** Map of attribute name and value for this column. */
  core.Map<core.String, core.String> attributes;

  /** Column id. */
  core.String id;

  /** Resource type for Analytics column. */
  core.String kind;


  Column();

  Column.fromJson(core.Map _json) {
    if (_json.containsKey("attributes")) {
      attributes = _json["attributes"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (attributes != null) {
      _json["attributes"] = attributes;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    return _json;
  }
}


/** Lists columns (dimensions and metrics) for a particular report type. */
class Columns {
  /** List of attributes names returned by columns. */
  core.List<core.String> attributeNames;

  /**
   * Etag of collection. This etag can be compared with the last response etag
   * to check if response has changed.
   */
  core.String etag;

  /** List of columns for a report type. */
  core.List<Column> items;

  /** Collection type. */
  core.String kind;

  /** Total number of columns returned in the response. */
  core.int totalResults;


  Columns();

  Columns.fromJson(core.Map _json) {
    if (_json.containsKey("attributeNames")) {
      attributeNames = _json["attributeNames"];
    }
    if (_json.containsKey("etag")) {
      etag = _json["etag"];
    }
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Column.fromJson(value)).toList();
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (attributeNames != null) {
      _json["attributeNames"] = attributeNames;
    }
    if (etag != null) {
      _json["etag"] = etag;
    }
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    return _json;
  }
}


/** Not documented yet. */
class CustomDataSourceChildLink {
  /**
   * Link to the list of daily uploads for this custom data source. Link to the
   * list of uploads for this custom data source.
   */
  core.String href;

  /** Value is "analytics#dailyUploads". Value is "analytics#uploads". */
  core.String type;


  CustomDataSourceChildLink();

  CustomDataSourceChildLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/**
 * Parent link for this custom data source. Points to the web property to which
 * this custom data source belongs.
 */
class CustomDataSourceParentLink {
  /** Link to the web property to which this custom data source belongs. */
  core.String href;

  /** Value is "analytics#webproperty". */
  core.String type;


  CustomDataSourceParentLink();

  CustomDataSourceParentLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** JSON template for an Analytics custom data source. */
class CustomDataSource {
  /** Account ID to which this custom data source belongs. */
  core.String accountId;

  /** Not documented yet. */
  CustomDataSourceChildLink childLink;

  /** Time this custom data source was created. */
  core.DateTime created;

  /** Description of custom data source. */
  core.String description;

  /** Custom data source ID. */
  core.String id;

  /** Not documented yet. */
  core.String importBehavior;

  /** Resource type for Analytics custom data source. */
  core.String kind;

  /** Name of this custom data source. */
  core.String name;

  /**
   * Parent link for this custom data source. Points to the web property to
   * which this custom data source belongs.
   */
  CustomDataSourceParentLink parentLink;

  /** IDs of views (profiles) linked to the custom data source. */
  core.List<core.String> profilesLinked;

  /** Link for this Analytics custom data source. */
  core.String selfLink;

  /** Type of the custom data source. */
  core.String type;

  /** Time this custom data source was last modified. */
  core.DateTime updated;

  /** Not documented yet. */
  core.String uploadType;

  /**
   * Web property ID of the form UA-XXXXX-YY to which this custom data source
   * belongs.
   */
  core.String webPropertyId;


  CustomDataSource();

  CustomDataSource.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("childLink")) {
      childLink = new CustomDataSourceChildLink.fromJson(_json["childLink"]);
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("description")) {
      description = _json["description"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("importBehavior")) {
      importBehavior = _json["importBehavior"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("parentLink")) {
      parentLink = new CustomDataSourceParentLink.fromJson(_json["parentLink"]);
    }
    if (_json.containsKey("profilesLinked")) {
      profilesLinked = _json["profilesLinked"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
    if (_json.containsKey("uploadType")) {
      uploadType = _json["uploadType"];
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (childLink != null) {
      _json["childLink"] = (childLink).toJson();
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (description != null) {
      _json["description"] = description;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (importBehavior != null) {
      _json["importBehavior"] = importBehavior;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (parentLink != null) {
      _json["parentLink"] = (parentLink).toJson();
    }
    if (profilesLinked != null) {
      _json["profilesLinked"] = profilesLinked;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (type != null) {
      _json["type"] = type;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    if (uploadType != null) {
      _json["uploadType"] = uploadType;
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/**
 * Lists Analytics custom data sources to which the user has access. Each
 * resource in the collection corresponds to a single Analytics custom data
 * source.
 */
class CustomDataSources {
  /** Collection of custom data sources. */
  core.List<CustomDataSource> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this custom data source collection. */
  core.String nextLink;

  /** Link to previous page for this custom data source collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  CustomDataSources();

  CustomDataSources.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new CustomDataSource.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/**
 * Parent link for a daily upload. Points to the custom data source to which
 * this daily upload belongs.
 */
class DailyUploadParentLink {
  /** Link to the custom data source to which this daily upload belongs. */
  core.String href;

  /** Value is "analytics#customDataSource". */
  core.String type;


  DailyUploadParentLink();

  DailyUploadParentLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Not documented yet. */
class DailyUploadRecentChanges {
  /** The type of change: APPEND, RESET, or DELETE. */
  core.String change;

  /** The time when the change occurred. */
  core.DateTime time;


  DailyUploadRecentChanges();

  DailyUploadRecentChanges.fromJson(core.Map _json) {
    if (_json.containsKey("change")) {
      change = _json["change"];
    }
    if (_json.containsKey("time")) {
      time = core.DateTime.parse(_json["time"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (change != null) {
      _json["change"] = change;
    }
    if (time != null) {
      _json["time"] = (time).toIso8601String();
    }
    return _json;
  }
}


/** Metadata for daily upload entity. */
class DailyUpload {
  /** Account ID to which this daily upload belongs. */
  core.String accountId;

  /** Number of appends for this date. */
  core.int appendCount;

  /** Time this daily upload was created. */
  core.DateTime createdTime;

  /** Custom data source ID to which this daily upload belongs. */
  core.String customDataSourceId;

  /** Date associated with daily upload. */
  core.String date;

  /** Resource type for Analytics daily upload. */
  core.String kind;

  /** Time this daily upload was last modified. */
  core.DateTime modifiedTime;

  /**
   * Parent link for a daily upload. Points to the custom data source to which
   * this daily upload belongs.
   */
  DailyUploadParentLink parentLink;

  /** Change log for last 10 changes in chronological order. */
  core.List<DailyUploadRecentChanges> recentChanges;

  /** Link for this daily upload. */
  core.String selfLink;

  /**
   * Web property ID of the form UA-XXXXX-YY to which this daily upload belongs.
   */
  core.String webPropertyId;


  DailyUpload();

  DailyUpload.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("appendCount")) {
      appendCount = _json["appendCount"];
    }
    if (_json.containsKey("createdTime")) {
      createdTime = core.DateTime.parse(_json["createdTime"]);
    }
    if (_json.containsKey("customDataSourceId")) {
      customDataSourceId = _json["customDataSourceId"];
    }
    if (_json.containsKey("date")) {
      date = _json["date"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("modifiedTime")) {
      modifiedTime = core.DateTime.parse(_json["modifiedTime"]);
    }
    if (_json.containsKey("parentLink")) {
      parentLink = new DailyUploadParentLink.fromJson(_json["parentLink"]);
    }
    if (_json.containsKey("recentChanges")) {
      recentChanges = _json["recentChanges"].map((value) => new DailyUploadRecentChanges.fromJson(value)).toList();
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (appendCount != null) {
      _json["appendCount"] = appendCount;
    }
    if (createdTime != null) {
      _json["createdTime"] = (createdTime).toIso8601String();
    }
    if (customDataSourceId != null) {
      _json["customDataSourceId"] = customDataSourceId;
    }
    if (date != null) {
      _json["date"] = date;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (modifiedTime != null) {
      _json["modifiedTime"] = (modifiedTime).toIso8601String();
    }
    if (parentLink != null) {
      _json["parentLink"] = (parentLink).toJson();
    }
    if (recentChanges != null) {
      _json["recentChanges"] = recentChanges.map((value) => (value).toJson()).toList();
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/** Metadata returned for a successful append operation. */
class DailyUploadAppend {
  /** Account Id to which this daily upload append belongs. */
  core.String accountId;

  /** Append number. */
  core.int appendNumber;

  /** Custom data source Id to which this daily upload append belongs. */
  core.String customDataSourceId;

  /** Date associated with daily upload append. */
  core.String date;

  /** Resource type for Analytics daily upload append. */
  core.String kind;

  /** Not documented yet. */
  core.String nextAppendLink;

  /**
   * Web property Id of the form UA-XXXXX-YY to which this daily upload append
   * belongs.
   */
  core.String webPropertyId;


  DailyUploadAppend();

  DailyUploadAppend.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("appendNumber")) {
      appendNumber = _json["appendNumber"];
    }
    if (_json.containsKey("customDataSourceId")) {
      customDataSourceId = _json["customDataSourceId"];
    }
    if (_json.containsKey("date")) {
      date = _json["date"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextAppendLink")) {
      nextAppendLink = _json["nextAppendLink"];
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (appendNumber != null) {
      _json["appendNumber"] = appendNumber;
    }
    if (customDataSourceId != null) {
      _json["customDataSourceId"] = customDataSourceId;
    }
    if (date != null) {
      _json["date"] = date;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextAppendLink != null) {
      _json["nextAppendLink"] = nextAppendLink;
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/**
 * A daily upload collection lists Analytics daily uploads to which the user has
 * access. Each resource in the collection corresponds to a single Analytics
 * daily upload.
 */
class DailyUploads {
  /** A collection of daily uploads. */
  core.List<DailyUpload> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. Value is analytics#dailyUploads. */
  core.String kind;

  /** Link to next page for this daily upload collection. */
  core.String nextLink;

  /** Link to previous page for this daily upload collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  DailyUploads();

  DailyUploads.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new DailyUpload.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** Web property being linked. */
class EntityAdWordsLinkEntity {
  /** Not documented yet. */
  WebPropertyRef webPropertyRef;


  EntityAdWordsLinkEntity();

  EntityAdWordsLinkEntity.fromJson(core.Map _json) {
    if (_json.containsKey("webPropertyRef")) {
      webPropertyRef = new WebPropertyRef.fromJson(_json["webPropertyRef"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (webPropertyRef != null) {
      _json["webPropertyRef"] = (webPropertyRef).toJson();
    }
    return _json;
  }
}


/** JSON template for Analytics Entity AdWords Link. */
class EntityAdWordsLink {
  /**
   * A list of AdWords client accounts. These cannot be MCC accounts. This field
   * is required when creating an AdWords link. It cannot be empty.
   */
  core.List<AdWordsAccount> adWordsAccounts;

  /** Web property being linked. */
  EntityAdWordsLinkEntity entity;

  /** Entity AdWords link ID */
  core.String id;

  /** Resource type for entity AdWords link. */
  core.String kind;

  /**
   * Name of the link. This field is required when creating an AdWords link.
   */
  core.String name;

  /** IDs of linked Views (Profiles) represented as strings. */
  core.List<core.String> profileIds;

  /** URL link for this Google Analytics - Google AdWords link. */
  core.String selfLink;


  EntityAdWordsLink();

  EntityAdWordsLink.fromJson(core.Map _json) {
    if (_json.containsKey("adWordsAccounts")) {
      adWordsAccounts = _json["adWordsAccounts"].map((value) => new AdWordsAccount.fromJson(value)).toList();
    }
    if (_json.containsKey("entity")) {
      entity = new EntityAdWordsLinkEntity.fromJson(_json["entity"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("profileIds")) {
      profileIds = _json["profileIds"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (adWordsAccounts != null) {
      _json["adWordsAccounts"] = adWordsAccounts.map((value) => (value).toJson()).toList();
    }
    if (entity != null) {
      _json["entity"] = (entity).toJson();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (profileIds != null) {
      _json["profileIds"] = profileIds;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    return _json;
  }
}


/**
 * An entity AdWords link collection provides a list of GA-AdWords links Each
 * resource in this collection corresponds to a single link.
 */
class EntityAdWordsLinks {
  /** A list of entity AdWords links. */
  core.List<EntityAdWordsLink> items;

  /**
   * The maximum number of entries the response can contain, regardless of the
   * actual number of entries returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Next link for this AdWords link collection. */
  core.String nextLink;

  /** Previous link for this AdWords link collection. */
  core.String previousLink;

  /**
   * The starting index of the entries, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;


  EntityAdWordsLinks();

  EntityAdWordsLinks.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new EntityAdWordsLink.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    return _json;
  }
}


/**
 * Entity for this link. It can be an account, a web property, or a view
 * (profile).
 */
class EntityUserLinkEntity {
  /** Account for this link. */
  AccountRef accountRef;

  /** View (Profile) for this link. */
  ProfileRef profileRef;

  /** Web property for this link. */
  WebPropertyRef webPropertyRef;


  EntityUserLinkEntity();

  EntityUserLinkEntity.fromJson(core.Map _json) {
    if (_json.containsKey("accountRef")) {
      accountRef = new AccountRef.fromJson(_json["accountRef"]);
    }
    if (_json.containsKey("profileRef")) {
      profileRef = new ProfileRef.fromJson(_json["profileRef"]);
    }
    if (_json.containsKey("webPropertyRef")) {
      webPropertyRef = new WebPropertyRef.fromJson(_json["webPropertyRef"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountRef != null) {
      _json["accountRef"] = (accountRef).toJson();
    }
    if (profileRef != null) {
      _json["profileRef"] = (profileRef).toJson();
    }
    if (webPropertyRef != null) {
      _json["webPropertyRef"] = (webPropertyRef).toJson();
    }
    return _json;
  }
}


/** Permissions the user has for this entity. */
class EntityUserLinkPermissions {
  /**
   * Effective permissions represent all the permissions that a user has for
   * this entity. These include any implied permissions (e.g., EDIT implies
   * VIEW) or inherited permissions from the parent entity. Effective
   * permissions are read-only.
   */
  core.List<core.String> effective;

  /**
   * Permissions that a user has been assigned at this very level. Does not
   * include any implied or inherited permissions. Local permissions are
   * modifiable.
   */
  core.List<core.String> local;


  EntityUserLinkPermissions();

  EntityUserLinkPermissions.fromJson(core.Map _json) {
    if (_json.containsKey("effective")) {
      effective = _json["effective"];
    }
    if (_json.containsKey("local")) {
      local = _json["local"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (effective != null) {
      _json["effective"] = effective;
    }
    if (local != null) {
      _json["local"] = local;
    }
    return _json;
  }
}


/**
 * JSON template for an Analytics Entity-User Link. Returns permissions that a
 * user has for an entity.
 */
class EntityUserLink {
  /**
   * Entity for this link. It can be an account, a web property, or a view
   * (profile).
   */
  EntityUserLinkEntity entity;

  /** Entity user link ID */
  core.String id;

  /** Resource type for entity user link. */
  core.String kind;

  /** Permissions the user has for this entity. */
  EntityUserLinkPermissions permissions;

  /** Self link for this resource. */
  core.String selfLink;

  /** User reference. */
  UserRef userRef;


  EntityUserLink();

  EntityUserLink.fromJson(core.Map _json) {
    if (_json.containsKey("entity")) {
      entity = new EntityUserLinkEntity.fromJson(_json["entity"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("permissions")) {
      permissions = new EntityUserLinkPermissions.fromJson(_json["permissions"]);
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("userRef")) {
      userRef = new UserRef.fromJson(_json["userRef"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (entity != null) {
      _json["entity"] = (entity).toJson();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (permissions != null) {
      _json["permissions"] = (permissions).toJson();
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (userRef != null) {
      _json["userRef"] = (userRef).toJson();
    }
    return _json;
  }
}


/**
 * An entity user link collection provides a list of Analytics ACL links Each
 * resource in this collection corresponds to a single link.
 */
class EntityUserLinks {
  /** A list of entity user links. */
  core.List<EntityUserLink> items;

  /**
   * The maximum number of entries the response can contain, regardless of the
   * actual number of entries returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Next link for this account collection. */
  core.String nextLink;

  /** Previous link for this account collection. */
  core.String previousLink;

  /**
   * The starting index of the entries, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;


  EntityUserLinks();

  EntityUserLinks.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new EntityUserLink.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    return _json;
  }
}


/**
 * Parent link for an experiment. Points to the view (profile) to which this
 * experiment belongs.
 */
class ExperimentParentLink {
  /**
   * Link to the view (profile) to which this experiment belongs. This field is
   * read-only.
   */
  core.String href;

  /** Value is "analytics#profile". This field is read-only. */
  core.String type;


  ExperimentParentLink();

  ExperimentParentLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Not documented yet. */
class ExperimentVariations {
  /**
   * The name of the variation. This field is required when creating an
   * experiment. This field may not be changed for an experiment whose status is
   * ENDED.
   */
  core.String name;

  /**
   * Status of the variation. Possible values: "ACTIVE", "INACTIVE". INACTIVE
   * variations are not served. This field may not be changed for an experiment
   * whose status is ENDED.
   */
  core.String status;

  /**
   * The URL of the variation. This field may not be changed for an experiment
   * whose status is RUNNING or ENDED.
   */
  core.String url;

  /**
   * Weight that this variation should receive. Only present if the experiment
   * is running. This field is read-only.
   */
  core.double weight;

  /**
   * True if the experiment has ended and this variation performed
   * (statistically) significantly better than the original. This field is
   * read-only.
   */
  core.bool won;


  ExperimentVariations();

  ExperimentVariations.fromJson(core.Map _json) {
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("status")) {
      status = _json["status"];
    }
    if (_json.containsKey("url")) {
      url = _json["url"];
    }
    if (_json.containsKey("weight")) {
      weight = _json["weight"];
    }
    if (_json.containsKey("won")) {
      won = _json["won"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (name != null) {
      _json["name"] = name;
    }
    if (status != null) {
      _json["status"] = status;
    }
    if (url != null) {
      _json["url"] = url;
    }
    if (weight != null) {
      _json["weight"] = weight;
    }
    if (won != null) {
      _json["won"] = won;
    }
    return _json;
  }
}


/** JSON template for Analytics experiment resource. */
class Experiment {
  /** Account ID to which this experiment belongs. This field is read-only. */
  core.String accountId;

  /** Time the experiment was created. This field is read-only. */
  core.DateTime created;

  /** Notes about this experiment. */
  core.String description;

  /**
   * If true, the end user will be able to edit the experiment via the Google
   * Analytics user interface.
   */
  core.bool editableInGaUi;

  /**
   * The ending time of the experiment (the time the status changed from RUNNING
   * to ENDED). This field is present only if the experiment has ended. This
   * field is read-only.
   */
  core.DateTime endTime;

  /**
   * Boolean specifying whether to distribute traffic evenly across all
   * variations. If the value is False, content experiments follows the default
   * behavior of adjusting traffic dynamically based on variation performance.
   * Optional -- defaults to False. This field may not be changed for an
   * experiment whose status is ENDED.
   */
  core.bool equalWeighting;

  /** Experiment ID. Required for patch and update. Disallowed for create. */
  core.String id;

  /**
   * Internal ID for the web property to which this experiment belongs. This
   * field is read-only.
   */
  core.String internalWebPropertyId;

  /** Resource type for an Analytics experiment. This field is read-only. */
  core.String kind;

  /**
   * An integer number in [3, 90]. Specifies the minimum length of the
   * experiment. Can be changed for a running experiment. This field may not be
   * changed for an experiments whose status is ENDED.
   */
  core.int minimumExperimentLengthInDays;

  /**
   * Experiment name. This field may not be changed for an experiment whose
   * status is ENDED. This field is required when creating an experiment.
   */
  core.String name;

  /**
   * The metric that the experiment is optimizing. Valid values:
   * "ga:goal(n)Completions", "ga:adsenseAdsClicks", "ga:adsenseAdsViewed",
   * "ga:adsenseRevenue", "ga:bounces", "ga:pageviews", "ga:sessionDuration",
   * "ga:transactions", "ga:transactionRevenue". This field is required if
   * status is "RUNNING" and servingFramework is one of "REDIRECT" or "API".
   */
  core.String objectiveMetric;

  /**
   * Whether the objectiveMetric should be minimized or maximized. Possible
   * values: "MAXIMUM", "MINIMUM". Optional--defaults to "MAXIMUM". Cannot be
   * specified without objectiveMetric. Cannot be modified when status is
   * "RUNNING" or "ENDED".
   */
  core.String optimizationType;

  /**
   * Parent link for an experiment. Points to the view (profile) to which this
   * experiment belongs.
   */
  ExperimentParentLink parentLink;

  /**
   * View (Profile) ID to which this experiment belongs. This field is
   * read-only.
   */
  core.String profileId;

  /**
   * Why the experiment ended. Possible values: "STOPPED_BY_USER",
   * "WINNER_FOUND", "EXPERIMENT_EXPIRED", "ENDED_WITH_NO_WINNER",
   * "GOAL_OBJECTIVE_CHANGED". "ENDED_WITH_NO_WINNER" means that the experiment
   * didn't expire but no winner was projected to be found. If the experiment
   * status is changed via the API to ENDED this field is set to
   * STOPPED_BY_USER. This field is read-only.
   */
  core.String reasonExperimentEnded;

  /**
   * Boolean specifying whether variations URLS are rewritten to match those of
   * the original. This field may not be changed for an experiments whose status
   * is ENDED.
   */
  core.bool rewriteVariationUrlsAsOriginal;

  /** Link for this experiment. This field is read-only. */
  core.String selfLink;

  /**
   * The framework used to serve the experiment variations and evaluate the
   * results. One of:
   * - REDIRECT: Google Analytics redirects traffic to different variation
   * pages, reports the chosen variation and evaluates the results.
   * - API: Google Analytics chooses and reports the variation to serve and
   * evaluates the results; the caller is responsible for serving the selected
   * variation.
   * - EXTERNAL: The variations will be served externally and the chosen
   * variation reported to Google Analytics. The caller is responsible for
   * serving the selected variation and evaluating the results.
   */
  core.String servingFramework;

  /**
   * The snippet of code to include on the control page(s). This field is
   * read-only.
   */
  core.String snippet;

  /**
   * The starting time of the experiment (the time the status changed from
   * READY_TO_RUN to RUNNING). This field is present only if the experiment has
   * started. This field is read-only.
   */
  core.DateTime startTime;

  /**
   * Experiment status. Possible values: "DRAFT", "READY_TO_RUN", "RUNNING",
   * "ENDED". Experiments can be created in the "DRAFT", "READY_TO_RUN" or
   * "RUNNING" state. This field is required when creating an experiment.
   */
  core.String status;

  /**
   * A floating-point number between 0 and 1. Specifies the fraction of the
   * traffic that participates in the experiment. Can be changed for a running
   * experiment. This field may not be changed for an experiments whose status
   * is ENDED.
   */
  core.double trafficCoverage;

  /** Time the experiment was last modified. This field is read-only. */
  core.DateTime updated;

  /**
   * Array of variations. The first variation in the array is the original. The
   * number of variations may not change once an experiment is in the RUNNING
   * state. At least two variations are required before status can be set to
   * RUNNING.
   */
  core.List<ExperimentVariations> variations;

  /**
   * Web property ID to which this experiment belongs. The web property ID is of
   * the form UA-XXXXX-YY. This field is read-only.
   */
  core.String webPropertyId;

  /**
   * A floating-point number between 0 and 1. Specifies the necessary confidence
   * level to choose a winner. This field may not be changed for an experiments
   * whose status is ENDED.
   */
  core.double winnerConfidenceLevel;

  /**
   * Boolean specifying whether a winner has been found for this experiment.
   * This field is read-only.
   */
  core.bool winnerFound;


  Experiment();

  Experiment.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("description")) {
      description = _json["description"];
    }
    if (_json.containsKey("editableInGaUi")) {
      editableInGaUi = _json["editableInGaUi"];
    }
    if (_json.containsKey("endTime")) {
      endTime = core.DateTime.parse(_json["endTime"]);
    }
    if (_json.containsKey("equalWeighting")) {
      equalWeighting = _json["equalWeighting"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("minimumExperimentLengthInDays")) {
      minimumExperimentLengthInDays = _json["minimumExperimentLengthInDays"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("objectiveMetric")) {
      objectiveMetric = _json["objectiveMetric"];
    }
    if (_json.containsKey("optimizationType")) {
      optimizationType = _json["optimizationType"];
    }
    if (_json.containsKey("parentLink")) {
      parentLink = new ExperimentParentLink.fromJson(_json["parentLink"]);
    }
    if (_json.containsKey("profileId")) {
      profileId = _json["profileId"];
    }
    if (_json.containsKey("reasonExperimentEnded")) {
      reasonExperimentEnded = _json["reasonExperimentEnded"];
    }
    if (_json.containsKey("rewriteVariationUrlsAsOriginal")) {
      rewriteVariationUrlsAsOriginal = _json["rewriteVariationUrlsAsOriginal"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("servingFramework")) {
      servingFramework = _json["servingFramework"];
    }
    if (_json.containsKey("snippet")) {
      snippet = _json["snippet"];
    }
    if (_json.containsKey("startTime")) {
      startTime = core.DateTime.parse(_json["startTime"]);
    }
    if (_json.containsKey("status")) {
      status = _json["status"];
    }
    if (_json.containsKey("trafficCoverage")) {
      trafficCoverage = _json["trafficCoverage"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
    if (_json.containsKey("variations")) {
      variations = _json["variations"].map((value) => new ExperimentVariations.fromJson(value)).toList();
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
    if (_json.containsKey("winnerConfidenceLevel")) {
      winnerConfidenceLevel = _json["winnerConfidenceLevel"];
    }
    if (_json.containsKey("winnerFound")) {
      winnerFound = _json["winnerFound"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (description != null) {
      _json["description"] = description;
    }
    if (editableInGaUi != null) {
      _json["editableInGaUi"] = editableInGaUi;
    }
    if (endTime != null) {
      _json["endTime"] = (endTime).toIso8601String();
    }
    if (equalWeighting != null) {
      _json["equalWeighting"] = equalWeighting;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (minimumExperimentLengthInDays != null) {
      _json["minimumExperimentLengthInDays"] = minimumExperimentLengthInDays;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (objectiveMetric != null) {
      _json["objectiveMetric"] = objectiveMetric;
    }
    if (optimizationType != null) {
      _json["optimizationType"] = optimizationType;
    }
    if (parentLink != null) {
      _json["parentLink"] = (parentLink).toJson();
    }
    if (profileId != null) {
      _json["profileId"] = profileId;
    }
    if (reasonExperimentEnded != null) {
      _json["reasonExperimentEnded"] = reasonExperimentEnded;
    }
    if (rewriteVariationUrlsAsOriginal != null) {
      _json["rewriteVariationUrlsAsOriginal"] = rewriteVariationUrlsAsOriginal;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (servingFramework != null) {
      _json["servingFramework"] = servingFramework;
    }
    if (snippet != null) {
      _json["snippet"] = snippet;
    }
    if (startTime != null) {
      _json["startTime"] = (startTime).toIso8601String();
    }
    if (status != null) {
      _json["status"] = status;
    }
    if (trafficCoverage != null) {
      _json["trafficCoverage"] = trafficCoverage;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    if (variations != null) {
      _json["variations"] = variations.map((value) => (value).toJson()).toList();
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    if (winnerConfidenceLevel != null) {
      _json["winnerConfidenceLevel"] = winnerConfidenceLevel;
    }
    if (winnerFound != null) {
      _json["winnerFound"] = winnerFound;
    }
    return _json;
  }
}


/**
 * An experiment collection lists Analytics experiments to which the user has
 * access. Each view (profile) can have a set of experiments. Each resource in
 * the Experiment collection corresponds to a single Analytics experiment.
 */
class Experiments {
  /** A list of experiments. */
  core.List<Experiment> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this experiment collection. */
  core.String nextLink;

  /** Link to previous page for this experiment collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * resources in the result.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  Experiments();

  Experiments.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Experiment.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** Details for the filter of the type ADVANCED. */
class FilterAdvancedDetails {
  /** Indicates if the filter expressions are case sensitive. */
  core.bool caseSensitive;

  /** Expression to extract from field A. */
  core.String extractA;

  /** Expression to extract from field B. */
  core.String extractB;

  /** Field A. */
  core.String fieldA;

  /** Indicates if field A is required to match. */
  core.bool fieldARequired;

  /** Field B. */
  core.String fieldB;

  /** Indicates if field B is required to match. */
  core.bool fieldBRequired;

  /** Expression used to construct the output value. */
  core.String outputConstructor;

  /** Output field. */
  core.String outputToField;

  /**
   * Indicates if the existing value of the output field, if any, should be
   * overridden by the output expression.
   */
  core.bool overrideOutputField;


  FilterAdvancedDetails();

  FilterAdvancedDetails.fromJson(core.Map _json) {
    if (_json.containsKey("caseSensitive")) {
      caseSensitive = _json["caseSensitive"];
    }
    if (_json.containsKey("extractA")) {
      extractA = _json["extractA"];
    }
    if (_json.containsKey("extractB")) {
      extractB = _json["extractB"];
    }
    if (_json.containsKey("fieldA")) {
      fieldA = _json["fieldA"];
    }
    if (_json.containsKey("fieldARequired")) {
      fieldARequired = _json["fieldARequired"];
    }
    if (_json.containsKey("fieldB")) {
      fieldB = _json["fieldB"];
    }
    if (_json.containsKey("fieldBRequired")) {
      fieldBRequired = _json["fieldBRequired"];
    }
    if (_json.containsKey("outputConstructor")) {
      outputConstructor = _json["outputConstructor"];
    }
    if (_json.containsKey("outputToField")) {
      outputToField = _json["outputToField"];
    }
    if (_json.containsKey("overrideOutputField")) {
      overrideOutputField = _json["overrideOutputField"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (caseSensitive != null) {
      _json["caseSensitive"] = caseSensitive;
    }
    if (extractA != null) {
      _json["extractA"] = extractA;
    }
    if (extractB != null) {
      _json["extractB"] = extractB;
    }
    if (fieldA != null) {
      _json["fieldA"] = fieldA;
    }
    if (fieldARequired != null) {
      _json["fieldARequired"] = fieldARequired;
    }
    if (fieldB != null) {
      _json["fieldB"] = fieldB;
    }
    if (fieldBRequired != null) {
      _json["fieldBRequired"] = fieldBRequired;
    }
    if (outputConstructor != null) {
      _json["outputConstructor"] = outputConstructor;
    }
    if (outputToField != null) {
      _json["outputToField"] = outputToField;
    }
    if (overrideOutputField != null) {
      _json["overrideOutputField"] = overrideOutputField;
    }
    return _json;
  }
}


/** Details for the filter of the type LOWER. */
class FilterLowercaseDetails {
  /** Field to use in the filter. */
  core.String field;


  FilterLowercaseDetails();

  FilterLowercaseDetails.fromJson(core.Map _json) {
    if (_json.containsKey("field")) {
      field = _json["field"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (field != null) {
      _json["field"] = field;
    }
    return _json;
  }
}


/**
 * Parent link for this filter. Points to the account to which this filter
 * belongs.
 */
class FilterParentLink {
  /** Link to the account to which this filter belongs. */
  core.String href;

  /** Value is "analytics#account". */
  core.String type;


  FilterParentLink();

  FilterParentLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Details for the filter of the type SEARCH_AND_REPLACE. */
class FilterSearchAndReplaceDetails {
  /** Determines if the filter is case sensitive. */
  core.bool caseSensitive;

  /** Field to use in the filter. */
  core.String field;

  /** Term to replace the search term with. */
  core.String replaceString;

  /** Term to search. */
  core.String searchString;


  FilterSearchAndReplaceDetails();

  FilterSearchAndReplaceDetails.fromJson(core.Map _json) {
    if (_json.containsKey("caseSensitive")) {
      caseSensitive = _json["caseSensitive"];
    }
    if (_json.containsKey("field")) {
      field = _json["field"];
    }
    if (_json.containsKey("replaceString")) {
      replaceString = _json["replaceString"];
    }
    if (_json.containsKey("searchString")) {
      searchString = _json["searchString"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (caseSensitive != null) {
      _json["caseSensitive"] = caseSensitive;
    }
    if (field != null) {
      _json["field"] = field;
    }
    if (replaceString != null) {
      _json["replaceString"] = replaceString;
    }
    if (searchString != null) {
      _json["searchString"] = searchString;
    }
    return _json;
  }
}


/** Details for the filter of the type UPPER. */
class FilterUppercaseDetails {
  /** Field to use in the filter. */
  core.String field;


  FilterUppercaseDetails();

  FilterUppercaseDetails.fromJson(core.Map _json) {
    if (_json.containsKey("field")) {
      field = _json["field"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (field != null) {
      _json["field"] = field;
    }
    return _json;
  }
}


/** JSON template for an Analytics account filter. */
class Filter {
  /** Account ID to which this filter belongs. */
  core.String accountId;

  /** Details for the filter of the type ADVANCED. */
  FilterAdvancedDetails advancedDetails;

  /** Time this filter was created. */
  core.DateTime created;

  /** Details for the filter of the type EXCLUDE. */
  FilterExpression excludeDetails;

  /** Filter ID. */
  core.String id;

  /** Details for the filter of the type INCLUDE. */
  FilterExpression includeDetails;

  /** Resource type for Analytics filter. */
  core.String kind;

  /** Details for the filter of the type LOWER. */
  FilterLowercaseDetails lowercaseDetails;

  /** Name of this filter. */
  core.String name;

  /**
   * Parent link for this filter. Points to the account to which this filter
   * belongs.
   */
  FilterParentLink parentLink;

  /** Details for the filter of the type SEARCH_AND_REPLACE. */
  FilterSearchAndReplaceDetails searchAndReplaceDetails;

  /** Link for this filter. */
  core.String selfLink;

  /**
   * Type of this filter. Possible values are INCLUDE, EXCLUDE, LOWERCASE,
   * UPPERCASE, SEARCH_AND_REPLACE and ADVANCED.
   */
  core.String type;

  /** Time this filter was last modified. */
  core.DateTime updated;

  /** Details for the filter of the type UPPER. */
  FilterUppercaseDetails uppercaseDetails;


  Filter();

  Filter.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("advancedDetails")) {
      advancedDetails = new FilterAdvancedDetails.fromJson(_json["advancedDetails"]);
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("excludeDetails")) {
      excludeDetails = new FilterExpression.fromJson(_json["excludeDetails"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("includeDetails")) {
      includeDetails = new FilterExpression.fromJson(_json["includeDetails"]);
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("lowercaseDetails")) {
      lowercaseDetails = new FilterLowercaseDetails.fromJson(_json["lowercaseDetails"]);
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("parentLink")) {
      parentLink = new FilterParentLink.fromJson(_json["parentLink"]);
    }
    if (_json.containsKey("searchAndReplaceDetails")) {
      searchAndReplaceDetails = new FilterSearchAndReplaceDetails.fromJson(_json["searchAndReplaceDetails"]);
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
    if (_json.containsKey("uppercaseDetails")) {
      uppercaseDetails = new FilterUppercaseDetails.fromJson(_json["uppercaseDetails"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (advancedDetails != null) {
      _json["advancedDetails"] = (advancedDetails).toJson();
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (excludeDetails != null) {
      _json["excludeDetails"] = (excludeDetails).toJson();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (includeDetails != null) {
      _json["includeDetails"] = (includeDetails).toJson();
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (lowercaseDetails != null) {
      _json["lowercaseDetails"] = (lowercaseDetails).toJson();
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (parentLink != null) {
      _json["parentLink"] = (parentLink).toJson();
    }
    if (searchAndReplaceDetails != null) {
      _json["searchAndReplaceDetails"] = (searchAndReplaceDetails).toJson();
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (type != null) {
      _json["type"] = type;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    if (uppercaseDetails != null) {
      _json["uppercaseDetails"] = (uppercaseDetails).toJson();
    }
    return _json;
  }
}


/** JSON template for an Analytics filter expression. */
class FilterExpression {
  /** Determines if the filter is case sensitive. */
  core.bool caseSensitive;

  /** Filter expression value */
  core.String expressionValue;

  /**
   * Field to filter. Possible values:
   * - Reserved
   * - UNUSED,
   * - Content and Traffic
   * - PAGE_REQUEST_URI,
   * - PAGE_HOSTNAME,
   * - PAGE_TITLE,
   * - REFERRAL,
   * - COST_DATA_URI (Campaign target URL),
   * - HIT_TYPE,
   * - INTERNAL_SEARCH_TERM,
   * - INTERNAL_SEARCH_TYPE,
   * - SOURCE_PROPERTY_TRACKING_ID,
   * - Campaign or AdGroup
   * - CAMPAIGN_SOURCE,
   * - CAMPAIGN_MEDIUM,
   * - CAMPAIGN_NAME,
   * - CAMPAIGN_AD_GROUP,
   * - CAMPAIGN_TERM,
   * - CAMPAIGN_CONTENT,
   * - CAMPAIGN_CODE,
   * - CAMPAIGN_REFERRAL_PATH,
   * - E-Commerce
   * - TRANSACTION_COUNTRY,
   * - TRANSACTION_REGION,
   * - TRANSACTION_CITY,
   * - TRANSACTION_AFFILIATION (Store or order location),
   * - ITEM_NAME,
   * - ITEM_CODE,
   * - ITEM_VARIATION,
   * - TRANSACTION_ID,
   * - TRANSACTION_CURRENCY_CODE,
   * - PRODUCT_ACTION_TYPE,
   * - Audience/Users
   * - BROWSER,
   * - BROWSER_VERSION,
   * - BROWSER_SIZE,
   * - PLATFORM,
   * - PLATFORM_VERSION,
   * - LANGUAGE,
   * - SCREEN_RESOLUTION,
   * - SCREEN_COLORS,
   * - JAVA_ENABLED,
   * - FLASH_VERSION,
   * - GEO_SPEED (Connection speed),
   * - VISITOR_TYPE,
   * - GEO_ORGANIZATION (ISP organization),
   * - GEO_DOMAIN,
   * - GEO_IP_ADDRESS,
   * - GEO_IP_VERSION,
   * - Location
   * - GEO_COUNTRY,
   * - GEO_REGION,
   * - GEO_CITY,
   * - Event
   * - EVENT_CATEGORY,
   * - EVENT_ACTION,
   * - EVENT_LABEL,
   * - Other
   * - CUSTOM_FIELD_1,
   * - CUSTOM_FIELD_2,
   * - USER_DEFINED_VALUE,
   * - Application
   * - APP_ID,
   * - APP_INSTALLER_ID,
   * - APP_NAME,
   * - APP_VERSION,
   * - SCREEN,
   * - IS_APP,
   * - IS_FATAL_EXCEPTION,
   * - EXCEPTION_DESCRIPTION,
   * - Mobile device
   * - IS_MOBILE,
   * - IS_TABLET,
   * - MOBILE_HAS_QWERTY_KEYBOARD,
   * - MOBILE_HAS_NFC_SUPPORT,
   * - MOBILE_HAS_CELLULAR_RADIO,
   * - MOBILE_HAS_WIFI_SUPPORT,
   * - MOBILE_BRAND_NAME,
   * - MOBILE_MODEL_NAME,
   * - MOBILE_MARKETING_NAME,
   * - MOBILE_POINTING_METHOD,
   * - Social
   * - SOCIAL_NETWORK,
   * - SOCIAL_ACTION,
   * - SOCIAL_ACTION_TARGET,
   */
  core.String field;

  /** Kind value for filter expression */
  core.String kind;

  /**
   * Match type for this filter. Possible values are BEGINS_WITH, EQUAL,
   * ENDS_WITH, CONTAINS, MATCHES. Include and Exclude filters can use any match
   * type. Match type is not applicable to Upper case and Lower case filters.
   * Search and Replace expressions in the Search and Replace filter and all
   * filter expressions in the Advanced filter default to MATCHES. User should
   * not set match type for those filters.
   */
  core.String matchType;


  FilterExpression();

  FilterExpression.fromJson(core.Map _json) {
    if (_json.containsKey("caseSensitive")) {
      caseSensitive = _json["caseSensitive"];
    }
    if (_json.containsKey("expressionValue")) {
      expressionValue = _json["expressionValue"];
    }
    if (_json.containsKey("field")) {
      field = _json["field"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("matchType")) {
      matchType = _json["matchType"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (caseSensitive != null) {
      _json["caseSensitive"] = caseSensitive;
    }
    if (expressionValue != null) {
      _json["expressionValue"] = expressionValue;
    }
    if (field != null) {
      _json["field"] = field;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (matchType != null) {
      _json["matchType"] = matchType;
    }
    return _json;
  }
}


/** JSON template for a profile filter link. */
class FilterRef {
  /** Account ID to which this filter belongs. */
  core.String accountId;

  /** Link for this filter. */
  core.String href;

  /** Filter ID. */
  core.String id;

  /** Kind value for filter reference. */
  core.String kind;

  /** Name of this filter. */
  core.String name;


  FilterRef();

  FilterRef.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (href != null) {
      _json["href"] = href;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}


/**
 * A filter collection lists filters created by users in an Analytics account.
 * Each resource in the collection corresponds to a filter.
 */
class Filters {
  /** A list of filters. */
  core.List<Filter> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1,000 with
   * a value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this filter collection. */
  core.String nextLink;

  /** Link to previous page for this filter collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  Filters();

  Filters.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Filter.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** Not documented yet. */
class GaDataColumnHeaders {
  /** Column Type. Either DIMENSION or METRIC. */
  core.String columnType;

  /**
   * Data type. Dimension column headers have only STRING as the data type.
   * Metric column headers have data types for metric values such as INTEGER,
   * DOUBLE, CURRENCY etc.
   */
  core.String dataType;

  /** Column name. */
  core.String name;


  GaDataColumnHeaders();

  GaDataColumnHeaders.fromJson(core.Map _json) {
    if (_json.containsKey("columnType")) {
      columnType = _json["columnType"];
    }
    if (_json.containsKey("dataType")) {
      dataType = _json["dataType"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (columnType != null) {
      _json["columnType"] = columnType;
    }
    if (dataType != null) {
      _json["dataType"] = dataType;
    }
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}


/** Not documented yet. */
class GaDataDataTableCols {
  /** Not documented yet. */
  core.String id;

  /** Not documented yet. */
  core.String label;

  /** Not documented yet. */
  core.String type;


  GaDataDataTableCols();

  GaDataDataTableCols.fromJson(core.Map _json) {
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("label")) {
      label = _json["label"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (id != null) {
      _json["id"] = id;
    }
    if (label != null) {
      _json["label"] = label;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Not documented yet. */
class GaDataDataTableRowsC {
  /** Not documented yet. */
  core.String v;


  GaDataDataTableRowsC();

  GaDataDataTableRowsC.fromJson(core.Map _json) {
    if (_json.containsKey("v")) {
      v = _json["v"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (v != null) {
      _json["v"] = v;
    }
    return _json;
  }
}


/** Not documented yet. */
class GaDataDataTableRows {
  /** Not documented yet. */
  core.List<GaDataDataTableRowsC> c;


  GaDataDataTableRows();

  GaDataDataTableRows.fromJson(core.Map _json) {
    if (_json.containsKey("c")) {
      c = _json["c"].map((value) => new GaDataDataTableRowsC.fromJson(value)).toList();
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (c != null) {
      _json["c"] = c.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}


/** Not documented yet. */
class GaDataDataTable {
  /** Not documented yet. */
  core.List<GaDataDataTableCols> cols;

  /** Not documented yet. */
  core.List<GaDataDataTableRows> rows;


  GaDataDataTable();

  GaDataDataTable.fromJson(core.Map _json) {
    if (_json.containsKey("cols")) {
      cols = _json["cols"].map((value) => new GaDataDataTableCols.fromJson(value)).toList();
    }
    if (_json.containsKey("rows")) {
      rows = _json["rows"].map((value) => new GaDataDataTableRows.fromJson(value)).toList();
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (cols != null) {
      _json["cols"] = cols.map((value) => (value).toJson()).toList();
    }
    if (rows != null) {
      _json["rows"] = rows.map((value) => (value).toJson()).toList();
    }
    return _json;
  }
}


/**
 * Information for the view (profile), for which the Analytics data was
 * requested.
 */
class GaDataProfileInfo {
  /** Account ID to which this view (profile) belongs. */
  core.String accountId;

  /** Internal ID for the web property to which this view (profile) belongs. */
  core.String internalWebPropertyId;

  /** View (Profile) ID. */
  core.String profileId;

  /** View (Profile) name. */
  core.String profileName;

  /** Table ID for view (profile). */
  core.String tableId;

  /** Web Property ID to which this view (profile) belongs. */
  core.String webPropertyId;


  GaDataProfileInfo();

  GaDataProfileInfo.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("profileId")) {
      profileId = _json["profileId"];
    }
    if (_json.containsKey("profileName")) {
      profileName = _json["profileName"];
    }
    if (_json.containsKey("tableId")) {
      tableId = _json["tableId"];
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (profileId != null) {
      _json["profileId"] = profileId;
    }
    if (profileName != null) {
      _json["profileName"] = profileName;
    }
    if (tableId != null) {
      _json["tableId"] = tableId;
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/** Analytics data request query parameters. */
class GaDataQuery {
  /** List of analytics dimensions. */
  core.String dimensions;

  /** End date. */
  core.String end_date;

  /** Comma-separated list of dimension or metric filters. */
  core.String filters;

  /** Unique table ID. */
  core.String ids;

  /** Maximum results per page. */
  core.int max_results;

  /** List of analytics metrics. */
  core.List<core.String> metrics;

  /** Desired sampling level */
  core.String samplingLevel;

  /** Analytics advanced segment. */
  core.String segment;

  /** List of dimensions or metrics based on which Analytics data is sorted. */
  core.List<core.String> sort;

  /** Start date. */
  core.String start_date;

  /** Start index. */
  core.int start_index;


  GaDataQuery();

  GaDataQuery.fromJson(core.Map _json) {
    if (_json.containsKey("dimensions")) {
      dimensions = _json["dimensions"];
    }
    if (_json.containsKey("end-date")) {
      end_date = _json["end-date"];
    }
    if (_json.containsKey("filters")) {
      filters = _json["filters"];
    }
    if (_json.containsKey("ids")) {
      ids = _json["ids"];
    }
    if (_json.containsKey("max-results")) {
      max_results = _json["max-results"];
    }
    if (_json.containsKey("metrics")) {
      metrics = _json["metrics"];
    }
    if (_json.containsKey("samplingLevel")) {
      samplingLevel = _json["samplingLevel"];
    }
    if (_json.containsKey("segment")) {
      segment = _json["segment"];
    }
    if (_json.containsKey("sort")) {
      sort = _json["sort"];
    }
    if (_json.containsKey("start-date")) {
      start_date = _json["start-date"];
    }
    if (_json.containsKey("start-index")) {
      start_index = _json["start-index"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (dimensions != null) {
      _json["dimensions"] = dimensions;
    }
    if (end_date != null) {
      _json["end-date"] = end_date;
    }
    if (filters != null) {
      _json["filters"] = filters;
    }
    if (ids != null) {
      _json["ids"] = ids;
    }
    if (max_results != null) {
      _json["max-results"] = max_results;
    }
    if (metrics != null) {
      _json["metrics"] = metrics;
    }
    if (samplingLevel != null) {
      _json["samplingLevel"] = samplingLevel;
    }
    if (segment != null) {
      _json["segment"] = segment;
    }
    if (sort != null) {
      _json["sort"] = sort;
    }
    if (start_date != null) {
      _json["start-date"] = start_date;
    }
    if (start_index != null) {
      _json["start-index"] = start_index;
    }
    return _json;
  }
}


/** Analytics data for a given view (profile). */
class GaData {
  /**
   * Column headers that list dimension names followed by the metric names. The
   * order of dimensions and metrics is same as specified in the request.
   */
  core.List<GaDataColumnHeaders> columnHeaders;

  /** Determines if Analytics data contains samples. */
  core.bool containsSampledData;

  /** Not documented yet. */
  GaDataDataTable dataTable;

  /** Unique ID for this data response. */
  core.String id;

  /**
   * The maximum number of rows the response can contain, regardless of the
   * actual number of rows returned. Its value ranges from 1 to 10,000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Resource type. */
  core.String kind;

  /** Link to next page for this Analytics data query. */
  core.String nextLink;

  /** Link to previous page for this Analytics data query. */
  core.String previousLink;

  /**
   * Information for the view (profile), for which the Analytics data was
   * requested.
   */
  GaDataProfileInfo profileInfo;

  /** Analytics data request query parameters. */
  GaDataQuery query;

  /**
   * Analytics data rows, where each row contains a list of dimension values
   * followed by the metric values. The order of dimensions and metrics is same
   * as specified in the request.
   */
  core.List<core.List<core.String>> rows;

  /** The number of samples used to calculate the result. */
  core.String sampleSize;

  /** Total size of the sample space from which the samples were selected. */
  core.String sampleSpace;

  /** Link to this page. */
  core.String selfLink;

  /**
   * The total number of rows for the query, regardless of the number of rows in
   * the response.
   */
  core.int totalResults;

  /**
   * Total values for the requested metrics over all the results, not just the
   * results returned in this response. The order of the metric totals is same
   * as the metric order specified in the request.
   */
  core.Map<core.String, core.String> totalsForAllResults;


  GaData();

  GaData.fromJson(core.Map _json) {
    if (_json.containsKey("columnHeaders")) {
      columnHeaders = _json["columnHeaders"].map((value) => new GaDataColumnHeaders.fromJson(value)).toList();
    }
    if (_json.containsKey("containsSampledData")) {
      containsSampledData = _json["containsSampledData"];
    }
    if (_json.containsKey("dataTable")) {
      dataTable = new GaDataDataTable.fromJson(_json["dataTable"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("profileInfo")) {
      profileInfo = new GaDataProfileInfo.fromJson(_json["profileInfo"]);
    }
    if (_json.containsKey("query")) {
      query = new GaDataQuery.fromJson(_json["query"]);
    }
    if (_json.containsKey("rows")) {
      rows = _json["rows"];
    }
    if (_json.containsKey("sampleSize")) {
      sampleSize = _json["sampleSize"];
    }
    if (_json.containsKey("sampleSpace")) {
      sampleSpace = _json["sampleSpace"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("totalsForAllResults")) {
      totalsForAllResults = _json["totalsForAllResults"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (columnHeaders != null) {
      _json["columnHeaders"] = columnHeaders.map((value) => (value).toJson()).toList();
    }
    if (containsSampledData != null) {
      _json["containsSampledData"] = containsSampledData;
    }
    if (dataTable != null) {
      _json["dataTable"] = (dataTable).toJson();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (profileInfo != null) {
      _json["profileInfo"] = (profileInfo).toJson();
    }
    if (query != null) {
      _json["query"] = (query).toJson();
    }
    if (rows != null) {
      _json["rows"] = rows;
    }
    if (sampleSize != null) {
      _json["sampleSize"] = sampleSize;
    }
    if (sampleSpace != null) {
      _json["sampleSpace"] = sampleSpace;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (totalsForAllResults != null) {
      _json["totalsForAllResults"] = totalsForAllResults;
    }
    return _json;
  }
}


/** Not documented yet. */
class GoalEventDetailsEventConditions {
  /**
   * Type of comparison. Possible values are LESS_THAN, GREATER_THAN or EQUAL.
   */
  core.String comparisonType;

  /** Value used for this comparison. */
  core.String comparisonValue;

  /** Expression used for this match. */
  core.String expression;

  /**
   * Type of the match to be performed. Possible values are REGEXP, BEGINS_WITH,
   * or EXACT.
   */
  core.String matchType;

  /**
   * Type of this event condition. Possible values are CATEGORY, ACTION, LABEL,
   * or VALUE.
   */
  core.String type;


  GoalEventDetailsEventConditions();

  GoalEventDetailsEventConditions.fromJson(core.Map _json) {
    if (_json.containsKey("comparisonType")) {
      comparisonType = _json["comparisonType"];
    }
    if (_json.containsKey("comparisonValue")) {
      comparisonValue = _json["comparisonValue"];
    }
    if (_json.containsKey("expression")) {
      expression = _json["expression"];
    }
    if (_json.containsKey("matchType")) {
      matchType = _json["matchType"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (comparisonType != null) {
      _json["comparisonType"] = comparisonType;
    }
    if (comparisonValue != null) {
      _json["comparisonValue"] = comparisonValue;
    }
    if (expression != null) {
      _json["expression"] = expression;
    }
    if (matchType != null) {
      _json["matchType"] = matchType;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Details for the goal of the type EVENT. */
class GoalEventDetails {
  /** List of event conditions. */
  core.List<GoalEventDetailsEventConditions> eventConditions;

  /**
   * Determines if the event value should be used as the value for this goal.
   */
  core.bool useEventValue;


  GoalEventDetails();

  GoalEventDetails.fromJson(core.Map _json) {
    if (_json.containsKey("eventConditions")) {
      eventConditions = _json["eventConditions"].map((value) => new GoalEventDetailsEventConditions.fromJson(value)).toList();
    }
    if (_json.containsKey("useEventValue")) {
      useEventValue = _json["useEventValue"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (eventConditions != null) {
      _json["eventConditions"] = eventConditions.map((value) => (value).toJson()).toList();
    }
    if (useEventValue != null) {
      _json["useEventValue"] = useEventValue;
    }
    return _json;
  }
}


/**
 * Parent link for a goal. Points to the view (profile) to which this goal
 * belongs.
 */
class GoalParentLink {
  /** Link to the view (profile) to which this goal belongs. */
  core.String href;

  /** Value is "analytics#profile". */
  core.String type;


  GoalParentLink();

  GoalParentLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Not documented yet. */
class GoalUrlDestinationDetailsSteps {
  /** Step name. */
  core.String name;

  /** Step number. */
  core.int number;

  /** URL for this step. */
  core.String url;


  GoalUrlDestinationDetailsSteps();

  GoalUrlDestinationDetailsSteps.fromJson(core.Map _json) {
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("number")) {
      number = _json["number"];
    }
    if (_json.containsKey("url")) {
      url = _json["url"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (name != null) {
      _json["name"] = name;
    }
    if (number != null) {
      _json["number"] = number;
    }
    if (url != null) {
      _json["url"] = url;
    }
    return _json;
  }
}


/** Details for the goal of the type URL_DESTINATION. */
class GoalUrlDestinationDetails {
  /**
   * Determines if the goal URL must exactly match the capitalization of visited
   * URLs.
   */
  core.bool caseSensitive;

  /** Determines if the first step in this goal is required. */
  core.bool firstStepRequired;

  /**
   * Match type for the goal URL. Possible values are HEAD, EXACT, or REGEX.
   */
  core.String matchType;

  /** List of steps configured for this goal funnel. */
  core.List<GoalUrlDestinationDetailsSteps> steps;

  /** URL for this goal. */
  core.String url;


  GoalUrlDestinationDetails();

  GoalUrlDestinationDetails.fromJson(core.Map _json) {
    if (_json.containsKey("caseSensitive")) {
      caseSensitive = _json["caseSensitive"];
    }
    if (_json.containsKey("firstStepRequired")) {
      firstStepRequired = _json["firstStepRequired"];
    }
    if (_json.containsKey("matchType")) {
      matchType = _json["matchType"];
    }
    if (_json.containsKey("steps")) {
      steps = _json["steps"].map((value) => new GoalUrlDestinationDetailsSteps.fromJson(value)).toList();
    }
    if (_json.containsKey("url")) {
      url = _json["url"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (caseSensitive != null) {
      _json["caseSensitive"] = caseSensitive;
    }
    if (firstStepRequired != null) {
      _json["firstStepRequired"] = firstStepRequired;
    }
    if (matchType != null) {
      _json["matchType"] = matchType;
    }
    if (steps != null) {
      _json["steps"] = steps.map((value) => (value).toJson()).toList();
    }
    if (url != null) {
      _json["url"] = url;
    }
    return _json;
  }
}


/** Details for the goal of the type VISIT_NUM_PAGES. */
class GoalVisitNumPagesDetails {
  /**
   * Type of comparison. Possible values are LESS_THAN, GREATER_THAN, or EQUAL.
   */
  core.String comparisonType;

  /** Value used for this comparison. */
  core.String comparisonValue;


  GoalVisitNumPagesDetails();

  GoalVisitNumPagesDetails.fromJson(core.Map _json) {
    if (_json.containsKey("comparisonType")) {
      comparisonType = _json["comparisonType"];
    }
    if (_json.containsKey("comparisonValue")) {
      comparisonValue = _json["comparisonValue"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (comparisonType != null) {
      _json["comparisonType"] = comparisonType;
    }
    if (comparisonValue != null) {
      _json["comparisonValue"] = comparisonValue;
    }
    return _json;
  }
}


/** Details for the goal of the type VISIT_TIME_ON_SITE. */
class GoalVisitTimeOnSiteDetails {
  /** Type of comparison. Possible values are LESS_THAN or GREATER_THAN. */
  core.String comparisonType;

  /** Value used for this comparison. */
  core.String comparisonValue;


  GoalVisitTimeOnSiteDetails();

  GoalVisitTimeOnSiteDetails.fromJson(core.Map _json) {
    if (_json.containsKey("comparisonType")) {
      comparisonType = _json["comparisonType"];
    }
    if (_json.containsKey("comparisonValue")) {
      comparisonValue = _json["comparisonValue"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (comparisonType != null) {
      _json["comparisonType"] = comparisonType;
    }
    if (comparisonValue != null) {
      _json["comparisonValue"] = comparisonValue;
    }
    return _json;
  }
}


/** JSON template for Analytics goal resource. */
class Goal {
  /** Account ID to which this goal belongs. */
  core.String accountId;

  /** Determines whether this goal is active. */
  core.bool active;

  /** Time this goal was created. */
  core.DateTime created;

  /** Details for the goal of the type EVENT. */
  GoalEventDetails eventDetails;

  /** Goal ID. */
  core.String id;

  /** Internal ID for the web property to which this goal belongs. */
  core.String internalWebPropertyId;

  /** Resource type for an Analytics goal. */
  core.String kind;

  /** Goal name. */
  core.String name;

  /**
   * Parent link for a goal. Points to the view (profile) to which this goal
   * belongs.
   */
  GoalParentLink parentLink;

  /** View (Profile) ID to which this goal belongs. */
  core.String profileId;

  /** Link for this goal. */
  core.String selfLink;

  /**
   * Goal type. Possible values are URL_DESTINATION, VISIT_TIME_ON_SITE,
   * VISIT_NUM_PAGES, AND EVENT.
   */
  core.String type;

  /** Time this goal was last modified. */
  core.DateTime updated;

  /** Details for the goal of the type URL_DESTINATION. */
  GoalUrlDestinationDetails urlDestinationDetails;

  /** Goal value. */
  core.double value;

  /** Details for the goal of the type VISIT_NUM_PAGES. */
  GoalVisitNumPagesDetails visitNumPagesDetails;

  /** Details for the goal of the type VISIT_TIME_ON_SITE. */
  GoalVisitTimeOnSiteDetails visitTimeOnSiteDetails;

  /**
   * Web property ID to which this goal belongs. The web property ID is of the
   * form UA-XXXXX-YY.
   */
  core.String webPropertyId;


  Goal();

  Goal.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("active")) {
      active = _json["active"];
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("eventDetails")) {
      eventDetails = new GoalEventDetails.fromJson(_json["eventDetails"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("parentLink")) {
      parentLink = new GoalParentLink.fromJson(_json["parentLink"]);
    }
    if (_json.containsKey("profileId")) {
      profileId = _json["profileId"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
    if (_json.containsKey("urlDestinationDetails")) {
      urlDestinationDetails = new GoalUrlDestinationDetails.fromJson(_json["urlDestinationDetails"]);
    }
    if (_json.containsKey("value")) {
      value = _json["value"];
    }
    if (_json.containsKey("visitNumPagesDetails")) {
      visitNumPagesDetails = new GoalVisitNumPagesDetails.fromJson(_json["visitNumPagesDetails"]);
    }
    if (_json.containsKey("visitTimeOnSiteDetails")) {
      visitTimeOnSiteDetails = new GoalVisitTimeOnSiteDetails.fromJson(_json["visitTimeOnSiteDetails"]);
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (active != null) {
      _json["active"] = active;
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (eventDetails != null) {
      _json["eventDetails"] = (eventDetails).toJson();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (parentLink != null) {
      _json["parentLink"] = (parentLink).toJson();
    }
    if (profileId != null) {
      _json["profileId"] = profileId;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (type != null) {
      _json["type"] = type;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    if (urlDestinationDetails != null) {
      _json["urlDestinationDetails"] = (urlDestinationDetails).toJson();
    }
    if (value != null) {
      _json["value"] = value;
    }
    if (visitNumPagesDetails != null) {
      _json["visitNumPagesDetails"] = (visitNumPagesDetails).toJson();
    }
    if (visitTimeOnSiteDetails != null) {
      _json["visitTimeOnSiteDetails"] = (visitTimeOnSiteDetails).toJson();
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/**
 * A goal collection lists Analytics goals to which the user has access. Each
 * view (profile) can have a set of goals. Each resource in the Goal collection
 * corresponds to a single Analytics goal.
 */
class Goals {
  /** A list of goals. */
  core.List<Goal> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this goal collection. */
  core.String nextLink;

  /** Link to previous page for this goal collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * resources in the result.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  Goals();

  Goals.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Goal.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** Not documented yet. */
class McfDataColumnHeaders {
  /** Column Type. Either DIMENSION or METRIC. */
  core.String columnType;

  /**
   * Data type. Dimension and metric values data types such as INTEGER, DOUBLE,
   * CURRENCY, MCF_SEQUENCE etc.
   */
  core.String dataType;

  /** Column name. */
  core.String name;


  McfDataColumnHeaders();

  McfDataColumnHeaders.fromJson(core.Map _json) {
    if (_json.containsKey("columnType")) {
      columnType = _json["columnType"];
    }
    if (_json.containsKey("dataType")) {
      dataType = _json["dataType"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (columnType != null) {
      _json["columnType"] = columnType;
    }
    if (dataType != null) {
      _json["dataType"] = dataType;
    }
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}


/**
 * Information for the view (profile), for which the Analytics data was
 * requested.
 */
class McfDataProfileInfo {
  /** Account ID to which this view (profile) belongs. */
  core.String accountId;

  /** Internal ID for the web property to which this view (profile) belongs. */
  core.String internalWebPropertyId;

  /** View (Profile) ID. */
  core.String profileId;

  /** View (Profile) name. */
  core.String profileName;

  /** Table ID for view (profile). */
  core.String tableId;

  /** Web Property ID to which this view (profile) belongs. */
  core.String webPropertyId;


  McfDataProfileInfo();

  McfDataProfileInfo.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("profileId")) {
      profileId = _json["profileId"];
    }
    if (_json.containsKey("profileName")) {
      profileName = _json["profileName"];
    }
    if (_json.containsKey("tableId")) {
      tableId = _json["tableId"];
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (profileId != null) {
      _json["profileId"] = profileId;
    }
    if (profileName != null) {
      _json["profileName"] = profileName;
    }
    if (tableId != null) {
      _json["tableId"] = tableId;
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/** Analytics data request query parameters. */
class McfDataQuery {
  /** List of analytics dimensions. */
  core.String dimensions;

  /** End date. */
  core.String end_date;

  /** Comma-separated list of dimension or metric filters. */
  core.String filters;

  /** Unique table ID. */
  core.String ids;

  /** Maximum results per page. */
  core.int max_results;

  /** List of analytics metrics. */
  core.List<core.String> metrics;

  /** Desired sampling level */
  core.String samplingLevel;

  /** Analytics advanced segment. */
  core.String segment;

  /** List of dimensions or metrics based on which Analytics data is sorted. */
  core.List<core.String> sort;

  /** Start date. */
  core.String start_date;

  /** Start index. */
  core.int start_index;


  McfDataQuery();

  McfDataQuery.fromJson(core.Map _json) {
    if (_json.containsKey("dimensions")) {
      dimensions = _json["dimensions"];
    }
    if (_json.containsKey("end-date")) {
      end_date = _json["end-date"];
    }
    if (_json.containsKey("filters")) {
      filters = _json["filters"];
    }
    if (_json.containsKey("ids")) {
      ids = _json["ids"];
    }
    if (_json.containsKey("max-results")) {
      max_results = _json["max-results"];
    }
    if (_json.containsKey("metrics")) {
      metrics = _json["metrics"];
    }
    if (_json.containsKey("samplingLevel")) {
      samplingLevel = _json["samplingLevel"];
    }
    if (_json.containsKey("segment")) {
      segment = _json["segment"];
    }
    if (_json.containsKey("sort")) {
      sort = _json["sort"];
    }
    if (_json.containsKey("start-date")) {
      start_date = _json["start-date"];
    }
    if (_json.containsKey("start-index")) {
      start_index = _json["start-index"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (dimensions != null) {
      _json["dimensions"] = dimensions;
    }
    if (end_date != null) {
      _json["end-date"] = end_date;
    }
    if (filters != null) {
      _json["filters"] = filters;
    }
    if (ids != null) {
      _json["ids"] = ids;
    }
    if (max_results != null) {
      _json["max-results"] = max_results;
    }
    if (metrics != null) {
      _json["metrics"] = metrics;
    }
    if (samplingLevel != null) {
      _json["samplingLevel"] = samplingLevel;
    }
    if (segment != null) {
      _json["segment"] = segment;
    }
    if (sort != null) {
      _json["sort"] = sort;
    }
    if (start_date != null) {
      _json["start-date"] = start_date;
    }
    if (start_index != null) {
      _json["start-index"] = start_index;
    }
    return _json;
  }
}


/** Not documented yet. */
class McfDataRowsConversionPathValue {
  /**
   * Type of an interaction on conversion path. Such as CLICK, IMPRESSION etc.
   */
  core.String interactionType;

  /**
   * Node value of an interaction on conversion path. Such as source, medium
   * etc.
   */
  core.String nodeValue;


  McfDataRowsConversionPathValue();

  McfDataRowsConversionPathValue.fromJson(core.Map _json) {
    if (_json.containsKey("interactionType")) {
      interactionType = _json["interactionType"];
    }
    if (_json.containsKey("nodeValue")) {
      nodeValue = _json["nodeValue"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (interactionType != null) {
      _json["interactionType"] = interactionType;
    }
    if (nodeValue != null) {
      _json["nodeValue"] = nodeValue;
    }
    return _json;
  }
}


/**
 * A union object representing a dimension or metric value. Only one of
 * "primitiveValue" or "conversionPathValue" attribute will be populated.
 */
class McfDataRows {
  /**
   * A conversion path dimension value, containing a list of interactions with
   * their attributes.
   */
  core.List<McfDataRowsConversionPathValue> conversionPathValue;

  /** A primitive dimension value. A primitive metric value. */
  core.String primitiveValue;


  McfDataRows();

  McfDataRows.fromJson(core.Map _json) {
    if (_json.containsKey("conversionPathValue")) {
      conversionPathValue = _json["conversionPathValue"].map((value) => new McfDataRowsConversionPathValue.fromJson(value)).toList();
    }
    if (_json.containsKey("primitiveValue")) {
      primitiveValue = _json["primitiveValue"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (conversionPathValue != null) {
      _json["conversionPathValue"] = conversionPathValue.map((value) => (value).toJson()).toList();
    }
    if (primitiveValue != null) {
      _json["primitiveValue"] = primitiveValue;
    }
    return _json;
  }
}


/** Multi-Channel Funnels data for a given view (profile). */
class McfData {
  /**
   * Column headers that list dimension names followed by the metric names. The
   * order of dimensions and metrics is same as specified in the request.
   */
  core.List<McfDataColumnHeaders> columnHeaders;

  /** Determines if the Analytics data contains sampled data. */
  core.bool containsSampledData;

  /** Unique ID for this data response. */
  core.String id;

  /**
   * The maximum number of rows the response can contain, regardless of the
   * actual number of rows returned. Its value ranges from 1 to 10,000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Resource type. */
  core.String kind;

  /** Link to next page for this Analytics data query. */
  core.String nextLink;

  /** Link to previous page for this Analytics data query. */
  core.String previousLink;

  /**
   * Information for the view (profile), for which the Analytics data was
   * requested.
   */
  McfDataProfileInfo profileInfo;

  /** Analytics data request query parameters. */
  McfDataQuery query;

  /**
   * Analytics data rows, where each row contains a list of dimension values
   * followed by the metric values. The order of dimensions and metrics is same
   * as specified in the request.
   */
  core.List<core.List<McfDataRows>> rows;

  /** The number of samples used to calculate the result. */
  core.String sampleSize;

  /** Total size of the sample space from which the samples were selected. */
  core.String sampleSpace;

  /** Link to this page. */
  core.String selfLink;

  /**
   * The total number of rows for the query, regardless of the number of rows in
   * the response.
   */
  core.int totalResults;

  /**
   * Total values for the requested metrics over all the results, not just the
   * results returned in this response. The order of the metric totals is same
   * as the metric order specified in the request.
   */
  core.Map<core.String, core.String> totalsForAllResults;


  McfData();

  McfData.fromJson(core.Map _json) {
    if (_json.containsKey("columnHeaders")) {
      columnHeaders = _json["columnHeaders"].map((value) => new McfDataColumnHeaders.fromJson(value)).toList();
    }
    if (_json.containsKey("containsSampledData")) {
      containsSampledData = _json["containsSampledData"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("profileInfo")) {
      profileInfo = new McfDataProfileInfo.fromJson(_json["profileInfo"]);
    }
    if (_json.containsKey("query")) {
      query = new McfDataQuery.fromJson(_json["query"]);
    }
    if (_json.containsKey("rows")) {
      rows = _json["rows"].map((value) => value.map((value) => new McfDataRows.fromJson(value)).toList()).toList();
    }
    if (_json.containsKey("sampleSize")) {
      sampleSize = _json["sampleSize"];
    }
    if (_json.containsKey("sampleSpace")) {
      sampleSpace = _json["sampleSpace"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("totalsForAllResults")) {
      totalsForAllResults = _json["totalsForAllResults"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (columnHeaders != null) {
      _json["columnHeaders"] = columnHeaders.map((value) => (value).toJson()).toList();
    }
    if (containsSampledData != null) {
      _json["containsSampledData"] = containsSampledData;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (profileInfo != null) {
      _json["profileInfo"] = (profileInfo).toJson();
    }
    if (query != null) {
      _json["query"] = (query).toJson();
    }
    if (rows != null) {
      _json["rows"] = rows.map((value) => value.map((value) => (value).toJson()).toList()).toList();
    }
    if (sampleSize != null) {
      _json["sampleSize"] = sampleSize;
    }
    if (sampleSpace != null) {
      _json["sampleSpace"] = sampleSpace;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (totalsForAllResults != null) {
      _json["totalsForAllResults"] = totalsForAllResults;
    }
    return _json;
  }
}


/**
 * Child link for this view (profile). Points to the list of goals for this view
 * (profile).
 */
class ProfileChildLink {
  /** Link to the list of goals for this view (profile). */
  core.String href;

  /** Value is "analytics#goals". */
  core.String type;


  ProfileChildLink();

  ProfileChildLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/**
 * Parent link for this view (profile). Points to the web property to which this
 * view (profile) belongs.
 */
class ProfileParentLink {
  /** Link to the web property to which this view (profile) belongs. */
  core.String href;

  /** Value is "analytics#webproperty". */
  core.String type;


  ProfileParentLink();

  ProfileParentLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Permissions the user has for this view (profile). */
class ProfilePermissions {
  /**
   * All the permissions that the user has for this view (profile). These
   * include any implied permissions (e.g., EDIT implies VIEW) or inherited
   * permissions from the parent web property.
   */
  core.List<core.String> effective;


  ProfilePermissions();

  ProfilePermissions.fromJson(core.Map _json) {
    if (_json.containsKey("effective")) {
      effective = _json["effective"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (effective != null) {
      _json["effective"] = effective;
    }
    return _json;
  }
}


/** JSON template for an Analytics view (profile). */
class Profile {
  /** Account ID to which this view (profile) belongs. */
  core.String accountId;

  /**
   * Child link for this view (profile). Points to the list of goals for this
   * view (profile).
   */
  ProfileChildLink childLink;

  /** Time this view (profile) was created. */
  core.DateTime created;

  /**
   * The currency type associated with this view (profile). The supported values
   * are:
   * ARS, AUD, BGN, BRL, CAD, CHF, CNY, CZK, DKK, EUR, GBP, HKD, HUF, IDR, INR,
   * JPY, KRW, LTL, MXN, NOK, NZD, PHP, PLN, RUB, SEK, THB, TRY, TWD, USD, VND,
   * ZAR
   */
  core.String currency;

  /** Default page for this view (profile). */
  core.String defaultPage;

  /**
   * Indicates whether ecommerce tracking is enabled for this view (profile).
   */
  core.bool eCommerceTracking;

  /**
   * Indicates whether enhanced ecommerce tracking is enabled for this view
   * (profile).
   */
  core.bool enhancedECommerceTracking;

  /** The query parameters that are excluded from this view (profile). */
  core.String excludeQueryParameters;

  /** View (Profile) ID. */
  core.String id;

  /** Internal ID for the web property to which this view (profile) belongs. */
  core.String internalWebPropertyId;

  /** Resource type for Analytics view (profile). */
  core.String kind;

  /** Name of this view (profile). */
  core.String name;

  /**
   * Parent link for this view (profile). Points to the web property to which
   * this view (profile) belongs.
   */
  ProfileParentLink parentLink;

  /** Permissions the user has for this view (profile). */
  ProfilePermissions permissions;

  /** Link for this view (profile). */
  core.String selfLink;

  /** Site search category parameters for this view (profile). */
  core.String siteSearchCategoryParameters;

  /** The site search query parameters for this view (profile). */
  core.String siteSearchQueryParameters;

  /**
   * Whether or not Analytics will strip search category parameters from the
   * URLs in your reports.
   */
  core.bool stripSiteSearchCategoryParameters;

  /**
   * Whether or not Analytics will strip search query parameters from the URLs
   * in your reports.
   */
  core.bool stripSiteSearchQueryParameters;

  /**
   * Time zone for which this view (profile) has been configured. Time zones are
   * identified by strings from the TZ database.
   */
  core.String timezone;

  /** View (Profile) type. Supported types: WEB or APP. */
  core.String type;

  /** Time this view (profile) was last modified. */
  core.DateTime updated;

  /**
   * Web property ID of the form UA-XXXXX-YY to which this view (profile)
   * belongs.
   */
  core.String webPropertyId;

  /** Website URL for this view (profile). */
  core.String websiteUrl;


  Profile();

  Profile.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("childLink")) {
      childLink = new ProfileChildLink.fromJson(_json["childLink"]);
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("currency")) {
      currency = _json["currency"];
    }
    if (_json.containsKey("defaultPage")) {
      defaultPage = _json["defaultPage"];
    }
    if (_json.containsKey("eCommerceTracking")) {
      eCommerceTracking = _json["eCommerceTracking"];
    }
    if (_json.containsKey("enhancedECommerceTracking")) {
      enhancedECommerceTracking = _json["enhancedECommerceTracking"];
    }
    if (_json.containsKey("excludeQueryParameters")) {
      excludeQueryParameters = _json["excludeQueryParameters"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("parentLink")) {
      parentLink = new ProfileParentLink.fromJson(_json["parentLink"]);
    }
    if (_json.containsKey("permissions")) {
      permissions = new ProfilePermissions.fromJson(_json["permissions"]);
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("siteSearchCategoryParameters")) {
      siteSearchCategoryParameters = _json["siteSearchCategoryParameters"];
    }
    if (_json.containsKey("siteSearchQueryParameters")) {
      siteSearchQueryParameters = _json["siteSearchQueryParameters"];
    }
    if (_json.containsKey("stripSiteSearchCategoryParameters")) {
      stripSiteSearchCategoryParameters = _json["stripSiteSearchCategoryParameters"];
    }
    if (_json.containsKey("stripSiteSearchQueryParameters")) {
      stripSiteSearchQueryParameters = _json["stripSiteSearchQueryParameters"];
    }
    if (_json.containsKey("timezone")) {
      timezone = _json["timezone"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
    if (_json.containsKey("websiteUrl")) {
      websiteUrl = _json["websiteUrl"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (childLink != null) {
      _json["childLink"] = (childLink).toJson();
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (currency != null) {
      _json["currency"] = currency;
    }
    if (defaultPage != null) {
      _json["defaultPage"] = defaultPage;
    }
    if (eCommerceTracking != null) {
      _json["eCommerceTracking"] = eCommerceTracking;
    }
    if (enhancedECommerceTracking != null) {
      _json["enhancedECommerceTracking"] = enhancedECommerceTracking;
    }
    if (excludeQueryParameters != null) {
      _json["excludeQueryParameters"] = excludeQueryParameters;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (parentLink != null) {
      _json["parentLink"] = (parentLink).toJson();
    }
    if (permissions != null) {
      _json["permissions"] = (permissions).toJson();
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (siteSearchCategoryParameters != null) {
      _json["siteSearchCategoryParameters"] = siteSearchCategoryParameters;
    }
    if (siteSearchQueryParameters != null) {
      _json["siteSearchQueryParameters"] = siteSearchQueryParameters;
    }
    if (stripSiteSearchCategoryParameters != null) {
      _json["stripSiteSearchCategoryParameters"] = stripSiteSearchCategoryParameters;
    }
    if (stripSiteSearchQueryParameters != null) {
      _json["stripSiteSearchQueryParameters"] = stripSiteSearchQueryParameters;
    }
    if (timezone != null) {
      _json["timezone"] = timezone;
    }
    if (type != null) {
      _json["type"] = type;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    if (websiteUrl != null) {
      _json["websiteUrl"] = websiteUrl;
    }
    return _json;
  }
}


/** JSON template for an Analytics profile filter link. */
class ProfileFilterLink {
  /** Filter for this link. */
  FilterRef filterRef;

  /** Profile filter link ID. */
  core.String id;

  /** Resource type for Analytics filter. */
  core.String kind;

  /** View (Profile) for this link. */
  ProfileRef profileRef;

  /**
   * The rank of this profile filter link relative to the other filters linked
   * to the same profile.
   * For readonly (i.e., list and get) operations, the rank always starts at 1.
   * For write (i.e., create, update, or delete) operations, you may specify a
   * value between 0 and 255 inclusively, [0, 255]. In order to insert a link at
   * the end of the list, either don't specify a rank or set a rank to a number
   * greater than the largest rank in the list. In order to insert a link to the
   * beginning of the list specify a rank that is less than or equal to 1. The
   * new link will move all existing filters with the same or lower rank down
   * the list. After the link is inserted/updated/deleted all profile filter
   * links will be renumbered starting at 1.
   */
  core.int rank;

  /** Link for this profile filter link. */
  core.String selfLink;


  ProfileFilterLink();

  ProfileFilterLink.fromJson(core.Map _json) {
    if (_json.containsKey("filterRef")) {
      filterRef = new FilterRef.fromJson(_json["filterRef"]);
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("profileRef")) {
      profileRef = new ProfileRef.fromJson(_json["profileRef"]);
    }
    if (_json.containsKey("rank")) {
      rank = _json["rank"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (filterRef != null) {
      _json["filterRef"] = (filterRef).toJson();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (profileRef != null) {
      _json["profileRef"] = (profileRef).toJson();
    }
    if (rank != null) {
      _json["rank"] = rank;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    return _json;
  }
}


/**
 * A profile filter link collection lists profile filter links between profiles
 * and filters. Each resource in the collection corresponds to a profile filter
 * link.
 */
class ProfileFilterLinks {
  /** A list of profile filter links. */
  core.List<ProfileFilterLink> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1,000 with
   * a value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this profile filter link collection. */
  core.String nextLink;

  /** Link to previous page for this profile filter link collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  ProfileFilterLinks();

  ProfileFilterLinks.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new ProfileFilterLink.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** JSON template for a linked view (profile). */
class ProfileRef {
  /** Account ID to which this view (profile) belongs. */
  core.String accountId;

  /** Link for this view (profile). */
  core.String href;

  /** View (Profile) ID. */
  core.String id;

  /** Internal ID for the web property to which this view (profile) belongs. */
  core.String internalWebPropertyId;

  /** Analytics view (profile) reference. */
  core.String kind;

  /** Name of this view (profile). */
  core.String name;

  /**
   * Web property ID of the form UA-XXXXX-YY to which this view (profile)
   * belongs.
   */
  core.String webPropertyId;


  ProfileRef();

  ProfileRef.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (href != null) {
      _json["href"] = href;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/**
 * JSON template for an Analytics ProfileSummary. ProfileSummary returns basic
 * information (i.e., summary) for a profile.
 */
class ProfileSummary {
  /** View (profile) ID. */
  core.String id;

  /** Resource type for Analytics ProfileSummary. */
  core.String kind;

  /** View (profile) name. */
  core.String name;

  /** View (Profile) type. Supported types: WEB or APP. */
  core.String type;


  ProfileSummary();

  ProfileSummary.fromJson(core.Map _json) {
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/**
 * A view (profile) collection lists Analytics views (profiles) to which the
 * user has access. Each resource in the collection corresponds to a single
 * Analytics view (profile).
 */
class Profiles {
  /** A list of views (profiles). */
  core.List<Profile> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this view (profile) collection. */
  core.String nextLink;

  /** Link to previous page for this view (profile) collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  Profiles();

  Profiles.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Profile.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** Not documented yet. */
class RealtimeDataColumnHeaders {
  /** Column Type. Either DIMENSION or METRIC. */
  core.String columnType;

  /**
   * Data type. Dimension column headers have only STRING as the data type.
   * Metric column headers have data types for metric values such as INTEGER,
   * DOUBLE, CURRENCY etc.
   */
  core.String dataType;

  /** Column name. */
  core.String name;


  RealtimeDataColumnHeaders();

  RealtimeDataColumnHeaders.fromJson(core.Map _json) {
    if (_json.containsKey("columnType")) {
      columnType = _json["columnType"];
    }
    if (_json.containsKey("dataType")) {
      dataType = _json["dataType"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (columnType != null) {
      _json["columnType"] = columnType;
    }
    if (dataType != null) {
      _json["dataType"] = dataType;
    }
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}


/**
 * Information for the view (profile), for which the real time data was
 * requested.
 */
class RealtimeDataProfileInfo {
  /** Account ID to which this view (profile) belongs. */
  core.String accountId;

  /** Internal ID for the web property to which this view (profile) belongs. */
  core.String internalWebPropertyId;

  /** View (Profile) ID. */
  core.String profileId;

  /** View (Profile) name. */
  core.String profileName;

  /** Table ID for view (profile). */
  core.String tableId;

  /** Web Property ID to which this view (profile) belongs. */
  core.String webPropertyId;


  RealtimeDataProfileInfo();

  RealtimeDataProfileInfo.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("profileId")) {
      profileId = _json["profileId"];
    }
    if (_json.containsKey("profileName")) {
      profileName = _json["profileName"];
    }
    if (_json.containsKey("tableId")) {
      tableId = _json["tableId"];
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (profileId != null) {
      _json["profileId"] = profileId;
    }
    if (profileName != null) {
      _json["profileName"] = profileName;
    }
    if (tableId != null) {
      _json["tableId"] = tableId;
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/** Real time data request query parameters. */
class RealtimeDataQuery {
  /** List of real time dimensions. */
  core.String dimensions;

  /** Comma-separated list of dimension or metric filters. */
  core.String filters;

  /** Unique table ID. */
  core.String ids;

  /** Maximum results per page. */
  core.int max_results;

  /** List of real time metrics. */
  core.List<core.String> metrics;

  /** List of dimensions or metrics based on which real time data is sorted. */
  core.List<core.String> sort;


  RealtimeDataQuery();

  RealtimeDataQuery.fromJson(core.Map _json) {
    if (_json.containsKey("dimensions")) {
      dimensions = _json["dimensions"];
    }
    if (_json.containsKey("filters")) {
      filters = _json["filters"];
    }
    if (_json.containsKey("ids")) {
      ids = _json["ids"];
    }
    if (_json.containsKey("max-results")) {
      max_results = _json["max-results"];
    }
    if (_json.containsKey("metrics")) {
      metrics = _json["metrics"];
    }
    if (_json.containsKey("sort")) {
      sort = _json["sort"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (dimensions != null) {
      _json["dimensions"] = dimensions;
    }
    if (filters != null) {
      _json["filters"] = filters;
    }
    if (ids != null) {
      _json["ids"] = ids;
    }
    if (max_results != null) {
      _json["max-results"] = max_results;
    }
    if (metrics != null) {
      _json["metrics"] = metrics;
    }
    if (sort != null) {
      _json["sort"] = sort;
    }
    return _json;
  }
}


/** Real time data for a given view (profile). */
class RealtimeData {
  /**
   * Column headers that list dimension names followed by the metric names. The
   * order of dimensions and metrics is same as specified in the request.
   */
  core.List<RealtimeDataColumnHeaders> columnHeaders;

  /** Unique ID for this data response. */
  core.String id;

  /** Resource type. */
  core.String kind;

  /**
   * Information for the view (profile), for which the real time data was
   * requested.
   */
  RealtimeDataProfileInfo profileInfo;

  /** Real time data request query parameters. */
  RealtimeDataQuery query;

  /**
   * Real time data rows, where each row contains a list of dimension values
   * followed by the metric values. The order of dimensions and metrics is same
   * as specified in the request.
   */
  core.List<core.List<core.String>> rows;

  /** Link to this page. */
  core.String selfLink;

  /**
   * The total number of rows for the query, regardless of the number of rows in
   * the response.
   */
  core.int totalResults;

  /**
   * Total values for the requested metrics over all the results, not just the
   * results returned in this response. The order of the metric totals is same
   * as the metric order specified in the request.
   */
  core.Map<core.String, core.String> totalsForAllResults;


  RealtimeData();

  RealtimeData.fromJson(core.Map _json) {
    if (_json.containsKey("columnHeaders")) {
      columnHeaders = _json["columnHeaders"].map((value) => new RealtimeDataColumnHeaders.fromJson(value)).toList();
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("profileInfo")) {
      profileInfo = new RealtimeDataProfileInfo.fromJson(_json["profileInfo"]);
    }
    if (_json.containsKey("query")) {
      query = new RealtimeDataQuery.fromJson(_json["query"]);
    }
    if (_json.containsKey("rows")) {
      rows = _json["rows"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("totalsForAllResults")) {
      totalsForAllResults = _json["totalsForAllResults"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (columnHeaders != null) {
      _json["columnHeaders"] = columnHeaders.map((value) => (value).toJson()).toList();
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (profileInfo != null) {
      _json["profileInfo"] = (profileInfo).toJson();
    }
    if (query != null) {
      _json["query"] = (query).toJson();
    }
    if (rows != null) {
      _json["rows"] = rows;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (totalsForAllResults != null) {
      _json["totalsForAllResults"] = totalsForAllResults;
    }
    return _json;
  }
}


/** JSON template for an Analytics segment. */
class Segment {
  /** Time the segment was created. */
  core.DateTime created;

  /** Segment definition. */
  core.String definition;

  /** Segment ID. */
  core.String id;

  /** Resource type for Analytics segment. */
  core.String kind;

  /** Segment name. */
  core.String name;

  /**
   * Segment ID. Can be used with the 'segment' parameter in Core Reporting API.
   */
  core.String segmentId;

  /** Link for this segment. */
  core.String selfLink;

  /** Type for a segment. Possible values are "BUILT_IN" or "CUSTOM". */
  core.String type;

  /** Time the segment was last modified. */
  core.DateTime updated;


  Segment();

  Segment.fromJson(core.Map _json) {
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("definition")) {
      definition = _json["definition"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("segmentId")) {
      segmentId = _json["segmentId"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (definition != null) {
      _json["definition"] = definition;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (segmentId != null) {
      _json["segmentId"] = segmentId;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (type != null) {
      _json["type"] = type;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    return _json;
  }
}


/**
 * An segment collection lists Analytics segments that the user has access to.
 * Each resource in the collection corresponds to a single Analytics segment.
 */
class Segments {
  /** A list of segments. */
  core.List<Segment> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type for segments. */
  core.String kind;

  /** Link to next page for this segment collection. */
  core.String nextLink;

  /** Link to previous page for this segment collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  Segments();

  Segments.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Segment.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** Download details for a file stored in Google Cloud Storage. */
class UnsampledReportCloudStorageDownloadDetails {
  /** Id of the bucket the file object is stored in. */
  core.String bucketId;

  /** Id of the file object containing the report data. */
  core.String objectId;


  UnsampledReportCloudStorageDownloadDetails();

  UnsampledReportCloudStorageDownloadDetails.fromJson(core.Map _json) {
    if (_json.containsKey("bucketId")) {
      bucketId = _json["bucketId"];
    }
    if (_json.containsKey("objectId")) {
      objectId = _json["objectId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (bucketId != null) {
      _json["bucketId"] = bucketId;
    }
    if (objectId != null) {
      _json["objectId"] = objectId;
    }
    return _json;
  }
}


/** Download details for a file stored in Google Drive. */
class UnsampledReportDriveDownloadDetails {
  /** Id of the document/file containing the report data. */
  core.String documentId;


  UnsampledReportDriveDownloadDetails();

  UnsampledReportDriveDownloadDetails.fromJson(core.Map _json) {
    if (_json.containsKey("documentId")) {
      documentId = _json["documentId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (documentId != null) {
      _json["documentId"] = documentId;
    }
    return _json;
  }
}


/** JSON template for Analytics unsampled report resource. */
class UnsampledReport {
  /** Account ID to which this unsampled report belongs. */
  core.String accountId;

  /** Download details for a file stored in Google Cloud Storage. */
  UnsampledReportCloudStorageDownloadDetails cloudStorageDownloadDetails;

  /** Time this unsampled report was created. */
  core.DateTime created;

  /** The dimensions for the unsampled report. */
  core.String dimensions;

  /** The type of download you need to use for the report data file. */
  core.String downloadType;

  /** Download details for a file stored in Google Drive. */
  UnsampledReportDriveDownloadDetails driveDownloadDetails;

  /** The end date for the unsampled report. */
  core.String end_date;

  /** The filters for the unsampled report. */
  core.String filters;

  /** Unsampled report ID. */
  core.String id;

  /** Resource type for an Analytics unsampled report. */
  core.String kind;

  /** The metrics for the unsampled report. */
  core.String metrics;

  /** View (Profile) ID to which this unsampled report belongs. */
  core.String profileId;

  /** The segment for the unsampled report. */
  core.String segment;

  /** Link for this unsampled report. */
  core.String selfLink;

  /** The start date for the unsampled report. */
  core.String start_date;

  /**
   * Status of this unsampled report. Possible values are PENDING, COMPLETED, or
   * FAILED.
   */
  core.String status;

  /** Title of the unsampled report. */
  core.String title;

  /** Time this unsampled report was last modified. */
  core.DateTime updated;

  /**
   * Web property ID to which this unsampled report belongs. The web property ID
   * is of the form UA-XXXXX-YY.
   */
  core.String webPropertyId;


  UnsampledReport();

  UnsampledReport.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("cloudStorageDownloadDetails")) {
      cloudStorageDownloadDetails = new UnsampledReportCloudStorageDownloadDetails.fromJson(_json["cloudStorageDownloadDetails"]);
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("dimensions")) {
      dimensions = _json["dimensions"];
    }
    if (_json.containsKey("downloadType")) {
      downloadType = _json["downloadType"];
    }
    if (_json.containsKey("driveDownloadDetails")) {
      driveDownloadDetails = new UnsampledReportDriveDownloadDetails.fromJson(_json["driveDownloadDetails"]);
    }
    if (_json.containsKey("end-date")) {
      end_date = _json["end-date"];
    }
    if (_json.containsKey("filters")) {
      filters = _json["filters"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("metrics")) {
      metrics = _json["metrics"];
    }
    if (_json.containsKey("profileId")) {
      profileId = _json["profileId"];
    }
    if (_json.containsKey("segment")) {
      segment = _json["segment"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("start-date")) {
      start_date = _json["start-date"];
    }
    if (_json.containsKey("status")) {
      status = _json["status"];
    }
    if (_json.containsKey("title")) {
      title = _json["title"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
    if (_json.containsKey("webPropertyId")) {
      webPropertyId = _json["webPropertyId"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (cloudStorageDownloadDetails != null) {
      _json["cloudStorageDownloadDetails"] = (cloudStorageDownloadDetails).toJson();
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (dimensions != null) {
      _json["dimensions"] = dimensions;
    }
    if (downloadType != null) {
      _json["downloadType"] = downloadType;
    }
    if (driveDownloadDetails != null) {
      _json["driveDownloadDetails"] = (driveDownloadDetails).toJson();
    }
    if (end_date != null) {
      _json["end-date"] = end_date;
    }
    if (filters != null) {
      _json["filters"] = filters;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (metrics != null) {
      _json["metrics"] = metrics;
    }
    if (profileId != null) {
      _json["profileId"] = profileId;
    }
    if (segment != null) {
      _json["segment"] = segment;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (start_date != null) {
      _json["start-date"] = start_date;
    }
    if (status != null) {
      _json["status"] = status;
    }
    if (title != null) {
      _json["title"] = title;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    if (webPropertyId != null) {
      _json["webPropertyId"] = webPropertyId;
    }
    return _json;
  }
}


/**
 * An unsampled report collection lists Analytics unsampled reports to which the
 * user has access. Each view (profile) can have a set of unsampled reports.
 * Each resource in the unsampled report collection corresponds to a single
 * Analytics unsampled report.
 */
class UnsampledReports {
  /** A list of unsampled reports. */
  core.List<UnsampledReport> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this unsampled report collection. */
  core.String nextLink;

  /** Link to previous page for this unsampled report collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * resources in the result.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  UnsampledReports();

  UnsampledReports.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new UnsampledReport.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/** Metadata returned for an upload operation. */
class Upload {
  /** Account Id to which this upload belongs. */
  core.String accountId;

  /** Custom data source Id to which this data import belongs. */
  core.String customDataSourceId;

  /** Data import errors collection. */
  core.List<core.String> errors;

  /** A unique ID for this upload. */
  core.String id;

  /** Resource type for Analytics upload. */
  core.String kind;

  /**
   * Upload status. Possible values: PENDING, COMPLETED, FAILED, DELETING,
   * DELETED.
   */
  core.String status;


  Upload();

  Upload.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("customDataSourceId")) {
      customDataSourceId = _json["customDataSourceId"];
    }
    if (_json.containsKey("errors")) {
      errors = _json["errors"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("status")) {
      status = _json["status"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (customDataSourceId != null) {
      _json["customDataSourceId"] = customDataSourceId;
    }
    if (errors != null) {
      _json["errors"] = errors;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (status != null) {
      _json["status"] = status;
    }
    return _json;
  }
}


/**
 * Upload collection lists Analytics uploads to which the user has access. Each
 * custom data source can have a set of uploads. Each resource in the upload
 * collection corresponds to a single Analytics data upload.
 */
class Uploads {
  /** A list of uploads. */
  core.List<Upload> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this upload collection. */
  core.String nextLink;

  /** Link to previous page for this upload collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * resources in the result.
   */
  core.int totalResults;


  Uploads();

  Uploads.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Upload.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    return _json;
  }
}


/** JSON template for a user reference. */
class UserRef {
  /** Email ID of this user. */
  core.String email;

  /** User ID. */
  core.String id;

  /** Not documented yet. */
  core.String kind;


  UserRef();

  UserRef.fromJson(core.Map _json) {
    if (_json.containsKey("email")) {
      email = _json["email"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (email != null) {
      _json["email"] = email;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    return _json;
  }
}


/** JSON template for a web property reference. */
class WebPropertyRef {
  /** Account ID to which this web property belongs. */
  core.String accountId;

  /** Link for this web property. */
  core.String href;

  /** Web property ID of the form UA-XXXXX-YY. */
  core.String id;

  /** Internal ID for this web property. */
  core.String internalWebPropertyId;

  /** Analytics web property reference. */
  core.String kind;

  /** Name of this web property. */
  core.String name;


  WebPropertyRef();

  WebPropertyRef.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (href != null) {
      _json["href"] = href;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (name != null) {
      _json["name"] = name;
    }
    return _json;
  }
}


/**
 * JSON template for an Analytics WebPropertySummary. WebPropertySummary returns
 * basic information (i.e., summary) for a web property.
 */
class WebPropertySummary {
  /** Web property ID of the form UA-XXXXX-YY. */
  core.String id;

  /** Internal ID for this web property. */
  core.String internalWebPropertyId;

  /** Resource type for Analytics WebPropertySummary. */
  core.String kind;

  /** Level for this web property. Possible values are STANDARD or PREMIUM. */
  core.String level;

  /** Web property name. */
  core.String name;

  /** List of profiles under this web property. */
  core.List<ProfileSummary> profiles;

  /** Website url for this web property. */
  core.String websiteUrl;


  WebPropertySummary();

  WebPropertySummary.fromJson(core.Map _json) {
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("level")) {
      level = _json["level"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("profiles")) {
      profiles = _json["profiles"].map((value) => new ProfileSummary.fromJson(value)).toList();
    }
    if (_json.containsKey("websiteUrl")) {
      websiteUrl = _json["websiteUrl"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (id != null) {
      _json["id"] = id;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (level != null) {
      _json["level"] = level;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (profiles != null) {
      _json["profiles"] = profiles.map((value) => (value).toJson()).toList();
    }
    if (websiteUrl != null) {
      _json["websiteUrl"] = websiteUrl;
    }
    return _json;
  }
}


/**
 * A web property collection lists Analytics web properties to which the user
 * has access. Each resource in the collection corresponds to a single Analytics
 * web property.
 */
class Webproperties {
  /** A list of web properties. */
  core.List<Webproperty> items;

  /**
   * The maximum number of resources the response can contain, regardless of the
   * actual number of resources returned. Its value ranges from 1 to 1000 with a
   * value of 1000 by default, or otherwise specified by the max-results query
   * parameter.
   */
  core.int itemsPerPage;

  /** Collection type. */
  core.String kind;

  /** Link to next page for this web property collection. */
  core.String nextLink;

  /** Link to previous page for this web property collection. */
  core.String previousLink;

  /**
   * The starting index of the resources, which is 1 by default or otherwise
   * specified by the start-index query parameter.
   */
  core.int startIndex;

  /**
   * The total number of results for the query, regardless of the number of
   * results in the response.
   */
  core.int totalResults;

  /** Email ID of the authenticated user */
  core.String username;


  Webproperties();

  Webproperties.fromJson(core.Map _json) {
    if (_json.containsKey("items")) {
      items = _json["items"].map((value) => new Webproperty.fromJson(value)).toList();
    }
    if (_json.containsKey("itemsPerPage")) {
      itemsPerPage = _json["itemsPerPage"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("nextLink")) {
      nextLink = _json["nextLink"];
    }
    if (_json.containsKey("previousLink")) {
      previousLink = _json["previousLink"];
    }
    if (_json.containsKey("startIndex")) {
      startIndex = _json["startIndex"];
    }
    if (_json.containsKey("totalResults")) {
      totalResults = _json["totalResults"];
    }
    if (_json.containsKey("username")) {
      username = _json["username"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (items != null) {
      _json["items"] = items.map((value) => (value).toJson()).toList();
    }
    if (itemsPerPage != null) {
      _json["itemsPerPage"] = itemsPerPage;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (nextLink != null) {
      _json["nextLink"] = nextLink;
    }
    if (previousLink != null) {
      _json["previousLink"] = previousLink;
    }
    if (startIndex != null) {
      _json["startIndex"] = startIndex;
    }
    if (totalResults != null) {
      _json["totalResults"] = totalResults;
    }
    if (username != null) {
      _json["username"] = username;
    }
    return _json;
  }
}


/**
 * Child link for this web property. Points to the list of views (profiles) for
 * this web property.
 */
class WebpropertyChildLink {
  /** Link to the list of views (profiles) for this web property. */
  core.String href;

  /** Type of the parent link. Its value is "analytics#profiles". */
  core.String type;


  WebpropertyChildLink();

  WebpropertyChildLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/**
 * Parent link for this web property. Points to the account to which this web
 * property belongs.
 */
class WebpropertyParentLink {
  /** Link to the account for this web property. */
  core.String href;

  /** Type of the parent link. Its value is "analytics#account". */
  core.String type;


  WebpropertyParentLink();

  WebpropertyParentLink.fromJson(core.Map _json) {
    if (_json.containsKey("href")) {
      href = _json["href"];
    }
    if (_json.containsKey("type")) {
      type = _json["type"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (href != null) {
      _json["href"] = href;
    }
    if (type != null) {
      _json["type"] = type;
    }
    return _json;
  }
}


/** Permissions the user has for this web property. */
class WebpropertyPermissions {
  /**
   * All the permissions that the user has for this web property. These include
   * any implied permissions (e.g., EDIT implies VIEW) or inherited permissions
   * from the parent account.
   */
  core.List<core.String> effective;


  WebpropertyPermissions();

  WebpropertyPermissions.fromJson(core.Map _json) {
    if (_json.containsKey("effective")) {
      effective = _json["effective"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (effective != null) {
      _json["effective"] = effective;
    }
    return _json;
  }
}


/** JSON template for an Analytics web property. */
class Webproperty {
  /** Account ID to which this web property belongs. */
  core.String accountId;

  /**
   * Child link for this web property. Points to the list of views (profiles)
   * for this web property.
   */
  WebpropertyChildLink childLink;

  /** Time this web property was created. */
  core.DateTime created;

  /** Default view (profile) ID. */
  core.String defaultProfileId;

  /** Web property ID of the form UA-XXXXX-YY. */
  core.String id;

  /** The industry vertical/category selected for this web property. */
  core.String industryVertical;

  /** Internal ID for this web property. */
  core.String internalWebPropertyId;

  /** Resource type for Analytics WebProperty. */
  core.String kind;

  /** Level for this web property. Possible values are STANDARD or PREMIUM. */
  core.String level;

  /** Name of this web property. */
  core.String name;

  /**
   * Parent link for this web property. Points to the account to which this web
   * property belongs.
   */
  WebpropertyParentLink parentLink;

  /** Permissions the user has for this web property. */
  WebpropertyPermissions permissions;

  /** View (Profile) count for this web property. */
  core.int profileCount;

  /** Link for this web property. */
  core.String selfLink;

  /** Time this web property was last modified. */
  core.DateTime updated;

  /** Website url for this web property. */
  core.String websiteUrl;


  Webproperty();

  Webproperty.fromJson(core.Map _json) {
    if (_json.containsKey("accountId")) {
      accountId = _json["accountId"];
    }
    if (_json.containsKey("childLink")) {
      childLink = new WebpropertyChildLink.fromJson(_json["childLink"]);
    }
    if (_json.containsKey("created")) {
      created = core.DateTime.parse(_json["created"]);
    }
    if (_json.containsKey("defaultProfileId")) {
      defaultProfileId = _json["defaultProfileId"];
    }
    if (_json.containsKey("id")) {
      id = _json["id"];
    }
    if (_json.containsKey("industryVertical")) {
      industryVertical = _json["industryVertical"];
    }
    if (_json.containsKey("internalWebPropertyId")) {
      internalWebPropertyId = _json["internalWebPropertyId"];
    }
    if (_json.containsKey("kind")) {
      kind = _json["kind"];
    }
    if (_json.containsKey("level")) {
      level = _json["level"];
    }
    if (_json.containsKey("name")) {
      name = _json["name"];
    }
    if (_json.containsKey("parentLink")) {
      parentLink = new WebpropertyParentLink.fromJson(_json["parentLink"]);
    }
    if (_json.containsKey("permissions")) {
      permissions = new WebpropertyPermissions.fromJson(_json["permissions"]);
    }
    if (_json.containsKey("profileCount")) {
      profileCount = _json["profileCount"];
    }
    if (_json.containsKey("selfLink")) {
      selfLink = _json["selfLink"];
    }
    if (_json.containsKey("updated")) {
      updated = core.DateTime.parse(_json["updated"]);
    }
    if (_json.containsKey("websiteUrl")) {
      websiteUrl = _json["websiteUrl"];
    }
  }

  core.Map toJson() {
    var _json = new core.Map();
    if (accountId != null) {
      _json["accountId"] = accountId;
    }
    if (childLink != null) {
      _json["childLink"] = (childLink).toJson();
    }
    if (created != null) {
      _json["created"] = (created).toIso8601String();
    }
    if (defaultProfileId != null) {
      _json["defaultProfileId"] = defaultProfileId;
    }
    if (id != null) {
      _json["id"] = id;
    }
    if (industryVertical != null) {
      _json["industryVertical"] = industryVertical;
    }
    if (internalWebPropertyId != null) {
      _json["internalWebPropertyId"] = internalWebPropertyId;
    }
    if (kind != null) {
      _json["kind"] = kind;
    }
    if (level != null) {
      _json["level"] = level;
    }
    if (name != null) {
      _json["name"] = name;
    }
    if (parentLink != null) {
      _json["parentLink"] = (parentLink).toJson();
    }
    if (permissions != null) {
      _json["permissions"] = (permissions).toJson();
    }
    if (profileCount != null) {
      _json["profileCount"] = profileCount;
    }
    if (selfLink != null) {
      _json["selfLink"] = selfLink;
    }
    if (updated != null) {
      _json["updated"] = (updated).toIso8601String();
    }
    if (websiteUrl != null) {
      _json["websiteUrl"] = websiteUrl;
    }
    return _json;
  }
}


